using Cis.Application.Cb; using Cis.Application.Cm; using Cis.Application.Tb; using System.Collections.Concurrent; namespace Cis.Application.Core; public class CameraDataCenter { #region Attr private readonly SqlSugarRepository _cbCameraRep; private readonly SqlSugarRepository _cmMarkLableRep; private readonly SqlSugarRepository _tbPtzCameraRep; private readonly PtzServerApi _ptzServerApi; private readonly CameraDataOptions options = App.GetOptions(); private Thread _thread { get; set; } /// /// (cbCameraId, cbCameraIp) /// private Dictionary _cbCameraId2IpDict { get; set; } = new(); /// /// (cameraIp, TbPtzCamera) /// private ConcurrentDictionary _tbPtzCameraDict { get; set; } = new(); /// /// (cameraIp, PtzInfo) /// private ConcurrentDictionary _cameraPtzInfoDict { get; set; } = new(); /// /// _markSearcherDict 锁对象,写锁 /// private static readonly ReaderWriterLockSlim msDictLock = new(); /// /// (cbCameraId, MarkSearcherBase) /// private ConcurrentDictionary _markSearcherDict { get; set; } = new(); /// /// (cameraId, List(MarkLabelCalcResult)) /// private ConcurrentDictionary> _markLabelCalcResultListDict { get; set; } = new(); #endregion Attr public CameraDataCenter() { _cbCameraRep = App.GetService>(); _cmMarkLableRep = App.GetService>(); _tbPtzCameraRep = App.GetService>(); _ptzServerApi = App.GetService(); Init(); } private void Init() { if (!options.LazyInit) { List list = _tbPtzCameraRep.GetList(); // 根据 Ip 去重 foreach (TbPtzCamera item in list) { if (!_tbPtzCameraDict.ContainsKey(item.Ip)) _tbPtzCameraDict[item.Ip] = item; } } // 初始化 thread _thread = new Thread(WorkLoop) { IsBackground = true// 设置后台线程 }; _thread.Start(); } #region Loop /// /// 循环运行 /// private void WorkLoop() { while (true) { RefreshPtzInfoByApi(); RefreshMarkSearcher(); Thread.Sleep(options.LoopInterval); } } private void RefreshPtzInfoByApi() { foreach (TbPtzCamera item in _tbPtzCameraDict.Values) { PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId); _cameraPtzInfoDict[item.Ip] = ptzInfo; } } private void RefreshMarkSearcher() { foreach (KeyValuePair pair in _markSearcherDict) { long cameraId = pair.Key; MarkSearcherBase markSearcher = pair.Value; string cameraIp = _cbCameraId2IpDict[cameraId]; if (cameraIp == null) continue; PtzInfo ptzInfo = _cameraPtzInfoDict[cameraIp]; if (ptzInfo == null) continue; markSearcher.UpdateCameraCalcInfo(ptzInfo); List resultList = markSearcher.Calc(); _markLabelCalcResultListDict[cameraId] = resultList; } } #endregion Loop #region external call /// /// 激活 cbCamera 进入运算 /// /// /// public bool ActiveCamera(long cameraId) { try { msDictLock.EnterWriteLock(); if (_markSearcherDict.ExistsKey(cameraId)) return false; // 获取 cbCamera CbCamera cbCamera = _cbCameraRep.GetById(cameraId); if (cbCamera == null) return false; // 获取 tbPtzCamera TbPtzCamera tbPtzCamera; string cameraIp = cbCamera.Ip; if (!_tbPtzCameraDict.ExistsKey(cameraIp)) { tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); if (tbPtzCamera == null) return false; _tbPtzCameraDict[cameraIp] = tbPtzCamera; } else { tbPtzCamera = _tbPtzCameraDict[cameraIp]; } // 存储 cbCamera id 对应 ip 关系 _cbCameraId2IpDict[cbCamera.Id] = cameraIp; // 创建 cameraCalcInfo CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); // 创建 markSeacher HikMarkSeacher markSeacher = new(cameraCalcInfo); // 获取 cmMarkLabel 列表 List cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); // 将 cmMarkLabel 一一添加到 markSeacher foreach (CmMarkLabel item in cmMarkLabelList) { MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( item.Id, PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition), item.CanvasWidth, item.CanvasHeight, item.CanvasLeft, item.CanvasTop ); markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); } // 将 markSeacher 放入字典 _markSearcherDict[cameraId] = markSeacher; } finally { msDictLock.ExitWriteLock(); } return true; } /// /// 解除 cbCamera 进入运算 /// /// /// public bool DeActiveCamera(long cameraId) { try { msDictLock.EnterWriteLock(); _markSearcherDict.Remove(cameraId); _markLabelCalcResultListDict.Remove(cameraId); } finally { msDictLock.ExitWriteLock(); } return true; } public bool AddCameraMarkLabel(long cameraId, long markLabelId) { if (!_markSearcherDict.ExistsKey(cameraId)) return false; MarkSearcherBase markSearcher = _markSearcherDict[cameraId]; if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId)) return false; CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId); if (label == null) return false; MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( label.Id, PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition), label.CanvasWidth, label.CanvasHeight, label.CanvasLeft, label.CanvasTop ); return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); } public bool DeleteCameraMarkLabel(long cameraId, long marklabelId) { if (!_markSearcherDict.ExistsKey(cameraId)) return false; MarkSearcherBase markSearcher = _markSearcherDict[cameraId]; return markSearcher.DeleteMarkLabelCalcInfo(marklabelId); } public List GetMarkLabelCalcResults(long cameraId) { return null; } #endregion external call }