From 905796a7eab0471b5ce409a4e5ceb5594224ec23 Mon Sep 17 00:00:00 2001 From: fengyarnom Date: Tue, 5 Nov 2024 09:37:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8D=95=E6=AC=A1=E8=A7=A3?= =?UTF-8?q?=E7=AE=97=E7=BC=93=E5=AD=98=E6=9C=8D=E5=8A=A1=E5=92=8C=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=8E=A7=E5=88=B6=E7=B1=BB=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20GnssSingleBufferService=20=E6=9C=8D=E5=8A=A1=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=8C=81=E4=B9=85=E5=8C=96=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E5=8D=95=E6=AC=A1=E8=A7=A3=E7=AE=97=E7=9A=84=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=20-=20=E6=96=B0=E5=A2=9E=E5=8D=95=E6=AC=A1=E8=A7=A3?= =?UTF-8?q?=E7=AE=97=E6=9C=89=E5=85=B3=E7=9A=84=E9=A1=B5=E9=9D=A2=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E7=B1=BB=E5=92=8C=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calc/SingleLineGNSSCalcService.java | 43 ++- .../D3F2StopIndicationMessageExecutor.java | 8 + .../sideslope/sal/DbDeviceServiceImpl.java | 1 + .../service/GnssSingleBufferService.java | 10 + .../service/GnssSingleBufferServiceImpl.java | 84 ++++++ .../controller/GnssSingleDataController.java | 95 +++++++ .../static/api/init_super_admin.json | 6 + .../templates/page/gnss_single_data.html | 249 ++++++++++++++++++ 8 files changed, 492 insertions(+), 4 deletions(-) create mode 100644 sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/GnssSingleBufferService.java create mode 100644 sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/service/GnssSingleBufferServiceImpl.java create mode 100644 sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssSingleDataController.java create mode 100644 sec-beidou/src/main/resources/templates/page/gnss_single_data.html diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java index 04ee65b1..139d34c6 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/calc/SingleLineGNSSCalcService.java @@ -3,16 +3,14 @@ package com.imdroid.sideslope.calc; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.imdroid.common.util.DataTypeUtil; import com.imdroid.common.util.ThreadManager; -import com.imdroid.secapi.dto.GnssCalcData; -import com.imdroid.secapi.dto.GnssCalcDataMapper; -import com.imdroid.secapi.dto.GnssGroupCalc; -import com.imdroid.secapi.dto.GnssGroupCalcMapper; +import com.imdroid.secapi.dto.*; import com.imdroid.sideslope.bd.*; import com.imdroid.sideslope.message.D341LocationMessage; import com.imdroid.sideslope.sal.Device; import com.imdroid.sideslope.sal.DeviceService; import com.imdroid.sideslope.server.DeviceChannel; import com.imdroid.sideslope.server.OnlineChannels; +import com.imdroid.sideslope.service.GnssSingleBufferService; import com.imdroid.sideslope.service.WarningService; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -56,6 +54,9 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService { @Autowired GnssCalcDataMapper dataMapper; + @Autowired + private GnssSingleBufferService gnssSingleDataService; + // 非线程安全,需加同步保护 List groupCalcList; @@ -121,21 +122,27 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService { // 读取惯导 Tilt tilt = message.getTilt(); + if(tilt != null) { focusCalculator.addTilt(tilt); if (logger.isDebugEnabled()) { logger.debug("测站{}惯导单次解析结果:{}", deviceId,tilt); } + + } // 延迟 focusCalculator.addDelayMs(message.getPps()); + + // 单次b562 double[] doubles = message.getB562_loc();//unit: mm if(doubles !=null) { focusCalculator.addXyz(doubles, message.getCreateTime()); logger.info("测站{}的b562单次解析结果:{}", deviceId,Arrays.toString(doubles)); + } // 单次GGA @@ -144,11 +151,39 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService { focusCalculator.addGGA(gga); logger.info("测站{}的gga单次解析结果:{},{},{},{}",deviceId, gga.getLongitude(), gga.getLatitude(), gga.getAltitude(), gga.getQuality()); + + if(groupCalc.getVer() == 7 && focusCalculator.isJump()){ logger.info("{}发生周跳",deviceId); hardResetDevice(deviceId); } } + + // 保存单次解析的原始数据,受 loggingmode 字段控制 + GnssSingleData gnssSingleData = new GnssSingleData(); + gnssSingleData.setDeviceid(device.getDeviceId()); + gnssSingleData.setCreatetime(LocalDateTime.now()); + gnssSingleData.setModel(device.getModel()); + // 若是该设备开启了日志记录,则保存单次解析的数据 + if(device.getLoggingmode() == GnssDevice.LOGGING_MODE_FULL){ + if((device.getModel() == GnssDevice.MODEL_G505) && (doubles !=null)){ + gnssSingleData.setX(doubles[0]); + gnssSingleData.setY(doubles[1]); + gnssSingleData.setZ(doubles[2]); + gnssSingleData.setStatus((int) doubles[3]); + gnssSingleDataService.addData(gnssSingleData); + } + else if((device.getModel() == GnssDevice.MODEL_G510) && (gga !=null)){ + gnssSingleData.setX(gga.getLatitude()); + gnssSingleData.setY(gga.getLongitude()); + gnssSingleData.setZ(gga.getAltitude()); + gnssSingleData.setStatus(gga.getQuality()); + gnssSingleDataService.addData(gnssSingleData); + } + } + + + } @Override diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D3F2StopIndicationMessageExecutor.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D3F2StopIndicationMessageExecutor.java index 1876acd2..8edfb147 100644 --- a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D3F2StopIndicationMessageExecutor.java +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/executor/D3F2StopIndicationMessageExecutor.java @@ -9,6 +9,7 @@ import com.imdroid.sideslope.message.D3F2StopIndicationMessage; import com.imdroid.sideslope.sal.Device; import com.imdroid.sideslope.sal.DeviceService; import com.imdroid.sideslope.service.DataPersistService; +import com.imdroid.sideslope.service.GnssSingleBufferServiceImpl; import com.imdroid.sideslope.service.WarningService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,6 +40,9 @@ public class D3F2StopIndicationMessageExecutor implements Executor buffer = new ArrayList<>(); + + // BUFFER_SIZE 暂定此大小 + private static final int BUFFER_SIZE = 1024; + // 资源锁 + private final Object lock = new Object(); + + @Autowired + private GnssSingleDataMapper gnssDataMapper; + + @Autowired + private GnssSingleDataMapper gnssSingleDataMapper; + + @Override + public void addData(GnssSingleData data) { + if (data == null) { + return; + } + synchronized (lock) { + buffer.add(data); + if (buffer.size() >= BUFFER_SIZE) { + // 溢出时直接保存 + // 此处暂定,但很有必要引入一个线程来保存,避免阻塞主线程 + flush(); + } + } + } + + @Override + public void flush() { + synchronized (lock) { + if (buffer.isEmpty()) { + return; + } + + try { + List batchList = new ArrayList<>(buffer); + buffer.clear(); + // 由于每秒写数据库操作频繁,这里采用批量保存的方式 + saveBatch(batchList); + + logger.debug("批量插入{}条数据成功", batchList.size()); + } catch (Exception e) { + logger.error("批量插入数据失败", e); + throw e; + } + } + } + + private void saveBatch(List dataList) { + for (GnssSingleData data : dataList) { + gnssSingleDataMapper.insert(data); + } + } + + @Override + public void clear() { + synchronized (lock) { + buffer.clear(); + } + } + + @Override + public int getBufferSize() { + synchronized(lock) { + return buffer.size(); + } + } +} diff --git a/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssSingleDataController.java b/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssSingleDataController.java new file mode 100644 index 00000000..5076867c --- /dev/null +++ b/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssSingleDataController.java @@ -0,0 +1,95 @@ +package com.imdroid.beidou.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.imdroid.beidou.service.CommonExcelService; +import com.imdroid.secapi.dto.GnssCalcData; +import com.imdroid.secapi.dto.GnssCalcDataMapper; +import com.imdroid.secapi.dto.GnssSingleData; +import com.imdroid.secapi.dto.GnssSingleDataMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpSession; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Controller +public class GnssSingleDataController extends BasicController implements CommonExcelService { + + @Autowired + GnssSingleDataMapper gnssSingleDataMapper; + + final DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + + @RequestMapping("/page/gnss_single_data") + public String gnssSingleData(Model m, HttpSession session){ + initModel(m, session); + + return "/page/gnss_single_data"; + } + + + @RequestMapping("/gnss/data/list_single_data") + @ResponseBody + public JSONObject listData(HttpSession session, Integer page, Integer limit, String searchParams) { + // 检查查询条件 + JSONObject search = null; + if (searchParams != null) { + search = (JSONObject) JSONObject.parse(searchParams); + System.out.println(search); + String deviceId = search.getString("deviceid"); + Integer freqency = search.getInteger("freqency"); + String begin = search.getString("dgt_.createtime"); + String end = search.getString("dlt_.createtime"); + + if(deviceId != null && !deviceId.isEmpty() && freqency!=0){ + Page pageable = new Page<>(page == null ? 1 : page, limit == null ? 10 : limit); + + // 缺省按1小时采样,如果时间跨度较大,则按最多300条记录的采样率采样 + int sample = 6; + + if(freqency == 2){ + LocalDateTime endTime = LocalDateTime.now(); + LocalDateTime beginTime = endTime.minusDays(30); + if(begin!=null && !begin.isEmpty()){ + beginTime = LocalDateTime.parse(begin,df); + } + if(end!=null && !end.isEmpty()){ + endTime = LocalDateTime.parse(end,df); + } + Duration duration = Duration.between(beginTime, endTime); + int hours = (int)duration.toHours(); + if(hours > 300) sample = hours*6/300; + } + Page calcDataList = gnssSingleDataMapper.queryByDeviceId(pageable, deviceId,begin,end,sample); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", 0); + jsonObject.put("msg", ""); + jsonObject.put("count", calcDataList.getTotal()); + jsonObject.put("data", calcDataList.getRecords()); + return jsonObject; + } + } + + return this.pageList(session, page, limit, searchParams); + } + + + @Override + public Class getEntityClass() { + return GnssSingleData.class; + } + + @Override + public BaseMapper getMapper() { + return gnssSingleDataMapper; + } +} diff --git a/sec-beidou/src/main/resources/static/api/init_super_admin.json b/sec-beidou/src/main/resources/static/api/init_super_admin.json index 5229f44c..5691ebf9 100644 --- a/sec-beidou/src/main/resources/static/api/init_super_admin.json +++ b/sec-beidou/src/main/resources/static/api/init_super_admin.json @@ -53,6 +53,12 @@ "icon": "fa fa-calculator", "target": "_self" }, + { + "title": "单次解算记录", + "href": "page/gnss_single_data", + "icon": "fa fa-clipboard", + "target": "_self" + }, { "title": "配置管理", "href": "", diff --git a/sec-beidou/src/main/resources/templates/page/gnss_single_data.html b/sec-beidou/src/main/resources/templates/page/gnss_single_data.html new file mode 100644 index 00000000..3555a637 --- /dev/null +++ b/sec-beidou/src/main/resources/templates/page/gnss_single_data.html @@ -0,0 +1,249 @@ + + + + + 单次解算记录 + + + + + + + +
+
+
+ 搜索信息 +
+
+
+
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+ +
+
+ +
+ + +
+
+
+
+
+
+
    +
  • 数据表格
  • +
  • 单个设备曲线
  • +
+
+
+
+
+
+
+
+
+
+ + +
+
+ + + + + + \ No newline at end of file