Commit 0e2b705d authored by zhoushiguang's avatar zhoushiguang

Merge remote-tracking branch 'origin/master'

parents 32ebc8e2 476fc473
......@@ -696,7 +696,14 @@ public class PlanSendServiceImpl implements PlanSendService {
Integer phaseTime = optLogPO.getPhaseTime();
//绿灯时间
int greenTime = phaseTime - yellowTime - redTime;
optPhase.setGreenTime(greenTime);
if (greenTime <= 0){
optPhase.setGreenTime(phaseTime);
optPhase.setYellowTime(0);
optPhase.setRedTime(0);
}else {
optPhase.setGreenTime(greenTime);
}
optPhaseList.add(optPhase);
}
}
......
package net.wanji.opt.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
/**
* @author duanruiming
* @date 2024/12/10 17:27
*/
@Getter
@AllArgsConstructor
public enum GreenWaveInDirEnum {
E2W(3, "东向西"),
W2E(7, "西向东"),
N2S(1, "北向南"),
S2N(5, "南向北");
private Integer code;
private String desc;
public static String getDesc(Integer code) {
for (GreenWaveInDirEnum value : GreenWaveInDirEnum.values()) {
if (Objects.equals(code, value.getCode())) {
return value.desc;
}
}
return "";
}
}
package net.wanji.opt.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
/**
* @author duanruiming
* @date 2024/12/11 20:33
*/
@Getter
@AllArgsConstructor
public enum OptStatusEnum {
ONE(1, "优化中"),
TWO(2, "优化完");
private Integer code;
private String desc;
public static String getDesc(Integer code) {
for (OptStatusEnum value : OptStatusEnum.values()) {
if (Objects.equals(code, value.getCode())) {
return value.getDesc();
}
}
return OptStatusEnum.ONE.getDesc();
}
}
......@@ -107,6 +107,7 @@ public class InduceSendController {
param.setEndTime(DateUtil.format(System.currentTimeMillis() + 1000 * 60, Constants.DATE_FORMAT.E_DATE_FORMAT_SECOND));
}
induceSendService.send(param);
Thread.sleep(1000);
}
}
return jsonView.success();
......
......@@ -11,7 +11,9 @@ import net.wanji.databus.po.CrossDirDataRealtimePO;
import net.wanji.databus.po.TBaseCrossInfo;
import net.wanji.opt.dto.strategy.AddOrUpdateSceneDTO;
import net.wanji.opt.service.CrossIndexService;
import net.wanji.opt.vo.AIOptResultVO;
import net.wanji.opt.vo.CrossOptResult;
import net.wanji.opt.vo.crossStatusCountVO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
......@@ -83,4 +85,37 @@ public class CrossIndexController {
return JsonViewObject.newInstance().success(results);
}
@ApiOperation(value = "AI路口", notes = "优化监测-AI路口", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@GetMapping(value = "/crossAIList")
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = AddOrUpdateSceneDTO.class),
})
public JsonViewObject crossAIList() {
List<AIOptResultVO> results = null;
try {
results = crossIndexService.crossAIList();
} catch (Exception e) {
JsonViewObject.newInstance().fail("优化监测-AI路口");
}
return JsonViewObject.newInstance().success(results);
}
@ApiOperation(value = "问题诊断", notes = "优化监测-问题诊断", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@GetMapping(value = "/crossStatusCount")
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = AddOrUpdateSceneDTO.class),
})
public JsonViewObject crossStatusCount(String crossId) {
crossStatusCountVO result = new crossStatusCountVO();
try {
result = crossIndexService.crossStatusCount(crossId);
} catch (Exception e) {
JsonViewObject.newInstance().fail("优化监测-问题诊断");
}
return JsonViewObject.newInstance().success(result);
}
}
......@@ -74,10 +74,10 @@ public class InduceTemplate implements Serializable {
private Integer textSize;
/**
* 0:横向生成、1:竖向生成
* 字体类型
*/
@TableField("text_sign")
private Boolean textSign;
@TableField("text_font")
private String textFont;
/**
* 是否默认模板 0:否 1:是
......
......@@ -4,7 +4,9 @@ import net.wanji.databus.bo.CrossIdBO;
import net.wanji.databus.po.CrossDataRealtimePO;
import net.wanji.databus.po.CrossDirDataRealtimePO;
import net.wanji.databus.po.TBaseCrossInfo;
import net.wanji.opt.vo.AIOptResultVO;
import net.wanji.opt.vo.CrossOptResult;
import net.wanji.opt.vo.crossStatusCountVO;
import java.util.List;
import java.util.Map;
......@@ -21,4 +23,8 @@ public interface CrossIndexService {
List<TBaseCrossInfo> crossInfoList();
List<CrossOptResult> crossOptResultList(CrossIdBO crossIdBO) throws Exception;
List<AIOptResultVO> crossAIList();
crossStatusCountVO crossStatusCount(String crossId);
}
......@@ -11,11 +11,14 @@ import net.wanji.databus.po.CrossDataRealtimePO;
import net.wanji.databus.po.CrossDirDataRealtimePO;
import net.wanji.databus.po.TBaseCrossInfo;
import net.wanji.opt.common.enums.CrossOptStrategyEnum;
import net.wanji.opt.common.enums.OptStatusEnum;
import net.wanji.opt.common.enums.StrategyControlEnum;
import net.wanji.opt.dao.mapper.StrategyCrossResultMapper;
import net.wanji.opt.service.CrossIndexService;
import net.wanji.opt.synthesis.pojo.StrategyCrossResultEntity;
import net.wanji.opt.vo.AIOptResultVO;
import net.wanji.opt.vo.CrossOptResult;
import org.drools.core.util.DateUtils;
import net.wanji.opt.vo.crossStatusCountVO;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
......@@ -101,4 +104,68 @@ public class CrossIndexServiceImpl implements CrossIndexService {
}
return crossOptResults;
}
@Override
public List<AIOptResultVO> crossAIList() {
List<AIOptResultVO> results = new ArrayList<>();
LocalDate currentDate = LocalDate.now();
LocalTime startTime = LocalTime.MIDNIGHT;
LocalDateTime startOfDay = LocalDateTime.of(currentDate, startTime);
LambdaQueryWrapper<StrategyCrossResultEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.ge(StrategyCrossResultEntity::getIssueTime, startOfDay);
List<StrategyCrossResultEntity> list = strategyCrossResultMapper.selectList(queryWrapper);
if (!CollectionUtils.isEmpty(list)) {
// 查询出表中当天最新数据
Map<String, Optional<StrategyCrossResultEntity>> crossTimeMap = list.stream().collect(Collectors.groupingBy(StrategyCrossResultEntity::getCrossId,
Collectors.maxBy(Comparator.comparing(StrategyCrossResultEntity::getIssueTime))));
List<StrategyCrossResultEntity> crossMaxTimeList = crossTimeMap.values().stream().map(Optional::get).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(crossMaxTimeList)) {
for (StrategyCrossResultEntity resultEntity : crossMaxTimeList) {
AIOptResultVO aiOptResultVO = new AIOptResultVO();
aiOptResultVO.setId(resultEntity.getCrossId());
aiOptResultVO.setName(resultEntity.getCrossName());
Integer currentAlgo = resultEntity.getCurrentAlgo();
aiOptResultVO.setStrategy(currentAlgo);
// 失衡 均衡调控,其他效率提升
aiOptResultVO.setOptMethod(Objects.equals(1, currentAlgo) ? StrategyControlEnum.ONE.getMethod() : StrategyControlEnum.TWO.getMethod());
// 失衡 优化中,其他,优化完
Integer optStatus = Objects.equals(1, currentAlgo) ? OptStatusEnum.ONE.getCode() : OptStatusEnum.TWO.getCode();
aiOptResultVO.setOptStatus(optStatus);
aiOptResultVO.setOptStatusName(Objects.equals(1, currentAlgo) ? OptStatusEnum.ONE.getDesc() : OptStatusEnum.TWO.getDesc());
results.add(aiOptResultVO);
}
}
}
Collections.sort(results, Comparator.comparingInt(AIOptResultVO::getOptStatus));
return results;
}
@Override
public crossStatusCountVO crossStatusCount(String crossId) {
LocalDate currentDate = LocalDate.now();
LocalTime startTime = LocalTime.MIDNIGHT;
LocalDateTime startOfDay = LocalDateTime.of(currentDate, startTime);
LambdaQueryWrapper<StrategyCrossResultEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrategyCrossResultEntity::getCrossId, crossId);
queryWrapper.ge(StrategyCrossResultEntity::getIssueTime, startOfDay);
List<StrategyCrossResultEntity> list = strategyCrossResultMapper.selectList(queryWrapper);
crossStatusCountVO crossStatusCountVO = new crossStatusCountVO();
if (!CollectionUtils.isEmpty(list)) {
Map<Integer, List<StrategyCrossResultEntity>> listMap = list.stream().collect(Collectors.groupingBy(StrategyCrossResultEntity::getCurrentAlgo));
for (Map.Entry<Integer, List<StrategyCrossResultEntity>> entry : listMap.entrySet()) {
Integer currentAlgo = entry.getKey();
List<StrategyCrossResultEntity> value = entry.getValue();
if (Objects.equals(currentAlgo, CrossOptStrategyEnum.ONE.getCode())) {
crossStatusCountVO.setPhaseEmptyCount(value.size());
}
if (Objects.equals(currentAlgo, CrossOptStrategyEnum.TWO.getCode())) {
crossStatusCountVO.setUnbalanceCount(value.size());
}
if (Objects.equals(currentAlgo, CrossOptStrategyEnum.THREE.getCode())) {
crossStatusCountVO.setOverFlowCount(value.size());
}
}
}
return crossStatusCountVO;
}
}
......@@ -228,7 +228,7 @@ public class TrendServiceImpl implements TrendService {
}
wDirVo.setSpeed(speed / 2);
wDirVo.setStopTimes((int) (stopTimes / 2));
wDirVo.setTrafficIndex(trafficIndex / 2 < 1 ? 1 : trafficIndex / 2);
wDirVo.setTrafficIndex(trafficIndex / 2 < 1 ? 1 : trafficIndex / 2);
wDirVo.setTravelTime(travelTime / 2);
wDirVo.setType("双向绿波");
greenwaveListVOList.add(wDirVo);
......@@ -287,19 +287,19 @@ public class TrendServiceImpl implements TrendService {
List<AbnormalCrossListVO> abnormalCrossListVOList =
crossDataRealtimeMapper.selectAbnormalCross(status, name, type);
// 添加优化状态
for (AbnormalCrossListVO abnormalCrossListVO : abnormalCrossListVOList) {
abnormalCrossListVO.setOptStatus(2); // 2未优化
String crossId = abnormalCrossListVO.getId();
// 查询优化日志
List<CrossSchemeOptLogPO> crossSchemeOptLogPOS = crossSchemeOptLogMapper.selectMaxByCrossId(crossId);
if (CollectionUtil.isNotEmpty(crossSchemeOptLogPOS)) {
CrossSchemeOptLogPO crossSchemeOptLogPO = crossSchemeOptLogPOS.get(0);
Date endTime = crossSchemeOptLogPO.getEndTime();
if (ObjectUtil.isEmpty(endTime)) {
abnormalCrossListVO.setOptStatus(1); // 1优化中
}
}
}
//for (AbnormalCrossListVO abnormalCrossListVO : abnormalCrossListVOList) {
// abnormalCrossListVO.setOptStatus(2); // 2未优化
// String crossId = abnormalCrossListVO.getId();
// // 查询优化日志
// List<CrossSchemeOptLogPO> crossSchemeOptLogPOS = crossSchemeOptLogMapper.selectMaxByCrossId(crossId);
// if (CollectionUtil.isNotEmpty(crossSchemeOptLogPOS)) {
// CrossSchemeOptLogPO crossSchemeOptLogPO = crossSchemeOptLogPOS.get(0);
// Date endTime = crossSchemeOptLogPO.getEndTime();
// if (ObjectUtil.isEmpty(endTime)) {
// abnormalCrossListVO.setOptStatus(1); // 1优化中
// }
// }
//}
// 坐标格式转换
for (AbnormalCrossListVO abnormalCrossListVO : abnormalCrossListVOList) {
String locationStr = abnormalCrossListVO.getLocationStr();
......@@ -330,24 +330,24 @@ public class TrendServiceImpl implements TrendService {
abnormalCrossListVOList.sort(crossComparator);
// 设置拥堵指数同比 环比
for (AbnormalCrossListVO abnormalCrossListVO : abnormalCrossListVOList) {
String crossId = abnormalCrossListVO.getId();
Integer batchTime = abnormalCrossListVO.getBatchTime();
double roundedTrafficIndex = Math.round(abnormalCrossListVO.getCongestionIndex() * 100.0) / 100.0;
abnormalCrossListVO.setCongestionIndex(roundedTrafficIndex);
// todo
//Double congestionIndex = abnormalCrossListVO.getCongestionIndex();
//double lastWeekIndex = getIndex(congestionIndex, crossId, batchTime - 604800);
//double lastPeriodIndex = getIndex(congestionIndex, crossId, batchTime - 300);
//abnormalCrossListVO.setLastWeekIndex(Math.floor(lastWeekIndex));
//abnormalCrossListVO.setLastPeriodIndex(Math.floor(lastPeriodIndex));
// 常发性偶发性 一个月内超过三次
int frequent = getFrequent(crossId, batchTime);
abnormalCrossListVO.setFrequent(frequent);
}
//for (AbnormalCrossListVO abnormalCrossListVO : abnormalCrossListVOList) {
// String crossId = abnormalCrossListVO.getId();
// Integer batchTime = abnormalCrossListVO.getBatchTime();
//
// double roundedTrafficIndex = Math.round(abnormalCrossListVO.getCongestionIndex() * 100.0) / 100.0;
// abnormalCrossListVO.setCongestionIndex(roundedTrafficIndex);
// // todo
// //Double congestionIndex = abnormalCrossListVO.getCongestionIndex();
// //double lastWeekIndex = getIndex(congestionIndex, crossId, batchTime - 604800);
// //double lastPeriodIndex = getIndex(congestionIndex, crossId, batchTime - 300);
// //abnormalCrossListVO.setLastWeekIndex(Math.floor(lastWeekIndex));
// //abnormalCrossListVO.setLastPeriodIndex(Math.floor(lastPeriodIndex));
//
// // 常发性偶发性 一个月内超过三次
// int frequent = getFrequent(crossId, batchTime);
//
// abnormalCrossListVO.setFrequent(frequent);
//}
List<AbnormalCrossListVO> sorted = abnormalCrossListVOList.stream().sorted(Comparator.comparingDouble(AbnormalCrossListVO::getTrafficIndex).reversed()).collect(Collectors.toList());
abnormalCrossVO.setAbnormalCrossList(sorted);
......@@ -1817,6 +1817,9 @@ public class TrendServiceImpl implements TrendService {
}
}
}
if (StringUtils.isNotBlank(crossId)) {
return hotspotCrossVOS.stream().sorted(Comparator.comparing(HotspotCrossVO::getTimeStamp).reversed()).collect(Collectors.toList());
}
return hotspotCrossVOS.stream().sorted(Comparator.comparing(HotspotCrossVO::getTimeStamp)).collect(Collectors.toList());
} catch (Exception e) {
log.error("重点路口监测异常:", e);
......@@ -2051,6 +2054,7 @@ public class TrendServiceImpl implements TrendService {
/**
* 设置状态时间比例
*
* @param crossStatusTimeRateVO
* @param status
* @param rate
......@@ -2159,7 +2163,7 @@ public class TrendServiceImpl implements TrendService {
resultPojo.setDirName(BaseEnum.SignalDirectionEnum.getNameByCode(dir));
resultPojo.setOverflowId(String.valueOf(dir));
resultPojo.setOverflowNums(overflowNums);
resultPojo.setSpeed( Math.round((meanV / dirList.size()) * 100) / 100.0);
resultPojo.setSpeed(Math.round((meanV / dirList.size()) * 100) / 100.0);
resultPojo.setVehicleLengthRatio(Math.round(vehicleLengthRatio / dirList.size() * 100));
return resultPojo;
}
......
......@@ -116,7 +116,7 @@ public class InduceSendServiceImpl implements InduceSendService {
int bottomRightY = Integer.parseInt(bottomRight[1]);
// 图片生成操作
boolean upDown = param.getContents()[0].contains("▲") || param.getContents()[0].contains("▼");
createImageWithText(induceTemplate, image, param.getContents(), induceTemplate.getTextSign(), upDown, topLeftX, topLeftY, bottomRightX, bottomRightY);
createImageWithText(induceTemplate, image, param.getContents(), upDown, topLeftX, topLeftY, bottomRightX, bottomRightY);
}
} catch (Exception ex) {
log.error(ex.getMessage());
......@@ -296,9 +296,17 @@ public class InduceSendServiceImpl implements InduceSendService {
* @param width 绘制区域宽度
* @param height 绘制区域高度
*/
private static FontMetrics autoFont(InduceTemplate pictureFile, Graphics2D g2d, boolean sign, String[] text, int width, int height) {
/**
* 根据绘制的区域,动态调整字体大小,以适应文本区域
*
* @param g2d graphics2d对象
* @param drawParam 绘制内容
* @param width 绘制区域宽度
* @param height 绘制区域高度
*/
private static FontMetrics autoFont(Graphics2D g2d, InduceTemplate drawParam,String[] contents, int width, int height) {
// 初始化字体
Font font = new Font("Arial", Font.BOLD, 1);
Font font = new Font(drawParam.getTextFont(), Font.BOLD, 1);
g2d.setFont(font);
FontMetrics metrics = g2d.getFontMetrics();
// 字体最大、最小限制
......@@ -306,32 +314,29 @@ public class InduceSendServiceImpl implements InduceSendService {
int maxFontSize = 100;
// 动态调整字体大小以适应文本区域
for (int fontSize = minFontSize; fontSize <= maxFontSize; fontSize++) {
font = new Font("Arial", Font.BOLD, fontSize);
font = new Font(drawParam.getTextFont(), Font.BOLD, fontSize);
g2d.setFont(font);
metrics = g2d.getFontMetrics();
pictureFile.setTextSize(fontSize);
// 确保绘制区域能够容纳文本,考虑字体长度和高度
if (sign) {
// 高度考虑上下边距
if (metrics.stringWidth(text[0]) > width || (metrics.getHeight() - 4) > height) {
// 设置字体大小
font = new Font("Arial", Font.BOLD, --fontSize);
g2d.setFont(font);
metrics = g2d.getFontMetrics();
pictureFile.setTextSize(fontSize);
return metrics;
}
} else {
// if (drawParam.getTextDirection()) {
// // 高度考虑上下边距
// if (metrics.stringWidth(contents[0]) > width || (metrics.getHeight() - 4) > height) {
// // 设置字体大小
// font = new Font(drawParam.getTextFont(), Font.BOLD, --fontSize);
// g2d.setFont(font);
// metrics = g2d.getFontMetrics();
// return metrics;
// }
// } else {
// 高度只考虑上边距
if (metrics.stringWidth(text[0]) > width || (metrics.getHeight() - 1) * text.length > height) {
if (metrics.stringWidth(contents[0]) > width || (metrics.getHeight() - 1) * contents.length > height) {
// 设置字体大小
font = new Font("Arial", Font.BOLD, --fontSize);
font = new Font(drawParam.getTextFont(), Font.BOLD, --fontSize);
g2d.setFont(font);
metrics = g2d.getFontMetrics();
pictureFile.setTextSize(fontSize);
return metrics;
}
}
// }
}
// 若字体大小超出限制,则返回最小字体
return metrics;
......@@ -348,7 +353,7 @@ public class InduceSendServiceImpl implements InduceSendService {
* @param bottomRightX 区域右下角x坐标
* @param bottomRightY 区域右下角y坐标
*/
public static void createImageWithText(InduceTemplate pictureFile, BufferedImage image, String[] text, boolean sign,boolean updown, int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) {
public static void createImageWithText(InduceTemplate pictureFile, BufferedImage image, String[] text, boolean updown, int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) {
// 创建Graphics2D对象
Graphics2D g2d = image.createGraphics();
// 转换坐标,原始坐标从底部开始,转换为顶部坐标
......@@ -359,7 +364,7 @@ public class InduceSendServiceImpl implements InduceSendService {
int width = bottomRightX - topLeftX;
int height = bottomRightY - topLeftY;
// 动态调整字体大小,以适应文本区域
FontMetrics metrics = autoFont(pictureFile, g2d, sign, text, width, height);
FontMetrics metrics = autoFont( g2d,pictureFile, text, width, height);
// 绘制坐标点
int textWidth;
// 考虑文字绘制方向、文字居中。垂直居中要根据文字高度,水平居中要根据文字宽度。
......@@ -369,7 +374,7 @@ public class InduceSendServiceImpl implements InduceSendService {
// 设置文字颜色
g2d.setColor(Color.green);
// 根据方向开始文字绘制
if (sign) {
if (true) {
// 因文字动态调整的字体大小,所以此处代码不应该被执行
// if (currentX < topLeftX) {
// currentX = topLeftX; // 若超出左边界,调整为左边界
......@@ -380,9 +385,6 @@ public class InduceSendServiceImpl implements InduceSendService {
currentX = topLeftX + (width - textWidth) / 2;
// 计算居中的y坐标
currentY = currentY + (height - metrics.getHeight()) / 2;
if (updown) {
currentX -= 33;
}
g2d.drawString(text[0], currentX, currentY);
} else {
// 计算每个文本内容的竖向绘制坐标
......
......@@ -16,9 +16,11 @@ import net.wanji.databus.dao.entity.GreenwaveRealtimePO;
import net.wanji.databus.dao.mapper.*;
import net.wanji.databus.po.CrossDataHistPO;
import net.wanji.databus.po.CrossDataRealtimePO;
import net.wanji.databus.po.CrossDirDataHistPO;
import net.wanji.opt.cache.BaseCrossInfoCache;
import net.wanji.opt.cache.GreenWaveInfoCache;
import net.wanji.opt.common.enums.GreenBeltDirEnum;
import net.wanji.opt.common.enums.GreenWaveInDirEnum;
import net.wanji.opt.dao.mapper.StrategyGreenOptHistMapper;
import net.wanji.opt.po.StrategyGreenOptHistEntity;
import net.wanji.opt.service.signalopt.GreenBeltInfoService;
......@@ -60,6 +62,8 @@ public class GreenBeltServiceImpl implements GreenBeltInfoService {
private CrossDataRealtimeMapper crossDataRealtimeMapper;
@Resource
private BaseCrossInfoCache baseCrossInfoCache;
@Resource
private CrossDirDataHistMapper crossDirDataHistMapper;
@Override
......@@ -257,32 +261,41 @@ public class GreenBeltServiceImpl implements GreenBeltInfoService {
public List<GreenBeltFlowStopTimeVO> greenBeltCrossDetailHist(Integer greenId) throws Exception {
try {
List<String> crossIds = greenwaveInfoMapper.selectCrossIdsById(greenId);
GreenwaveInfoPO greenwaveInfoPO = greenwaveInfoMapper.selectById(greenId);
long currentTimeMillis = System.currentTimeMillis();
int startSecond = (int) (currentTimeMillis / 1000 - 3600);
int startSecond = ((int) (currentTimeMillis / 1000)) - 3600;
int endSecond = (int) (currentTimeMillis / 1000);
List<CrossDataHistPO> crossDataHistPOS = crossDataHistMapper.selectByCrossIdsAndTimestamp(crossIds, startSecond, endSecond);
if (!CollectionUtils.isEmpty(crossDataHistPOS)) {
List<GreenBeltFlowStopTimeVO> results = new ArrayList<>();
Map<Date, List<CrossDataHistPO>> startTimeMap = crossDataHistPOS.stream().collect(Collectors.groupingBy(CrossDataHistPO::getStartTime));
for (Map.Entry<Date, List<CrossDataHistPO>> entry : startTimeMap.entrySet()) {
GreenBeltFlowStopTimeVO greenBeltFlowStopTimeVO = new GreenBeltFlowStopTimeVO();
Date startDate = entry.getKey();
List<GreenBeltFlowStopTimeVO.FlowStopTimeDetail> crossList = new ArrayList<>();
greenBeltFlowStopTimeVO.setStartTime(startDate);
List<CrossDataHistPO> value = entry.getValue();
if (!CollectionUtils.isEmpty(value)) {
for (CrossDataHistPO crossDataHistPO : value) {
GreenBeltFlowStopTimeVO.FlowStopTimeDetail flowStopTimeDetail = new GreenBeltFlowStopTimeVO.FlowStopTimeDetail();
flowStopTimeDetail.setFlow(crossDataHistPO.getFlow());
flowStopTimeDetail.setStopTimes(crossDataHistPO.getStopTimes());
flowStopTimeDetail.setCrossId(crossDataHistPO.getCrossId());
// todo 先删除,后续通过路口距离/速度计算 距离通过卫博发送数据
flowStopTimeDetail.setTravelTime(0.0);
crossList.add(flowStopTimeDetail);
List<GreenBeltFlowStopTimeVO> results = new ArrayList<>();
if (Objects.nonNull(greenwaveInfoPO)) {
String greenDir = greenwaveInfoPO.getGreenDir();
String[] split = greenDir.split(",");
List<Integer> dirList = new ArrayList<>(split.length);
for (String s : split) {
dirList.add(Integer.valueOf(s));
}
List<CrossDirDataHistPO> dirDataHistPOS = crossDirDataHistMapper.selectByCrossIdsDirsAndTimestamp(crossIds, dirList, startSecond, endSecond);
if (!CollectionUtils.isEmpty(dirDataHistPOS)) {
Map<Date, List<CrossDirDataHistPO>> dateMap = dirDataHistPOS.stream().collect(Collectors.groupingBy(CrossDirDataHistPO::getStartTime));
for (Map.Entry<Date, List<CrossDirDataHistPO>> entry : dateMap.entrySet()) {
Date date = entry.getKey();
List<CrossDirDataHistPO> value = entry.getValue();
GreenBeltFlowStopTimeVO greenBeltFlowStopTimeVO = new GreenBeltFlowStopTimeVO();
greenBeltFlowStopTimeVO.setStartTime(date);
List<GreenBeltFlowStopTimeVO.FlowStopTimeDetail> detailList = new ArrayList<>();
if (!CollectionUtils.isEmpty(value)) {
for (CrossDirDataHistPO crossDirDataHistPO : value) {
GreenBeltFlowStopTimeVO.FlowStopTimeDetail detail = new GreenBeltFlowStopTimeVO.FlowStopTimeDetail();
Integer dirType = crossDirDataHistPO.getDirType();
detail.setGreenDir(GreenWaveInDirEnum.getDesc(dirType));
detail.setCrossId(crossDirDataHistPO.getCrossId());
detail.setFlow(crossDirDataHistPO.getFlow());
detail.setStopTimes(crossDirDataHistPO.getStopTimes());
detailList.add(detail);
}
}
greenBeltFlowStopTimeVO.setDetailList(detailList);
results.add(greenBeltFlowStopTimeVO);
}
greenBeltFlowStopTimeVO.setDetailList(crossList);
results.add(greenBeltFlowStopTimeVO);
}
Collections.sort(results, Comparator.comparing(GreenBeltFlowStopTimeVO::getStartTime));
return results;
......
......@@ -349,6 +349,8 @@ public class StrategyControlServiceImpl implements StrategyControlService {
queryWrapper.eq(StrategyControlDataEntity::getBizType, type);
queryWrapper.le(StrategyControlDataEntity::getScheduleStart, current);
queryWrapper.ge(StrategyControlDataEntity::getScheduleEnd, current);
//queryWrapper.ge(StrategyControlDataEntity::getScheduleStart, current);
//queryWrapper.le(StrategyControlDataEntity::getScheduleEnd, current);
List<StrategyControlDataEntity> entities = strategyControlInfoMapper.selectList(queryWrapper);
List<StrategyControlDataEntity> results = new ArrayList<>(entities.size());
for (StrategyControlDataEntity entity : entities) {
......@@ -410,11 +412,13 @@ public class StrategyControlServiceImpl implements StrategyControlService {
BeanUtils.copyProperties(strategyControlDataEntity, strategyControlDataExt);
strategyControlDataExt.setStrategyName(StrategyControlEnum.getDesc(strategy));
strategyControlDataExt.setOptMethod(StrategyControlEnum.getMethod(strategy));
strategyControlDataExt.setOptStatus("未优化");
if (StringUtils.isNotBlank(strategyControlDataEntity.getTime())) {
strategyControlDataExt.setOptStatus("优化中");
strategyControlDataExts.add(strategyControlDataExt);
}
}
// 路口无优化模式
if (Objects.equals(0, type)) {
List<BaseCrossInfoPO> crossInfoCache = baseCrossInfoCache.getCrossInfoCache();
if (!CollectionUtils.isEmpty(crossInfoCache)) {
......@@ -438,8 +442,25 @@ public class StrategyControlServiceImpl implements StrategyControlService {
}
}
}
// 干线无优化模式
if (Objects.equals(1, type)) {
results.addAll(strategyControlDataExts);
if (CollectionUtils.isEmpty(strategyControlDataExts)) {
Map<Integer, GreenwaveInfoPO> greenWaveMap = GreenWaveInfoCache.greenWaveMap;
for (Map.Entry<Integer, GreenwaveInfoPO> entry : greenWaveMap.entrySet()) {
StrategyControlDataExt ext = new StrategyControlDataExt();
ext.setStrategy(0);
ext.setStrategyName("无策略");
ext.setOptStatus("未优化");
ext.setOptMethod("效率提升");
ext.setStatus(0);
ext.setWkt(entry.getValue().getWkt());
ext.setCrossName(entry.getValue().getName());
ext.setBizId(String.valueOf(entry.getKey()));
results.add(ext);
}
} else {
results.addAll(strategyControlDataExts);
}
}
results.sort(Comparator.comparing(StrategyControlDataExt::getOptStatus));
return jsonViewObject.success(results, "路网优化监测查询成功");
......
......@@ -157,11 +157,15 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
private static GreenBeltChartVO calGreenChart(GreenBeltInfoVO greenBeltInfoVO) throws JsonProcessingException {
ObjectMapper mapper = JacksonUtils.getInstance();
Map<String, List<List<Double>>> crossRedTimesMap = new LinkedHashMap<>();
Map<String, List<List<Double>>> backCrossRedTimesMap = new LinkedHashMap<>();
List<List<Double>> crossRedTimeList = new LinkedList<List<Double>>();
Map<String, List<List<Double>>> backCrossRedTimesMap = new TreeMap<>();
List<List<Double>> backCrossRedTimeList = new LinkedList<List<Double>>();
Map<String, Double> crossGreenStartMap = new LinkedHashMap<>();
Map<String, Double> backCrossGreenStartMap = new LinkedHashMap<>();
LinkedList<Double> crossGreenStartList = new LinkedList<>();
Map<String, Double> backCrossGreenStartMap = new TreeMap<>();
LinkedList<Double> backCrossGreenStartList = new LinkedList<>();
Map<String, Double> distanceMap = new LinkedHashMap<>();
Map<String, Double> backDistanceMap = new LinkedHashMap<>();
Map<String, Double> backDistanceMap = new TreeMap<>();
String decideSpeed = "";
String backDecideSpeed = "";
String crossSpeed = "";
......@@ -180,7 +184,7 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
if (dirType == 1) {
greenWidthTime = dirGreenDetail.getGreenWidthTime();
List<GreenBeltInfoVO.CrossGreenDetail> list = dirGreenDetail.getCrossGreenDetailList();
getaDouble(crossRedTimesMap, crossGreenStartMap, distanceMap, cycle, list);
getaDouble(crossRedTimesMap, crossGreenStartMap, distanceMap, cycle, list, crossGreenStartList);
decideSpeed = String.join("~", String.valueOf(dirGreenDetail.getMinSpeed()), String.valueOf(dirGreenDetail.getMaxSpeed()));
List<Double> travelTimeList = list.stream().map(GreenBeltInfoVO.CrossGreenDetail::getTravelTime).collect(Collectors.toList());
travelTime = mapper.writeValueAsString(travelTimeList);
......@@ -200,7 +204,7 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
backGreenWidthTime = dirGreenDetail.getGreenWidthTime();
List<GreenBeltInfoVO.CrossGreenDetail> list = dirGreenDetail.getCrossGreenDetailList();
Collections.reverse(list);
getaDouble(backCrossRedTimesMap, backCrossGreenStartMap, backDistanceMap, cycle, list);
getaDouble(backCrossRedTimesMap, backCrossGreenStartMap, backDistanceMap, cycle, list, backCrossGreenStartList);
List<Double> travelTimeList = list.stream().map(GreenBeltInfoVO.CrossGreenDetail::getTravelTime).collect(Collectors.toList());
backtravelTime = mapper.writeValueAsString(travelTimeList);
List<Double> speedList = list.stream().map(GreenBeltInfoVO.CrossGreenDetail::getSpeed).collect(Collectors.toList());
......@@ -230,11 +234,25 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
greenBeltChartVO.setCrossSpeed(crossSpeed);
greenBeltChartVO.setBackCrossSpeed(backCrossSpeed);
greenBeltChartVO.setOffset(offset);
greenBeltChartVO.setCrossGreenStartList(strArray(crossGreenStartList));
Collections.reverse(backCrossGreenStartList);
greenBeltChartVO.setBackCrossGreenStartList(strArray(backCrossGreenStartList));
return greenBeltChartVO;
}
private static String strArray(List<Double> crossGreenStartList) {
StringBuilder sb = new StringBuilder();
if (!CollectionUtils.isEmpty(crossGreenStartList)) {
for (Double aDouble : crossGreenStartList) {
sb.append(aDouble).append(",");
}
}
return sb.toString();
}
private static void getaDouble(Map<String, List<List<Double>>> crossRedTimesMap, Map<String, Double> crossGreenStartMap, Map<String, Double> distanceMap,
Integer cycle, List<GreenBeltInfoVO.CrossGreenDetail> crossGreenDetailList) {
Integer cycle, List<GreenBeltInfoVO.CrossGreenDetail> crossGreenDetailList,
LinkedList<Double> crossGreenStartList) {
if (!CollectionUtils.isEmpty(crossGreenDetailList)) {
// 所有行程时间
......@@ -291,7 +309,8 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
// endCycleExt红灯
redTimes.add(Arrays.asList(cycleIndex + offset + cycleD, cycleIndex + offset + cycleD + phaseStartTime));
// offset红灯
redTimes.add(Arrays.asList(phaseEndTime - offsetIndex, offset));
double a = phaseEndTime - offsetIndex;
redTimes.add(Arrays.asList(a < 0.0 ? 0.0 : a, offset));
} else {
// endCycleExt红灯
redTimes.add(Arrays.asList(cycleIndex + offset + cycleD, cycleIndex + offset + cycleD + endCycleExt));
......@@ -313,6 +332,7 @@ public class StrategyGreenBeltServiceImpl implements StrategyGreenBeltService {
crossRedTimesMap.put(crossId, uniqueSortedRedTimes);
}
crossGreenStartMap.put(crossId, crossGreenStartTime);
crossGreenStartList.add(crossGreenStartTime);
crossGreenStartTime += travelTime;
distanceMap.put(crossId, distance);
}
......
......@@ -196,10 +196,10 @@ public class InducesMonitorTask {
// 计算绿波速度变化趋势
if (Objects.nonNull(greenwaveInducesHist.getMinSpeed()) && Objects.nonNull(greenwaveInducesHist.getMaxSpeed()) && Objects.nonNull(greenOptHistEntity.getMinSpeed()) && Objects.nonNull(greenOptHistEntity.getMaxSpeed())) {
if (greenwaveInducesHist.getMinSpeed() > greenOptHistEntity.getMinSpeed() || greenwaveInducesHist.getMaxSpeed() > greenOptHistEntity.getMaxSpeed()) {
upDown = "▼ ";
upDown = "▼";
}
if (greenwaveInducesHist.getMinSpeed() < greenOptHistEntity.getMinSpeed() || greenwaveInducesHist.getMaxSpeed() < greenOptHistEntity.getMaxSpeed()) {
upDown = "▲ ";
upDown = "▲";
}
}
greenwaveInducesHist.setMinSpeed(greenOptHistEntity.getMinSpeed());
......@@ -246,7 +246,7 @@ public class InducesMonitorTask {
messageParam.setEndTime(DateUtil.format(System.currentTimeMillis() + 1000 * 60, Constants.DATE_FORMAT.E_DATE_FORMAT_SECOND));
}
induceSendService.send(messageParam);
Thread.sleep(1000);
Thread.sleep(10000);
}
}
greenwaveInducesHist.setStatus(1);
......
package net.wanji.opt.vo;
import lombok.Data;
/**
* @author duanruiming
* @date 2024/12/11 17:52
*/
@Data
public class AIOptResultVO {
private String id;
private String name;
/** 0:无策略 1:绿灯空放 2:失衡 3:溢出 */
private Integer strategy;
private String optMethod;
private String optStatusName;
private Integer optStatus;
}
......@@ -5,14 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.wanji.common.utils.tool.JacksonUtils;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @author duanruiming
......@@ -48,6 +41,8 @@ public class GreenBeltChartVO {
private String crossSpeed;
private String backCrossSpeed;
private String offset;
private String crossGreenStartList;
private String backCrossGreenStartList;
@JsonCreator
public GreenBeltChartVO(){
......
package net.wanji.opt.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import net.wanji.opt.config.Double2TwoDecimalPlacesSerializer;
import java.util.Date;
import java.util.List;
......@@ -25,11 +27,15 @@ public class GreenBeltFlowStopTimeVO {
public static class FlowStopTimeDetail {
@ApiModelProperty("路口编号")
private String crossId;
@ApiModelProperty("绿波方向")
private String greenDir;
@ApiModelProperty("流量")
private Integer flow;
@ApiModelProperty("停车次数")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double stopTimes;
@ApiModelProperty("行程时间")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double travelTime;
}
}
package net.wanji.opt.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import net.wanji.opt.config.Double2TwoDecimalPlacesSerializer;
import java.util.Date;
......@@ -20,7 +22,9 @@ public class GreenBeltSpeedWidthVO {
@ApiModelProperty("干线方向")
private String dirName;
@ApiModelProperty("速度")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double speed;
@ApiModelProperty("带宽")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double width;
}
package net.wanji.opt.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import net.wanji.opt.config.Double2TwoDecimalPlacesSerializer;
import java.util.Date;
......@@ -24,8 +26,10 @@ public class GreenBeltStopTimesQueueLengthVO {
@ApiModelProperty("绿波方向")
private String roadDirection;
@ApiModelProperty("停车次数")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double stopTimes;
@ApiModelProperty("空间占比")
@JsonSerialize(using = Double2TwoDecimalPlacesSerializer.class)
private Double cordQueueRatio;
@ApiModelProperty("行程时间")
private Integer travelTime;
......
package net.wanji.opt.vo;
import lombok.Data;
/**
* @author duanruiming
* @date 2024/12/11 22:50
*/
@Data
public class crossStatusCountVO {
private int overFlowCount;
private int unbalanceCount;
private int phaseEmptyCount;
private int congestionCount;
}
......@@ -5,7 +5,11 @@
<mapper namespace="net.wanji.opt.dao.mapper.StrategyGreenOptHistMapper">
<select id="selectByGreenId" resultType="net.wanji.opt.po.StrategyGreenOptHistEntity" parameterType="String" >
select * from t_strategy_green_opt_hist where `green_id` = #{greenId} and `control_method`=1 and TIMESTAMPDIFF(SECOND,`control_time`, now()) &lt; `control_duration` order by create_time desc limit 2;
select * from t_strategy_green_opt_hist a
inner join (
-- 先查询出最后一条数据的时间
select `green_id`, MAX(`control_time`) control_time from t_strategy_green_opt_hist group by `green_id`
) b on a.`green_id` = b.`green_id` and a.`control_time` = b.`control_time` and a.`green_id` = #{greenId} and a.`control_method` = 1 and TIMESTAMPDIFF(SECOND,a.`control_time`, now()) &lt; a.`control_duration`
</select>
</mapper>
\ No newline at end of file
......@@ -22,6 +22,9 @@ public class GreenwaveInfoPO {
/** 协调方向:0正向;1反向;2双向 */
@ApiModelProperty(name = "协调方向:0正向;1反向;2双向",notes = "")
private Integer dir ;
/** 协调方向详情, 1,7 南北方向 反向 7, 1 */
@ApiModelProperty(name = "协调方向详情, 1,7 南北方向 反向 7, 1",notes = "")
private String greenDir ;
/** 开始时间 */
@ApiModelProperty(name = "开始时间",notes = "")
private Date startTime ;
......
......@@ -44,7 +44,8 @@
ROUND(AVG(traffic_index), 2) AS congestion_index,
ROUND(AVG(trval_time), 2) AS trval_time
FROM t_greenwave_hist
WHERE gmt_modified &gt;= DATE_SUB(DATE_FORMAT(#{nowTime}, '%Y-%m-%d %H:00:00'), INTERVAL 10 HOUR)
<!-- WHERE gmt_modified &gt;= DATE_SUB(DATE_FORMAT(#{nowTime}, '%Y-%m-%d %H:00:00'), INTERVAL 10 HOUR)-->
WHERE gmt_modified &gt;= DATE_FORMAT(#{nowTime}, '%Y-%m-%d 00:00:00')
AND gmt_modified &lt; DATE_FORMAT(DATE_ADD(#{nowTime}, INTERVAL 1 HOUR), '%Y-%m-%d %H:00:00')
GROUP BY hour
ORDER BY hour
......
......@@ -3,7 +3,8 @@
<mapper namespace="net.wanji.databus.dao.mapper.GreenwaveInfoMapper">
<sql id="Base_Column_List">
id,name,length,width,dir,start_time,end_time,design_speed,design_cycly,section_id,status,wkt,gmt_create,gmt_modified
id,name,length,width,dir,start_time,end_time,design_speed,design_cycly,section_id,status,wkt,gmt_create,gmt_modified,
green_dir
</sql>
<select id="listGreenwave" resultType="net.wanji.databus.vo.GreenwaveListVO">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment