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 ReaderWriterLockSlim msDictLock { get; } = 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; bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp); if (!ret) continue; ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo); if (!ret) continue; markSearcher.UpdateCameraCalcInfo(ptzInfo); List resultList = markSearcher.Calc(); _markLabelCalcResultListDict[cameraId] = resultList; } } #endregion Loop #region external call /// /// 激活 cbCamera 进入运算 /// /// /// public bool ActivateSearcher(long cameraId) { try { msDictLock.EnterWriteLock(); if (_markSearcherDict.ContainsKey(cameraId)) return false; // 获取 cbCamera CbCamera cbCamera = _cbCameraRep.GetById(cameraId); if (cbCamera == null) return false; // 获取 tbPtzCamera string cameraIp = cbCamera.Ip; bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera); if (!ret) { tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); if (tbPtzCamera == null) return false; _tbPtzCameraDict[cameraIp] = tbPtzCamera; } // 存储 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.VideoWidth, item.VideoHeight, item.CanvasLeftRatio, item.CanvasTopRatio ); markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); } // 将 markSeacher 放入字典 _markSearcherDict[cameraId] = markSeacher; } finally { msDictLock.ExitWriteLock(); } return true; } /// /// 解除 cbCamera 进入运算 /// /// /// public bool DeActivateSearcher(long cameraId) { try { msDictLock.EnterWriteLock(); _markSearcherDict.Remove(cameraId); _markLabelCalcResultListDict.Remove(cameraId); } finally { msDictLock.ExitWriteLock(); } return true; } public bool IsExistSearcher(long cameraId) { return _markSearcherDict.ContainsKey(cameraId); } public bool ActivateMarkLabel(long cameraId, long markLabelId) { bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); if (!ret) return false; 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.VideoWidth, label.VideoHeight, label.CanvasLeftRatio, label.CanvasTopRatio ); return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); } public bool DectivateMarkLabel(long cameraId, long markLabelId) { bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false; } public bool IsExistCameraMarkLabel(long cameraId, long markLabelId) { bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) && markSearcher.ExistsMarkLabelCalcInfo(markLabelId); return ret; } public List GetMarkLabelCalcResultList(long cameraId) { bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List list); return ret ? list : new(); } public PtzInfo GetCameraPtzInfo(long cameraId) { PtzInfo ptzInfo = null; bool ret = _cbCameraId2IpDict.TryGetValue(cameraId,out string cameraIp) && _cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo); return ret ? ptzInfo : null; } public async Task ActivateSearcherAsync(long cameraId) { return await Task.Run(() => { return ActivateSearcher(cameraId); }); } public async Task DeActivateSearcherAsync(long cameraId) { return await Task.Run(() => { return DeActivateSearcher(cameraId); }); } public async Task IsExistSearcherAsync(long cameraId) { return await Task.Run(() => { return IsExistSearcher(cameraId); }); } public async Task ActivateMarkLabelAsync(long cameraId, long markLabelId) { return await Task.Run(() => { return ActivateMarkLabel(cameraId, markLabelId); }); } public async Task DeactivateMarkLabelAsync(long cameraId, long markLabelId) { return await Task.Run(() => { return DectivateMarkLabel(cameraId, markLabelId); }); } public async Task IsExistMarkLabelAysnc(long cameraId, long markLabelId) { return await Task.Run(() => { return IsExistCameraMarkLabel(cameraId, markLabelId); }); } public async Task> GetMarkLabelCalcResultListAsync(long cameraId) { return await Task.Run(() => { return GetMarkLabelCalcResultList(cameraId); }); } #endregion external call }