fajiao
2 years ago
29 changed files with 1034 additions and 112 deletions
@ -0,0 +1,52 @@ |
|||
namespace Cis.Application.Cm; |
|||
|
|||
/// <summary>
|
|||
/// 标记标签表
|
|||
/// </summary>
|
|||
[SugarTable(CmInfo.CmMarkLabelTbName, CmInfo.CmMarkLabelTbDesc)] |
|||
[Tenant(CmInfo.DbName)] |
|||
public class CmMarkLabel : EntityBase |
|||
{ |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "名称", Length = 64)] |
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Pan 位置
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "Pan位置")] |
|||
public double PanPosition { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Tilt 位置
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "Tilt位置")] |
|||
public double TiltPosition { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Zoom 位置
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "Zoom位置")] |
|||
public double ZoomPosition { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 备注
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "备注", Length = 256)] |
|||
[MaxLength(256)] |
|||
public string Remark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 相机 Id
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "相机Id")] |
|||
public long CbCameraId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 标记组 Id
|
|||
/// </summary>
|
|||
[SugarColumn(ColumnDescription = "标记组Id")] |
|||
public long CmMarkGroupId { get; set; } |
|||
} |
@ -0,0 +1,55 @@ |
|||
using Newtonsoft.Json.Linq; |
|||
|
|||
namespace Cis.Application.Cm; |
|||
|
|||
/// <summary>
|
|||
/// 标记标签服务
|
|||
/// </summary>
|
|||
[ApiDescriptionSettings(CmInfo.GroupName, Order = CmInfo.GroupOrder)] |
|||
public class CmMarkLabelService : IDynamicApiController, ITransient |
|||
{ |
|||
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLabelRep; |
|||
|
|||
public CmMarkLabelService(SqlSugarRepository<CmMarkLabel> cmMarkLabelRep) |
|||
{ |
|||
_cmMarkLabelRep = cmMarkLabelRep; |
|||
} |
|||
|
|||
public async Task<CmMarkLabel> Get(long id) |
|||
{ |
|||
CmMarkLabel entity = await _cmMarkLabelRep.GetByIdAsync(id); |
|||
return entity; |
|||
} |
|||
|
|||
public async Task<List<CmMarkLabel>> GetList(string queryJson = "") |
|||
{ |
|||
JObject queryObj = queryJson.ToJObject(); |
|||
List<CmMarkLabel> list = await _cmMarkLabelRep.AsQueryable() |
|||
.ToListAsync(); |
|||
return list; |
|||
} |
|||
|
|||
public async Task<List<CmMarkLabel>> GetPageList(string queryJson, string pagination) |
|||
{ |
|||
Pagination pageObj = pagination.ToObject<Pagination>(); |
|||
JObject queryObj = queryJson.ToJObject(); |
|||
List<CmMarkLabel> list = await _cmMarkLabelRep.AsQueryable() |
|||
.ToPageListAsync(pageObj.Index, pageObj.Size); |
|||
return list; |
|||
} |
|||
|
|||
public async Task Add(CmMarkLabel entity) |
|||
{ |
|||
await _cmMarkLabelRep.InsertAsync(entity); |
|||
} |
|||
|
|||
public async Task Update(CmMarkLabel entity) |
|||
{ |
|||
await _cmMarkLabelRep.UpdateAsync(entity); |
|||
} |
|||
|
|||
public async Task Delete(CmMarkLabel entity) |
|||
{ |
|||
await _cmMarkLabelRep.DeleteAsync(entity); |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
namespace Cis.Application.Core; |
|||
|
|||
public class MarkSearcherBase |
|||
{ |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace Cis.Application.Core; |
|||
|
|||
/// <summary>
|
|||
/// Ptz Api 接口
|
|||
/// </summary>
|
|||
public interface IPtzApi |
|||
{ |
|||
|
|||
} |
@ -0,0 +1,198 @@ |
|||
using System.Net.Sockets; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace Cis.Application.Core; |
|||
|
|||
/// <summary>
|
|||
/// Ptz Api
|
|||
/// </summary>
|
|||
public class PtzServerApi : IPtzApi, ISingleton |
|||
{ |
|||
#region Attr
|
|||
|
|||
private TcpClient _tcpClient { get; set; } |
|||
|
|||
private NetworkStream _stream { get; set; } |
|||
|
|||
#endregion Attr
|
|||
|
|||
public PtzServerApi() |
|||
{ |
|||
PtzServerOptions options = App.GetOptions<PtzServerOptions>(); |
|||
_tcpClient = new TcpClient(options.Ip, options.Port); |
|||
//创建一个 networkstream 用来写入和读取数据
|
|||
_stream = _tcpClient.GetStream(); |
|||
} |
|||
|
|||
public RequestRealControl GetPtzInfo(int cameraId) |
|||
{ |
|||
RequestRealControl realControl = new(); |
|||
try |
|||
{ |
|||
string recieve_string = string.Empty; |
|||
realControl.token = 666; |
|||
|
|||
realControl.CameraInfo.cameraid = cameraId; |
|||
realControl.Status = true; |
|||
realControl.realControlType = RealControlType.PTZINFO_GET_; |
|||
byte[] data = StructToByte(realControl); |
|||
_stream.Write(data, 0, data.Length); |
|||
|
|||
byte[] recieve_byte = new byte[_tcpClient.ReceiveBufferSize]; |
|||
_stream.Read(recieve_byte, 0, (int)_tcpClient.ReceiveBufferSize); |
|||
//stream.BeginRead(recieve_byte, 0, (int)tcp_client.ReceiveBufferSize,EndRead, stream);
|
|||
realControl = (RequestRealControl)BytetoStruct(recieve_byte, typeof(RequestRealControl)); |
|||
if (realControl.PTZPositionInfo.FT < 0) |
|||
{ |
|||
realControl.PTZPositionInfo.FT = 3600 + realControl.PTZPositionInfo.FT; |
|||
} |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
realControl = default; |
|||
} |
|||
return realControl; |
|||
} |
|||
|
|||
public static byte[] StructToByte(object structObj) |
|||
{ |
|||
//获取结构体大小
|
|||
int size = Marshal.SizeOf(structObj); |
|||
|
|||
byte[] data = new byte[size]; |
|||
|
|||
//分配内存空间
|
|||
IntPtr structPtr = Marshal.AllocHGlobal(size); |
|||
// 将结构体数据复制到内存空间
|
|||
Marshal.StructureToPtr(structObj, structPtr, false); |
|||
// 将内存空间的数据拷贝到byte数组
|
|||
Marshal.Copy(structPtr, data, 0, size); |
|||
//释放内存
|
|||
Marshal.FreeHGlobal(structPtr); |
|||
return data; |
|||
} |
|||
|
|||
public static object BytetoStruct(byte[] bytes, Type type) |
|||
{ |
|||
object obj = new object(); |
|||
try |
|||
{ |
|||
byte[] temp = bytes; |
|||
// 获取结构体大小
|
|||
int size = Marshal.SizeOf(type); |
|||
if (size > bytes.Length) |
|||
return null; |
|||
// 分配结构体内存空间
|
|||
IntPtr structPtr = Marshal.AllocHGlobal(size); |
|||
// 将byte数组内容拷贝到内存中
|
|||
Marshal.Copy(temp, 0, structPtr, size); |
|||
|
|||
// 将内存空间转化为目标结构体
|
|||
obj = Marshal.PtrToStructure(structPtr, type); |
|||
//释放内存
|
|||
Marshal.FreeHGlobal(structPtr); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
} |
|||
return obj; |
|||
} |
|||
|
|||
} |
|||
|
|||
#region 与ptz服务交互使用结构体
|
|||
|
|||
//----------------------------------------------------------------------------------------
|
|||
// 与ptz服务交互使用结构体
|
|||
//----------------------------------------------------------------------------------------
|
|||
//注意这个属性不能少
|
|||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] |
|||
public struct RequestRealControl |
|||
{ |
|||
public int token; |
|||
|
|||
public CameraInfo CameraInfo; |
|||
|
|||
public RealControlType realControlType; |
|||
|
|||
//请求时 状态 true:开始;false:结束 答复时:true:成功;其他:失败
|
|||
public bool Status; |
|||
|
|||
public PresentInfo PresentInfo; |
|||
|
|||
public PTZPosInfo PTZPositionInfo; |
|||
//int数组,SizeConst表示数组的个数,在转换成
|
|||
//byte数组前必须先初始化数组,再使用,初始化
|
|||
//的数组长度必须和SizeConst一致,例test = new int[6];
|
|||
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
|||
//public int[] test;
|
|||
} |
|||
|
|||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] |
|||
public struct CameraInfo |
|||
{ |
|||
public int cameraid; |
|||
|
|||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] |
|||
public char[] ip; |
|||
|
|||
public ushort port; |
|||
|
|||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] |
|||
private char[] user; |
|||
|
|||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] |
|||
private char[] password; |
|||
} |
|||
|
|||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] |
|||
public struct PresentInfo |
|||
{ |
|||
public int presentNo;//预置位编号
|
|||
|
|||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] |
|||
private char[] PresentName; // 预置位名称
|
|||
} |
|||
|
|||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] |
|||
public struct PTZPosInfo |
|||
{ |
|||
public int FP;//p信息
|
|||
public int FT;//T信息
|
|||
public int FZ;//Z信息
|
|||
public int TitlePosMin;//描述点垂直参数min
|
|||
public int ZoomPosMin;//描述点变倍参数min
|
|||
|
|||
public float FHorWidth;//水平宽度 精确到小数点后两位 *10000
|
|||
public float FVerWidth;//垂直宽度 精确到小数点后两位 *10000
|
|||
public float FFold;//zoom=1没变时的焦距 精确到小数点后两位 *100
|
|||
|
|||
public int CameraType; |
|||
} |
|||
|
|||
public enum RealControlType |
|||
{ |
|||
MOVE_UP_ = 1, |
|||
MOVE_DOWN_, |
|||
MOVE_LEFT_, |
|||
MOVE_RIGHT_, |
|||
MOVE_LEFTUP_, |
|||
MOVE_LEFTDOWN_, |
|||
MOVE_RIGHTUP_, |
|||
MOVE_RIGHTDOWN_, |
|||
|
|||
ZOOM_IN_, |
|||
ZOOM_OUT_, |
|||
FOCUS_NEAR_, |
|||
FOCUS_FAR_, |
|||
IRIS_OPEN_, |
|||
IRIS_CLOSE_, |
|||
|
|||
PRESET_SET_, |
|||
PRESET_CALL_, |
|||
|
|||
PTZINFO_GET_, |
|||
PTZINFO_SET_ |
|||
} |
|||
|
|||
#endregion 与ptz服务交互使用结构体
|
@ -0,0 +1,113 @@ |
|||
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 Thread _thread { get; set; } |
|||
private List<TbPtzCamera> _tbPtzCameraList { get; set; } |
|||
private ConcurrentDictionary<string, CameraCalcInfo> _cameraPtzInfoDict { get; set; } |
|||
|
|||
private readonly SqlSugarRepository<CbCamera> _cbCameraRep; |
|||
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep; |
|||
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep; |
|||
private readonly PtzServerApi _ptzServerApi; |
|||
|
|||
#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() |
|||
{ |
|||
// 初始化 tbPtzCameraList
|
|||
_tbPtzCameraList = _tbPtzCameraRep.GetList(); |
|||
// 根据 Ip 去重
|
|||
_tbPtzCameraList = _tbPtzCameraList.Where((a, i) => _tbPtzCameraList.FindIndex(b => b.Ip == a.Ip) == i).ToList(); |
|||
|
|||
// 初始化 ptzInfoDict
|
|||
_cameraPtzInfoDict = new ConcurrentDictionary<string, CameraCalcInfo>(); |
|||
|
|||
// 初始化 thread
|
|||
_thread = new Thread(WorkLoop) |
|||
{ |
|||
IsBackground = true// 设置后台线程
|
|||
}; |
|||
_thread.Start(); |
|||
} |
|||
|
|||
private void LazyInit() |
|||
{ |
|||
// 初始化 tbPtzCameraList
|
|||
_tbPtzCameraList = new(); |
|||
|
|||
// 初始化 ptzInfoDict
|
|||
_cameraPtzInfoDict = new ConcurrentDictionary<string, CameraCalcInfo>(); |
|||
|
|||
// 初始化 thread
|
|||
_thread = new Thread(WorkLoop) |
|||
{ |
|||
IsBackground = true// 设置后台线程
|
|||
}; |
|||
_thread.Start(); |
|||
} |
|||
|
|||
#region Loop
|
|||
|
|||
private void WorkLoop() |
|||
{ |
|||
while (true) |
|||
{ |
|||
GetPtzInfoByApi(); |
|||
Thread.Sleep(10000); |
|||
} |
|||
} |
|||
|
|||
private void GetPtzInfoByApi() |
|||
{ |
|||
foreach (TbPtzCamera item in _tbPtzCameraList) |
|||
{ |
|||
RequestRealControl rrc = _ptzServerApi.GetPtzInfo(item.CameraId); |
|||
CameraCalcInfo ptzInfo = new() |
|||
{ |
|||
Pan = rrc.PTZPositionInfo.FP, |
|||
Tilt = rrc.PTZPositionInfo.FT, |
|||
Zoom = rrc.PTZPositionInfo.FZ |
|||
}; |
|||
_cameraPtzInfoDict[item.Ip] = ptzInfo; |
|||
} |
|||
} |
|||
|
|||
private void Calc() |
|||
{ |
|||
} |
|||
|
|||
#endregion Loop
|
|||
|
|||
#region external call
|
|||
|
|||
public bool GetCamera(string ip) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public bool ActiveCamera(string ip) |
|||
{ |
|||
|
|||
|
|||
return false; |
|||
} |
|||
|
|||
#endregion external call
|
|||
} |
@ -0,0 +1,22 @@ |
|||
namespace Cis.Application.Core; |
|||
|
|||
/// <summary>
|
|||
/// PtzServer选项
|
|||
/// </summary>
|
|||
public class PtzServerOptions : IConfigurableOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 服务类别
|
|||
/// </summary>
|
|||
public string Type { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 服务IP
|
|||
/// </summary>
|
|||
public string Ip { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 服务端口
|
|||
/// </summary>
|
|||
public int Port { get; set; } |
|||
} |
@ -0,0 +1,32 @@ |
|||
namespace Cis.Application.Core; |
|||
|
|||
/// <summary>
|
|||
/// 相机 Ptz 信息
|
|||
/// </summary>
|
|||
public class CameraCalcInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 图像的宽度
|
|||
/// </summary>
|
|||
public int ImageWidth { get; set; } = 1920; |
|||
|
|||
/// <summary>
|
|||
/// 图像的宽度
|
|||
/// </summary>
|
|||
public int ImageHeight { get; set; } = 1080; |
|||
|
|||
/// <summary>
|
|||
/// Pan
|
|||
/// </summary>
|
|||
public double Pan { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Tilt
|
|||
/// </summary>
|
|||
public double Tilt { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Zoom
|
|||
/// </summary>
|
|||
public double Zoom { get; set; } |
|||
} |
@ -0,0 +1,22 @@ |
|||
using Cis.Application.Cm; |
|||
|
|||
namespace Cis.Application.Core; |
|||
|
|||
[ApiDescriptionSettings(CmInfo.GroupName, Order = CmInfo.GroupOrder)] |
|||
public class MarkSearchService : IDynamicApiController, ITransient |
|||
{ |
|||
#region Attr
|
|||
|
|||
private CameraDataCenter _cameraDataCenter { get; set; } |
|||
|
|||
#endregion Attr
|
|||
|
|||
public MarkSearchService(CameraDataCenter cameraDataCenter) |
|||
{ |
|||
_cameraDataCenter = cameraDataCenter; |
|||
} |
|||
|
|||
public void ActivateCamera() |
|||
{ |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Cis.Application.Tb; |
|||
|
|||
public class TbInfo |
|||
{ |
|||
#region Database Info
|
|||
|
|||
/// <summary>
|
|||
/// 数据库标识
|
|||
/// </summary>
|
|||
public const string DbName = "serverdb"; |
|||
|
|||
#endregion Database Info
|
|||
|
|||
#region Table Info
|
|||
|
|||
/// <summary>
|
|||
/// TbPtzCamera 表名
|
|||
/// </summary>
|
|||
public const string TbPtzCameraTbName = "tb_ptzcamera"; |
|||
|
|||
#endregion Table Info
|
|||
} |
|||
|
@ -0,0 +1,28 @@ |
|||
namespace Cis.Application.Tb; |
|||
|
|||
[SugarTable(TbInfo.TbPtzCameraTbName)] |
|||
[Tenant(TbInfo.DbName)] |
|||
public class TbPtzCamera |
|||
{ |
|||
public int Id { get; set; } |
|||
|
|||
public int Type { get; set; } |
|||
|
|||
public string Ip { get; set; } |
|||
|
|||
public int Port { get; set; } |
|||
|
|||
public string User { get; set; } |
|||
|
|||
public string Pass { get; set; } |
|||
|
|||
public int CameraId { get; set; } |
|||
|
|||
public double PanPosition { get; set; } |
|||
|
|||
public double TitlePosition { get; set; } |
|||
|
|||
public double ZoomPosition { get; set; } |
|||
|
|||
public byte Request { get; set; } |
|||
} |
@ -0,0 +1,51 @@ |
|||
using Newtonsoft.Json.Linq; |
|||
|
|||
namespace Cis.Application.Tb; |
|||
|
|||
public class TbPtzCameraService : ITransient |
|||
{ |
|||
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep; |
|||
|
|||
public TbPtzCameraService(SqlSugarRepository<TbPtzCamera> tbPtzCameraRep) |
|||
{ |
|||
_tbPtzCameraRep = tbPtzCameraRep; |
|||
} |
|||
|
|||
public async Task<TbPtzCamera> Get(int id) |
|||
{ |
|||
TbPtzCamera entity = await _tbPtzCameraRep.GetByIdAsync(id); |
|||
return entity; |
|||
} |
|||
|
|||
public async Task<List<TbPtzCamera>> GetList(string queryJson = "") |
|||
{ |
|||
JObject queryObj = !string.IsNullOrEmpty(queryJson) ? queryJson.ToJObject():default; |
|||
List<TbPtzCamera> list = await _tbPtzCameraRep.AsQueryable() |
|||
.ToListAsync(); |
|||
return list; |
|||
} |
|||
|
|||
public async Task<List<TbPtzCamera>> GetPageList(string pagination, string queryJson = "") |
|||
{ |
|||
Pagination pageObj = pagination.ToObject<Pagination>(); |
|||
JObject queryObj = queryJson.ToJObject(); |
|||
List<TbPtzCamera> list = await _tbPtzCameraRep.AsQueryable() |
|||
.ToPageListAsync(pageObj.Index, pageObj.Size); |
|||
return list; |
|||
} |
|||
|
|||
public async Task Add(TbPtzCamera entity) |
|||
{ |
|||
await _tbPtzCameraRep.InsertAsync(entity); |
|||
} |
|||
|
|||
public async Task Update(TbPtzCamera entity) |
|||
{ |
|||
await _tbPtzCameraRep.UpdateAsync(entity); |
|||
} |
|||
|
|||
public async Task Delete(TbPtzCamera entity) |
|||
{ |
|||
await _tbPtzCameraRep.DeleteAsync(entity); |
|||
} |
|||
} |
After Width: | Height: | Size: 25 KiB |
Loading…
Reference in new issue