Commit ab6f6700 authored by hanbing's avatar hanbing

[add] 信号优化首页,子区路口指标

parent 50b34366
package net.wanji.opt.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author Kent HAN
* @date 2023/6/9 13:52
*/
@Data
@ApiModel(value = "GreenwaveIdAndTimeStampBO", description = "绿波ID和时间戳")
public class GreenwaveIdAndTimeStampBO {
@ApiModelProperty(value = "绿波ID")
private Integer greenwaveId;
@ApiModelProperty(value = "时间戳(秒)")
private Long timeStamp;
}
......@@ -6,12 +6,22 @@ import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import net.wanji.common.dto.CrossIdDTO;
import net.wanji.common.framework.rest.JsonViewObject;
import net.wanji.opt.bo.GreenwaveIdAndTimeStampBO;
import net.wanji.opt.bo.GreenwaveIdBO;
import net.wanji.opt.dto.trend.AbnormalCrossListDTO;
import net.wanji.opt.dto.trend.EventAlarmDTO;
import net.wanji.opt.dto.trend.GreenwaveListDTO;
import net.wanji.opt.service.impl.TrendServiceImpl;
import net.wanji.opt.vo.*;
import net.wanji.opt.vo.AbnormalCrossDetailVO;
import net.wanji.opt.vo.AbnormalCrossVO;
import net.wanji.opt.vo.EventAlarmVO;
import net.wanji.opt.vo.GreenWaveCrossMonitorVO;
import net.wanji.opt.vo.GreenwaveCrossMetricsVO;
import net.wanji.opt.vo.GreenwaveDetailVO;
import net.wanji.opt.vo.GreenwaveListVO;
import net.wanji.opt.vo.GreenwaveRunMonitorVO;
import net.wanji.opt.vo.GreenwaveStats;
import net.wanji.opt.vo.GreenwaveVO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -57,10 +67,34 @@ public class TrendController {
@PostMapping(value = "/greenwaveRunMonitor",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = GreenWaveRunMonitorVO.class),
@ApiResponse(code = 200, message = "OK", response = GreenwaveRunMonitorVO.class),
})
public JsonViewObject greenwaveRunMonitor(@RequestBody GreenwaveIdBO greenwaveIdBO) {
List<GreenWaveRunMonitorVO> res = trendService.greenwaveRunMonitor(greenwaveIdBO);
List<GreenwaveRunMonitorVO> res = trendService.greenwaveRunMonitor(greenwaveIdBO);
return JsonViewObject.newInstance().success(res);
}
@ApiOperation(value = "子区详情", notes = "子区详情", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@PostMapping(value = "/greenwaveDetail",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = GreenwaveDetailVO.class),
})
public JsonViewObject greenwaveDetail(@RequestBody GreenwaveIdBO greenwaveIdBO) {
GreenwaveDetailVO res = trendService.greenwaveDetail(greenwaveIdBO);
return JsonViewObject.newInstance().success(res);
}
@ApiOperation(value = "子区路口指标", notes = "子区路口指标", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@PostMapping(value = "/greenwaveCrossMetrics",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = GreenwaveCrossMetricsVO.class),
})
public JsonViewObject greenwaveCrossMetrics(@RequestBody GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO) {
List<GreenwaveCrossMetricsVO> res = trendService.greenwaveCrossMetrics(greenwaveIdAndTimeStampBO);
return JsonViewObject.newInstance().success(res);
}
......
package net.wanji.opt.service;
import net.wanji.common.dto.CrossIdDTO;
import net.wanji.opt.bo.GreenwaveIdAndTimeStampBO;
import net.wanji.opt.bo.GreenwaveIdBO;
import net.wanji.opt.dto.trend.AbnormalCrossListDTO;
import net.wanji.opt.dto.trend.GreenwaveListDTO;
......@@ -28,5 +29,9 @@ public interface TrendService {
List<GreenWaveCrossMonitorVO> greenwaveCrossMonitor(GreenwaveIdBO greenwaveIdBO);
List<GreenWaveRunMonitorVO> greenwaveRunMonitor(GreenwaveIdBO greenwaveIdBO);
List<GreenwaveRunMonitorVO> greenwaveRunMonitor(GreenwaveIdBO greenwaveIdBO);
GreenwaveDetailVO greenwaveDetail(GreenwaveIdBO greenwaveIdBO);
List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO);
}
......@@ -27,6 +27,7 @@ import net.wanji.databus.po.CrossDirDataHistPO;
import net.wanji.databus.po.CrossTurnDataRealtimePO;
import net.wanji.databus.po.TBaseCrossInfo;
import net.wanji.databus.vo.AbnormalCrossListVO;
import net.wanji.opt.bo.GreenwaveIdAndTimeStampBO;
import net.wanji.opt.bo.GreenwaveIdBO;
import net.wanji.opt.dao.mapper.CrossSchemeOptLogMapper;
import net.wanji.opt.dao.mapper.trend.EventAlarmMapper;
......@@ -41,7 +42,9 @@ import net.wanji.opt.vo.AbnormalCrossStats;
import net.wanji.opt.vo.AbnormalCrossVO;
import net.wanji.opt.vo.EventAlarmVO;
import net.wanji.opt.vo.GreenWaveCrossMonitorVO;
import net.wanji.opt.vo.GreenWaveRunMonitorVO;
import net.wanji.opt.vo.GreenwaveCrossMetricsVO;
import net.wanji.opt.vo.GreenwaveDetailVO;
import net.wanji.opt.vo.GreenwaveRunMonitorVO;
import net.wanji.opt.vo.GreenwaveListVO;
import net.wanji.opt.vo.GreenwaveStats;
import org.springframework.stereotype.Service;
......@@ -331,14 +334,14 @@ public class TrendServiceImpl implements TrendService {
}
@Override
public List<GreenWaveRunMonitorVO> greenwaveRunMonitor(GreenwaveIdBO greenwaveIdBO) {
List<GreenWaveRunMonitorVO> res = new ArrayList<>();
public List<GreenwaveRunMonitorVO> greenwaveRunMonitor(GreenwaveIdBO greenwaveIdBO) {
List<GreenwaveRunMonitorVO> res = new ArrayList<>();
Date nowTime = new Date();
// todo 测试用,固定当前时间
nowTime = DateUtil.parse("2023-06-09 15:00:00","yyyy-MM-dd HH:mm:ss");
List<GreenwaveHistPOExt> extList = greenwaveHistMapper.selectRunMonitor(nowTime);
for (GreenwaveHistPOExt greenwaveHistPOExt : extList) {
GreenWaveRunMonitorVO greenWaveRunMonitorVO = new GreenWaveRunMonitorVO();
GreenwaveRunMonitorVO greenWaveRunMonitorVO = new GreenwaveRunMonitorVO();
String hour = greenwaveHistPOExt.getHour();
String hourSub = hour.substring(11, 16); // 截取小时
greenWaveRunMonitorVO.setHour(hourSub);
......@@ -349,6 +352,118 @@ public class TrendServiceImpl implements TrendService {
return res;
}
@Override
public GreenwaveDetailVO greenwaveDetail(GreenwaveIdBO greenwaveIdBO) {
return null;
}
@Override
public List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO) {
List<GreenwaveCrossMetricsVO> res = new ArrayList<>();
Integer greenwaveId = greenwaveIdAndTimeStampBO.getGreenwaveId();
Long timeStamp = greenwaveIdAndTimeStampBO.getTimeStamp();
// todo 测试用,时间戳设定为 1676082600
timeStamp = 1676082600L;
List<GreenwaveCrossPO> greenwaveCrossList = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId);
int crossListSize = greenwaveCrossList.size();
int lastCrossIndex = crossListSize - 1;
for (int i = 0; i < crossListSize; i++) {
GreenwaveCrossPO greenwaveCrossPO = greenwaveCrossList.get(i);
GreenwaveCrossMetricsVO greenwaveCrossMetricsVO = new GreenwaveCrossMetricsVO();
String crossId = greenwaveCrossPO.getCrossId();
greenwaveCrossMetricsVO.setCrossId(crossId);
BaseCrossInfoPO baseCrossInfoPO = baseCrossInfoMapper.selectById(crossId);
if (baseCrossInfoPO != null) {
greenwaveCrossMetricsVO.setCrossName(baseCrossInfoPO.getName());
}
String currentCrossId = crossId;
long currentSeconds = timeStamp;
long preSeconds = currentSeconds - 60 * 5;
// 如果不是最后一个路口
if (i != lastCrossIndex) {
GreenwaveCrossPO nextCross = greenwaveCrossList.get(i + 1);
String nextCrossId = nextCross.getCrossId();
// 计算当前路口出口方向
RidInfoEntity ridInfoEntity = ridInfoMapper.selectByStartEnd(currentCrossId, nextCrossId);
if (ObjectUtil.isEmpty(ridInfoEntity)) {
throw new RuntimeException("路网数据不连续");
}
Integer outDir = ridInfoEntity.getOutDir();
List<CrossDirDataHistPO> listForNoPark =
crossDirDataHistMapper.selectNoPark(currentCrossId, outDir, currentSeconds, preSeconds);
List<CrossDirDataHistPO> listForPhaseQueue =
crossDirDataHistMapper.selectPhaseQueue(currentCrossId, outDir, currentSeconds, preSeconds);
setMetrics(greenwaveCrossMetricsVO, ridInfoEntity, listForNoPark, listForPhaseQueue);
} else {
// 最后一个路口
GreenwaveCrossPO preCross = greenwaveCrossList.get(i - 1);
String preCrossId = preCross.getCrossId();
// 计算当前路口入口方向
RidInfoEntity ridInfoEntity = ridInfoMapper.selectByStartEnd(preCrossId, currentCrossId);
if (ObjectUtil.isEmpty(ridInfoEntity)) {
throw new RuntimeException("路网数据不连续");
}
Integer inDir = ridInfoEntity.getInDir();
List<CrossDirDataHistPO> listForNoPark =
crossDirDataHistMapper.selectNoParkEnd(currentCrossId, inDir, currentSeconds, preSeconds);
List<CrossDirDataHistPO> listForPhaseQueue =
crossDirDataHistMapper.selectPhaseQueueEnd(currentCrossId, inDir, currentSeconds, preSeconds);
setMetrics(greenwaveCrossMetricsVO, ridInfoEntity, listForNoPark, listForPhaseQueue);
}
res.add(greenwaveCrossMetricsVO);
}
return res;
}
private void setMetrics(GreenwaveCrossMetricsVO greenwaveCrossMetricsVO, RidInfoEntity ridInfoEntity,
List<CrossDirDataHistPO> listForNoPark, List<CrossDirDataHistPO> listForPhaseQueue) {
if (CollectionUtil.isNotEmpty(listForNoPark) && CollectionUtil.isNotEmpty(listForPhaseQueue)) {
Integer noparkPassRate = getAveRate(listForNoPark);
greenwaveCrossMetricsVO.setNoparkPassRate(noparkPassRate);
Integer uncoordinatePhaseQueue = getPhaseQueue(listForPhaseQueue);
greenwaveCrossMetricsVO.setUncoordinatePhaseQueue(uncoordinatePhaseQueue);
Double length = ridInfoEntity.getLength();
Double speed = getSpeed(listForNoPark);
double travelTime = length / speed;
greenwaveCrossMetricsVO.setTrvalTime((int)travelTime);
}
}
private Double getSpeed(List<CrossDirDataHistPO> listForNoPark) {
Double total = 0.0;
for (CrossDirDataHistPO crossDirDataHistPO : listForNoPark) {
Double speed = crossDirDataHistPO.getSpeed();
total += speed;
}
double avgSpeed = total / listForNoPark.size();
return avgSpeed;
}
private Integer getPhaseQueue(List<CrossDirDataHistPO> listForPhaseQueue) {
double maxQueue = 0.0;
for (CrossDirDataHistPO crossDirDataHistPO : listForPhaseQueue) {
double queueLength = crossDirDataHistPO.getQueueLength();
if (queueLength > maxQueue) {
maxQueue = queueLength;
}
}
return (int)maxQueue;
}
private Integer getAveRate(List<CrossDirDataHistPO> crossDirDataHistPOList) {
Double total = 0.0;
for (CrossDirDataHistPO crossDirDataHistPO : crossDirDataHistPOList) {
Double noStopRate = crossDirDataHistPO.getNoStopRate();
total += noStopRate;
}
int size = crossDirDataHistPOList.size();
double avg = total / size;
return (int)(avg * 100);
}
private List<GreenWaveCrossMonitorVO> buildRes(List<GreenwaveCrossPO> greenwaveCrossPOList) {
List<GreenWaveCrossMonitorVO> res = new ArrayList<>();
for (GreenwaveCrossPO greenwaveCrossPO : greenwaveCrossPOList) {
......
package net.wanji.opt.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
@ApiModel(value = "GreenwaveCrossMetricsVO", description = "子区路口指标返回值")
public class GreenwaveCrossMetricsVO {
@ApiModelProperty(value = "路口ID")
private String crossId;
@ApiModelProperty(value = "路口名称")
private String crossName;
@ApiModelProperty(value = "协调相位不停车通过率(%)")
private Integer noparkPassRate;
@ApiModelProperty(value = "非协调相位二次排队")
private Integer uncoordinatePhaseQueue;
@ApiModelProperty(value = "路段行程时间")
private Integer trvalTime;
}
package net.wanji.opt.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@NoArgsConstructor
@Data
@ApiModel(value = "GreenwaveDetailVO", description = "子区详情返回值")
public class GreenwaveDetailVO {
@ApiModelProperty(value = "子区名称")
private String name;
@ApiModelProperty(value = "子区状态")
private Integer status;
@ApiModelProperty(value = "非协调相位二次排队")
private Integer uncoordinatePhaseQueue;
@ApiModelProperty(value = "协调不停车通过率(%)")
private Integer noparkPassRate;
@ApiModelProperty(value = "干线行程时间(秒)")
private Integer trvalTime;
@ApiModelProperty(value = "优化策略列表")
private List<String> strategyList;
@ApiModelProperty(value = "优化策略")
private String strategy;
@ApiModelProperty(value = "子区路口信息")
List<GreenwaveCross> greenwaveCrossList;
@NoArgsConstructor
@Data
public static class GreenwaveCross {
@ApiModelProperty(value = "路口ID")
private String crossId;
@ApiModelProperty(value = "路口名称")
private String crossName;
@ApiModelProperty(value = "相位差")
private Integer offset;
@ApiModelProperty(value = "到下一路口距离")
private Integer distanceToNextCross;
@ApiModelProperty(value = "行程速度")
private Double speed;
@ApiModelProperty(value = "绿波相位列表")
private List<GreenwavePhase> greenwavePhaseList;
}
@NoArgsConstructor
@Data
public static class GreenwavePhase {
}
}
......@@ -7,8 +7,8 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
@ApiModel(value = "GreenWaveRunMonitorVO", description = "子区信息-运行监测返回值")
public class GreenWaveRunMonitorVO {
@ApiModel(value = "GreenwaveRunMonitorVO", description = "子区信息-运行监测返回值")
public class GreenwaveRunMonitorVO {
@ApiModelProperty(value = "时间")
private String hour;
@ApiModelProperty(value = "平均速度")
......
......@@ -23,4 +23,12 @@ public interface CrossDirDataHistMapper extends BaseMapper<CrossDirDataHistPO> {
List<CrossDirDataHistPO> selectByCrossIdDirAndTimestamp(String crossId, Integer dir, long preSeconds);
List<CrossDirDataHistAvgBO> selectByCrossIdInOutTimestamp(String crossId, Integer inOutType, long preSeconds);
List<CrossDirDataHistPO> selectNoPark(String crossId, Integer dir, long currentSeconds, long preSeconds);
List<CrossDirDataHistPO> selectPhaseQueue(String crossId, Integer dir, long currentSeconds, long preSeconds);
List<CrossDirDataHistPO> selectNoParkEnd(String crossId, Integer dir, long currentSeconds, long preSeconds);
List<CrossDirDataHistPO> selectPhaseQueueEnd(String crossId, Integer dir, long currentSeconds, long preSeconds);
}
......@@ -47,6 +47,16 @@ public class CrossDirDataRealtimePO {
private Integer delayTime;
@ApiModelProperty(name = "饱和度",notes = "")
private Double sturation;
@ApiModelProperty(name = "不停车率",notes = "")
private Double noStopRate;
@ApiModelProperty(name = "一次停车率",notes = "")
private Double oneStopRate;
@ApiModelProperty(name = "二次停车率",notes = "")
private Double twoStopRate;
@ApiModelProperty(name = "三次停车率",notes = "")
private Double threeStopRate;
@ApiModelProperty(name = "采集时间(10位时间戳)",notes = "")
private Integer batchTime;
@ApiModelProperty(name = "创建时间",notes = "")
......
......@@ -27,7 +27,7 @@
<sql id="Base_Column_List">
id,dir_type,in_out_type,cross_id,length,status,traffic_index,start_time,capacity,flow,speed,queue_length,stop_times,
delay_time,sturation,batch_time,gmt_create,gmt_modified,effusion_time
delay_time,sturation,no_stop_rate,one_stop_rate,two_stop_rate,three_stop_rate,batch_time,gmt_create,gmt_modified,effusion_time
</sql>
<insert id="insertBatch" parameterType="net.wanji.databus.po.CrossDirDataHistPO">
......@@ -74,4 +74,36 @@
AND batch_time <![CDATA[ >= ]]> #{preSeconds}
GROUP BY dir_type
</select>
<select id="selectNoPark" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"/>
from t_cross_dir_data_hist
where cross_id = #{crossId} and in_out_type = 1 and dir_type = #{dir}
and batch_time <![CDATA[ <= ]]> #{currentSeconds}
and batch_time <![CDATA[ >= ]]> #{preSeconds}
</select>
<select id="selectPhaseQueue" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"/>
from t_cross_dir_data_hist
where cross_id = #{crossId} and in_out_type = 1 and dir_type != #{dir}
and batch_time <![CDATA[ <= ]]> #{currentSeconds}
and batch_time <![CDATA[ >= ]]> #{preSeconds}
</select>
<select id="selectNoParkEnd" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"/>
from t_cross_dir_data_hist
where cross_id = #{crossId} and in_out_type = 2 and dir_type = #{dir}
and batch_time <![CDATA[ <= ]]> #{currentSeconds}
and batch_time <![CDATA[ >= ]]> #{preSeconds}
</select>
<select id="selectPhaseQueueEnd" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"/>
from t_cross_dir_data_hist
where cross_id = #{crossId} and in_out_type = 2 and dir_type != #{dir}
and batch_time <![CDATA[ <= ]]> #{currentSeconds}
and batch_time <![CDATA[ >= ]]> #{preSeconds}
</select>
</mapper>
\ No newline at end of file
......@@ -8,6 +8,7 @@
id,green_id,cross_id,in_dir,out_dir,offset,sort,section_id,next_cross_len,is_key_route,gmt_create,gmt_modified
from t_greenwave_cross
where green_id = #{id}
order by sort
</select>
</mapper>
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