Browse Source

Merge remote-tracking branch 'origin/develop' into develop

develop
wangsixiang 1 year ago
parent
commit
0664682ad3
  1. 18
      zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java
  2. 38
      zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java
  3. 37
      zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java
  4. 13
      zc-business/src/main/java/com/zc/business/controller/WordController.java
  5. 6
      zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java
  6. 2
      zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java
  7. 5
      zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java
  8. 10
      zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java
  9. 38
      zc-business/src/main/java/com/zc/business/message/device/handler/DeviceMessageHandler.java
  10. 5
      zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java
  11. 44
      zc-business/src/main/java/com/zc/business/request/DcTrafficSectionDataRequest.java
  12. 31
      zc-business/src/main/java/com/zc/business/service/DcTrafficStatisticsService.java
  13. 164
      zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java
  14. 1
      zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java
  15. 6
      zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java

18
zc-business/src/main/java/com/zc/business/controller/DcBoardReleaseLogController.java

@ -1,8 +1,11 @@
package com.zc.business.controller; package com.zc.business.controller;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
@ -62,6 +65,21 @@ public class DcBoardReleaseLogController extends BaseController
public void export(HttpServletResponse response, DcBoardReleaseLog dcBoardReleaseLog) public void export(HttpServletResponse response, DcBoardReleaseLog dcBoardReleaseLog)
{ {
List<DcBoardReleaseLog> list = dcBoardReleaseLogService.selectDcBoardReleaseLogList(dcBoardReleaseLog); List<DcBoardReleaseLog> list = dcBoardReleaseLogService.selectDcBoardReleaseLogList(dcBoardReleaseLog);
for (DcBoardReleaseLog releaseLog : list) {
String content = releaseLog.getReleaseContent();
List<Map<String,Object>> 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<DcBoardReleaseLog> util = new ExcelUtil<>(DcBoardReleaseLog.class); ExcelUtil<DcBoardReleaseLog> util = new ExcelUtil<>(DcBoardReleaseLog.class);
util.exportExcel(response, list, "情报板内容发布日志数据"); util.exportExcel(response, list, "情报板内容发布日志数据");
} }

38
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.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 设备Controller * 设备Controller
@ -240,17 +241,26 @@ public class DcDeviceController extends BaseController {
Object data = JSON.parseObject(queryDeviceProperties(deviceId, propertyId, props).get("data").toString()).get("data"); Object data = JSON.parseObject(queryDeviceProperties(deviceId, propertyId, props).get("data").toString()).get("data");
JSONArray dataArray = JSON.parseArray(data.toString()); JSONArray dataArray = JSON.parseArray(data.toString());
List<Object> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
dataArray.forEach(o -> { dataArray.forEach(o -> {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
JSONObject jsonObject = JSON.parseObject(o.toString()); JSONObject jsonObject = JSON.parseObject(o.toString());
JSONObject formatValue = JSON.parseObject(jsonObject.get("formatValue").toString()); JSONObject formatValue = JSON.parseObject(jsonObject.get("formatValue").toString());
map.put("1", formatValue.get("1")); map.put("1", formatValue.get("1"));
map.put("3", formatValue.get("3")); 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); list.add(map);
}); });
return AjaxResult.success(list); List<Map<String, Object>> newList = list.stream()
.filter(map-> !map.get("timestamp").equals(""))
.collect(Collectors.toList());
Collections.sort(newList, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> map1, Map<String, Object> 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("批量设备功能调用") @ApiOperation("批量设备功能调用")
@PostMapping("/batchFunctions") @PostMapping("/batchFunctions")
public AjaxResult batchInvokedFunction(@RequestBody Map<String, Object> props) throws HttpException, IOException, InterruptedException { public AjaxResult batchInvokedFunction(@RequestBody Map<String, Object> props) throws HttpException, IOException, InterruptedException {
List<DcDevice> devices = (List<DcDevice>) props.get("devices"); ArrayList<JSONObject> devices = (ArrayList<JSONObject>) props.get("devices");
JSONArray functions = (JSONArray) props.get("functions"); ArrayList<JSONObject> functions = (ArrayList<JSONObject>) props.get("functions");
JSONArray resultArray = new JSONArray(); JSONArray resultArray = new JSONArray();
for (DcDevice device : devices) { for (Object dev : devices) {
String iotDeviceId = device.getIotDeviceId(); // 将Object转换为JSONObject
JSONObject device = (JSONObject) JSON.toJSON(dev);
//JSONObject device = (JSONObject) JSON.toJSON(dev.toString());
String iotDeviceId = device.getString("iotDeviceId");
for (Object function : functions) { 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"); 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)); resultArray.add(getResult(device, iotDeviceId, functionId, jsonObject));
} }
} }
return AjaxResult.success(resultArray); 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<String, Object> params = jsonObject.toJavaObject(new TypeReference<HashMap<String, Object>>() { HashMap<String, Object> params = jsonObject.toJavaObject(new TypeReference<HashMap<String, Object>>() {
}); });
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
result.put("device", device.getId()); result.put("device", device.getString("id"));
if (device.getDeviceType().equals(DeviceTypeConstants.ROAD_SECTION_VOICE_BROADCASTING)) { if (device.getInteger("deviceType").equals(DeviceTypeConstants.ROAD_SECTION_VOICE_BROADCASTING)) {
result.put("result", broadcastController.nearCamListDistance(jsonObject)); result.put("result", broadcastController.nearCamListDistance(jsonObject));
} else { } else {
result.put("result", invokedFunction(iotDeviceId, functionId, params)); result.put("result", invokedFunction(iotDeviceId, functionId, params));

37
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.ruoyi.common.core.domain.AjaxResult;
import com.zc.business.domain.DcTrafficMetricsData; import com.zc.business.domain.DcTrafficMetricsData;
import com.zc.business.domain.DcTrafficSectionData;
import com.zc.business.request.DcTrafficMetricsDataRequest; import com.zc.business.request.DcTrafficMetricsDataRequest;
import com.zc.business.request.DcTrafficSectionDataRequest;
import com.zc.business.service.DcTrafficStatisticsService; import com.zc.business.service.DcTrafficStatisticsService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
@ -27,6 +27,37 @@ public class DcTrafficStatisticsController {
private DcTrafficStatisticsService dcTrafficStatisticsService; private DcTrafficStatisticsService dcTrafficStatisticsService;
/**
* 获取当前交通截面数据
*
* @param request 请求参数封装了对于交通截面数据查询的详细要求
* @return 返回一个AjaxResult对象其中包含了查询结果如果查询成功则结果中封装了当前交通截面的数据DcTrafficSectionData类型
*/
@ApiOperation("获取当前交通截面数据")
@GetMapping("/current/sections")
public AjaxResult currentSections(DcTrafficSectionDataRequest request){
// 调用服务层方法,查询当前交通截面数据
List<DcTrafficSectionData> dcTrafficMetricsData = dcTrafficStatisticsService.currentSections(request);
// 将查询结果封装为AjaxResult对象返回
return AjaxResult.success(dcTrafficMetricsData);
}
/**
* 获取历史交通截面数据
*
* @param request 包含交通截面数据请求参数的对象
* @return 返回一个包含历史交通截面数据的AjaxResult对象
*/
@ApiOperation("获取历史交通截面数据")
@GetMapping("/history/sections")
public AjaxResult historySections(DcTrafficSectionDataRequest request){
// 调用服务层方法,获取历史交通截面的统计数据
List<DcTrafficSectionData> dcTrafficMetricsData = dcTrafficStatisticsService.historySections(request);
// 将获取到的历史交通截面数据封装成AjaxResult对象并返回
return AjaxResult.success(dcTrafficMetricsData);
}
/** /**
* 获取当前交通特征指数 * 获取当前交通特征指数
* *
@ -37,7 +68,7 @@ public class DcTrafficStatisticsController {
@GetMapping("/current/metrics") @GetMapping("/current/metrics")
public AjaxResult currentTrafficMetrics(DcTrafficMetricsDataRequest request){ public AjaxResult currentTrafficMetrics(DcTrafficMetricsDataRequest request){
// 调用服务层方法,获取当前交通指标数据 // 调用服务层方法,获取当前交通指标数据
DcTrafficMetricsData dcTrafficMetricsData = dcTrafficStatisticsService.currentTrafficMetrics(request); List<DcTrafficMetricsData> dcTrafficMetricsData = dcTrafficStatisticsService.currentTrafficMetrics(request);
// 将获取到的交通指标数据封装为成功的结果并返回 // 将获取到的交通指标数据封装为成功的结果并返回
return AjaxResult.success(dcTrafficMetricsData); return AjaxResult.success(dcTrafficMetricsData);
} }

13
zc-business/src/main/java/com/zc/business/controller/WordController.java

@ -128,15 +128,18 @@ public class WordController {
PoiUtil.createHeading2(doc,"天气情况统计"); PoiUtil.createHeading2(doc,"天气情况统计");
AjaxResult ajaxResult = weatherForecastController.hourlyWeather();
if (ajaxResult.get("code").equals(200)) {
Map<String,List<Map<String,Object>>> data = (Map<String, List<Map<String,Object>>>) ajaxResult.get("data");
if (data != null && data.size() != 0){
XWPFTable table = doc.createTable(9, 25); XWPFTable table = doc.createTable(9, 25);
//列宽自动分割 //列宽自动分割
CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW(); CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
infoTableWidth.setType(STTblWidth.DXA); infoTableWidth.setType(STTblWidth.DXA);
infoTableWidth.setW(BigInteger.valueOf(9072)); infoTableWidth.setW(BigInteger.valueOf(9072));
AjaxResult ajaxResult = weatherForecastController.hourlyWeather();
if (ajaxResult.get("code").equals(200)) {
Map<String,List<Map<String,Object>>> data = (Map<String, List<Map<String,Object>>>) ajaxResult.get("data");
data.keySet().forEach(key ->{ data.keySet().forEach(key ->{
if ("hourlyWeather1".equals(key)){ if ("hourlyWeather1".equals(key)){
setTableFonts(table.getRow(1).getCell(0), "长清区"); setTableFonts(table.getRow(1).getCell(0), "长清区");
@ -190,6 +193,10 @@ public class WordController {
} }
} }
}); });
} else {
addDescription(doc,"暂无数据");
}
} }
//换行 //换行

6
zc-business/src/main/java/com/zc/business/domain/DcBoardReleaseLog.java

@ -40,7 +40,7 @@ public class DcBoardReleaseLog extends BaseEntity
private String stakeMark; private String stakeMark;
/** 方向1-上行,2-中,3-下行 */ /** 方向1-上行,2-中,3-下行 */
@Excel(name = "方向1-上行,2-中,3-下行") @Excel(name = "方向",readConverterExp = "1=上行,2=中,3=下行")
@ApiModelProperty(value="方向1-上行,2-中,3-下行") @ApiModelProperty(value="方向1-上行,2-中,3-下行")
private String direction; private String direction;
@ -50,7 +50,7 @@ public class DcBoardReleaseLog extends BaseEntity
private String releaseContent; private String releaseContent;
/** 发布状态(0:成功;1:失败) */ /** 发布状态(0:成功;1:失败) */
@Excel(name = "发布状态", readConverterExp = "0=:成功;1:失败") @Excel(name = "发布状态", readConverterExp = "0=成功,1失败")
@ApiModelProperty(value="发布状态0=:成功;1:失败") @ApiModelProperty(value="发布状态0=:成功;1:失败")
private String releaseStatus; private String releaseStatus;
@ -81,7 +81,7 @@ public class DcBoardReleaseLog extends BaseEntity
private String releaseUserId; private String releaseUserId;
/** 发布端 */ /** 发布端 */
@Excel(name = "发布端") @Excel(name = "发布端", readConverterExp = "00=系统用户,01=智慧大脑,02=GIS+BIM")
@ApiModelProperty(value="发布端(00=系统用户,01=智慧大脑,02=GIS+BIM") @ApiModelProperty(value="发布端(00=系统用户,01=智慧大脑,02=GIS+BIM")
private String platform; private String platform;

2
zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java

@ -63,7 +63,7 @@ public class DcTrafficMetricsData {
private Integer congestedSectionQuantity; private Integer congestedSectionQuantity;
/** /**
* 拥堵里程 * 拥堵里程单位m
*/ */
private Integer congestedDistance; private Integer congestedDistance;
} }

5
zc-business/src/main/java/com/zc/business/domain/DcTrafficSectionData.java

@ -72,6 +72,11 @@ public class DcTrafficSectionData {
*/ */
private Integer stakeMark; private Integer stakeMark;
/**
* 设备类型
*/
private Integer deviceType;
/** 创建时间 */ /** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

10
zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java

@ -22,17 +22,17 @@ public enum ChannelCongestionLevelEnum {
/** /**
* 表示通道轻度拥堵速度阈值为40 km/h * 表示通道轻度拥堵速度阈值为40 km/h
*/ */
LIGHT_CONGESTION(40, 1, "轻度拥堵"), LIGHT_CONGESTION(40, 1000, "轻度拥堵"),
/** /**
* 表示通道中度拥堵速度阈值为20 km/h * 表示通道中度拥堵速度阈值为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 speedThreshold 速度阈值
* @param description 等级描述 * @param description 等级描述
*/ */
ChannelCongestionLevelEnum(int speedThreshold, int defaultCongestionMiles, String description) { ChannelCongestionLevelEnum(int speedThreshold, int defaultCongestionDistance, String description) {
this.speedThreshold = speedThreshold; this.speedThreshold = speedThreshold;
this.defaultCongestionDistance = defaultCongestionMiles; this.defaultCongestionDistance = defaultCongestionDistance;
this.description = description; this.description = description;
} }

38
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_AI = 1;
private final int EVENT_STATE = 1; private final int EVENT_STATE = 1;
private final int EVENTEND_STATE = 4; private final int EVENTEND_STATE = 4;
private final int VISIBILITY_LEVEL = 8;
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource @Resource
@ -168,8 +169,13 @@ public class DeviceMessageHandler {
dcWarning.setWarningTime(new Date(captureTime)); dcWarning.setWarningTime(new Date(captureTime));
// 信息来源 // 信息来源
dcWarning.setWarningSource(WarningSourceEnum.VIDEO_AI.getCode()); dcWarning.setWarningSource(WarningSourceEnum.VIDEO_AI.getCode());
// 事件主类型 // 事件主类型
dcWarning.setWarningType(data.getInteger("warningType")); dcWarning.setWarningType(data.getInteger("warningType"));
//异常天气等级
if (data.getInteger("warningType") == VISIBILITY_LEVEL) {
dcWarning.setWarningLevel(data.getInteger("visibilityLevel"));
}
String warningSubclass = data.getString("warningSubclass"); String warningSubclass = data.getString("warningSubclass");
// 子类型 // 子类型
@ -181,10 +187,10 @@ public class DeviceMessageHandler {
//方向 //方向
if (arr[2] != null) { if (arr[2] != null) {
if (arr[2].equals("上行")) { if (arr[2].equals("上行")) {
direction=arr[0]+" "+arr[1]+ " 菏泽方向 "; direction = arr[0] + " " + arr[1] + " 菏泽方向 ";
} }
if (arr[2].equals("下行")) { if (arr[2].equals("下行")) {
direction=arr[0]+" "+arr[1]+ " 济南方向 "; direction = arr[0] + " " + arr[1] + " 济南方向 ";
} }
} }
@ -450,7 +456,7 @@ public class DeviceMessageHandler {
DcMeteorologicalDetectorData meteorologicalDetectorData = jsonObject.toJavaObject(DcMeteorologicalDetectorData.class); DcMeteorologicalDetectorData meteorologicalDetectorData = jsonObject.toJavaObject(DcMeteorologicalDetectorData.class);
JSONObject jsonObjectHeaders = (JSONObject)msg.get("headers"); JSONObject jsonObjectHeaders = (JSONObject) msg.get("headers");
String parts = jsonObjectHeaders.getString("deviceName"); String parts = jsonObjectHeaders.getString("deviceName");
String[] strings = parts.split("-"); String[] strings = parts.split("-");
String deviceName = strings[0]; String deviceName = strings[0];
@ -474,19 +480,19 @@ public class DeviceMessageHandler {
mdDeviceData.setTimeStamp(new Date()); mdDeviceData.setTimeStamp(new Date());
mdDeviceData.setCreatorUserId("自动存储"); mdDeviceData.setCreatorUserId("自动存储");
Map<String,Object> expands = new HashMap<>(); Map<String, Object> expands = new HashMap<>();
expands.put("rainFall",meteorologicalDetectorData.getRainfall()); //雨量 expands.put("rainFall", meteorologicalDetectorData.getRainfall()); //雨量
expands.put("windDirection",meteorologicalDetectorData.getWindDirection()); //风向 expands.put("windDirection", meteorologicalDetectorData.getWindDirection()); //风向
expands.put("windSpeed",meteorologicalDetectorData.getWindSpeed()); //风速 expands.put("windSpeed", meteorologicalDetectorData.getWindSpeed()); //风速
expands.put("temperature",meteorologicalDetectorData.getTemperature()); //大气温度 expands.put("temperature", meteorologicalDetectorData.getTemperature()); //大气温度
expands.put("humidity",meteorologicalDetectorData.getHumidity()); //大气湿度 expands.put("humidity", meteorologicalDetectorData.getHumidity()); //大气湿度
expands.put("airPressure",meteorologicalDetectorData.getAtmosphericPressure()); //气压 expands.put("airPressure", meteorologicalDetectorData.getAtmosphericPressure()); //气压
expands.put("waterThick",meteorologicalDetectorData.getWaterFilmIceSnowValue()); //水膜厚度 expands.put("waterThick", meteorologicalDetectorData.getWaterFilmIceSnowValue()); //水膜厚度
expands.put("wet",meteorologicalDetectorData.getWetSlipperyCoefficient()); //湿滑 expands.put("wet", meteorologicalDetectorData.getWetSlipperyCoefficient()); //湿滑
expands.put("rainXingTai",meteorologicalDetectorData.getPrecipitationType()); //雨量降水形态 expands.put("rainXingTai", meteorologicalDetectorData.getPrecipitationType()); //雨量降水形态
expands.put("visibility",meteorologicalDetectorData.getVisibility()); //能见度 expands.put("visibility", meteorologicalDetectorData.getVisibility()); //能见度
expands.put("remoteRoadSurfaceTemperature",meteorologicalDetectorData.getRemoteRoadSurfaceTemperature()); //路面温度 expands.put("remoteRoadSurfaceTemperature", meteorologicalDetectorData.getRemoteRoadSurfaceTemperature()); //路面温度
expands.put("pathContactZhuang",meteorologicalDetectorData.getRemoteRoadSurfaceStatus()); //路面状况 expands.put("pathContactZhuang", meteorologicalDetectorData.getRemoteRoadSurfaceStatus()); //路面状况
mdDeviceData.setExpands(JSONObject.toJSONString(expands)); mdDeviceData.setExpands(JSONObject.toJSONString(expands));

5
zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java

@ -41,4 +41,9 @@ public class DcTrafficMetricsDataRequest {
* 是否分路段统计 * 是否分路段统计
*/ */
private boolean segmented; private boolean segmented;
/**
* 设备类型
*/
private Integer deviceType;
} }

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

31
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.DcTrafficMetricsData;
import com.zc.business.domain.DcTrafficSectionData; import com.zc.business.domain.DcTrafficSectionData;
import com.zc.business.request.DcTrafficMetricsDataRequest; import com.zc.business.request.DcTrafficMetricsDataRequest;
import com.zc.business.request.DcTrafficSectionDataRequest;
import java.util.List; import java.util.List;
@ -17,22 +18,36 @@ public interface DcTrafficStatisticsService extends IService<DcTrafficSectionDat
*/ */
void processRealtimeOneStopMessage(JSONObject msg); void processRealtimeOneStopMessage(JSONObject msg);
/**
* 根据提供的请求参数获取当前的交通截面数据
*
* @param request 包含获取交通截面所需的所有请求参数的对象
* @return DcTrafficSectionData 返回一个包含当前交通截面数据列表
*/
List<DcTrafficSectionData> currentSections(DcTrafficSectionDataRequest request);
/**
* 根据提供的请求参数获取历史的交通截面数据
*
* @param request 包含获取交通截面所需的所有请求参数的对象
* @return DcTrafficSectionData 返回一个包含历史交通截面数据列表
*/
List<DcTrafficSectionData> historySections(DcTrafficSectionDataRequest request);
/** /**
* 根据提供的请求参数获取当前的流量指标数据 * 根据提供的请求参数获取当前的交通指标数据
* *
* @param request 包含获取流量指标所需的所有请求参数的对象 * @param request 包含获取交通指标所需的所有请求参数的对象
* @return DcTrafficMetricsData 返回一个包含当前流量指标数据的对象 * @return DcTrafficMetricsData 返回一个包含当前交通指标数据列表
* 该对象包含了关于数据中心网络流量的各种度量指标
*/ */
DcTrafficMetricsData currentTrafficMetrics(DcTrafficMetricsDataRequest request); List<DcTrafficMetricsData> currentTrafficMetrics(DcTrafficMetricsDataRequest request);
/** /**
* 获取历史流量指标数据列表 * 获取历史交通指标数据列表
* *
* @param request 包含获取流量指标所需的所有请求参数的对象 * @param request 包含获取交通指标所需的所有请求参数的对象
* @return 返回符合查询条件的历史流量指标数据列表 * @return 返回符合查询条件的历史交通指标数据列表
*/ */
List<DcTrafficMetricsData> historyTrafficMetrics(DcTrafficMetricsDataRequest request); List<DcTrafficMetricsData> historyTrafficMetrics(DcTrafficMetricsDataRequest request);
} }

164
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.zc.business.constant.DeviceTypeConstants;
import com.zc.business.constant.RedisKeyConstants; import com.zc.business.constant.RedisKeyConstants;
import com.zc.business.controller.DcDeviceController; import com.zc.business.controller.DcDeviceController;
import com.zc.business.domain.DcRoadSection; 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.domain.DcTrafficSectionData;
import com.zc.business.enums.*; import com.zc.business.enums.*;
import com.zc.business.request.DcTrafficMetricsDataRequest; import com.zc.business.request.DcTrafficMetricsDataRequest;
import com.zc.business.request.DcTrafficSectionDataRequest;
import com.zc.business.statistics.cache.*; import com.zc.business.statistics.cache.*;
import com.zc.business.mapper.DcTrafficSectionDataMapper; import com.zc.business.mapper.DcTrafficSectionDataMapper;
import com.zc.business.service.DcTrafficStatisticsService; import com.zc.business.service.DcTrafficStatisticsService;
@ -86,20 +88,63 @@ public class DcTrafficStatisticsServiceImpl
} }
/** /**
* 根据请求获取当前交通流量指标数据 * 根据提供的请求参数获取当前的交通截面数据
* *
* @param request 包含获取流量指标所需的所有请求参数的对象 * @param request 包含获取交通截面所需的所有请求参数的对象
* @return 返回当前交通流量指标数据 * @return DcTrafficSectionData 返回一个包含当前交通截面数据列表
*/
@Override
public List<DcTrafficSectionData> currentSections(DcTrafficSectionDataRequest request) {
// 从Redis缓存中获取指定方向的交通路段数据列表
List<DcTrafficSectionData> dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection());
return filterTrafficDataByRequest(request, dcTrafficSectionDataCaches);
}
/**
* 根据提供的请求参数获取历史的交通截面数据
*
* @param request 包含获取交通截面所需的所有请求参数的对象
* @return DcTrafficSectionData 返回一个包含历史交通截面数据列表
*/
@Override
public List<DcTrafficSectionData> historySections(DcTrafficSectionDataRequest request) {
if (request.getStartTime() == null || request.getEndTime() == null) {
throw new ServiceException("开始时间或结束时间不能为空");
}
if (request.getPeriodType() == null) {
throw new ServiceException("时段类型不能为空");
}
// 构建查询条件
LambdaQueryWrapper<DcTrafficSectionData> 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 如果没有获取到交通数据则抛出异常 * @throws ServiceException 如果没有获取到交通数据则抛出异常
*/ */
@Override @Override
public DcTrafficMetricsData currentTrafficMetrics(DcTrafficMetricsDataRequest request) { public List<DcTrafficMetricsData> currentTrafficMetrics(DcTrafficMetricsDataRequest request) {
// 从Redis缓存中获取指定方向的交通路段数据列表 // 从Redis缓存中获取指定方向的交通路段数据列表
List<DcTrafficSectionData> dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection()); List<DcTrafficSectionData> dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection());
// 根据指定的方向和路段ID范围获取交通数据 // 根据请求过滤交通数据
List<DcTrafficSectionData> trafficSectionDataList = fetchTrafficDataByDirAndRange(request.getRoadSectionId(), dcTrafficSectionDataCaches); List<DcTrafficSectionData> trafficSectionDataList = filterTrafficDataByRequest(request, dcTrafficSectionDataCaches);
// 对获取的交通路段数据进行分析,得到交通指标数据 // 对获取的交通路段数据进行分析,得到交通指标数据
List<DcTrafficMetricsData> dcTrafficMetricsDataList = trafficAnalysis.calculateTrafficMetrics(request, trafficSectionDataList); List<DcTrafficMetricsData> dcTrafficMetricsDataList = trafficAnalysis.calculateTrafficMetrics(request, trafficSectionDataList);
@ -110,15 +155,15 @@ public class DcTrafficStatisticsServiceImpl
} }
// 根据收集到的交通段数据计算并返回交通指标数据 // 根据收集到的交通段数据计算并返回交通指标数据
return dcTrafficMetricsDataList.get(0); return dcTrafficMetricsDataList;
} }
/** /**
* 计算获取指定条件下的历史交通流量指标数据 * 计算获取指定条件下的历史交通指标数据
* *
* @param request 包含查询条件的请求对象包括开始时间结束时间方向周期类型和所属路段ID等信息 * @param request 包含查询条件的请求对象包括开始时间结束时间方向周期类型和所属路段ID等信息
* @return 返回一个包含交通流量指标数据的列表 * @return 返回一个包含交通指标数据的列表
*/ */
@Override @Override
public List<DcTrafficMetricsData> historyTrafficMetrics(DcTrafficMetricsDataRequest request) { public List<DcTrafficMetricsData> 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)); return trafficAnalysis.calculateTrafficMetrics(request, list(queryWrapper));
} }
@ -266,19 +321,19 @@ public class DcTrafficStatisticsServiceImpl
} }
/** /**
* 根据方向获取交通流量数据 * 根据方向获取交通数据
* *
* @param direction 方向 * @param direction 方向
* @return 单向交通流量数据 * @return 单向交通数据
*/ */
private Map<String, DcTrafficSectionData> getTrafficDataByDirection(Byte direction) { private Map<String, DcTrafficSectionData> getTrafficDataByDirection(Byte direction) {
return redisCache.getCacheMapValue(RedisKeyConstants.getDcDevicesTrafficStatisticsKey(direction)); return redisCache.getCacheMapValue(RedisKeyConstants.getDcDevicesTrafficStatisticsKey(direction));
} }
/** /**
* 获取上行和下行所有交通流量数据 * 获取上行和下行所有交通数据
* *
* @return 所有交通流量数据 * @return 所有交通数据
*/ */
private Map<String, DcTrafficSectionData> getTrafficDataForBothDirections() { private Map<String, DcTrafficSectionData> getTrafficDataForBothDirections() {
Map<String, DcTrafficSectionData> allData = new HashMap<>(); Map<String, DcTrafficSectionData> allData = new HashMap<>();
@ -288,18 +343,29 @@ public class DcTrafficStatisticsServiceImpl
} }
/** /**
* 根据指定的方向和路段ID范围获取交通数据 * 根据请求过滤交通数据
* *
* @param roadSectionId 指定的路段ID如果为null则不根据路段筛选数据 * @param request 包含交通数据查询条件的请求对象可以指定路段ID和设备类型
* @return 返回符合指定方向和路段范围的交通段数据列表 * @param dcTrafficSectionDataCaches 存储的交通数据段列表
* @return 过滤后的交通数据段列表仅包含满足请求条件的数据
*/ */
public List<DcTrafficSectionData> fetchTrafficDataByDirAndRange(Long roadSectionId, List<DcTrafficSectionData> dcTrafficSectionDataCaches) { public List<DcTrafficSectionData> filterTrafficDataByRequest(
DcTrafficMetricsDataRequest request,
List<DcTrafficSectionData> dcTrafficSectionDataCaches
) {
if (request == null) {
return dcTrafficSectionDataCaches; // 如果请求对象为空,直接返回原始交通数据列表
}
Long roadSectionId = request.getRoadSectionId();
// 初始化路段起始和终止桩号 // 初始化路段起始和终止桩号
Integer startStakeMark; Integer startStakeMark = null;
Integer endStakeMark; Integer endStakeMark = null;
// 根据提供的路段ID查询路段信息,并转换为起始和终止桩号
if (roadSectionId != null) { if (roadSectionId != null) {
// 根据提供的路段ID查询路段信息,并转换为起始和终止桩号
DcRoadSection dcRoadSection = redisCache.getCacheMapValue(RedisKeyConstants.DC_ROAD_SECTION, roadSectionId); DcRoadSection dcRoadSection = redisCache.getCacheMapValue(RedisKeyConstants.DC_ROAD_SECTION, roadSectionId);
// 验证路段ID是否存在 // 验证路段ID是否存在
@ -309,16 +375,62 @@ public class DcTrafficStatisticsServiceImpl
startStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSection.getStartStakeMark()); startStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSection.getStartStakeMark());
endStakeMark = StakeMarkUtils.stakeMarkToInt(dcRoadSection.getEndStakeMark()); 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 -> (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<DcTrafficSectionData> filterTrafficDataByRequest(
DcTrafficSectionDataRequest request,
List<DcTrafficSectionData> 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() return dcTrafficSectionDataCaches.stream()
.filter(data -> startStakeMark == null || endStakeMark == null .filter(data -> {
|| (data.getStakeMark() >= startStakeMark && data.getStakeMark() <= endStakeMark)) boolean typeMatches = deviceType == null || data.getDeviceType().equals(deviceType); // 设备类型匹配条件
boolean idMatches = deviceId == null || data.getDeviceId().equals(deviceId); // 设备ID匹配条件
return typeMatches && idMatches; // 只有当两者都匹配时,数据才被保留
})
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
} }

1
zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java

@ -444,6 +444,7 @@ public class TrafficAnalysis {
totalCongestionDistance.addAndGet(defaultCongestionDistance); totalCongestionDistance.addAndGet(defaultCongestionDistance);
} else { } else {
totalCongestionDistance.addAndGet(congestionDistance); totalCongestionDistance.addAndGet(congestionDistance);
// 如果当前路段被计算过,则累加拥堵路段数量
congestedSectionQuantity.addAndGet(1); congestedSectionQuantity.addAndGet(1);
} }
} }

