tdwy-service/src/main/java/com/whdc/service/impl/VehicleDetectionService.java

311 lines
11 KiB
Java
Raw Normal View History

2025-12-03 11:25:15 +08:00
package com.whdc.service.impl;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.whdc.alarm.NVSSDK2;
import com.whdc.alarm.NetClient2;
import com.whdc.entity.AlarmRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@Service
public class VehicleDetectionService {
@Value("${app.image-save-path}")
private String imageSavePath;
@Autowired
private AlarmRecordService alarmRecordService;
private int m_iLogonID = -1;
private int m_iConnectID = -1;
private boolean isRunning = false;
private ExecutorService executorService;
private String[] strCarPlateColor = new String[NVSSDK2.MAX_CAR_PLATE_COLOR];
private String[] strCarColor = new String[NVSSDK2.MAX_CAR_COLOR];
// @PostConstruct
public void init() {
executorService = Executors.newSingleThreadExecutor();
initValueString();
createImageDirectory();
startDetection();
}
@PreDestroy
public void destroy() {
stopDetection();
if (executorService != null) {
executorService.shutdown();
}
}
private void initValueString() {
strCarPlateColor[0] = "unknown";
strCarPlateColor[1] = "white on blue";
strCarPlateColor[2] = "black on yellow";
strCarPlateColor[3] = "Black on white";
strCarPlateColor[4] = "black and white";
strCarPlateColor[5] = "white on green";
strCarColor[0] = "white";
strCarColor[1] = "red";
strCarColor[2] = "yellow";
// ... 其他颜色定义
}
private void createImageDirectory() {
File dir = new File(imageSavePath);
if (!dir.exists()) {
if (dir.mkdirs()) {
System.out.println("创建图片保存目录成功: " + imageSavePath);
} else {
System.err.println("创建图片保存目录失败: " + imageSavePath);
}
}
}
public void startDetection() {
if (isRunning) {
return;
}
executorService.execute(() -> {
try {
isRunning = true;
System.out.println("开始车辆检测...");
// SDK初始化
if (sdkInit() != 0) {
System.err.println("SDK初始化失败");
return;
}
// 设备登录(这里需要根据实际情况配置)
if (logonDevice("192.168.1.100", "admin", "password", 3000) != 0) {
System.err.println("设备登录失败");
return;
}
// 开始抓拍
startSnap();
// 保持运行
while (isRunning) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
} catch (Exception e) {
System.err.println("车辆检测服务异常: " + e.getMessage());
e.printStackTrace();
} finally {
stopDetection();
}
});
}
public void stopDetection() {
isRunning = false;
if (m_iConnectID != -1) {
NetClient2.StopRecv(m_iConnectID);
m_iConnectID = -1;
}
if (m_iLogonID != -1) {
NetClient2.Logoff(m_iLogonID);
m_iLogonID = -1;
}
NetClient2.Cleanup();
System.out.println("车辆检测服务已停止");
}
private int sdkInit() {
NVSSDK2.SDK_VERSION ver = new NVSSDK2.SDK_VERSION();
int iRet = NetClient2.GetVersion(ver);
System.out.println("[SDK_VERSION]" + ver.m_cVerInfo);
// 设置回调函数
iRet = NetClient2.SetNotifyFunction(
new NVSSDK2.MAIN_NOTIFY() {
public void MainNotify(int iLogonID, int wParam, Pointer lParam, Pointer noitfyUserData) {
// 处理主通知
}
},
new NVSSDK2.ALARM_NOTIFY() {
public void AlarmNotify(int iLogonID, int iChannel, int iAlarmState, int iAlarmType, Pointer pUserData) {
// 处理告警通知
}
},
new NVSSDK2.PARACHANGE_NOTIFY() {
public void ParaChangeNotify(int iLogonID, int iChannel, int paraType, Pointer para, Pointer noitfyUserData) {
// 处理参数变化通知
}
}
);
System.out.println("SetNotifyFunction(" + iRet + ")");
iRet = NetClient2.Startup();
System.out.println("Startup(" + iRet + ")");
return iRet;
}
private int logonDevice(String ip, String username, String password, int port) {
m_iLogonID = NetClient2.Logon("", ip, username, password, "", port);
// 等待登录成功
int retryCount = 0;
while (retryCount < 30) {
int logonStatus = NetClient2.GetLogonStatus(m_iLogonID);
if (logonStatus == NVSSDK2.LOGON_SUCCESS) {
log.info("设备登录成功: {}", ip);
return 0;
} else if (logonStatus == NVSSDK2.LOGON_FAILED) {
System.err.println("设备登录失败: " + ip);
return -1;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return -1;
}
retryCount++;
}
System.err.println("设备登录超时: " + ip);
return -1;
}
private int startSnap() {
NVSSDK2.NetPicPara tNetPicParam = new NVSSDK2.NetPicPara();
tNetPicParam.iStructLen = tNetPicParam.size();
tNetPicParam.iChannelNo = 0;
tNetPicParam.cbkPicStreamNotify = new NVSSDK2.NET_PICSTREAM_NOTIFY() {
public int PicDataNotify(int ulID, int lCommand, Pointer tInfo, int iLen, Pointer lpUserData) {
return handlePicData(ulID, lCommand, tInfo, iLen, lpUserData);
}
};
tNetPicParam.pvUser = null;
IntByReference pConnectID = new IntByReference();
int iRet = NetClient2.StartRecvNetPicStream(m_iLogonID, tNetPicParam, tNetPicParam.size(), pConnectID);
if (iRet < 0) {
m_iConnectID = -1;
System.out.println("StartRecvNetPicStream Failed!");
return -1;
} else {
m_iConnectID = pConnectID.getValue();
System.out.println("StartRecvNetPicStream Success! ConnectID(" + m_iConnectID + ")");
return 0;
}
}
private int handlePicData(int ulID, int lCommand, Pointer tInfo, int iLen, Pointer lpUserData) {
if (lCommand != NVSSDK2.NET_PICSTREAM_CMD_ITS) {
return 0;
}
try {
NVSSDK2.ItsPicStream tItsPicStream = new NVSSDK2.ItsPicStream();
tItsPicStream.write();
Pointer pItsBuffer = tItsPicStream.getPointer();
byte[] RecvBuffer = tInfo.getByteArray(0, iLen);
int iCopySize = Math.min(tItsPicStream.size(), iLen);
pItsBuffer.write(0, RecvBuffer, 0, iCopySize);
tItsPicStream.read();
String strIP = new String(tItsPicStream.cCameraIP).trim();
String strPlate = new String(tItsPicStream.cPlate).trim();
// 检测到车辆,生成告警
if (!strPlate.isEmpty() && !strPlate.equals("未知")) {
log.info("检测到车辆闯入: {}, IP: {}", strPlate, strIP);
// 保存图片
String imageFileName = saveVehicleImage(tItsPicStream);
// 创建告警记录
createAlarmRecord(tItsPicStream, imageFileName);
}
} catch (Exception e) {
System.err.println("处理图片数据异常: " + e.getMessage());
e.printStackTrace();
}
return 0;
}
private String saveVehicleImage(NVSSDK2.ItsPicStream tItsPicStream) {
String fileName = "vehicle_" + System.currentTimeMillis() + "_" +
new String(tItsPicStream.cPlate).trim() + ".jpg";
String filePath = imageSavePath + File.separator + fileName;
// 这里简化图片保存逻辑实际需要根据SDK的图片数据结构来保存
try {
// 实际实现需要根据tItsPicStream中的图片数据来保存
log.info("保存车辆图片: " + filePath);
return fileName;
} catch (Exception e) {
System.err.println("保存车辆图片失败: " + e.getMessage());
return "";
}
}
private void createAlarmRecord(NVSSDK2.ItsPicStream tItsPicStream, String imageFileName) {
try {
AlarmRecord alarm = new AlarmRecord();
alarm.setCameraIP(new String(tItsPicStream.cCameraIP).trim());
alarm.setLicensePlate(new String(tItsPicStream.cPlate).trim());
alarm.setChannelID(tItsPicStream.iChannelID);
alarm.setSpeed((double) tItsPicStream.fSpeed);
alarm.setAlarmType(tItsPicStream.iAlarmType);
alarm.setAlarmCode(new String(tItsPicStream.cAlarmCode).trim());
alarm.setImagePath(imageFileName);
alarm.setAlarmTime(LocalDateTime.now());
// 设置车辆颜色
if (tItsPicStream.iCarColor >= 0 && tItsPicStream.iCarColor < strCarColor.length) {
alarm.setCarColor(strCarColor[tItsPicStream.iCarColor]);
} else {
alarm.setCarColor("unknown");
}
// 设置车牌颜色
if (tItsPicStream.iPlateColor >= 0 && tItsPicStream.iPlateColor < strCarPlateColor.length) {
alarm.setPlateColor(strCarPlateColor[tItsPicStream.iPlateColor]);
} else {
alarm.setPlateColor("unknown");
}
// 保存到数据库
alarmRecordService.saveAlarmRecord(alarm);
log.info("告警记录保存成功: {}", alarm.getLicensePlate());
} catch (Exception e) {
log.error("创建告警记录失败: {}", e.getMessage());
}
}
public boolean isRunning() {
return isRunning;
}
}