import { useState, useEffect, useRef } from 'react' import L from 'leaflet' import 'leaflet/dist/leaflet.css' type AssetsTab = 'management' | 'upload' | 'theory' | 'insurance' // ── Mock Data ── interface AssetOrg { id: number type: string jurisdiction: string area: string name: string address: string vessel: number skimmer: number pump: number vehicle: number sprayer: number totalAssets: number phone: string lat: number lng: number pinSize: 'hq' | 'lg' | 'md' equipment: { category: string; icon: string; count: number }[] contacts: { role: string; name: string; phone: string }[] } const organizations: AssetOrg[] = [ // ── 중부지방해양경찰청 ── { id: 1, type: '해경관할', jurisdiction: '중부지방해양경찰청', area: '인천', name: '인천해양경찰서', address: '인천광역시 중구 북성동1가 80-8', vessel: 19, skimmer: 30, pump: 18, vehicle: 2, sprayer: 15, totalAssets: 234, phone: '010-4779-4191', lat: 37.4563, lng: 126.5922, pinSize: 'hq', equipment: [ { category: '방제선', icon: '🚢', count: 19 }, { category: '유회수기', icon: '⚙', count: 30 }, { category: '비치크리너', icon: '🏖', count: 2 }, { category: '이송펌프', icon: '🔧', count: 18 }, { category: '방제차량', icon: '🚛', count: 2 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 26 }, { category: '저압세척기', icon: '🚿', count: 3 }, { category: '동력분무기', icon: '💨', count: 14 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 19 }, { category: '발전기', icon: '⚡', count: 9 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 9 }, { category: '장비부품', icon: '🔗', count: 46 }, { category: '경비함정방제', icon: '⚓', count: 18 }, { category: '살포장치', icon: '🌊', count: 15 }, ], contacts: [{ role: '방제과장', name: '김○○', phone: '032-835-0001' }, { role: '방제담당', name: '이○○', phone: '032-835-0002' }], }, { id: 2, type: '해경경찰서', jurisdiction: '중부지방해양경찰청', area: '평택', name: '평택해양경찰서', address: '평택시 만호리 706번지', vessel: 14, skimmer: 27, pump: 33, vehicle: 3, sprayer: 22, totalAssets: 193, phone: '010-9812-8102', lat: 36.9694, lng: 126.8300, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 14 }, { category: '유회수기', icon: '⚙', count: 27 }, { category: '비치크리너', icon: '🏖', count: 1 }, { category: '이송펌프', icon: '🔧', count: 33 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 12 }, { category: '저압세척기', icon: '🚿', count: 5 }, { category: '동력분무기', icon: '💨', count: 2 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 35 }, { category: '발전기', icon: '⚡', count: 9 }, { category: '지원장비', icon: '🔩', count: 10 }, { category: '장비부품', icon: '🔗', count: 4 }, { category: '경비함정방제', icon: '⚓', count: 14 }, { category: '살포장치', icon: '🌊', count: 22 }, ], contacts: [{ role: '방제담당', name: '박○○', phone: '031-682-0001' }], }, { id: 3, type: '해경경찰서', jurisdiction: '중부지방해양경찰청', area: '태안', name: '태안해양경찰서', address: '충남 태안군 근흥면 신진부두길2', vessel: 10, skimmer: 27, pump: 21, vehicle: 8, sprayer: 15, totalAssets: 185, phone: '010-2965-4423', lat: 36.7456, lng: 126.2978, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 10 }, { category: '유회수기', icon: '⚙', count: 27 }, { category: '비치크리너', icon: '🏖', count: 4 }, { category: '이송펌프', icon: '🔧', count: 21 }, { category: '방제차량', icon: '🚛', count: 8 }, { category: '해안운반차', icon: '🚜', count: 8 }, { category: '고압세척기', icon: '💧', count: 14 }, { category: '저압세척기', icon: '🚿', count: 8 }, { category: '동력분무기', icon: '💨', count: 6 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 28 }, { category: '발전기', icon: '⚡', count: 11 }, { category: '지원장비', icon: '🔩', count: 16 }, { category: '경비함정방제', icon: '⚓', count: 8 }, { category: '살포장치', icon: '🌊', count: 15 }, ], contacts: [{ role: '방제담당', name: '최○○', phone: '041-674-0001' }], }, { id: 4, type: '파출소', jurisdiction: '중부지방해양경찰청', area: '보령', name: '보령해양경찰서', address: '보령시 해안로 740', vessel: 3, skimmer: 8, pump: 5, vehicle: 3, sprayer: 11, totalAssets: 80, phone: '010-2940-6343', lat: 36.3335, lng: 126.5874, pinSize: 'md', equipment: [ { category: '방제선', icon: '🚢', count: 3 }, { category: '유회수기', icon: '⚙', count: 8 }, { category: '이송펌프', icon: '🔧', count: 5 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 22 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '지원장비', icon: '🔩', count: 6 }, { category: '장비부품', icon: '🔗', count: 4 }, { category: '경비함정방제', icon: '⚓', count: 6 }, { category: '살포장치', icon: '🌊', count: 11 }, ], contacts: [{ role: '방제담당', name: '정○○', phone: '041-931-0001' }], }, // ── 서해지방해양경찰청 ── { id: 5, type: '해경관할', jurisdiction: '서해지방해양경찰청', area: '여수', name: '여수해양경찰서', address: '광양시 항만9로 89', vessel: 55, skimmer: 92, pump: 63, vehicle: 12, sprayer: 47, totalAssets: 464, phone: '010-2785-2493', lat: 34.7407, lng: 127.7385, pinSize: 'hq', equipment: [ { category: '방제선', icon: '🚢', count: 55 }, { category: '유회수기', icon: '⚙', count: 92 }, { category: '비치크리너', icon: '🏖', count: 5 }, { category: '이송펌프', icon: '🔧', count: 63 }, { category: '방제차량', icon: '🚛', count: 12 }, { category: '해안운반차', icon: '🚜', count: 4 }, { category: '고압세척기', icon: '💧', count: 48 }, { category: '저압세척기', icon: '🚿', count: 7 }, { category: '동력분무기', icon: '💨', count: 25 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 37 }, { category: '발전기', icon: '⚡', count: 16 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 14 }, { category: '장비부품', icon: '🔗', count: 14 }, { category: '경비함정방제', icon: '⚓', count: 22 }, { category: '살포장치', icon: '🌊', count: 47 }, ], contacts: [{ role: '방제과장', name: '윤○○', phone: '061-660-0001' }, { role: '방제담당', name: '장○○', phone: '061-660-0002' }], }, { id: 6, type: '해경경찰서', jurisdiction: '서해지방해양경찰청', area: '목포', name: '목포해양경찰서', address: '목포시 고하대로 597번길 99-64', vessel: 10, skimmer: 19, pump: 18, vehicle: 3, sprayer: 16, totalAssets: 169, phone: '010-9812-8439', lat: 34.7936, lng: 126.3839, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 10 }, { category: '유회수기', icon: '⚙', count: 19 }, { category: '이송펌프', icon: '🔧', count: 18 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 7 }, { category: '저압세척기', icon: '🚿', count: 4 }, { category: '동력분무기', icon: '💨', count: 2 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 21 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '지원장비', icon: '🔩', count: 31 }, { category: '장비부품', icon: '🔗', count: 17 }, { category: '경비함정방제', icon: '⚓', count: 15 }, { category: '살포장치', icon: '🌊', count: 16 }, ], contacts: [{ role: '방제담당', name: '조○○', phone: '061-244-0001' }], }, { id: 7, type: '해경경찰서', jurisdiction: '서해지방해양경찰청', area: '군산', name: '군산해양경찰서', address: '전북 군산시 오식도동 506', vessel: 6, skimmer: 22, pump: 12, vehicle: 3, sprayer: 17, totalAssets: 155, phone: '010-2618-3406', lat: 35.9900, lng: 126.7133, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 6 }, { category: '유회수기', icon: '⚙', count: 22 }, { category: '비치크리너', icon: '🏖', count: 2 }, { category: '이송펌프', icon: '🔧', count: 12 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 4 }, { category: '동력분무기', icon: '💨', count: 2 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 6 }, { category: '발전기', icon: '⚡', count: 5 }, { category: '현장지휘소', icon: '🏕', count: 3 }, { category: '지원장비', icon: '🔩', count: 11 }, { category: '장비부품', icon: '🔗', count: 50 }, { category: '경비함정방제', icon: '⚓', count: 5 }, { category: '살포장치', icon: '🌊', count: 17 }, ], contacts: [{ role: '방제담당', name: '한○○', phone: '063-462-0001' }], }, { id: 8, type: '해경경찰서', jurisdiction: '서해지방해양경찰청', area: '완도', name: '완도해양경찰서', address: '완도군 완도읍 장보고대로 383', vessel: 3, skimmer: 9, pump: 7, vehicle: 3, sprayer: 11, totalAssets: 75, phone: '061-550-2183', lat: 34.3110, lng: 126.7550, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 3 }, { category: '유회수기', icon: '⚙', count: 9 }, { category: '이송펌프', icon: '🔧', count: 7 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 24 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '경비함정방제', icon: '⚓', count: 8 }, { category: '살포장치', icon: '🌊', count: 11 }, ], contacts: [{ role: '방제담당', name: '이○○', phone: '061-550-0001' }], }, { id: 9, type: '파출소', jurisdiction: '서해지방해양경찰청', area: '부안', name: '부안해양경찰서', address: '전북 군산시 오식도동 506', vessel: 2, skimmer: 8, pump: 7, vehicle: 2, sprayer: 7, totalAssets: 66, phone: '063-928-xxxx', lat: 35.7316, lng: 126.7328, pinSize: 'md', equipment: [ { category: '방제선', icon: '🚢', count: 2 }, { category: '유회수기', icon: '⚙', count: 8 }, { category: '이송펌프', icon: '🔧', count: 7 }, { category: '방제차량', icon: '🚛', count: 2 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 2 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 15 }, { category: '발전기', icon: '⚡', count: 3 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 6 }, { category: '경비함정방제', icon: '⚓', count: 7 }, { category: '살포장치', icon: '🌊', count: 7 }, ], contacts: [{ role: '방제담당', name: '김○○', phone: '063-928-0001' }], }, // ── 남해지방해양경찰청 ── { id: 10, type: '해경관할', jurisdiction: '남해지방해양경찰청', area: '부산', name: '부산해양경찰서', address: '부산시 영도구 해양로 293', vessel: 108, skimmer: 22, pump: 25, vehicle: 10, sprayer: 24, totalAssets: 313, phone: '010-2609-1456', lat: 35.0746, lng: 129.0686, pinSize: 'hq', equipment: [ { category: '방제선', icon: '🚢', count: 108 }, { category: '유회수기', icon: '⚙', count: 22 }, { category: '이송펌프', icon: '🔧', count: 25 }, { category: '방제차량', icon: '🚛', count: 10 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 38 }, { category: '저압세척기', icon: '🚿', count: 8 }, { category: '동력분무기', icon: '💨', count: 6 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 21 }, { category: '발전기', icon: '⚡', count: 11 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 20 }, { category: '경비함정방제', icon: '⚓', count: 16 }, { category: '살포장치', icon: '🌊', count: 24 }, ], contacts: [{ role: '방제과장', name: '임○○', phone: '051-400-0001' }], }, { id: 11, type: '해경관할', jurisdiction: '남해지방해양경찰청', area: '울산', name: '울산해양경찰서', address: '울산광역시 남구 장생포 고래로 166', vessel: 46, skimmer: 69, pump: 26, vehicle: 11, sprayer: 20, totalAssets: 311, phone: '010-9812-8210', lat: 35.5008, lng: 129.3824, pinSize: 'hq', equipment: [ { category: '방제선', icon: '🚢', count: 46 }, { category: '유회수기', icon: '⚙', count: 69 }, { category: '비치크리너', icon: '🏖', count: 4 }, { category: '이송펌프', icon: '🔧', count: 26 }, { category: '방제차량', icon: '🚛', count: 11 }, { category: '해안운반차', icon: '🚜', count: 5 }, { category: '고압세척기', icon: '💧', count: 23 }, { category: '저압세척기', icon: '🚿', count: 6 }, { category: '동력분무기', icon: '💨', count: 6 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 32 }, { category: '발전기', icon: '⚡', count: 7 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '지원장비', icon: '🔩', count: 40 }, { category: '경비함정방제', icon: '⚓', count: 14 }, { category: '살포장치', icon: '🌊', count: 20 }, ], contacts: [{ role: '방제과장', name: '강○○', phone: '052-228-0001' }], }, { id: 12, type: '해경경찰서', jurisdiction: '남해지방해양경찰청', area: '창원', name: '창원해양경찰서', address: '창원시 마산합포구 신포동 1가', vessel: 12, skimmer: 25, pump: 14, vehicle: 10, sprayer: 10, totalAssets: 139, phone: '010-4634-7364', lat: 35.1796, lng: 128.5681, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 12 }, { category: '유회수기', icon: '⚙', count: 25 }, { category: '비치크리너', icon: '🏖', count: 2 }, { category: '이송펌프', icon: '🔧', count: 14 }, { category: '방제차량', icon: '🚛', count: 10 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 7 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 21 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 20 }, { category: '경비함정방제', icon: '⚓', count: 7 }, { category: '살포장치', icon: '🌊', count: 10 }, ], contacts: [{ role: '방제담당', name: '송○○', phone: '055-220-0001' }], }, { id: 13, type: '해경경찰서', jurisdiction: '남해지방해양경찰청', area: '통영', name: '통영해양경찰서', address: '통영시 광도면 죽림리 1564-4', vessel: 6, skimmer: 15, pump: 9, vehicle: 5, sprayer: 13, totalAssets: 104, phone: '010-9812-8495', lat: 34.8544, lng: 128.4331, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 6 }, { category: '유회수기', icon: '⚙', count: 15 }, { category: '비치크리너', icon: '🏖', count: 2 }, { category: '이송펌프', icon: '🔧', count: 9 }, { category: '방제차량', icon: '🚛', count: 5 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 18 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '지원장비', icon: '🔩', count: 11 }, { category: '경비함정방제', icon: '⚓', count: 12 }, { category: '살포장치', icon: '🌊', count: 13 }, ], contacts: [{ role: '방제담당', name: '서○○', phone: '055-640-0001' }], }, { id: 14, type: '해경경찰서', jurisdiction: '남해지방해양경찰청', area: '사천', name: '사천해양경찰서', address: '사천시 신항만길 1길 17', vessel: 2, skimmer: 9, pump: 6, vehicle: 2, sprayer: 7, totalAssets: 80, phone: '010-9812-8352', lat: 34.9310, lng: 128.0660, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 2 }, { category: '유회수기', icon: '⚙', count: 9 }, { category: '이송펌프', icon: '🔧', count: 6 }, { category: '방제차량', icon: '🚛', count: 2 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 2 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 4 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 31 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 1 }, { category: '경비함정방제', icon: '⚓', count: 8 }, { category: '살포장치', icon: '🌊', count: 7 }, ], contacts: [{ role: '방제담당', name: '박○○', phone: '055-830-0001' }], }, // ── 동해지방해양경찰청 ── { id: 15, type: '해경경찰서', jurisdiction: '동해지방해양경찰청', area: '동해', name: '동해해양경찰서', address: '동해시 임항로 130', vessel: 6, skimmer: 23, pump: 11, vehicle: 6, sprayer: 14, totalAssets: 156, phone: '010-9812-8073', lat: 37.5247, lng: 129.1143, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 6 }, { category: '유회수기', icon: '⚙', count: 23 }, { category: '비치크리너', icon: '🏖', count: 1 }, { category: '이송펌프', icon: '🔧', count: 11 }, { category: '방제차량', icon: '🚛', count: 6 }, { category: '해안운반차', icon: '🚜', count: 3 }, { category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 5 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 38 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '지원장비', icon: '🔩', count: 20 }, { category: '장비부품', icon: '🔗', count: 10 }, { category: '경비함정방제', icon: '⚓', count: 8 }, { category: '살포장치', icon: '🌊', count: 14 }, ], contacts: [{ role: '방제담당', name: '남○○', phone: '033-530-0001' }], }, { id: 16, type: '해경경찰서', jurisdiction: '동해지방해양경찰청', area: '포항', name: '포항해양경찰서', address: '포항시 남구 희망대로 1341', vessel: 10, skimmer: 13, pump: 21, vehicle: 4, sprayer: 21, totalAssets: 135, phone: '010-3108-2183', lat: 36.0190, lng: 129.3651, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 10 }, { category: '유회수기', icon: '⚙', count: 13 }, { category: '비치크리너', icon: '🏖', count: 1 }, { category: '이송펌프', icon: '🔧', count: 21 }, { category: '방제차량', icon: '🚛', count: 4 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 7 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 3 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 15 }, { category: '발전기', icon: '⚡', count: 5 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '지원장비', icon: '🔩', count: 20 }, { category: '경비함정방제', icon: '⚓', count: 10 }, { category: '살포장치', icon: '🌊', count: 21 }, ], contacts: [{ role: '방제담당', name: '오○○', phone: '054-244-0001' }], }, { id: 17, type: '파출소', jurisdiction: '동해지방해양경찰청', area: '속초', name: '속초해양경찰서', address: '속초시 설악금강대교로 206', vessel: 2, skimmer: 6, pump: 4, vehicle: 1, sprayer: 17, totalAssets: 85, phone: '033-634-2186', lat: 38.2070, lng: 128.5918, pinSize: 'md', equipment: [ { category: '방제선', icon: '🚢', count: 2 }, { category: '유회수기', icon: '⚙', count: 6 }, { category: '이송펌프', icon: '🔧', count: 4 }, { category: '방제차량', icon: '🚛', count: 1 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 2 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 16 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '지원장비', icon: '🔩', count: 11 }, { category: '장비부품', icon: '🔗', count: 11 }, { category: '경비함정방제', icon: '⚓', count: 8 }, { category: '살포장치', icon: '🌊', count: 17 }, ], contacts: [{ role: '방제담당', name: '양○○', phone: '033-633-0001' }], }, { id: 18, type: '파출소', jurisdiction: '동해지방해양경찰청', area: '울진', name: '울진해양경찰서', address: '울진군 후포면 후포리 623-148', vessel: 2, skimmer: 6, pump: 4, vehicle: 1, sprayer: 8, totalAssets: 66, phone: '010-9812-8076', lat: 36.9932, lng: 129.4003, pinSize: 'md', equipment: [ { category: '방제선', icon: '🚢', count: 2 }, { category: '유회수기', icon: '⚙', count: 6 }, { category: '이송펌프', icon: '🔧', count: 4 }, { category: '방제차량', icon: '🚛', count: 1 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 13 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '지원장비', icon: '🔩', count: 4 }, { category: '장비부품', icon: '🔗', count: 4 }, { category: '경비함정방제', icon: '⚓', count: 10 }, { category: '살포장치', icon: '🌊', count: 8 }, ], contacts: [{ role: '방제담당', name: '배○○', phone: '054-782-0001' }], }, // ── 제주지방해양경찰청 ── { id: 19, type: '해경경찰서', jurisdiction: '제주지방해양경찰청', area: '제주', name: '제주해양경찰서', address: '제주시 임항로 85', vessel: 4, skimmer: 21, pump: 17, vehicle: 3, sprayer: 16, totalAssets: 113, phone: '064-766-2691', lat: 33.5154, lng: 126.5268, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 4 }, { category: '유회수기', icon: '⚙', count: 21 }, { category: '비치크리너', icon: '🏖', count: 2 }, { category: '이송펌프', icon: '🔧', count: 17 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 3 }, { category: '동력분무기', icon: '💨', count: 4 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 24 }, { category: '발전기', icon: '⚡', count: 6 }, { category: '현장지휘소', icon: '🏕', count: 2 }, { category: '경비함정방제', icon: '⚓', count: 4 }, { category: '살포장치', icon: '🌊', count: 16 }, ], contacts: [{ role: '방제담당', name: '문○○', phone: '064-750-0001' }], }, { id: 20, type: '해경경찰서', jurisdiction: '제주지방해양경찰청', area: '서귀포', name: '서귀포해양경찰서', address: '서귀포시 안덕면 화순해안로69', vessel: 3, skimmer: 9, pump: 15, vehicle: 3, sprayer: 14, totalAssets: 67, phone: '064-793-2186', lat: 33.2469, lng: 126.5600, pinSize: 'lg', equipment: [ { category: '방제선', icon: '🚢', count: 3 }, { category: '유회수기', icon: '⚙', count: 9 }, { category: '비치크리너', icon: '🏖', count: 1 }, { category: '이송펌프', icon: '🔧', count: 15 }, { category: '방제차량', icon: '🚛', count: 3 }, { category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '방제창고', icon: '🏭', count: 10 }, { category: '발전기', icon: '⚡', count: 3 }, { category: '경비함정방제', icon: '⚓', count: 4 }, { category: '살포장치', icon: '🌊', count: 14 }, ], contacts: [{ role: '방제담당', name: '고○○', phone: '064-730-0001' }], }, // ── 중앙특수구조단 ── { id: 21, type: '관련기관', jurisdiction: '해양경찰청(중앙)', area: '중앙', name: '중앙특수구조단', address: '부산광역시 영도구 해양로 301', vessel: 1, skimmer: 0, pump: 5, vehicle: 2, sprayer: 0, totalAssets: 39, phone: '051-580-2044', lat: 35.0580, lng: 129.0590, pinSize: 'md', equipment: [ { category: '방제선', icon: '🚢', count: 1 }, { category: '이송펌프', icon: '🔧', count: 5 }, { category: '방제차량', icon: '🚛', count: 2 }, { category: '유량계측기', icon: '📏', count: 1 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '지원장비', icon: '🔩', count: 27 }, { category: '경비함정방제', icon: '⚓', count: 1 }, ], contacts: [{ role: '구조단장', name: '김○○', phone: '051-580-2044' }], }, // ── 기름저장시설 ── { id: 22, type: '기름저장시설', jurisdiction: '서해지방해양경찰청', area: '여수', name: '오일허브코리아여수㈜ 외 4개', address: '전남 여수시 신덕동 325', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '061-686-3611', lat: 34.745, lng: 127.745, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }], contacts: [{ role: '담당', name: '오일허브코리아여수㈜', phone: '061-686-3611' }], }, { id: 23, type: '기름저장시설', jurisdiction: '남해지방해양경찰청', area: '부산', name: 'SK에너지 외 2개', address: '부산시 영도구 해양로 1', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 3, phone: '051-643-3331', lat: 35.175, lng: 129.075, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: 'HD현대오일뱅크㈜', phone: '051-643-3331' }], }, { id: 24, type: '기름저장시설', jurisdiction: '남해지방해양경찰청', area: '울산', name: 'SK지오센트릭 외 5개', address: '울산광역시 남구 신여천로 2', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 9, phone: '052-208-2851', lat: 35.535, lng: 129.305, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 4 }, { category: '방제창고', icon: '🏭', count: 5 }], contacts: [{ role: '담당', name: 'SK엔텀㈜', phone: '052-208-2851' }], }, { id: 25, type: '기름저장시설', jurisdiction: '남해지방해양경찰청', area: '통영', name: '한국가스공사 통영기지본부', address: '통영시 광도면 안정로 770', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '055-640-6014', lat: 35.05, lng: 128.41, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '한국가스공사', phone: '055-640-6014' }], }, { id: 26, type: '기름저장시설', jurisdiction: '동해지방해양경찰청', area: '동해', name: 'HD현대오일뱅크㈜ 외 4개', address: '강릉시 옥계면 동해대로 206', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 9, phone: '033-534-2093', lat: 37.52, lng: 129.11, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 2 }, { category: '방제창고', icon: '🏭', count: 6 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: 'HD현대오일뱅크㈜', phone: '033-534-2093' }], }, { id: 27, type: '기름저장시설', jurisdiction: '동해지방해양경찰청', area: '포항', name: '포스코케미칼 외 1개', address: '포항시 남구 동해안로 6262', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 2, phone: '054-290-8222', lat: 37.73, lng: 129.01, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 1 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: 'OCI(주)', phone: '054-290-8222' }], }, { id: 28, type: '기름저장시설', jurisdiction: '서해지방해양경찰청', area: '목포', name: '흑산도내연발전소 외 2개', address: '전남 신안군 흑산일주로70', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '061-351-2342', lat: 35.04, lng: 126.58, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: '안마도내연발전소', phone: '061-351-2342' }], }, { id: 29, type: '기름저장시설', jurisdiction: '서해지방해양경찰청', area: '여수', name: '오일허브코리아여수㈜ 외 4개', address: '전남 여수시 신덕동 325', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '061-686-3611', lat: 34.75, lng: 127.735, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 1 }, { category: '방제창고', icon: '🏭', count: 3 }], contacts: [{ role: '담당', name: '오일허브코리아여수㈜', phone: '061-686-3611' }], }, { id: 30, type: '기름저장시설', jurisdiction: '중부지방해양경찰청', area: '인천', name: 'GS칼텍스㈜ 외 10개', address: '인천광역시 중구 월미로 182', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 13, phone: '010-8777-6922', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 7 }, { category: '동력분무기', icon: '💨', count: 6 }], contacts: [{ role: '담당', name: 'GS칼텍스㈜', phone: '010-8777-6922' }], }, { id: 31, type: '기름저장시설', jurisdiction: '중부지방해양경찰청', area: '태안', name: 'HD현대케미칼 외 4개', address: '충남 서산시 대산읍 평신2로 26', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '041-924-1068', lat: 36.91, lng: 126.415, pinSize: 'md', equipment: [{ category: '해안운반차', icon: '🚜', count: 2 }, { category: '동력분무기', icon: '💨', count: 2 }], contacts: [{ role: '담당', name: 'HD현대케미칼', phone: '041-924-1068' }], }, { id: 32, type: '기름저장시설', jurisdiction: '중부지방해양경찰청', area: '평택', name: '현대오일터미널(주) 외 4개', address: '평택시 포승읍 포승공단순환로 11', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 4, phone: '031-683-5101', lat: 36.985, lng: 126.835, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 2 }, { category: '발전기', icon: '⚡', count: 1 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '(주)경동탱크터미널', phone: '031-683-5101' }], }, // ── 기타 ── { id: 33, type: '기타', jurisdiction: '남해지방해양경찰청', area: '사천', name: '한국남동발전(주) 외 2개', address: '고성군 하이면 하이로1', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 8, phone: '070-4486-7474', lat: 34.965, lng: 128.56, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 3 }, { category: '방제창고', icon: '🏭', count: 5 }], contacts: [{ role: '담당', name: '(주)고성그린파워', phone: '070-4486-7474' }], }, { id: 34, type: '기타', jurisdiction: '남해지방해양경찰청', area: '울산', name: 'HD현대미포', address: '울산광역시 동구 방어진순환도로100', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '052-250-3551', lat: 35.53, lng: 129.315, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: 'HD현대미포', phone: '052-250-3551' }], }, { id: 35, type: '기타', jurisdiction: '남해지방해양경찰청', area: '통영', name: '삼성중공업 외 1개', address: '거제시 장평3로 80', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '055-630-5373', lat: 35.05, lng: 128.41, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 2 }], contacts: [{ role: '담당', name: '삼성중공업', phone: '055-630-5373' }], }, { id: 36, type: '기타', jurisdiction: '동해지방해양경찰청', area: '동해', name: '한국남부발전㈜', address: '삼척시 원덕읍 삼척로 734', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '070-7713-5153', lat: 37.45, lng: 129.17, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 2 }], contacts: [{ role: '담당', name: '한국남부발전㈜', phone: '070-7713-5153' }], }, { id: 37, type: '기타', jurisdiction: '동해지방해양경찰청', area: '울진', name: '한울원전', address: '울진군 북면 울진북로 2040', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '054-785-4833', lat: 37.065, lng: 129.39, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 2 }, { category: '지원장비', icon: '🔩', count: 2 }], contacts: [{ role: '담당', name: '한울원전', phone: '054-785-4833' }], }, { id: 38, type: '기타', jurisdiction: '서해지방해양경찰청', area: '여수', name: '㈜HR-PORT 외 5개', address: '여수시 제철로', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 16, phone: '061-791-0358', lat: 34.755, lng: 127.73, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '동력분무기', icon: '💨', count: 7 }, { category: '방제창고', icon: '🏭', count: 3 }, { category: '발전기', icon: '⚡', count: 1 }, { category: '지원장비', icon: '🔩', count: 3 }], contacts: [{ role: '담당', name: '㈜ 한진', phone: '061-791-0358' }], }, { id: 39, type: '기타', jurisdiction: '중부지방해양경찰청', area: '인천', name: '삼광조선공업㈜ 외 1개', address: '인천 동구 보세로42번길41', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 5, phone: '010-3321-2959', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 5 }], contacts: [{ role: '담당', name: '삼광조선공업㈜', phone: '010-3321-2959' }], }, // ── 방제유창청소업체 ── { id: 40, type: '업체', jurisdiction: '중부지방해양경찰청', area: '인천', name: '방제유창청소업체(㈜클린포트)', address: '㈜클린포트', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 3, phone: '032-882-8279', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 2 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: '㈜클린포트', phone: '032-882-8279' }], }, { id: 41, type: '업체', jurisdiction: '남해지방해양경찰청', area: '부산', name: '방제유창청소업체(대용환경㈜ 외 38개)', address: '㈜태평양해양산업', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 51, phone: '051-242-0622', lat: 35.18, lng: 129.085, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 31 }, { category: '저압세척기', icon: '🚿', count: 5 }, { category: '동력분무기', icon: '💨', count: 3 }, { category: '방제창고', icon: '🏭', count: 5 }, { category: '발전기', icon: '⚡', count: 6 }, { category: '현장지휘소', icon: '🏕', count: 1 }], contacts: [{ role: '담당', name: '(주)경원마린서비스', phone: '051-242-0622' }], }, { id: 42, type: '업체', jurisdiction: '남해지방해양경찰청', area: '울산', name: '방제유창청소업체((주)한유마린서비스 외 8개)', address: '대상해운(주)', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 12, phone: '010-5499-7401', lat: 35.54, lng: 129.295, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 11 }, { category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '(주)골든씨', phone: '010-5499-7401' }], }, { id: 43, type: '업체', jurisdiction: '동해지방해양경찰청', area: '포항', name: '방제유창청소업체(블루씨 외 1개)', address: '(주)블루씨', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 3, phone: '054-278-8200', lat: 36.015, lng: 129.365, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 2 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '(주)블루씨', phone: '054-278-8200' }], }, { id: 44, type: '업체', jurisdiction: '서해지방해양경찰청', area: '목포', name: '방제유창청소업체(㈜한국해운 외 1개)', address: '㈜한국해운 목포지사', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '010-8615-4326', lat: 35.04, lng: 126.58, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }], contacts: [{ role: '담당', name: '㈜아라', phone: '010-8615-4326' }], }, { id: 45, type: '업체', jurisdiction: '서해지방해양경찰청', area: '여수', name: '방제유창청소업체(마로해운 외 11개)', address: '㈜우진실업', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 2, totalAssets: 54, phone: '061-654-9603', lat: 34.74, lng: 127.75, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 28 }, { category: '동력분무기', icon: '💨', count: 15 }, { category: '방제창고', icon: '🏭', count: 5 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '살포장치', icon: '🌊', count: 2 }], contacts: [{ role: '담당', name: '(유)피케이엘', phone: '061-654-9603' }], }, { id: 46, type: '업체', jurisdiction: '중부지방해양경찰청', area: '태안', name: '방제유창청소업체(우진해운㈜)', address: '우진해운㈜', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 6, phone: '010-4384-6817', lat: 36.905, lng: 126.42, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '발전기', icon: '⚡', count: 2 }], contacts: [{ role: '담당', name: '우진해운㈜', phone: '010-4384-6817' }], }, { id: 47, type: '업체', jurisdiction: '중부지방해양경찰청', area: '평택', name: '방제유창청소업체((주)씨앤 외 3개)', address: '㈜씨앤', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 6, phone: '031-683-2389', lat: 36.99, lng: 126.825, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '발전기', icon: '⚡', count: 2 }], contacts: [{ role: '담당', name: '(주)소스코리아', phone: '031-683-2389' }], }, { id: 48, type: '업체', jurisdiction: '남해지방해양경찰청', area: '부산', name: '방제유창청소업체(㈜지앤비마린서비스)', address: '㈜지앤비마린서비스', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '051-242-0622', lat: 35.185, lng: 129.07, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '(주)경원마린서비스', phone: '051-242-0622' }], }, // ── 정유사 ── { id: 49, type: '정유사', jurisdiction: '남해지방해양경찰청', area: '울산', name: 'SK엔텀(주) 외 4개', address: '울산광역시 남구 고사동 110-64', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 5, phone: '052-231-2318', lat: 35.545, lng: 129.31, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 5 }], contacts: [{ role: '담당', name: 'S-OIL㈜', phone: '052-231-2318' }], }, { id: 50, type: '정유사', jurisdiction: '서해지방해양경찰청', area: '여수', name: 'GS칼텍스㈜', address: '여수시 낙포단지길 251', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 20, totalAssets: 27, phone: '061-680-2121', lat: 34.735, lng: 127.755, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '방제창고', icon: '🏭', count: 4 }, { category: '살포장치', icon: '🌊', count: 20 }], contacts: [{ role: '담당', name: 'GS칼텍스㈜', phone: '061-680-2121' }], }, { id: 51, type: '정유사', jurisdiction: '중부지방해양경찰청', area: '태안', name: 'HD현대오일뱅크㈜', address: '서산시 대산읍 평신2로 182', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '010-2050-5291', lat: 36.915, lng: 126.41, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 2 }], contacts: [{ role: '담당', name: 'HD현대오일뱅크㈜', phone: '010-2050-5291' }], }, // ── 지자체 ── { id: 52, type: '지자체', jurisdiction: '남해지방해양경찰청', area: '부산', name: '부산광역시 외 8개', address: '부산광역시 동구 좌천동', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 12, phone: '051-607-4484', lat: 35.17, lng: 129.08, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '방제창고', icon: '🏭', count: 11 }], contacts: [{ role: '담당', name: '남구청', phone: '051-607-4484' }], }, { id: 53, type: '지자체', jurisdiction: '남해지방해양경찰청', area: '사천', name: '사천시 외 3개', address: '사천시 신항로 3', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 6, phone: '055-670-2484', lat: 34.935, lng: 128.075, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 6 }], contacts: [{ role: '담당', name: '고성군', phone: '055-670-2484' }], }, { id: 54, type: '지자체', jurisdiction: '남해지방해양경찰청', area: '울산', name: '울산북구청 외 2개', address: '울산광역시 북구 구유동 654-2', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '051-709-4611', lat: 35.55, lng: 129.32, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 4 }], contacts: [{ role: '담당', name: '부산기장군청', phone: '051-709-4611' }], }, { id: 55, type: '지자체', jurisdiction: '남해지방해양경찰청', area: '창원', name: '창원 진해구 외 1개', address: '창원시 진해구 천자로 105', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '051-970-4482', lat: 35.055, lng: 128.645, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '부산 강서구', phone: '051-970-4482' }], }, { id: 56, type: '지자체', jurisdiction: '동해지방해양경찰청', area: '동해', name: '삼척시 외 1개', address: '삼척시 근덕면 덕산리 107-74', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 4, phone: '033-640-5284', lat: 37.45, lng: 129.16, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '방제창고', icon: '🏭', count: 3 }], contacts: [{ role: '담당', name: '강릉시', phone: '033-640-5284' }], }, { id: 57, type: '지자체', jurisdiction: '동해지방해양경찰청', area: '울진', name: '영덕군', address: '남정면 장사리 74-1', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 3, phone: '054-730-6562', lat: 36.35, lng: 129.4, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 3 }], contacts: [{ role: '담당', name: '영덕군', phone: '054-730-6562' }], }, { id: 58, type: '지자체', jurisdiction: '서해지방해양경찰청', area: '목포', name: '영광군 외 1개', address: '영광군 염산면 향화로', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 5, phone: '061-270-3419', lat: 35.04, lng: 126.58, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 5 }], contacts: [{ role: '담당', name: '목포시', phone: '061-270-3419' }], }, { id: 59, type: '지자체', jurisdiction: '서해지방해양경찰청', area: '여수', name: '광양시 외 1개', address: '순천시 진상면 성지로 8', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 3, phone: '061-797-2791', lat: 34.76, lng: 127.725, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 3 }], contacts: [{ role: '담당', name: '광양시', phone: '061-797-2791' }], }, { id: 60, type: '지자체', jurisdiction: '중부지방해양경찰청', area: '인천', name: '옹진군청 외 4개', address: '인천광역시 옹진군 덕적면 진리 387', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 10, phone: '010-2740-9388', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 5 }, { category: '동력분무기', icon: '💨', count: 4 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: '김포시청', phone: '010-2740-9388' }], }, { id: 61, type: '지자체', jurisdiction: '중부지방해양경찰청', area: '태안', name: '태안군청', address: '충남 태안군 근흥면 신진도리 75-36', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '041-670-2877', lat: 36.745, lng: 126.305, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '태안군청', phone: '041-670-2877' }], }, { id: 62, type: '지자체', jurisdiction: '중부지방해양경찰청', area: '평택', name: '안산시청 외 2개', address: '경기도 안산시 단원구 진두길 97', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 6, phone: '041-350-4292', lat: 37.32, lng: 126.83, pinSize: 'md', equipment: [{ category: '동력분무기', icon: '💨', count: 1 }, { category: '방제창고', icon: '🏭', count: 5 }], contacts: [{ role: '담당', name: '당진시청', phone: '041-350-4292' }], }, // ── 하역시설 ── { id: 63, type: '기타', jurisdiction: '서해지방해양경찰청', area: '여수', name: '㈜HR-PORT 외 5개', address: '여수시 제철로', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '061-791-0358', lat: 34.748, lng: 127.74, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '㈜ 한진', phone: '061-791-0358' }], }, // ── 해군 ── { id: 64, type: '해군', jurisdiction: '동해지방해양경찰청', area: '동해', name: '해군1함대사령부 외 1개', address: '동해시 대동로 430', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '033-539-7323', lat: 37.525, lng: 129.115, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 1 }], contacts: [{ role: '담당', name: '1함대 사령부', phone: '033-539-7323' }], }, { id: 65, type: '해군', jurisdiction: '중부지방해양경찰청', area: '인천', name: '해병대 제9518부대', address: '인천광역시 옹진군', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '010-4801-3473', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '발전기', icon: '⚡', count: 2 }], contacts: [{ role: '담당', name: '해병대 제9518부대', phone: '010-4801-3473' }], }, // ── 해양환경공단 ── { id: 66, type: '해양환경공단', jurisdiction: '남해지방해양경찰청', area: '부산', name: '부산지사', address: '창원시 진해구 안골동', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 6, totalAssets: 14, phone: '051-466-3944', lat: 35.105, lng: 128.715, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '방제창고', icon: '🏭', count: 1 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '살포장치', icon: '🌊', count: 6 }], contacts: [{ role: '담당', name: '부산지사', phone: '051-466-3944' }], }, { id: 67, type: '해양환경공단', jurisdiction: '남해지방해양경찰청', area: '사천', name: '마산지사', address: '사천시 신항만1길 23', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 9, phone: '010-3598-4202', lat: 34.925, lng: 128.065, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 8 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: '마산지사', phone: '010-3598-4202' }], }, { id: 68, type: '해양환경공단', jurisdiction: '남해지방해양경찰청', area: '울산', name: '울산지사', address: '울산광역시 남구 장생포고래로 276번길 27', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 16, phone: '052-238-7718', lat: 35.538, lng: 129.3, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 6 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '방제창고', icon: '🏭', count: 4 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '울산지사', phone: '052-238-7718' }], }, { id: 69, type: '해양환경공단', jurisdiction: '남해지방해양경찰청', area: '창원', name: '마산지사', address: '창원시 마산합포구 드림베이대로59', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 7, phone: '010-2265-3928', lat: 35.055, lng: 128.645, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 4 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '마산지사', phone: '010-2265-3928' }], }, { id: 70, type: '해양환경공단', jurisdiction: '남해지방해양경찰청', area: '통영', name: '마산지사', address: '거제시 장승로 112', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 8, phone: '010-2636-5313', lat: 35.05, lng: 128.41, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 8 }], contacts: [{ role: '담당', name: '마산지사', phone: '010-2636-5313' }], }, { id: 71, type: '해양환경공단', jurisdiction: '동해지방해양경찰청', area: '동해', name: '동해지사', address: '동해시 대동로 210', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 2, totalAssets: 17, phone: '010-7499-0257', lat: 37.515, lng: 129.105, pinSize: 'md', equipment: [{ category: '해안운반차', icon: '🚜', count: 2 }, { category: '고압세척기', icon: '💧', count: 2 }, { category: '동력분무기', icon: '💨', count: 2 }, { category: '방제창고', icon: '🏭', count: 8 }, { category: '발전기', icon: '⚡', count: 1 }, { category: '살포장치', icon: '🌊', count: 2 }], contacts: [{ role: '담당', name: '동해지사', phone: '010-7499-0257' }], }, { id: 72, type: '해양환경공단', jurisdiction: '동해지방해양경찰청', area: '울진', name: '포항지사', address: '울진군 죽변면 죽변리 36-88', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 2, phone: '054-273-5595', lat: 37.06, lng: 129.42, pinSize: 'md', equipment: [{ category: '방제창고', icon: '🏭', count: 2 }], contacts: [{ role: '담당', name: '포항지사', phone: '054-273-5595' }], }, { id: 73, type: '해양환경공단', jurisdiction: '동해지방해양경찰청', area: '포항', name: '포항지사', address: '포항시 북구 해안로 44-10', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 2, totalAssets: 8, phone: '054-273-5595', lat: 36.025, lng: 129.375, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '발전기', icon: '⚡', count: 2 }, { category: '현장지휘소', icon: '🏕', count: 1 }, { category: '살포장치', icon: '🌊', count: 2 }], contacts: [{ role: '담당', name: '포항지사', phone: '054-273-5595' }], }, { id: 74, type: '해양환경공단', jurisdiction: '서해지방해양경찰청', area: '군산', name: '군산지사', address: '군산시 임해로 452', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 4, totalAssets: 12, phone: '063-443-4813', lat: 35.975, lng: 126.715, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 2 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '발전기', icon: '⚡', count: 3 }, { category: '살포장치', icon: '🌊', count: 4 }], contacts: [{ role: '담당', name: '군산지사', phone: '063-443-4813' }], }, { id: 75, type: '해양환경공단', jurisdiction: '서해지방해양경찰청', area: '목포', name: '목포지사', address: '전남 목포시 죽교동 683', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 10, phone: '061-242-9663', lat: 35.04, lng: 126.58, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '방제창고', icon: '🏭', count: 6 }, { category: '발전기', icon: '⚡', count: 1 }], contacts: [{ role: '담당', name: '목포지사', phone: '061-242-9663' }], }, { id: 76, type: '해양환경공단', jurisdiction: '서해지방해양경찰청', area: '여수', name: '여수지사', address: '여수시 덕충동', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 3, totalAssets: 12, phone: '061-654-6431', lat: 34.742, lng: 127.748, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '발전기', icon: '⚡', count: 3 }, { category: '살포장치', icon: '🌊', count: 3 }], contacts: [{ role: '담당', name: '여수지사', phone: '061-654-6431' }], }, { id: 77, type: '해양환경공단', jurisdiction: '서해지방해양경찰청', area: '완도', name: '목포지사 완도사업소', address: '완도군 완도읍 해변공원로 20-1', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 3, phone: '061-242-9663', lat: 34.315, lng: 126.755, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '방제창고', icon: '🏭', count: 2 }], contacts: [{ role: '담당', name: '목포지사', phone: '061-242-9663' }], }, { id: 78, type: '해양환경공단', jurisdiction: '제주지방해양경찰청', area: '서귀포', name: '제주지사(서귀포)', address: '서귀포시 칠십리로72번길 14', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 1, phone: '064-753-4356', lat: 33.245, lng: 126.565, pinSize: 'md', equipment: [{ category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '제주지사', phone: '064-753-4356' }], }, { id: 79, type: '해양환경공단', jurisdiction: '제주지방해양경찰청', area: '제주', name: '제주지사(제주)', address: '제주시 임항로97', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 3, totalAssets: 20, phone: '064-753-4356', lat: 33.517, lng: 126.528, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '동력분무기', icon: '💨', count: 2 }, { category: '방제창고', icon: '🏭', count: 10 }, { category: '발전기', icon: '⚡', count: 1 }, { category: '살포장치', icon: '🌊', count: 3 }], contacts: [{ role: '담당', name: '제주지사', phone: '064-753-4356' }], }, { id: 80, type: '해양환경공단', jurisdiction: '중부지방해양경찰청', area: '보령', name: '대산지사(보령)', address: '보령시 해안로 740', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 5, phone: '041-664-9101', lat: 36.333, lng: 126.612, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }, { category: '방제창고', icon: '🏭', count: 4 }], contacts: [{ role: '담당', name: '대산지사', phone: '041-664-9101' }], }, { id: 81, type: '해양환경공단', jurisdiction: '중부지방해양경찰청', area: '인천', name: '인천지사', address: '인천광역시 중구 연안부두로 128번길 35', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 11, phone: '010-7133-2167', lat: 37.45, lng: 126.505, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '동력분무기', icon: '💨', count: 3 }, { category: '발전기', icon: '⚡', count: 2 }], contacts: [{ role: '담당', name: '인천지사', phone: '010-7133-2167' }], }, { id: 82, type: '해양환경공단', jurisdiction: '중부지방해양경찰청', area: '태안', name: '대산지사(태안)', address: '서산시 대산읍 대죽1로 325', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 17, phone: '041-664-9101', lat: 36.908, lng: 126.413, pinSize: 'md', equipment: [{ category: '해안운반차', icon: '🚜', count: 1 }, { category: '고압세척기', icon: '💧', count: 5 }, { category: '저압세척기', icon: '🚿', count: 1 }, { category: '동력분무기', icon: '💨', count: 1 }, { category: '방제창고', icon: '🏭', count: 5 }, { category: '발전기', icon: '⚡', count: 3 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '대산지사', phone: '041-664-9101' }], }, { id: 83, type: '해양환경공단', jurisdiction: '중부지방해양경찰청', area: '평택', name: '평택지사', address: '당진시 송악읍 고대공단2길', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 1, totalAssets: 13, phone: '031-683-7973', lat: 36.905, lng: 126.635, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 3 }, { category: '저압세척기', icon: '🚿', count: 2 }, { category: '방제창고', icon: '🏭', count: 3 }, { category: '발전기', icon: '⚡', count: 4 }, { category: '살포장치', icon: '🌊', count: 1 }], contacts: [{ role: '담당', name: '평택지사', phone: '031-683-7973' }], }, // ── 수협 ── { id: 84, type: '기타', jurisdiction: '남해지방해양경찰청', area: '통영', name: '삼성중공업 외 1개', address: '거제시 장평3로 80', vessel: 0, skimmer: 0, pump: 0, vehicle: 0, sprayer: 0, totalAssets: 1, phone: '055-630-5373', lat: 35.05, lng: 128.41, pinSize: 'md', equipment: [{ category: '고압세척기', icon: '💧', count: 1 }], contacts: [{ role: '담당', name: '삼성중공업', phone: '055-630-5373' }], }, ] interface InsuranceRow { shipName: string mmsi: string imo: string insType: string insurer: string policyNo: string start: string expiry: string limit: string } const insuranceDemoData: InsuranceRow[] = [ { shipName: '유조선 한라호', mmsi: '440123456', imo: '9876001', insType: 'P&I 보험', insurer: '한국P&I클럽', policyNo: 'PI-2025-1234', start: '2025-07-01', expiry: '2026-06-30', limit: '50억' }, { shipName: '화학물질운반선 제주호', mmsi: '440345678', imo: '9876002', insType: '선주책임보험', insurer: '삼성화재', policyNo: 'SF-2025-9012', start: '2025-09-16', expiry: '2026-09-15', limit: '80억' }, { shipName: '방제선 OCEAN STAR', mmsi: '440123789', imo: '9876003', insType: 'P&I 보험', insurer: '한국P&I클럽', policyNo: 'PI-2025-3456', start: '2025-11-21', expiry: '2026-11-20', limit: '120억' }, { shipName: 'LNG운반선 부산호', mmsi: '440567890', imo: '9876004', insType: '해상보험', insurer: 'DB손해보험', policyNo: 'DB-2025-7890', start: '2025-08-02', expiry: '2026-08-01', limit: '200억' }, { shipName: '유조선 백두호', mmsi: '440789012', imo: '9876005', insType: 'P&I 보험', insurer: 'SK해운보험', policyNo: 'MH-2025-5678', start: '2025-01-01', expiry: '2025-12-31', limit: '30억' }, ] const uploadHistory = [ { filename: '여수서_장비자재_2601.xlsx', date: '2026-01-25 14:30', uploader: '남해청_방제과', count: 45 }, { filename: '인천서_오일펜스현황.xlsx', date: '2026-01-22 10:15', uploader: '중부청_방제과', count: 12 }, { filename: '전체_방제정_현황.xlsx', date: '2026-01-20 09:00', uploader: '본청_방제과', count: 18 }, ] const typeTagCls = (type: string) => { if (type === '해경관할') return 'bg-[rgba(239,68,68,0.1)] text-status-red' if (type === '해경경찰서') return 'bg-[rgba(59,130,246,0.1)] text-primary-blue' if (type === '파출소') return 'bg-[rgba(34,197,94,0.1)] text-status-green' if (type === '관련기관') return 'bg-[rgba(168,85,247,0.1)] text-primary-purple' if (type === '해양환경공단') return 'bg-[rgba(6,182,212,0.1)] text-primary-cyan' if (type === '업체') return 'bg-[rgba(245,158,11,0.1)] text-status-orange' if (type === '지자체') return 'bg-[rgba(236,72,153,0.1)] text-[#ec4899]' if (type === '기름저장시설') return 'bg-[rgba(139,92,246,0.1)] text-[#8b5cf6]' if (type === '정유사') return 'bg-[rgba(20,184,166,0.1)] text-[#14b8a6]' if (type === '해군') return 'bg-[rgba(100,116,139,0.1)] text-[#64748b]' if (type === '기타') return 'bg-[rgba(107,114,128,0.1)] text-[#6b7280]' return 'bg-[rgba(156,163,175,0.1)] text-[#9ca3af]' } const typeColor = (type: string) => { switch (type) { case '해경관할': return { bg: 'rgba(6,182,212,0.3)', border: '#06b6d4', selected: '#22d3ee' } case '해경경찰서': return { bg: 'rgba(59,130,246,0.3)', border: '#3b82f6', selected: '#60a5fa' } case '파출소': return { bg: 'rgba(34,197,94,0.3)', border: '#22c55e', selected: '#4ade80' } case '관련기관': return { bg: 'rgba(168,85,247,0.3)', border: '#a855f7', selected: '#c084fc' } case '해양환경공단': return { bg: 'rgba(20,184,166,0.3)', border: '#14b8a6', selected: '#2dd4bf' } case '업체': return { bg: 'rgba(245,158,11,0.3)', border: '#f59e0b', selected: '#fbbf24' } case '지자체': return { bg: 'rgba(236,72,153,0.3)', border: '#ec4899', selected: '#f472b6' } case '기름저장시설': return { bg: 'rgba(139,92,246,0.3)', border: '#8b5cf6', selected: '#a78bfa' } case '정유사': return { bg: 'rgba(13,148,136,0.3)', border: '#0d9488', selected: '#2dd4bf' } case '해군': return { bg: 'rgba(100,116,139,0.3)', border: '#64748b', selected: '#94a3b8' } default: return { bg: 'rgba(107,114,128,0.3)', border: '#6b7280', selected: '#9ca3af' } } } // ── AssetMap (Leaflet) ── function AssetMap({ organizations: orgs, selectedOrg, onSelectOrg, regionFilter, onRegionFilterChange, }: { organizations: AssetOrg[] selectedOrg: AssetOrg onSelectOrg: (o: AssetOrg) => void regionFilter: string onRegionFilterChange: (v: string) => void }) { const mapContainerRef = useRef(null) const mapRef = useRef(null) const markersRef = useRef(null) // Initialize map once useEffect(() => { if (!mapContainerRef.current || mapRef.current) return const map = L.map(mapContainerRef.current, { center: [35.9, 127.8], zoom: 7, zoomControl: false, attributionControl: false, }) // Dark-themed OpenStreetMap tiles L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { maxZoom: 19, }).addTo(map) L.control.zoom({ position: 'topright' }).addTo(map) L.control.attribution({ position: 'bottomright' }).addAttribution( '© OSM © CARTO' ).addTo(map) mapRef.current = map markersRef.current = L.layerGroup().addTo(map) return () => { map.remove() mapRef.current = null markersRef.current = null } }, []) // Update markers when orgs or selectedOrg changes useEffect(() => { if (!mapRef.current || !markersRef.current) return markersRef.current.clearLayers() orgs.forEach(org => { const isSelected = selectedOrg.id === org.id const tc = typeColor(org.type) const radius = org.pinSize === 'hq' ? 14 : org.pinSize === 'lg' ? 10 : 7 const cm = L.circleMarker([org.lat, org.lng], { radius: isSelected ? radius + 4 : radius, fillColor: isSelected ? tc.selected : tc.bg, color: isSelected ? tc.selected : tc.border, weight: isSelected ? 3 : 2, fillOpacity: isSelected ? 0.9 : 0.7, }) cm.bindTooltip( `
${org.name}
${org.type} · 자산 ${org.totalAssets}건
`, { permanent: org.pinSize === 'hq' || isSelected, direction: 'top', offset: [0, -radius - 2], className: 'asset-map-tooltip' } ) cm.on('click', () => onSelectOrg(org)) markersRef.current!.addLayer(cm) }) }, [orgs, selectedOrg, onSelectOrg]) // Pan to selected org useEffect(() => { if (!mapRef.current) return mapRef.current.flyTo([selectedOrg.lat, selectedOrg.lng], 10, { duration: 0.8 }) }, [selectedOrg]) return (
{/* Region filter overlay */}
{[ { value: 'all', label: '전체' }, { value: '남해', label: '남해청' }, { value: '서해', label: '서해청' }, { value: '중부', label: '중부청' }, { value: '동해', label: '동해청' }, { value: '제주', label: '제주청' }, ].map(r => ( ))}
{/* Legend overlay */}
범례
{[ { color: '#06b6d4', label: '해경관할' }, { color: '#3b82f6', label: '해경경찰서' }, { color: '#22c55e', label: '파출소' }, { color: '#a855f7', label: '관련기관' }, { color: '#14b8a6', label: '해양환경공단' }, { color: '#f59e0b', label: '업체' }, { color: '#ec4899', label: '지자체' }, { color: '#8b5cf6', label: '기름저장시설' }, { color: '#0d9488', label: '정유사' }, { color: '#64748b', label: '해군' }, { color: '#6b7280', label: '기타' }, ].map((item, i) => (
{item.label}
))}
) } // ── Tab 0: 자산 관리 ── function AssetManagementTab() { const [viewMode, setViewMode] = useState<'list' | 'map'>('list') const [selectedOrg, setSelectedOrg] = useState(organizations[0]) const [detailTab, setDetailTab] = useState<'equip' | 'material' | 'contact'>('equip') const [regionFilter, setRegionFilter] = useState('all') const [searchTerm, setSearchTerm] = useState('') const [typeFilterVal, setTypeFilterVal] = useState('all') const [currentPage, setCurrentPage] = useState(1) const pageSize = 15 const filtered = organizations.filter(o => { if (regionFilter !== 'all' && !o.jurisdiction.includes(regionFilter)) return false if (typeFilterVal !== 'all' && o.type !== typeFilterVal) return false if (searchTerm && !o.name.includes(searchTerm) && !o.address.includes(searchTerm)) return false return true }) const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize)) const safePage = Math.min(currentPage, totalPages) const paged = filtered.slice((safePage - 1) * pageSize, safePage * pageSize) // 필터 변경 시 첫 페이지로 // eslint-disable-next-line react-hooks/set-state-in-effect useEffect(() => { setCurrentPage(1) }, [regionFilter, typeFilterVal, searchTerm]) const regionShort = (j: string) => { if (j.includes('중부')) return '중부청' if (j.includes('서해')) return '서해청' if (j.includes('남해')) return '남해청' if (j.includes('동해')) return '동해청' if (j.includes('중앙')) return '중특단' return '제주청' } return (
{/* View Switcher & Filters */}
setSearchTerm(e.target.value)} className="prd-i w-40 py-1.5 px-2.5" />
{viewMode === 'list' ? ( /* ── LIST VIEW ── */
{['번호', '유형', '관할청', '기관명', '주소', '방제선', '유회수기', '이송펌프', '방제차량', '살포장치', '총자산'].map((h, i) => ( ))} {paged.map((org, idx) => ( { setSelectedOrg(org); setViewMode('map') }} > ))}
{h}
{(safePage - 1) * pageSize + idx + 1} {org.type} {regionShort(org.jurisdiction)} {org.name} {org.address} {org.vessel}척 {org.skimmer}대 {org.pump}대 {org.vehicle}대 {org.sprayer}대 {org.totalAssets}
{/* Pagination */}
전체 {filtered.length}건 중{' '} {(safePage - 1) * pageSize + 1}-{Math.min(safePage * pageSize, filtered.length)}
{Array.from({ length: totalPages }, (_, i) => i + 1).map(p => ( ))}
) : ( /* ── MAP VIEW ── */
{/* Map */}
{/* Right Detail Panel */}
)}
) } // ── Tab: 방제자원 이론 ── interface TheoryItem { title: string source: string desc: string tags?: { label: string; color: string }[] highlight?: boolean } interface TheorySection { icon: string title: string color: string bgTint: string items: TheoryItem[] dividerAfter?: number dividerLabel?: string } const THEORY_SECTIONS: TheorySection[] = [ { icon: '🚢', title: '방제선 성능 기준', color: 'var(--blue)', bgTint: 'rgba(59,130,246,.08)', items: [ { title: '해양경찰청 방제선 성능기준 고시', source: '해양경찰청 고시 제2022-11호 | 방제선·방제정 등급별 회수용량·속력·펌프사양 기준 정의', desc: '1~5등급 방제선 기준 · 회수능력(㎥/h) · 오일펜스 전장 탑재량 · WING 자산 등급 필터링 근거', }, { title: 'IMO OPRC 1990 — 방제자원 비축 기준', source: 'International Convention on Oil Pollution Preparedness, Response and Co-operation | IMO, 1990', desc: '국가 방제역량 비축 최저 기준 · 항만별 Tier 1/2/3 대응자원 분류 · 국내 방제자원 DB 설계 기초', }, { title: '해양오염방제업 등록기준 (해양환경관리법 시행규칙)', source: '해양수산부령 | 별표 9 — 방제업 종류별 방제선·기자재 보유기준', desc: '제1종·제2종 방제업 자산 보유기준 · 오일펜스 전장·회수기 용량 법적 최저기준 · WING 자산현황 적법성 검증 기준', }, ], }, { icon: '🪢', title: '오일펜스·흡착재 규격', color: 'var(--boom, #f59e0b)', bgTint: 'rgba(245,158,11,.08)', items: [ { title: 'ASTM F625 — Standard Guide for Selecting Mechanical Oil Spill Equipment', source: 'ASTM International | 오일펜스·회수기·흡착재 성능시험·선정 기준 가이드', desc: '오일펜스 인장강도·부력기준 · 흡착포 흡수율(g/g) 측정법 · WING 자산 성능등급 분류 참조 기준', }, { title: '기름오염방제시 오일펜스 사용지침 (ITOPF TIP 03 한국어판)', source: 'ITOPF | 해양경찰청·해양환경관리공단 번역, 2011', desc: '커튼형·펜스형·해안용 규격분류 · 유속별 운용한계(0.7~3.0 kt) · 힘 계산식 F=100·A·V² · 앵커 파지력 기준표', }, ], }, { icon: '⚙️', title: '방제자원 배치·동원 이론', color: 'var(--purple)', bgTint: 'rgba(168,85,247,.08)', dividerAfter: 2, dividerLabel: '📐 최적화 수리모델 참고문헌', items: [ { title: 'An Emergency Scheduling Model for Oil Containment Boom in Dynamically Changing Marine Oil Spills', source: 'Xu, Y. et al. | Ningbo Univ. | Systems 2025, 13, 716 · DOI: 10.3390/systems13080716', desc: 'IMOGWO 다목적 최적화 · 스케줄링 시간+경제·생태손실 동시 최소화 · 동적 오일필름 기반 방제정 라우팅', highlight: true, }, { title: 'Dynamic Resource Allocation to Support Oil Spill Response Planning', source: 'Garrett, R.A. et al. | Eur. J. Oper. Res. 257:272–286, 2017', desc: '불확실성 하 방제자원 동적 배분 최적화 · 시나리오별 비축량 산정 · WING 자산 우선순위 배치 알고리즘 이론 기반', }, { title: '해양오염방제 국가긴급방제계획 (NOSCP)', source: '해양경찰청 | 국가긴급방제계획, 2023년판', desc: 'Tier 3급 대형사고 자원 동원체계 · 기관별 역할분담·지휘계통 · WING 방제자산 연계 법적 근거', }, { title: 'A Mixed Integer Programming Approach to Improve Oil Spill Response Resource Allocation in the Canadian Arctic', source: 'Das, T., Goerlandt, F. & Pelot, R. | Multimodal Transportation Vol.3 No.1, 100110, 2023', desc: '혼합정수계획법으로 응급 방제자원 거점 위치 선택 + 자원 할당 동시 최적화. 비용·응답시간 트레이드오프 파레토 분석.', highlight: true, tags: [ { label: 'MIP 수리모델', color: 'var(--purple)' }, { label: '자원 위치 선택', color: 'var(--blue)' }, { label: '북극해 적용', color: 'var(--cyan)' }, ], }, { title: '유전알고리즘을 이용하여 최적화된 방제자원 배치안의 분포도 분석', source: '김혜진, 김용혁 | 한국융합학회논문지 Vol.11 No.4, pp.11–16, 2020', desc: 'GA(유전알고리즘)로 방제자원 배치 최적화 및 시뮬레이션 분포도 분석. 국내 해역 실정에 맞는 자원 배치 패턴 도출.', highlight: true, tags: [ { label: 'GA 메타휴리스틱', color: 'var(--purple)' }, { label: '국내 연구', color: 'var(--green, #22c55e)' }, { label: '배치 분포도 분석', color: 'var(--boom, #f59e0b)' }, ], }, { title: 'A Two-Stage Stochastic Optimization Framework for Environmentally Sensitive Oil Spill Response Resource Allocation', source: 'Rahman, M.A., Kuhel, M.T. & Novoa, C. | arXiv preprint arXiv:2511.22218, 2025', desc: '확률적 MILP 2단계 프레임워크로 불확실성 포함 최적 자원 배치. 환경민감구역 가중치 반영.', highlight: true, tags: [ { label: '확률적 MILP', color: 'var(--purple)' }, { label: '2단계 최적화', color: 'var(--blue)' }, { label: '환경민감구역', color: 'var(--green, #22c55e)' }, ], }, { title: 'Mixed-Integer Dynamic Optimization for Oil-Spill Response Planning with Integration of Dynamic Oil Weathering Model', source: 'You, F. & Leyffer, S. | Argonne National Laboratory Technical Note, 2008', desc: '동적 최적화(MINLP/MILP) 프레임워크로 오일스필 대응 스케줄링 + 오일 풍화·거동 물리모델 통합.', highlight: true, tags: [ { label: 'MINLP 동적 최적화', color: 'var(--purple)' }, { label: '오일 풍화 모델 통합', color: 'var(--boom, #f59e0b)' }, ], }, ], }, { icon: '🗄', title: '자산 현행화·데이터 관리', color: 'var(--green, #22c55e)', bgTint: 'rgba(34,197,94,.08)', items: [ { title: '해양오염방제자원 현황관리 지침', source: '해양경찰청 예규 | 방제자원 등록·현행화·이력관리 절차 규정', desc: '분기별 자산 실사 기준 · 자산분류코드 체계 · WING 업로드 양식(xlsx) 필드 정의 근거', }, { title: 'ISO 55000 — Asset Management: Overview, Principles and Terminology', source: 'International Organization for Standardization | ISO 55000:2014', desc: '자산 생애주기 관리 원칙 · 자산가치·상태 평가 프레임워크 · WING 자산 노후도·교체주기 산정 이론 기준', }, ], }, ] const TAG_COLORS: Record = { 'var(--purple)': { bg: 'rgba(168,85,247,0.08)', bd: 'rgba(168,85,247,0.2)', fg: '#a855f7' }, 'var(--blue)': { bg: 'rgba(59,130,246,0.08)', bd: 'rgba(59,130,246,0.2)', fg: '#3b82f6' }, 'var(--cyan)': { bg: 'rgba(6,182,212,0.08)', bd: 'rgba(6,182,212,0.2)', fg: '#06b6d4' }, 'var(--green, #22c55e)': { bg: 'rgba(34,197,94,0.08)', bd: 'rgba(34,197,94,0.2)', fg: '#22c55e' }, 'var(--boom, #f59e0b)': { bg: 'rgba(245,158,11,0.08)', bd: 'rgba(245,158,11,0.2)', fg: '#f59e0b' }, } function AssetTheoryTab() { return (
📚 방제자원 이론
방제자산 운용 기준·성능 이론 및 관련 법령·고시 근거 문헌
{/* Left column */}
{THEORY_SECTIONS.slice(0, 2).map((sec) => ( ))}
{/* Right column */}
{THEORY_SECTIONS.slice(2).map((sec) => ( ))}
) } function TheoryCard({ section }: { section: TheorySection }) { const badgeBg = section.bgTint.replace(/[\d.]+\)$/, '0.15)') return (
{/* Section Header */}
{section.icon} {section.title}
{/* Items */}
{section.items.map((item, i) => (
{/* Divider */} {section.dividerAfter !== undefined && i === section.dividerAfter + 1 && (
{section.dividerLabel}
)}
{/* Number badge */}
{['①','②','③','④','⑤','⑥','⑦','⑧','⑨','⑩'][i]}
{item.title}
{item.source}
{/* Tags */} {item.tags && (
{item.tags.map((tag, ti) => { const tc = TAG_COLORS[tag.color] || { bg: 'rgba(107,114,128,0.08)', bd: 'rgba(107,114,128,0.2)', fg: '#6b7280' } return ( {tag.label} ) })}
)}
{item.desc}
))}
) } // ── Tab 1: 자산 현행화 (업로드) ── function AssetUploadTab() { const [uploadMode, setUploadMode] = useState<'add' | 'replace'>('add') const [uploaded, setUploaded] = useState(false) const handleUpload = () => { setUploaded(true) setTimeout(() => setUploaded(false), 3000) } return (
{/* Left - Upload */}
📤 자산 데이터 업로드
{/* Drop Zone */}
📁
파일을 드래그하거나 클릭하여 업로드
엑셀(.xlsx), CSV 파일 지원 · 최대 10MB
{/* Asset Classification */}
{/* Jurisdiction */}
{/* Upload Mode */}
{/* Upload Button */}
{/* Right - Permission & History */}
{/* Permission System */}
🔐 수정 권한 체계
{[ { icon: '👑', role: '본청 관리자', desc: '전체 자산 조회·수정·삭제·업로드', color: 'text-status-red', bg: 'rgba(239,68,68,0.15)' }, { icon: '🏛', role: '지방청 담당자', desc: '소속 지방청 및 하위 해경서 자산 수정·업로드', color: 'text-status-orange', bg: 'rgba(249,115,22,0.15)' }, { icon: '⚓', role: '해경서 담당자', desc: '소속 해경서 자산 수정·업로드', color: 'text-primary-blue', bg: 'rgba(59,130,246,0.15)' }, { icon: '👤', role: '일반 사용자', desc: '조회·다운로드만 가능', color: 'text-text-2', bg: 'rgba(100,116,139,0.15)' }, ].map((p, i) => (
{p.icon}
{p.role}
{p.desc}
))}
{/* Upload History */}
📋 최근 업로드 이력
{uploadHistory.map((h, i) => (
{h.filename}
{h.date} · {h.uploader} · {h.count}건
완료
))}
) } // ── Tab 2: 선박 보험정보 — 한국해운조합 API 연동 ── function ShipInsuranceTab() { const [apiConnected, setApiConnected] = useState(false) const [showConfig, setShowConfig] = useState(false) const [configEndpoint, setConfigEndpoint] = useState('https://api.haewoon.or.kr/v1/insurance') const [configApiKey, setConfigApiKey] = useState('') const [configKeyType, setConfigKeyType] = useState('mmsi') const [configRespType, setConfigRespType] = useState('json') const [searchType, setSearchType] = useState('mmsi') const [searchVal, setSearchVal] = useState('') const [insTypeFilter, setInsTypeFilter] = useState('전체') const [viewState, setViewState] = useState<'empty' | 'loading' | 'result'>('empty') const [resultData, setResultData] = useState([]) const [lastSync, setLastSync] = useState('—') const placeholderMap: Record = { mmsi: 'MMSI 번호 입력 (예: 440123456)', imo: 'IMO 번호 입력 (예: 9876543)', shipname: '선박명 입력 (예: 한라호)', callsign: '호출부호 입력 (예: HLXX1)', } const getStatus = (expiry: string) => { const now = new Date() const exp = new Date(expiry) const daysLeft = Math.ceil((exp.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)) if (exp < now) return 'expired' as const if (daysLeft <= 30) return 'soon' as const return 'valid' as const } const handleSaveConfig = () => { if (!configApiKey) { alert('API Key를 입력하세요.'); return } setShowConfig(false) alert('API 설정이 저장되었습니다.') } const handleTestConnect = async () => { await new Promise(r => setTimeout(r, 1200)) alert('⚠ API Key가 설정되지 않았습니다.\n[API 설정] 버튼에서 한국해운조합 API Key를 먼저 등록하세요.') } const loadDemoData = () => { setResultData(insuranceDemoData) setViewState('result') setApiConnected(false) setLastSync(new Date().toLocaleString('ko-KR')) } const handleQuery = async () => { if (!searchVal.trim()) { alert('조회값을 입력하세요.'); return } setViewState('loading') await new Promise(r => setTimeout(r, 900)) loadDemoData() } const handleBatchQuery = async () => { setViewState('loading') await new Promise(r => setTimeout(r, 1400)) loadDemoData() } const handleFullSync = async () => { setLastSync('동기화 중...') await new Promise(r => setTimeout(r, 1000)) setLastSync(new Date().toLocaleString('ko-KR')) alert('전체 동기화는 API 연동 후 활성화됩니다.') } // summary computation const validCount = resultData.filter(r => getStatus(r.expiry) !== 'expired').length const soonList = resultData.filter(r => getStatus(r.expiry) === 'soon') const expiredList = resultData.filter(r => getStatus(r.expiry) === 'expired') return (
{/* ── 헤더 ── */}
🛡 선박 보험정보 조회
{apiConnected ? 'API 연결됨' : 'API 미연결'}
한국해운조합(KSA) Open API 연동 · 선박 P&I 보험 및 선주 책임보험 실시간 조회
{/* ── API 설정 패널 ── */} {showConfig && (
⚙ 한국해운조합 API 연동 설정
setConfigEndpoint(e.target.value)} placeholder="https://api.haewoon.or.kr/v1/..." style={{ width: '100%', padding: '9px 12px', background: 'var(--bg0)', border: '1px solid var(--bd)', borderRadius: 'var(--rS)', color: 'var(--t1)', fontFamily: 'var(--fM)', fontSize: 12, outline: 'none', boxSizing: 'border-box' }} />
setConfigApiKey(e.target.value)} placeholder="발급받은 API Key 입력" style={{ width: '100%', padding: '9px 12px', background: 'var(--bg0)', border: '1px solid var(--bd)', borderRadius: 'var(--rS)', color: 'var(--t1)', fontFamily: 'var(--fM)', fontSize: 12, outline: 'none', boxSizing: 'border-box' }} />
{/* API 연동 안내 */}
📋 한국해운조합 API 발급 안내
• 한국해운조합 공공데이터포털 또는 해운조합 IT지원팀에 API 키 신청
• 해양경찰청 기관 계정으로 신청 시 전용 엔드포인트 및 키 발급
• 조회 가능 데이터: P&I 보험, 선주책임보험, 해상보험 가입 여부, 증권번호, 보험기간, 보상한도
)} {/* ── 검색 영역 ── */}
🔍 보험정보 조회
setSearchVal(e.target.value)} placeholder={placeholderMap[searchType]} style={{ width: '100%', padding: '9px 14px', background: 'var(--bg0)', border: '1px solid var(--bd)', borderRadius: 'var(--rS)', color: 'var(--t1)', fontFamily: 'var(--fM)', fontSize: 13, outline: 'none', boxSizing: 'border-box' }} />
{/* ── 결과 영역 ── */} {/* 초기 안내 상태 */} {viewState === 'empty' && (
🛡
한국해운조합 API 연동 대기 중
API 설정에서 한국해운조합 API Key를 등록하거나
MMSI·IMO·선박명으로 직접 조회하세요.
자산목록 일괄조회 시 등록된 방제자산 전체의 보험 현황을 한번에 확인할 수 있습니다.
)} {/* 로딩 */} {viewState === 'loading' && (
한국해운조합 API 조회 중...
)} {/* 결과 테이블 */} {viewState === 'result' && ( <> {/* 요약 카드 */}
{[ { label: '전체', val: resultData.length, color: 'var(--cyan)', bg: 'rgba(6,182,212,.08)' }, { label: '유효', val: validCount, color: 'var(--green)', bg: 'rgba(34,197,94,.08)' }, { label: '만료임박(30일)', val: soonList.length, color: 'var(--yellow)', bg: 'rgba(234,179,8,.08)' }, { label: '만료/미가입', val: resultData.length - validCount, color: 'var(--red)', bg: 'rgba(239,68,68,.08)' }, ].map((c, i) => (
{c.val}
{c.label}
))}
{/* 테이블 */}
조회 결과 {resultData.length}
{[ { label: '선박명', align: 'left' }, { label: 'MMSI', align: 'center' }, { label: 'IMO', align: 'center' }, { label: '보험종류', align: 'center' }, { label: '보험사', align: 'center' }, { label: '증권번호', align: 'center' }, { label: '보험기간', align: 'center' }, { label: '보상한도', align: 'right' }, { label: '상태', align: 'center' }, ].map((h, i) => ( ))} {resultData.map((r, i) => { const st = getStatus(r.expiry) const isExp = st === 'expired' const isSoon = st === 'soon' return ( ) })}
{h.label}
{r.shipName} {r.mmsi || '—'} {r.imo || '—'} {r.insType} {r.insurer} {r.policyNo} {r.start} ~ {r.expiry} {r.limit} {isExp ? '만료' : isSoon ? '만료임박' : '유효'}
{/* 경고 */} {(expiredList.length > 0 || soonList.length > 0) && (
{expiredList.length > 0 && ( <>⛔ 만료 {expiredList.length}건: {expiredList.map(r => r.shipName).join(', ')}
)} {soonList.length > 0 && ( <>⚠ 만료임박(30일) {soonList.length}건: {soonList.map(r => r.shipName).join(', ')} )}
)} )} {/* ── API 연동 정보 푸터 ── */}
데이터 출처: 한국해운조합(KSA) · haewoon.or.kr
연동 방식: REST API (JSON) · 실시간 조회 · 캐시 TTL 1시간
마지막 동기화: {lastSync}
) } // ── Main AssetsView ── export function AssetsView() { const [activeTab, setActiveTab] = useState('management') return (
{/* Tab Navigation */}
{([ { id: 'management' as const, icon: '🗂', label: '자산 관리' }, { id: 'upload' as const, icon: '📤', label: '자산 현행화 (업로드)' }, { id: 'theory' as const, icon: '📚', label: '방제자원 이론' }, { id: 'insurance' as const, icon: '🛡', label: '선박 보험정보' }, ]).map(tab => ( ))}
👤 남해청_방제과 (수정 권한 ✅)
{/* Content */}
{activeTab === 'management' && } {activeTab === 'upload' && } {activeTab === 'theory' && } {activeTab === 'insurance' && }
) }