优化移动位置解析方式

This commit is contained in:
lin 2026-04-16 18:01:18 +08:00
parent 0984e8f1ed
commit 04789eecab
2 changed files with 93 additions and 57 deletions

View File

@ -1,6 +1,16 @@
package com.genersoft.iot.vmp.gb28181.bean; package com.genersoft.iot.vmp.gb28181.bean;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.utils.DateUtil;
import lombok.Data; import lombok.Data;
import org.dom4j.Element;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
/** /**
* @description: 移动位置bean * @description: 移动位置bean
@ -69,6 +79,50 @@ public class MobilePosition {
*/ */
private String createTime; private String createTime;
public static List<MobilePosition> decode(String deviceName, String deviceId, Element rootElementAfterCharset) {
List<MobilePosition> mobilePositions = new ArrayList<>();
MobilePosition mobilePosition = new MobilePosition();
mobilePosition.setCreateTime(DateUtil.getNow());
if (!ObjectUtils.isEmpty(deviceName)) {
mobilePosition.setDeviceName(deviceName);
}
mobilePosition.setDeviceId(deviceId);
String channelId = getText(rootElementAfterCharset, "DeviceID");
mobilePosition.setChannelDeviceId(channelId);
String time = getText(rootElementAfterCharset, "Time");
if (ObjectUtils.isEmpty(time)){
mobilePosition.setTime(DateUtil.getNow());
}else {
mobilePosition.setTime(SipUtils.parseTime(time));
}
mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude")));
mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude")));
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) {
mobilePosition.setSpeed(Double.parseDouble(getText(rootElementAfterCharset, "Speed")));
} else {
mobilePosition.setSpeed(0.0);
}
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Direction"))) {
mobilePosition.setDirection(Double.parseDouble(getText(rootElementAfterCharset, "Direction")));
} else {
mobilePosition.setDirection(0.0);
}
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Altitude"))) {
mobilePosition.setAltitude(Double.parseDouble(getText(rootElementAfterCharset, "Altitude")));
} else {
mobilePosition.setAltitude(0.0);
}
mobilePosition.setReportSource("Mobile Position");
mobilePositions.add(mobilePosition);
return mobilePositions;
}
@Override @Override
public String toString() { public String toString() {
return "MobilePosition{" + return "MobilePosition{" +

View File

@ -1,33 +1,29 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService; import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.service.IMobilePositionService;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.utils.DateUtil;
import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException; import org.dom4j.DocumentException;
import org.dom4j.Element; import org.dom4j.Element;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor; import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.sip.InvalidArgumentException; import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent; import javax.sip.RequestEvent;
import javax.sip.SipException; import javax.sip.SipException;
import javax.sip.message.Response; import javax.sip.message.Response;
import java.text.ParseException; import java.text.ParseException;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
/** /**
* 移动设备位置数据通知设备主动发起不需要上级订阅 * 移动设备位置数据通知设备主动发起不需要上级订阅
*/ */
@ -38,16 +34,17 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
private final String cmdType = "MobilePosition"; private final String cmdType = "MobilePosition";
@Autowired private final NotifyMessageHandler notifyMessageHandler;
private NotifyMessageHandler notifyMessageHandler;
@Autowired private final IMobilePositionService mobilePositionService;
private IDeviceChannelService deviceChannelService;
private ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>(); private final IDeviceChannelService deviceChannelService;
@Autowired private final ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>();
private TaskExecutor taskExecutor;
private final TaskExecutor taskExecutor;
private final EventPublisher eventPublisher;
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
@ -75,53 +72,38 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
log.warn("[移动位置通知] {}处理失败,未识别到信息体", device.getDeviceId()); log.warn("[移动位置通知] {}处理失败,未识别到信息体", device.getDeviceId());
continue; continue;
} }
String channelId = getText(rootElementAfterCharset, "DeviceID");
DeviceChannel deviceChannel = deviceChannelService.getOne(device.getDeviceId(), channelId);
if (deviceChannel == null) {
log.warn("[解析移动位置通知] 未找到通道:{}/{}", device.getDeviceId(), channelId);
continue;
}
MobilePosition mobilePosition = new MobilePosition(); List<MobilePosition> mobilePositionList = MobilePosition.decode(sipMsgInfo.getDevice().getName(), sipMsgInfo.getDevice().getDeviceId(), rootElementAfterCharset);
mobilePosition.setCreateTime(DateUtil.getNow()); mobilePositionList.forEach(mobilePosition -> {
if (!ObjectUtils.isEmpty(sipMsgInfo.getDevice().getName())) { try {
mobilePosition.setDeviceName(sipMsgInfo.getDevice().getName()); // 更新device channel 的经纬度
} DeviceChannel deviceChannel = deviceChannelService.getOne(device.getDeviceId(), mobilePosition.getChannelDeviceId());
mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); if (deviceChannel == null) {
log.warn("[解析移动位置通知] 未找到通道:{}/{}", device.getDeviceId(), mobilePosition.getChannelDeviceId());
return;
}
mobilePosition.setChannelId(deviceChannel.getId());
mobilePosition.setReportSource("Mobile Position");
mobilePosition.setChannelId(deviceChannel.getId()); log.info("[收到移动位置订阅通知]{}/{}->{}.{}, 时间: {}", mobilePosition.getDeviceId(), mobilePosition.getChannelDeviceId(),
mobilePosition.setChannelDeviceId(deviceChannel.getDeviceId()); mobilePosition.getLongitude(), mobilePosition.getLatitude(), mobilePosition.getTime());
String time = getText(rootElementAfterCharset, "Time");
if (ObjectUtils.isEmpty(time)){
mobilePosition.setTime(DateUtil.getNow());
}else {
mobilePosition.setTime(SipUtils.parseTime(time));
}
mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude")));
mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude")));
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) {
mobilePosition.setSpeed(Double.parseDouble(getText(rootElementAfterCharset, "Speed")));
} else {
mobilePosition.setSpeed(0.0);
}
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Direction"))) {
mobilePosition.setDirection(Double.parseDouble(getText(rootElementAfterCharset, "Direction")));
} else {
mobilePosition.setDirection(0.0);
}
if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Altitude"))) {
mobilePosition.setAltitude(Double.parseDouble(getText(rootElementAfterCharset, "Altitude")));
} else {
mobilePosition.setAltitude(0.0);
}
mobilePosition.setReportSource("Mobile Position");
// 更新device channel 的经纬度 mobilePositionService.add(mobilePosition);
deviceChannel.setLongitude(mobilePosition.getLongitude()); // 向关联了该通道并且开启移动位置订阅的上级平台发送移动位置订阅消息
deviceChannel.setLatitude(mobilePosition.getLatitude()); try {
deviceChannel.setGpsTime(mobilePosition.getTime()); eventPublisher.mobilePositionEventPublish(mobilePosition);
}catch (Exception e) {
log.error("[MobilePositionEvent] 发送失败: ", e);
}
deviceChannelService.updateChannelGPS(device, deviceChannel, mobilePosition); deviceChannel.setLongitude(mobilePosition.getLongitude());
deviceChannel.setLatitude(mobilePosition.getLatitude());
deviceChannel.setGpsTime(mobilePosition.getTime());
deviceChannelService.updateChannelGPS(device, deviceChannel, mobilePosition);
}catch (Exception e) {
log.error("未处理的异常 ", e);
}
});
} catch (DocumentException e) { } catch (DocumentException e) {
log.error("未处理的异常 ", e); log.error("未处理的异常 ", e);