|
|
|
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<CbCamera> _cbCameraRep;
|
|
|
|
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
|
|
|
|
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep;
|
|
|
|
private readonly PtzServerApi _ptzServerApi;
|
|
|
|
private readonly CameraDataOptions options = App.GetOptions<CameraDataOptions>();
|
|
|
|
|
|
|
|
private Thread _thread { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// (cbCameraId, MarkSearcherBase)
|
|
|
|
/// </summary>
|
|
|
|
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// (cbCameraId, cbCameraIp)
|
|
|
|
/// </summary>
|
|
|
|
private Dictionary<long, string> _cbCameraId2IpDict { get; set; } = new();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// (cameraIp, TbPtzCamera)
|
|
|
|
/// </summary>
|
|
|
|
private ConcurrentDictionary<string, TbPtzCamera> _tbPtzCameraDict { get; set; } = new();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// (cameraIp, PtzInfo)
|
|
|
|
/// </summary>
|
|
|
|
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new();
|
|
|
|
|
|
|
|
#endregion Attr
|
|
|
|
|
|
|
|
public CameraDataCenter()
|
|
|
|
{
|
|
|
|
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>();
|
|
|
|
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>();
|
|
|
|
_tbPtzCameraRep = App.GetService<SqlSugarRepository<TbPtzCamera>>();
|
|
|
|
_ptzServerApi = App.GetService<PtzServerApi>();
|
|
|
|
Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void Init()
|
|
|
|
{
|
|
|
|
if (!options.LazyInit)
|
|
|
|
{
|
|
|
|
List<TbPtzCamera> 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
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 循环运行
|
|
|
|
/// </summary>
|
|
|
|
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<long, MarkSearcherBase> 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<MarkLabelCalcResult> resultList = markSearcher.Calc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion Loop
|
|
|
|
|
|
|
|
#region external call
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 激活 cbCamera 进入运算
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cameraId"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool ActiveCamera(long cameraId)
|
|
|
|
{
|
|
|
|
CbCamera cbCamera = _cbCameraRep.GetById(cameraId);
|
|
|
|
if (cbCamera == null) return false;
|
|
|
|
TbPtzCamera tbPtzCamera;
|
|
|
|
string cameraIp = cbCamera.Ip;
|
|
|
|
if (!_tbPtzCameraDict.IsExistKey(cameraIp))
|
|
|
|
{
|
|
|
|
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp);
|
|
|
|
if (tbPtzCamera == null) return false;
|
|
|
|
_tbPtzCameraDict[cameraIp] = tbPtzCamera;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tbPtzCamera = _tbPtzCameraDict[cameraIp];
|
|
|
|
}
|
|
|
|
_cbCameraId2IpDict[cbCamera.Id] = cameraIp;
|
|
|
|
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id));
|
|
|
|
HikMarkSeacher markSeacher = new(cameraCalcInfo);
|
|
|
|
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
_markSearcherDict[cameraId] = markSeacher;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 解除 cbCamera 进入运算
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cameraId"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool DeActiveCamera(long cameraId)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool UpdateCamera(long cameraId, long markLabelId)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion external call
|
|
|
|
}
|