feat(aerial): CCTV 안전관리 감지 기능 추가 (선박 출입, 침입 감지)
This commit is contained in:
부모
9574594151
커밋
5b734d3cf1
@ -12,6 +12,8 @@ interface CCTVPlayerProps {
|
|||||||
sourceNm?: string | null;
|
sourceNm?: string | null;
|
||||||
cellIndex?: number;
|
cellIndex?: number;
|
||||||
oilDetectionEnabled?: boolean;
|
oilDetectionEnabled?: boolean;
|
||||||
|
vesselDetectionEnabled?: boolean;
|
||||||
|
intrusionDetectionEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CCTVPlayerHandle {
|
export interface CCTVPlayerHandle {
|
||||||
@ -36,6 +38,8 @@ export const CCTVPlayer = forwardRef<CCTVPlayerHandle, CCTVPlayerProps>(({
|
|||||||
sourceNm,
|
sourceNm,
|
||||||
cellIndex = 0,
|
cellIndex = 0,
|
||||||
oilDetectionEnabled = false,
|
oilDetectionEnabled = false,
|
||||||
|
vesselDetectionEnabled = false,
|
||||||
|
intrusionDetectionEnabled = false,
|
||||||
}, ref) => {
|
}, ref) => {
|
||||||
const videoRef = useRef<HTMLVideoElement>(null);
|
const videoRef = useRef<HTMLVideoElement>(null);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@ -309,6 +313,24 @@ export const CCTVPlayer = forwardRef<CCTVPlayerHandle, CCTVPlayerProps>(({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 안전관리 감지 상태 배지 */}
|
||||||
|
{(vesselDetectionEnabled || intrusionDetectionEnabled) && (
|
||||||
|
<div className="absolute top-2 right-2 flex flex-col gap-1 z-20">
|
||||||
|
{vesselDetectionEnabled && (
|
||||||
|
<div className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[8px] font-bold"
|
||||||
|
style={{ background: 'rgba(59,130,246,.3)', color: '#93c5fd' }}>
|
||||||
|
🚢 선박 출입 감지 중
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{intrusionDetectionEnabled && (
|
||||||
|
<div className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[8px] font-bold"
|
||||||
|
style={{ background: 'rgba(249,115,22,.3)', color: '#fdba74' }}>
|
||||||
|
🚨 침입 감지 중
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* OSD 오버레이 */}
|
{/* OSD 오버레이 */}
|
||||||
<div className="absolute top-2 left-2 flex items-center gap-1.5 z-20">
|
<div className="absolute top-2 left-2 flex items-center gap-1.5 z-20">
|
||||||
<span className="text-[9px] font-bold px-1.5 py-0.5 rounded bg-black/70 text-white">
|
<span className="text-[9px] font-bold px-1.5 py-0.5 rounded bg-black/70 text-white">
|
||||||
|
|||||||
@ -56,6 +56,8 @@ export function CctvView() {
|
|||||||
const [gridMode, setGridMode] = useState(1)
|
const [gridMode, setGridMode] = useState(1)
|
||||||
const [activeCells, setActiveCells] = useState<CctvCameraItem[]>([])
|
const [activeCells, setActiveCells] = useState<CctvCameraItem[]>([])
|
||||||
const [oilDetectionEnabled, setOilDetectionEnabled] = useState(false)
|
const [oilDetectionEnabled, setOilDetectionEnabled] = useState(false)
|
||||||
|
const [vesselDetectionEnabled, setVesselDetectionEnabled] = useState(false)
|
||||||
|
const [intrusionDetectionEnabled, setIntrusionDetectionEnabled] = useState(false)
|
||||||
const playerRefs = useRef<(CCTVPlayerHandle | null)[]>([])
|
const playerRefs = useRef<(CCTVPlayerHandle | null)[]>([])
|
||||||
|
|
||||||
const loadData = useCallback(async () => {
|
const loadData = useCallback(async () => {
|
||||||
@ -240,6 +242,28 @@ export function CctvView() {
|
|||||||
>
|
>
|
||||||
{oilDetectionEnabled ? '🛢 감지 ON' : '🛢 오일 감지'}
|
{oilDetectionEnabled ? '🛢 감지 ON' : '🛢 오일 감지'}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setVesselDetectionEnabled(v => !v)}
|
||||||
|
className="px-2.5 py-1 border rounded-[5px] text-[10px] font-semibold cursor-pointer font-korean transition-colors"
|
||||||
|
style={vesselDetectionEnabled
|
||||||
|
? { background: 'rgba(59,130,246,.15)', borderColor: 'rgba(59,130,246,.4)', color: 'var(--blue, #3b82f6)' }
|
||||||
|
: { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t2)' }
|
||||||
|
}
|
||||||
|
title={gridMode === 9 ? '9분할 모드에서는 비활성화됩니다' : '선박 출입 감지'}
|
||||||
|
>
|
||||||
|
{vesselDetectionEnabled ? '🚢 감지 ON' : '🚢 선박 출입'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setIntrusionDetectionEnabled(v => !v)}
|
||||||
|
className="px-2.5 py-1 border rounded-[5px] text-[10px] font-semibold cursor-pointer font-korean transition-colors"
|
||||||
|
style={intrusionDetectionEnabled
|
||||||
|
? { background: 'rgba(249,115,22,.15)', borderColor: 'rgba(249,115,22,.4)', color: 'var(--orange, #f97316)' }
|
||||||
|
: { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t2)' }
|
||||||
|
}
|
||||||
|
title={gridMode === 9 ? '9분할 모드에서는 비활성화됩니다' : '침입 감지'}
|
||||||
|
>
|
||||||
|
{intrusionDetectionEnabled ? '🚨 감지 ON' : '🚨 침입 감지'}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
playerRefs.current.forEach(r => r?.capture())
|
playerRefs.current.forEach(r => r?.capture())
|
||||||
@ -269,6 +293,8 @@ export function CctvView() {
|
|||||||
sourceNm={cam.sourceNm}
|
sourceNm={cam.sourceNm}
|
||||||
cellIndex={i}
|
cellIndex={i}
|
||||||
oilDetectionEnabled={oilDetectionEnabled && gridMode !== 9}
|
oilDetectionEnabled={oilDetectionEnabled && gridMode !== 9}
|
||||||
|
vesselDetectionEnabled={vesselDetectionEnabled && gridMode !== 9}
|
||||||
|
intrusionDetectionEnabled={intrusionDetectionEnabled && gridMode !== 9}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-[10px] text-text-3 font-korean opacity-40">카메라를 선택하세요</div>
|
<div className="text-[10px] text-text-3 font-korean opacity-40">카메라를 선택하세요</div>
|
||||||
|
|||||||
불러오는 중...
Reference in New Issue
Block a user