diff --git a/zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java b/zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java index 6a926a72..8d034717 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java @@ -1,8 +1,11 @@ package com.zc.business.controller; import java.util.List; +import java.util.Map; import javax.servlet.http.HttpServletResponse; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -62,6 +65,21 @@ public class DcBoardReleaseLogController extends BaseController public void export(HttpServletResponse response, DcBoardReleaseLog dcBoardReleaseLog) { List list = dcBoardReleaseLogService.selectDcBoardReleaseLogList(dcBoardReleaseLog); + for (DcBoardReleaseLog releaseLog : list) { + String content = releaseLog.getReleaseContent(); + List> contentList = JSONArray.parseObject(content,List.class); + if (contentList != null){ + StringBuilder contentText = new StringBuilder(); + for (int i = 0; i < contentList.size(); i++) { + String contentItem = contentList.get(i+1).get("CONTENT").toString().replace("\\\\n"," "); + contentText.append(i).append(".").append(contentItem).append("\n"); + } + releaseLog.setReleaseContent(contentText.toString()); + } else { + releaseLog.setReleaseContent(""); + } + + } ExcelUtil util = new ExcelUtil<>(DcBoardReleaseLog.class); util.exportExcel(response, list, "情报板内容发布日志数据"); } diff --git a/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java b/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java index 452e8407..bc99bd59 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java @@ -31,6 +31,7 @@ import javax.validation.Valid; import java.io.IOException; import java.lang.reflect.Field; import java.util.*; +import java.util.stream.Collectors; /** * 设备Controller @@ -240,17 +241,26 @@ public class DcDeviceController extends BaseController { Object data = JSON.parseObject(queryDeviceProperties(deviceId, propertyId, props).get("data").toString()).get("data"); JSONArray dataArray = JSON.parseArray(data.toString()); - List list = new ArrayList<>(); + List> list = new ArrayList<>(); dataArray.forEach(o -> { Map map = new HashMap<>(); JSONObject jsonObject = JSON.parseObject(o.toString()); JSONObject formatValue = JSON.parseObject(jsonObject.get("formatValue").toString()); map.put("1", formatValue.get("1")); map.put("3", formatValue.get("3")); - map.put("timestamp", jsonObject.get("timestamp")); + map.put("timestamp", formatValue.get("equipmentReportingTime") == null? "":formatValue.get("equipmentReportingTime")); list.add(map); }); - return AjaxResult.success(list); + List> newList = list.stream() + .filter(map-> !map.get("timestamp").equals("")) + .collect(Collectors.toList()); + Collections.sort(newList, new Comparator>() { + @Override + public int compare(Map map1, Map map2) { + return map1.get("timestamp").toString().compareTo(map2.get("timestamp").toString()); + } + }); + return AjaxResult.success(newList); } /** @@ -447,27 +457,31 @@ public class DcDeviceController extends BaseController { @ApiOperation("批量设备功能调用") @PostMapping("/batchFunctions") public AjaxResult batchInvokedFunction(@RequestBody Map props) throws HttpException, IOException, InterruptedException { - List devices = (List) props.get("devices"); - JSONArray functions = (JSONArray) props.get("functions"); + ArrayList devices = (ArrayList) props.get("devices"); + ArrayList functions = (ArrayList) props.get("functions"); JSONArray resultArray = new JSONArray(); - for (DcDevice device : devices) { - String iotDeviceId = device.getIotDeviceId(); + for (Object dev : devices) { + // 将Object转换为JSONObject + JSONObject device = (JSONObject) JSON.toJSON(dev); + //JSONObject device = (JSONObject) JSON.toJSON(dev.toString()); + String iotDeviceId = device.getString("iotDeviceId"); for (Object function : functions) { - JSONObject functionJSONObject = JSONObject.parseObject(String.valueOf(function)); + JSONObject functionJSONObject = (JSONObject) JSON.toJSON(function); + //JSONObject functionJSONObject = (JSONObject) JSON.toJSON(function.toString()) ; String functionId = functionJSONObject.getString("functionId"); - JSONObject jsonObject = functionJSONObject.getJSONObject("params"); + JSONObject jsonObject = functionJSONObject.getJSONObject("params") != null?functionJSONObject.getJSONObject("params"):new JSONObject(); resultArray.add(getResult(device, iotDeviceId, functionId, jsonObject)); } } return AjaxResult.success(resultArray); } - private JSONObject getResult(DcDevice device, String iotDeviceId, String functionId, JSONObject jsonObject) throws HttpException, IOException { + private JSONObject getResult(JSONObject device, String iotDeviceId, String functionId, JSONObject jsonObject) throws HttpException, IOException { HashMap params = jsonObject.toJavaObject(new TypeReference>() { }); JSONObject result = new JSONObject(); - result.put("device", device.getId()); - if (device.getDeviceType().equals(DeviceTypeConstants.ROAD_SECTION_VOICE_BROADCASTING)) { + result.put("device", device.getString("id")); + if (device.getInteger("deviceType").equals(DeviceTypeConstants.ROAD_SECTION_VOICE_BROADCASTING)) { result.put("result", broadcastController.nearCamListDistance(jsonObject)); } else { result.put("result", invokedFunction(iotDeviceId, functionId, params)); diff --git a/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java index 828e8712..eb1224cc 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java @@ -2,13 +2,13 @@ package com.zc.business.controller; import com.ruoyi.common.core.domain.AjaxResult; import com.zc.business.domain.DcTrafficMetricsData; +import com.zc.business.domain.DcTrafficSectionData; import com.zc.business.request.DcTrafficMetricsDataRequest; +import com.zc.business.request.DcTrafficSectionDataRequest; import com.zc.business.service.DcTrafficStatisticsService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -27,6 +27,37 @@ public class DcTrafficStatisticsController { private DcTrafficStatisticsService dcTrafficStatisticsService; + /** + * 获取当前交通截面数据 + * + * @param request 请求参数,封装了对于交通截面数据查询的详细要求 + * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前交通截面的数据(DcTrafficSectionData类型) + */ + @ApiOperation("获取当前交通截面数据") + @GetMapping("/current/sections") + public AjaxResult currentSections(DcTrafficSectionDataRequest request){ + // 调用服务层方法,查询当前交通截面数据 + List dcTrafficMetricsData = dcTrafficStatisticsService.currentSections(request); + // 将查询结果封装为AjaxResult对象返回 + return AjaxResult.success(dcTrafficMetricsData); + } + + /** + * 获取历史交通截面数据 + * + * @param request 包含交通截面数据请求参数的对象 + * @return 返回一个包含历史交通截面数据的AjaxResult对象 + */ + @ApiOperation("获取历史交通截面数据") + @GetMapping("/history/sections") + public AjaxResult historySections(DcTrafficSectionDataRequest request){ + // 调用服务层方法,获取历史交通截面的统计数据 + List dcTrafficMetricsData = dcTrafficStatisticsService.historySections(request); + // 将获取到的历史交通截面数据封装成AjaxResult对象并返回 + return AjaxResult.success(dcTrafficMetricsData); + } + + /** * 获取当前交通特征指数 * @@ -37,7 +68,7 @@ public class DcTrafficStatisticsController { @GetMapping("/current/metrics") public AjaxResult currentTrafficMetrics(DcTrafficMetricsDataRequest request){ // 调用服务层方法,获取当前交通指标数据 - DcTrafficMetricsData dcTrafficMetricsData = dcTrafficStatisticsService.currentTrafficMetrics(request); + List dcTrafficMetricsData = dcTrafficStatisticsService.currentTrafficMetrics(request); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(dcTrafficMetricsData); } diff --git a/zc-business/src/main/java/com/zc/business/controller/WordController.java b/zc-business/src/main/java/com/zc/business/controller/WordController.java index b2879914..775ff31f 100644 --- a/zc-business/src/main/java/com/zc/business/controller/WordController.java +++ b/zc-business/src/main/java/com/zc/business/controller/WordController.java @@ -128,68 +128,75 @@ public class WordController { PoiUtil.createHeading2(doc,"天气情况统计"); - XWPFTable table = doc.createTable(9, 25); - //列宽自动分割 - CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW(); - infoTableWidth.setType(STTblWidth.DXA); - infoTableWidth.setW(BigInteger.valueOf(9072)); - AjaxResult ajaxResult = weatherForecastController.hourlyWeather(); if (ajaxResult.get("code").equals(200)) { + Map>> data = (Map>>) ajaxResult.get("data"); - data.keySet().forEach(key ->{ - if ("hourlyWeather1".equals(key)){ - setTableFonts(table.getRow(1).getCell(0), "长清区"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - OffsetDateTime offsetDateTime = OffsetDateTime.parse(weatherList.get(i).get("fxTime").toString()); - setTableFonts(table.getRow(0).getCell(i+1),offsetDateTime.format(DateTimeFormatter.ofPattern("dd日HH时"))); - setTableFonts(table.getRow(1).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather2".equals(key)){ - setTableFonts(table.getRow(2).getCell(0), "平阴县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(2).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather3".equals(key)){ - setTableFonts(table.getRow(3).getCell(0), "东平县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(3).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather4".equals(key)){ - setTableFonts(table.getRow(4).getCell(0), "汶上县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(4).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather5".equals(key)){ - setTableFonts(table.getRow(5).getCell(0), "梁山县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(5).getCell(i+1), weatherList.get(i).get("text").toString()); + if (data != null && data.size() != 0){ + + XWPFTable table = doc.createTable(9, 25); + //列宽自动分割 + CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW(); + infoTableWidth.setType(STTblWidth.DXA); + infoTableWidth.setW(BigInteger.valueOf(9072)); + + data.keySet().forEach(key ->{ + if ("hourlyWeather1".equals(key)){ + setTableFonts(table.getRow(1).getCell(0), "长清区"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + OffsetDateTime offsetDateTime = OffsetDateTime.parse(weatherList.get(i).get("fxTime").toString()); + setTableFonts(table.getRow(0).getCell(i+1),offsetDateTime.format(DateTimeFormatter.ofPattern("dd日HH时"))); + setTableFonts(table.getRow(1).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather2".equals(key)){ + setTableFonts(table.getRow(2).getCell(0), "平阴县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(2).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather3".equals(key)){ + setTableFonts(table.getRow(3).getCell(0), "东平县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(3).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather4".equals(key)){ + setTableFonts(table.getRow(4).getCell(0), "汶上县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(4).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather5".equals(key)){ + setTableFonts(table.getRow(5).getCell(0), "梁山县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(5).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather6".equals(key)){ + setTableFonts(table.getRow(6).getCell(0), "嘉祥县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(6).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather7".equals(key)){ + setTableFonts(table.getRow(7).getCell(0), "巨野县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(7).getCell(i+1), weatherList.get(i).get("text").toString()); + } + } else if ("hourlyWeather8".equals(key)){ + setTableFonts(table.getRow(8).getCell(0), "郓城县"); + List> weatherList = data.get(key); + for (int i = 0; i < weatherList.size(); i++) { + setTableFonts(table.getRow(8).getCell(i+1), weatherList.get(i).get("text").toString()); + } } - } else if ("hourlyWeather6".equals(key)){ - setTableFonts(table.getRow(6).getCell(0), "嘉祥县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(6).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather7".equals(key)){ - setTableFonts(table.getRow(7).getCell(0), "巨野县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(7).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } else if ("hourlyWeather8".equals(key)){ - setTableFonts(table.getRow(8).getCell(0), "郓城县"); - List> weatherList = data.get(key); - for (int i = 0; i < weatherList.size(); i++) { - setTableFonts(table.getRow(8).getCell(i+1), weatherList.get(i).get("text").toString()); - } - } - }); + }); + } else { + addDescription(doc,"暂无数据"); + } + } //换行 diff --git a/zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java b/zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java index 262dc44c..00eed7d1 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java @@ -40,7 +40,7 @@ public class DcBoardReleaseLog extends BaseEntity private String stakeMark; /** 方向1-上行,2-中,3-下行 */ - @Excel(name = "方向1-上行,2-中,3-下行") + @Excel(name = "方向",readConverterExp = "1=上行,2=中,3=下行") @ApiModelProperty(value="方向1-上行,2-中,3-下行") private String direction; @@ -50,7 +50,7 @@ public class DcBoardReleaseLog extends BaseEntity private String releaseContent; /** 发布状态(0:成功;1:失败) */ - @Excel(name = "发布状态", readConverterExp = "0=:成功;1:失败") + @Excel(name = "发布状态", readConverterExp = "0=成功,1失败") @ApiModelProperty(value="发布状态0=:成功;1:失败") private String releaseStatus; @@ -81,7 +81,7 @@ public class DcBoardReleaseLog extends BaseEntity private String releaseUserId; /** 发布端 */ - @Excel(name = "发布端") + @Excel(name = "发布端", readConverterExp = "00=系统用户,01=智慧大脑,02=GIS+BIM") @ApiModelProperty(value="发布端(00=系统用户,01=智慧大脑,02=GIS+BIM") private String platform; diff --git a/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java b/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java index 29e180af..3fee49b5 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java @@ -63,7 +63,7 @@ public class DcTrafficMetricsData { private Integer congestedSectionQuantity; /** - * 拥堵里程 + * 拥堵里程(单位:m) */ private Integer congestedDistance; } diff --git a/zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java b/zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java index 3444312b..860bcf6a 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java @@ -72,6 +72,11 @@ public class DcTrafficSectionData { */ private Integer stakeMark; + /** + * 设备类型 + */ + private Integer deviceType; + /** 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") diff --git a/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java b/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java index f151e262..24922754 100644 --- a/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java +++ b/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java @@ -22,17 +22,17 @@ public enum ChannelCongestionLevelEnum { /** * 表示通道轻度拥堵,速度阈值为40 km/h */ - LIGHT_CONGESTION(40, 1, "轻度拥堵"), + LIGHT_CONGESTION(40, 1000, "轻度拥堵"), /** * 表示通道中度拥堵,速度阈值为20 km/h */ - MEDIUM_CONGESTION(20, 2, "中度拥堵"), + MEDIUM_CONGESTION(20, 2000, "中度拥堵"), /** * 使用负数作为默认值,表示无限小,始终小于其他速度阈值,表示通道严重拥堵 */ - SEVERE_CONGESTION(-1, 4, "严重拥堵"); + SEVERE_CONGESTION(-1, 4000, "严重拥堵"); /** * 速度阈值,用于判断通道拥挤程度 @@ -55,9 +55,9 @@ public enum ChannelCongestionLevelEnum { * @param speedThreshold 速度阈值 * @param description 等级描述 */ - ChannelCongestionLevelEnum(int speedThreshold, int defaultCongestionMiles, String description) { + ChannelCongestionLevelEnum(int speedThreshold, int defaultCongestionDistance, String description) { this.speedThreshold = speedThreshold; - this.defaultCongestionDistance = defaultCongestionMiles; + this.defaultCongestionDistance = defaultCongestionDistance; this.description = description; } diff --git a/zc-business/src/main/java/com/zc/business/message/device/handler/DeviceMessageHandler.java b/zc-business/src/main/java/com/zc/business/message/device/handler/DeviceMessageHandler.java index ec36ba9f..d2c12a66 100644 --- a/zc-business/src/main/java/com/zc/business/message/device/handler/DeviceMessageHandler.java +++ b/zc-business/src/main/java/com/zc/business/message/device/handler/DeviceMessageHandler.java @@ -37,6 +37,7 @@ public class DeviceMessageHandler { private final int EVENT_AI = 1; private final int EVENT_STATE = 1; private final int EVENTEND_STATE = 4; + private final int VISIBILITY_LEVEL = 8; private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource @@ -113,7 +114,7 @@ public class DeviceMessageHandler { // 气象检测器 if (IotProductEnum.WEATHER_DETECTOR.value().equals(productId)) { weatherDetectorMessageHandle(data); - return; + return; } // 护栏碰撞 @@ -168,8 +169,13 @@ public class DeviceMessageHandler { dcWarning.setWarningTime(new Date(captureTime)); // 信息来源 dcWarning.setWarningSource(WarningSourceEnum.VIDEO_AI.getCode()); + // 事件主类型 dcWarning.setWarningType(data.getInteger("warningType")); + //异常天气等级 + if (data.getInteger("warningType") == VISIBILITY_LEVEL) { + dcWarning.setWarningLevel(data.getInteger("visibilityLevel")); + } String warningSubclass = data.getString("warningSubclass"); // 子类型 @@ -181,10 +187,10 @@ public class DeviceMessageHandler { //方向 if (arr[2] != null) { if (arr[2].equals("上行")) { - direction=arr[0]+" "+arr[1]+ " 菏泽方向 "; + direction = arr[0] + " " + arr[1] + " 菏泽方向 "; } if (arr[2].equals("下行")) { - direction=arr[0]+" "+arr[1]+ " 济南方向 "; + direction = arr[0] + " " + arr[1] + " 济南方向 "; } } @@ -349,7 +355,7 @@ public class DeviceMessageHandler { * @param msg 设备消息 */ private void oneStopDeviceMessageHandle(JSONObject msg) { - dcTrafficSectionDataService.processRealtimeOneStopMessage(msg); + dcTrafficSectionDataService.processRealtimeOneStopMessage(msg); } @@ -445,12 +451,12 @@ public class DeviceMessageHandler { */ private void weatherDetectorMessageHandle(JSONObject msg) { - // DcMeteorologicalDetectorData meteorologicalDetectorData = (DcMeteorologicalDetectorData) msg.get("properties"); + // DcMeteorologicalDetectorData meteorologicalDetectorData = (DcMeteorologicalDetectorData) msg.get("properties"); JSONObject jsonObject = (JSONObject) msg.get("properties"); DcMeteorologicalDetectorData meteorologicalDetectorData = jsonObject.toJavaObject(DcMeteorologicalDetectorData.class); - JSONObject jsonObjectHeaders = (JSONObject)msg.get("headers"); + JSONObject jsonObjectHeaders = (JSONObject) msg.get("headers"); String parts = jsonObjectHeaders.getString("deviceName"); String[] strings = parts.split("-"); String deviceName = strings[0]; @@ -474,19 +480,19 @@ public class DeviceMessageHandler { mdDeviceData.setTimeStamp(new Date()); mdDeviceData.setCreatorUserId("自动存储"); - Map expands = new HashMap<>(); - expands.put("rainFall",meteorologicalDetectorData.getRainfall()); //雨量 - expands.put("windDirection",meteorologicalDetectorData.getWindDirection()); //风向 - expands.put("windSpeed",meteorologicalDetectorData.getWindSpeed()); //风速 - expands.put("temperature",meteorologicalDetectorData.getTemperature()); //大气温度 - expands.put("humidity",meteorologicalDetectorData.getHumidity()); //大气湿度 - expands.put("airPressure",meteorologicalDetectorData.getAtmosphericPressure()); //气压 - expands.put("waterThick",meteorologicalDetectorData.getWaterFilmIceSnowValue()); //水膜厚度 - expands.put("wet",meteorologicalDetectorData.getWetSlipperyCoefficient()); //湿滑 - expands.put("rainXingTai",meteorologicalDetectorData.getPrecipitationType()); //雨量降水形态 - expands.put("visibility",meteorologicalDetectorData.getVisibility()); //能见度 - expands.put("remoteRoadSurfaceTemperature",meteorologicalDetectorData.getRemoteRoadSurfaceTemperature()); //路面温度 - expands.put("pathContactZhuang",meteorologicalDetectorData.getRemoteRoadSurfaceStatus()); //路面状况 + Map expands = new HashMap<>(); + expands.put("rainFall", meteorologicalDetectorData.getRainfall()); //雨量 + expands.put("windDirection", meteorologicalDetectorData.getWindDirection()); //风向 + expands.put("windSpeed", meteorologicalDetectorData.getWindSpeed()); //风速 + expands.put("temperature", meteorologicalDetectorData.getTemperature()); //大气温度 + expands.put("humidity", meteorologicalDetectorData.getHumidity()); //大气湿度 + expands.put("airPressure", meteorologicalDetectorData.getAtmosphericPressure()); //气压 + expands.put("waterThick", meteorologicalDetectorData.getWaterFilmIceSnowValue()); //水膜厚度 + expands.put("wet", meteorologicalDetectorData.getWetSlipperyCoefficient()); //湿滑 + expands.put("rainXingTai", meteorologicalDetectorData.getPrecipitationType()); //雨量降水形态 + expands.put("visibility", meteorologicalDetectorData.getVisibility()); //能见度 + expands.put("remoteRoadSurfaceTemperature", meteorologicalDetectorData.getRemoteRoadSurfaceTemperature()); //路面温度 + expands.put("pathContactZhuang", meteorologicalDetectorData.getRemoteRoadSurfaceStatus()); //路面状况 mdDeviceData.setExpands(JSONObject.toJSONString(expands)); diff --git a/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java b/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java index bd882e7a..0e60621e 100644 --- a/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java +++ b/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java @@ -41,4 +41,9 @@ public class DcTrafficMetricsDataRequest { * 是否分路段统计 */ private boolean segmented; + + /** + * 设备类型 + */ + private Integer deviceType; } diff --git a/zc-business/src/main/java/com/zc/business/request/DcTrafficSectionDataRequest.java b/zc-business/src/main/java/com/zc/business/request/DcTrafficSectionDataRequest.java new file mode 100644 index 00000000..5c9540ff --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/request/DcTrafficSectionDataRequest.java @@ -0,0 +1,44 @@ +package com.zc.business.request; + +import lombok.Data; + +import java.util.Date; + +/** + * 交通截面数据请求参数定义 + * @author xiepufeng + */ +@Data +public class DcTrafficSectionDataRequest { + + /** + * 道路方向 + */ + private Byte direction; + + /** + * 时段类型 + * 1-年 2-月 3-季 4-日 + */ + private Byte periodType; + + /** + * 开始时间 + */ + private Date startTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 设备ID + */ + private Long deviceId; + + /** + * 设备类型 + */ + private Integer deviceType; +} diff --git a/zc-business/src/main/java/com/zc/business/service/DcTrafficStatisticsService.java b/zc-business/src/main/java/com/zc/business/service/DcTrafficStatisticsService.java index bceec71b..45611fec 100644 --- a/zc-business/src/main/java/com/zc/business/service/DcTrafficStatisticsService.java +++ b/zc-business/src/main/java/com/zc/business/service/DcTrafficStatisticsService.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.zc.business.domain.DcTrafficMetricsData; import com.zc.business.domain.DcTrafficSectionData; import com.zc.business.request.DcTrafficMetricsDataRequest; +import com.zc.business.request.DcTrafficSectionDataRequest; import java.util.List; @@ -17,22 +18,36 @@ public interface DcTrafficStatisticsService extends IService currentSections(DcTrafficSectionDataRequest request); + + /** + * 根据提供的请求参数获取历史的交通截面数据。 + * + * @param request 包含获取交通截面所需的所有请求参数的对象。 + * @return DcTrafficSectionData 返回一个包含历史交通截面数据列表。 + */ + List historySections(DcTrafficSectionDataRequest request); /** - * 根据提供的请求参数获取当前的流量指标数据。 + * 根据提供的请求参数获取当前的交通指标数据。 * - * @param request 包含获取流量指标所需的所有请求参数的对象。 - * @return DcTrafficMetricsData 返回一个包含当前流量指标数据的对象。 - * 该对象包含了关于数据中心网络流量的各种度量指标。 + * @param request 包含获取交通指标所需的所有请求参数的对象。 + * @return DcTrafficMetricsData 返回一个包含当前交通指标数据列表。 */ - DcTrafficMetricsData currentTrafficMetrics(DcTrafficMetricsDataRequest request); + List currentTrafficMetrics(DcTrafficMetricsDataRequest request); /** - * 获取历史流量指标数据列表。 + * 获取历史交通指标数据列表。 * - * @param request 包含获取流量指标所需的所有请求参数的对象。 - * @return 返回符合查询条件的历史流量指标数据列表。 + * @param request 包含获取交通指标所需的所有请求参数的对象。 + * @return 返回符合查询条件的历史交通指标数据列表。 */ List historyTrafficMetrics(DcTrafficMetricsDataRequest request); } diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java index 8fcd0f3f..e92bce6b 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; +import com.zc.business.constant.DeviceTypeConstants; import com.zc.business.constant.RedisKeyConstants; import com.zc.business.controller.DcDeviceController; import com.zc.business.domain.DcRoadSection; @@ -14,6 +15,7 @@ import com.zc.business.domain.DcTrafficMetricsData; import com.zc.business.domain.DcTrafficSectionData; import com.zc.business.enums.*; import com.zc.business.request.DcTrafficMetricsDataRequest; +import com.zc.business.request.DcTrafficSectionDataRequest; import com.zc.business.statistics.cache.*; import com.zc.business.mapper.DcTrafficSectionDataMapper; import com.zc.business.service.DcTrafficStatisticsService; @@ -86,20 +88,63 @@ public class DcTrafficStatisticsServiceImpl } /** - * 根据请求获取当前交通流量指标数据。 + * 根据提供的请求参数获取当前的交通截面数据。 * - * @param request 包含获取流量指标所需的所有请求参数的对象。 - * @return 返回当前交通流量指标数据。 + * @param request 包含获取交通截面所需的所有请求参数的对象。 + * @return DcTrafficSectionData 返回一个包含当前交通截面数据列表。 + */ + @Override + public List currentSections(DcTrafficSectionDataRequest request) { + + // 从Redis缓存中获取指定方向的交通路段数据列表 + List dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection()); + + return filterTrafficDataByRequest(request, dcTrafficSectionDataCaches); + } + + /** + * 根据提供的请求参数获取历史的交通截面数据。 + * + * @param request 包含获取交通截面所需的所有请求参数的对象。 + * @return DcTrafficSectionData 返回一个包含历史交通截面数据列表。 + */ + @Override + public List historySections(DcTrafficSectionDataRequest request) { + + if (request.getStartTime() == null || request.getEndTime() == null) { + throw new ServiceException("开始时间或结束时间不能为空"); + } + + if (request.getPeriodType() == null) { + throw new ServiceException("时段类型不能为空"); + } + + // 构建查询条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.between(DcTrafficSectionData::getStatisticalDate, request.getStartTime(), request.getEndTime()); + queryWrapper.eq(DcTrafficSectionData::getPeriodType, request.getPeriodType()); + queryWrapper.eq(DcTrafficSectionData::getDirection, request.getDirection()); + queryWrapper.eq(DcTrafficSectionData::getDeviceType, request.getDeviceType()); + queryWrapper.eq(DcTrafficSectionData::getDeviceId, request.getDeviceId()); + + return list(queryWrapper); + } + + /** + * 根据请求获取当前交通指标数据。 + * + * @param request 包含获取交通指标所需的所有请求参数的对象。 + * @return 返回当前交通指标数据。 * @throws ServiceException 如果没有获取到交通数据,则抛出异常。 */ @Override - public DcTrafficMetricsData currentTrafficMetrics(DcTrafficMetricsDataRequest request) { + public List currentTrafficMetrics(DcTrafficMetricsDataRequest request) { // 从Redis缓存中获取指定方向的交通路段数据列表 List dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection()); - // 根据指定的方向和路段ID范围获取交通数据 - List trafficSectionDataList = fetchTrafficDataByDirAndRange(request.getRoadSectionId(), dcTrafficSectionDataCaches); + // 根据请求过滤交通数据 + List trafficSectionDataList = filterTrafficDataByRequest(request, dcTrafficSectionDataCaches); // 对获取的交通路段数据进行分析,得到交通指标数据 List dcTrafficMetricsDataList = trafficAnalysis.calculateTrafficMetrics(request, trafficSectionDataList); @@ -110,15 +155,15 @@ public class DcTrafficStatisticsServiceImpl } // 根据收集到的交通段数据计算并返回交通指标数据 - return dcTrafficMetricsDataList.get(0); + return dcTrafficMetricsDataList; } /** - * 计算获取指定条件下的历史交通流量指标数据。 + * 计算获取指定条件下的历史交通指标数据。 * * @param request 包含查询条件的请求对象,包括开始时间、结束时间、方向、周期类型和所属路段ID等信息。 - * @return 返回一个包含交通流量指标数据的列表。 + * @return 返回一个包含交通指标数据的列表。 */ @Override public List historyTrafficMetrics(DcTrafficMetricsDataRequest request) { @@ -151,6 +196,16 @@ public class DcTrafficStatisticsServiceImpl } } + // 获取设备类型 + Integer deviceType = request.getDeviceType(); + + if (deviceType == null) { + // 如果没有指定设备类型,则默认为毫米波雷达 + deviceType = DeviceTypeConstants.MILLIMETER_WAVE_RADAR; + } + + queryWrapper.eq(DcTrafficSectionData::getDeviceType, deviceType); + // 根据收集到的交通段数据计算并返回交通指标数据 return trafficAnalysis.calculateTrafficMetrics(request, list(queryWrapper)); } @@ -266,19 +321,19 @@ public class DcTrafficStatisticsServiceImpl } /** - * 根据方向获取交通流量数据 + * 根据方向获取交通数据 * * @param direction 方向 - * @return 单向交通流量数据 + * @return 单向交通数据 */ private Map getTrafficDataByDirection(Byte direction) { return redisCache.getCacheMapValue(RedisKeyConstants.getDcDevicesTrafficStatisticsKey(direction)); } /** - * 获取上行和下行所有交通流量数据 + * 获取上行和下行所有交通数据 * - * @return 所有交通流量数据 + * @return 所有交通数据 */ private Map getTrafficDataForBothDirections() { Map allData = new HashMap<>(); @@ -288,18 +343,29 @@ public class DcTrafficStatisticsServiceImpl } /** - * 根据指定的方向和路段ID范围获取交通数据。 + * 根据请求过滤交通数据。 * - * @param roadSectionId 指定的路段ID,如果为null,则不根据路段筛选数据。 - * @return 返回符合指定方向和路段范围的交通段数据列表。 + * @param request 包含交通数据查询条件的请求对象,可以指定路段ID和设备类型。 + * @param dcTrafficSectionDataCaches 存储的交通数据段列表。 + * @return 过滤后的交通数据段列表,仅包含满足请求条件的数据。 */ - public List fetchTrafficDataByDirAndRange(Long roadSectionId, List dcTrafficSectionDataCaches) { + public List filterTrafficDataByRequest( + DcTrafficMetricsDataRequest request, + List dcTrafficSectionDataCaches + ) { + + if (request == null) { + return dcTrafficSectionDataCaches; // 如果请求对象为空,直接返回原始交通数据列表 + } + + Long roadSectionId = request.getRoadSectionId(); + // 初始化路段起始和终止桩号 - Integer startStakeMark; - Integer endStakeMark; + Integer startStakeMark = null; + Integer endStakeMark = null; - // 根据提供的路段ID查询路段信息,并转换为起始和终止桩号 if (roadSectionId != null) { + // 根据提供的路段ID查询路段信息,并转换为起始和终止桩号 DcRoadSection dcRoadSection = redisCache.getCacheMapValue(RedisKeyConstants.DC_ROAD_SECTION, roadSectionId); // 验证路段ID是否存在 @@ -309,16 +375,62 @@ public class DcTrafficStatisticsServiceImpl startStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSection.getStartStakeMark()); endStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSection.getEndStakeMark()); - } else { - startStakeMark = null; - endStakeMark = null; } - // 筛选并返回符合路段范围条件的交通数据列表 + // 获取请求中的设备类型 + Integer deviceType = request.getDeviceType(); + + // 如果设备类型为空,则默认为毫米波雷达 + if (deviceType == null) { + deviceType = DeviceTypeConstants.MILLIMETER_WAVE_RADAR; + } + + // 使用lambda表达式和流对交通数据进行过滤 + final Integer finalStartStakeMark = startStakeMark; + final Integer finalEndStakeMark = endStakeMark; + final Integer finalDeviceType = deviceType; + + // 筛选并返回符合路段范围条件和设备类型条件的交通数据列表 return dcTrafficSectionDataCaches.stream() - .filter(data -> startStakeMark == null || endStakeMark == null - || (data.getStakeMark() >= startStakeMark && data.getStakeMark() <= endStakeMark)) + .filter(data -> (finalStartStakeMark == null || finalEndStakeMark == null + || (data.getStakeMark() >= finalStartStakeMark && data.getStakeMark() <= finalEndStakeMark)) + && finalDeviceType.equals(data.getDeviceType())) .collect(Collectors.toList()); } + /** + * 根据请求过滤交通数据。 + * + * @param request 包含设备类型和设备ID的请求对象,用于指定过滤条件。 + * @param dcTrafficSectionDataCaches 原始的交通数据列表。 + * @return 过滤后的交通数据列表,仅包含与请求条件匹配的数据。 + */ + public List filterTrafficDataByRequest( + DcTrafficSectionDataRequest request, + List dcTrafficSectionDataCaches + ) { + + if (request == null) { + return dcTrafficSectionDataCaches; // 如果请求对象为空,直接返回原始交通数据列表 + } + + Integer deviceType = request.getDeviceType(); + Long deviceId = request.getDeviceId(); + + if (deviceType == null && deviceId == null) { + return dcTrafficSectionDataCaches; // 如果请求中既没有设备类型也没有设备ID,返回原始数据列表 + } + + // 使用流对交通数据进行过滤,只返回与请求中的设备类型和设备ID匹配的数据 + return dcTrafficSectionDataCaches.stream() + .filter(data -> { + boolean typeMatches = deviceType == null || data.getDeviceType().equals(deviceType); // 设备类型匹配条件 + boolean idMatches = deviceId == null || data.getDeviceId().equals(deviceId); // 设备ID匹配条件 + return typeMatches && idMatches; // 只有当两者都匹配时,数据才被保留 + }) + .collect(Collectors.toList()); + } + + + } diff --git a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java index 657927ac..1be1f17c 100644 --- a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java +++ b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java @@ -444,6 +444,7 @@ public class TrafficAnalysis { totalCongestionDistance.addAndGet(defaultCongestionDistance); } else { totalCongestionDistance.addAndGet(congestionDistance); + // 如果当前路段被计算过,则累加拥堵路段数量 congestedSectionQuantity.addAndGet(1); } } diff --git a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java index dbc9a939..f67fdf28 100644 --- a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java +++ b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java @@ -321,6 +321,8 @@ public class TrafficStatistics { data.setPeriodType(TrafficDataPeriodTypeEnum.DAY); // 将设备的桩号转换为整数后设置 data.setStakeMark(dcDevice.stakeMarkToInt()); + // 设置设备类型 + data.setDeviceType(Integer.valueOf(dcDevice.getDeviceType())); } @@ -372,7 +374,7 @@ public class TrafficStatistics { } /** - * 计算累积大型交通流量。 + * 计算累积大型车交通量数据。 * 该方法用于根据给定的车道数据,计算出特定类型的车辆(包括公共汽车、中型货车、大型货车、特大型货车和集装箱车)的交通量总和。 * * @param laneData 包含车道交通量数据的JSONObject对象。该对象应包含以下键: @@ -459,6 +461,8 @@ public class TrafficStatistics { aggregatedData.setDirection(firstDcTrafficSectionData.getDirection()); // 上报时间 aggregatedData.setReportTime(firstDcTrafficSectionData.getReportTime()); + // 设备类型 + aggregatedData.setDeviceType(firstDcTrafficSectionData.getDeviceType()); // 计算平均车速并设置到汇总统计对象中 if (trafficVolume != 0) {