6
zc-business/src/main/java/com/zc/business/statistics/handler/TrafficStatistics.java

@ -321,6 +321,8 @@ public class TrafficStatistics {
data.setPeriodType(TrafficDataPeriodTypeEnum.DAY); data.setPeriodType(TrafficDataPeriodTypeEnum.DAY);
// 将设备的桩号转换为整数后设置 // 将设备的桩号转换为整数后设置
data.setStakeMark(dcDevice.stakeMarkToInt()); data.setStakeMark(dcDevice.stakeMarkToInt());
// 设置设备类型
data.setDeviceType(Integer.valueOf(dcDevice.getDeviceType()));
} }
@ -372,7 +374,7 @@ public class TrafficStatistics {
} }
/** /**
* 计算累积大型交通 * 计算累积大型交通量数据
* 该方法用于根据给定的车道数据计算出特定类型的车辆包括公共汽车中型货车大型货车特大型货车和集装箱车的交通量总和 * 该方法用于根据给定的车道数据计算出特定类型的车辆包括公共汽车中型货车大型货车特大型货车和集装箱车的交通量总和
* *
* @param laneData 包含车道交通量数据的JSONObject对象该对象应包含以下键 * @param laneData 包含车道交通量数据的JSONObject对象该对象应包含以下键
@ -459,6 +461,8 @@ public class TrafficStatistics {
aggregatedData.setDirection(firstDcTrafficSectionData.getDirection()); aggregatedData.setDirection(firstDcTrafficSectionData.getDirection());
// 上报时间 // 上报时间
aggregatedData.setReportTime(firstDcTrafficSectionData.getReportTime()); aggregatedData.setReportTime(firstDcTrafficSectionData.getReportTime());
// 设备类型
aggregatedData.setDeviceType(firstDcTrafficSectionData.getDeviceType());
// 计算平均车速并设置到汇总统计对象中 // 计算平均车速并设置到汇总统计对象中
if (trafficVolume != 0) { if (trafficVolume != 0) {

Loading…
Cancel
Save