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

311 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}