Commit c29ea989 authored by hanbing's avatar hanbing

[add] 绿波评价-干线方案分析,评价结果

parent 4ae96a01
......@@ -20,6 +20,7 @@ public class SceneStrategyPO {
/** 策略ID */
@ApiModelProperty(name = "策略ID",notes = "")
private Integer strategyId ;
@ApiModelProperty(name = "优先级",notes = "")
private Integer sceneStrategyPriority ;
/** 创建时间 */
......
......@@ -4,15 +4,17 @@ import lombok.extern.slf4j.Slf4j;
import net.wanji.common.enums.BaseEnum;
import net.wanji.common.enums.StrategyAndMetricsEnum;
import net.wanji.common.enums.TurnConvertEnum;
import net.wanji.databus.dao.entity.BaseCrossDirInfoPO;
import net.wanji.databus.dao.entity.GreenwaveHistPO;
import net.wanji.databus.dao.entity.GreenwaveInfoPO;
import net.wanji.databus.dao.entity.*;
import net.wanji.databus.dao.mapper.*;
import net.wanji.databus.po.*;
import net.wanji.opt.bo.BottomCurveBO;
import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.bo.MainlineSchemeAnalysisBO;
import net.wanji.opt.dao.mapper.strategy.SceneStrategyMapper;
import net.wanji.opt.dao.mapper.strategy.StrategyMapper;
import net.wanji.opt.dao.mapper.trend.GreenwaveInfoMapper;
import net.wanji.opt.po.strategy.SceneStrategyPO;
import net.wanji.opt.po.strategy.StrategyPO;
import net.wanji.opt.service.MainlineEvaluateService;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO;
import net.wanji.opt.vo.MainlineSchemeAnalysisVO;
......@@ -40,15 +42,22 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
private final CrossLaneDataHistMapper crossLaneDataHistMapper;
private final GreenwaveInfoMapper greenwaveInfoMapper;
private final GreenwaveHistMapper greenwaveHistMapper;
private final GreenwaveCrossMapper greenwaveCrossMapper;
private final BaseCrossInfoMapper baseCrossInfoMapper;
private final GreenwaveSceneMapper greenwaveSceneMapper;
private final SceneStrategyMapper sceneStrategyMapper;
private final StrategyMapper strategyMapper;
private final BaseCrossSectionMapper baseCrossSectionMapper;
SimpleDateFormat hourMinuteFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat dateHourMinuteFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public MainlineEvaluateServiceImpl(@Qualifier("baseCrossDirInfoMapper") BaseCrossDirInfoMapper baseCrossDirInfoMapper,
@Qualifier("baseCrossTurnInfoMapper") BaseCrossTurnInfoMapper baseCrossTurnInfoMapper,
CrossBaseLaneInfoMapper crossBaseLaneInfoMapper,
@Qualifier("laneInfoMapper") LaneInfoMapper laneInfoMapper,
CrossDirDataHistMapper crossDirDataHistMapper, CrossDataHistMapper crossDataHistMapper, CrossTurnDataHistMapper crossTurnDataHistMapper, CrossLaneDataHistMapper crossLaneDataHistMapper, @Qualifier("greenwaveInfoMapper") GreenwaveInfoMapper greenwaveInfoMapper, @Qualifier("greenwaveHistMapper") GreenwaveHistMapper greenwaveHistMapper) {
CrossDirDataHistMapper crossDirDataHistMapper, CrossDataHistMapper crossDataHistMapper, CrossTurnDataHistMapper crossTurnDataHistMapper, CrossLaneDataHistMapper crossLaneDataHistMapper, @Qualifier("greenwaveInfoMapper") GreenwaveInfoMapper greenwaveInfoMapper, @Qualifier("greenwaveHistMapper") GreenwaveHistMapper greenwaveHistMapper, @Qualifier("greenwaveCrossMapper") GreenwaveCrossMapper greenwaveCrossMapper, @Qualifier("baseCrossInfoMapper") BaseCrossInfoMapper baseCrossInfoMapper, @Qualifier("greenwaveSceneMapper") GreenwaveSceneMapper greenwaveSceneMapper, @Qualifier("sceneStrategyMapper") SceneStrategyMapper sceneStrategyMapper, @Qualifier("strategyMapper") StrategyMapper strategyMapper, @Qualifier("baseCrossSectionMapper") BaseCrossSectionMapper baseCrossSectionMapper) {
this.baseCrossDirInfoMapper = baseCrossDirInfoMapper;
this.baseCrossTurnInfoMapper = baseCrossTurnInfoMapper;
this.laneInfoMapper = laneInfoMapper;
......@@ -58,6 +67,12 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
this.crossLaneDataHistMapper = crossLaneDataHistMapper;
this.greenwaveInfoMapper = greenwaveInfoMapper;
this.greenwaveHistMapper = greenwaveHistMapper;
this.greenwaveCrossMapper = greenwaveCrossMapper;
this.baseCrossInfoMapper = baseCrossInfoMapper;
this.greenwaveSceneMapper = greenwaveSceneMapper;
this.sceneStrategyMapper = sceneStrategyMapper;
this.strategyMapper = strategyMapper;
this.baseCrossSectionMapper = baseCrossSectionMapper;
}
@Override
......@@ -496,7 +511,6 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
String mainlineName = bo.getName();
Date poStartTime = bo.getStartTime();
Date poEndTime = bo.getEndTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String poStartTimeStr = sdf.format(poStartTime);
String poEndTimeStr = sdf.format(poEndTime);
// 根据时段查询所有发生的绿波
......@@ -517,16 +531,181 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
MainlineSchemeAnalysisVO res = new MainlineSchemeAnalysisVO();
res.setSceneData(calcSceneData(filteredList));
res.setCrossData(new ArrayList<>());
res.setEvaluateData(new ArrayList<>());
res.setCrossData(calcCrossData(filteredList));
res.setEvaluateData(calcEvaluateData(filteredList));
res.setGreenwaveData(new ArrayList<>());
return null;
}
private List<String> calcEvaluateData(List<GreenwaveHistPO> filteredList) {
int qualified = 0;
int notQualified = 0;
for (GreenwaveHistPO greenwaveHistPO : filteredList) {
Double noparkPassRate = greenwaveHistPO.getNoparkPassRate();
Double cordReliability = greenwaveHistPO.getCordReliability();
Double uncoordinatePhaseQueue = greenwaveHistPO.getUncoordinatePhaseQueue();
Double cordQueueRatio = greenwaveHistPO.getCordQueueRatio();
Integer greenwaveId = greenwaveHistPO.getId();
// 确定控制策略
GreenwaveScenePO greenwaveScenePO = greenwaveSceneMapper.selectByGreenwaveId(greenwaveId);
Integer sceneId = greenwaveScenePO.getSceneId();
List<SceneStrategyPO> sceneStrategyPOList = sceneStrategyMapper.selectBySceneId(sceneId);
Optional<SceneStrategyPO> maxPriorityPO = sceneStrategyPOList.stream()
.max(Comparator.comparingInt(SceneStrategyPO::getSceneStrategyPriority));
SceneStrategyPO sceneStrategyPO = maxPriorityPO.get();
Integer strategyId = sceneStrategyPO.getStrategyId();
StrategyPO strategyPO = strategyMapper.selectById(strategyId);
String strategyCode = strategyPO.getStrategyCode();
// 确定评价
// 获取时段
Integer sectionId = greenwaveHistPO.getSectionId();
CrossSectionPO crossSectionPO = baseCrossSectionMapper.selectById(sectionId);
String startHourMinuteStr = crossSectionPO.getStartTime();
String endHourMinuteStr = crossSectionPO.getEndTime();
Date day = greenwaveHistPO.getGmtModified();
Date startDate = combineDateAndTime(day, startHourMinuteStr);
Date endDate = combineDateAndTime(day, endHourMinuteStr);
// 获取路口
List<BaseCrossInfoPO> crossInfoPOList = getGreenwaveCross(greenwaveId);
// 获取路口历史数据
List<String> crossIdList = crossInfoPOList.stream()
.map(BaseCrossInfoPO::getId)
.collect(Collectors.toList());
int startTimeStamp = (int) (startDate.getTime() / 1000);
int endTimeStamp = (int) (endDate.getTime() / 1000);
List<CrossDataHistPO> crossDataHistPOList = crossDataHistMapper
.selectByCrossIdsAndTimestamp(crossIdList, startTimeStamp, endTimeStamp);
// 判断时段内的饱和度
double saturation = crossDataHistPOList.stream()
.mapToDouble(CrossDataHistPO::getSturation)
.average()
.orElse(0.0);
Integer dir = greenwaveHistPO.getDir();
if (dir == 0 || dir == 1) { // 单向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
if (saturation < 0.8) {
if (noparkPassRate > 0.8 && cordReliability > 0.7) {
// 协调不停车通过率需大于80%,并且协调方案可靠性需大于70%
qualified++;
} else if (uncoordinatePhaseQueue < 0.5) {
// 如果以上不满足,则非协调相位二次排队需小于50%
qualified++;
} else {
notQualified++;
}
} else {
// 协调方案可靠性需大于70%
if (cordReliability > 0.7) {
qualified++;
} else {
notQualified++;
}
}
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_BALANCE.getCode())) {
if (cordQueueRatio < 0.6) {
// 协调路段排队空间占比需小于60%
qualified++;
} else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100%
qualified ++;
} else {
notQualified++;
}
}
} else { // 双向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
// 协调不停车通过率需大于50%,并且协调方案可靠性需大于70%
if (noparkPassRate > 0.5 && cordReliability > 0.7) {
qualified++;
} else {
notQualified++;
}
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_BALANCE.getCode())) {
if (cordQueueRatio < 0.6) {
// 协调路段排队空间占比需小于60%
qualified++;
} else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100%
qualified ++;
} else {
notQualified++;
}
}
}
}
List<String> res = new ArrayList<>();
res.add("符合控制策略方案数 " + qualified + "个");
res.add("不符合控制策略方案数 " + notQualified + "个");
return res;
}
private List<BaseCrossInfoPO> getGreenwaveCross(Integer greenwaveId) {
List<BaseCrossInfoPO> res = new ArrayList<>();
List<GreenwaveCrossPO> greenwaveCrosses = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId);
for (GreenwaveCrossPO greenwaveCross : greenwaveCrosses) {
String crossId = greenwaveCross.getCrossId();
BaseCrossInfoPO baseCrossInfoPO = baseCrossInfoMapper.selectById(crossId);
res.add(baseCrossInfoPO);
}
return res;
}
private Date combineDateAndTime(Date day, String hourMinuteStr) {
String[] hourMinute = hourMinuteStr.split(":");
int hour = Integer.parseInt(hourMinute[0]);
int minute = Integer.parseInt(hourMinute[1]);
Calendar calendar = Calendar.getInstance();
calendar.setTime(day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
private List<MainlineSchemeAnalysisVO.CrossData> calcCrossData(List<GreenwaveHistPO> filteredList) {
List<MainlineSchemeAnalysisVO.CrossData> res = new ArrayList<>();
// 找出绿波对应的关键路口
Map<Integer, String> greenwaveCrossMap = new HashMap<>();
for (GreenwaveHistPO greenwaveHistPO : filteredList) {
Integer greenwaveId = greenwaveHistPO.getId();
GreenwaveCrossPO greenwaveCrossPO = greenwaveCrossMapper.selectByGreenwaveIdAndKeyRoute(greenwaveId);
Integer greenId = greenwaveCrossPO.getGreenId();
String crossId = greenwaveCrossPO.getCrossId();
greenwaveCrossMap.put(greenId, crossId);
}
// 统计关键路口次数
Map<String, Integer> crossTimesMap = new HashMap<>();
for (GreenwaveHistPO greenwaveHistPO : filteredList) {
Integer greenwaveHistPOId = greenwaveHistPO.getId();
String crossId = greenwaveCrossMap.get(greenwaveHistPOId);
crossTimesMap.put(crossId, crossTimesMap.getOrDefault(crossId, 0) + 1);
}
for (Map.Entry<String, Integer> entry : crossTimesMap.entrySet()) {
MainlineSchemeAnalysisVO.CrossData crossData = new MainlineSchemeAnalysisVO.CrossData();
String crossId = entry.getKey();
BaseCrossInfoPO baseCrossInfoPO = baseCrossInfoMapper.selectById(crossId);
String crossName = baseCrossInfoPO.getName();
crossData.setName(crossName);
crossData.setTimes(entry.getValue());
res.add(crossData);
}
return res;
}
private List<MainlineSchemeAnalysisVO.DirectionData> calcSceneData(List<GreenwaveHistPO> filteredList) {
List<MainlineSchemeAnalysisVO.DirectionData> res = new ArrayList<>();
......
......@@ -9,7 +9,9 @@ public class StrategyAndMetricsEnum {
public enum Strategy {
BALANCE("100030", "均衡调控"),
EFFICIENCY("100152", "效率提升"),
SECURITY("100010", "安全保障");
SECURITY("100010", "安全保障"),
LINE_EFFICIENCY("200001", "干线效率提升"),
LINE_BALANCE("200002", "干线均衡调控");
private final String code;
private final String msg;
......
......@@ -10,8 +10,12 @@ import lombok.Data;
@Data
public class GreenwaveHistPO extends GreenwaveRealtimePO{
@ApiModelProperty(value = "绿波名称",notes = "")
@ApiModelProperty(value = "绿波名称")
private String greenwaveName;
@ApiModelProperty(name = "协调方向:0正向;1反向;2双向")
@ApiModelProperty(value = "协调方向:0正向;1反向;2双向")
private Integer dir;
@ApiModelProperty(value = "时段ID")
private Integer sectionId;
}
......@@ -28,4 +28,6 @@ public interface CrossDataHistMapper extends BaseMapper<CrossDataHistPO> {
Double selectMaxSaturation(String crossId, int startStamp, int endStamp);
Integer selectCrossEmergencyCount(String crossId, int startStamp, int endStamp);
List<CrossDataHistPO> selectByCrossIdsAndTimestamp(List<String> crossIdList, int startTimeStamp, int endTimeStamp);
}
......@@ -12,4 +12,6 @@ import java.util.List;
@Repository
public interface GreenwaveCrossMapper {
List<GreenwaveCrossPO> selectByGreenwaveId(Integer id);
GreenwaveCrossPO selectByGreenwaveIdAndKeyRoute(Integer greenwaveId);
}
......@@ -12,4 +12,6 @@ public interface GreenwaveSceneMapper {
void deleteByGreenwaveId(Integer greenwaveId);
void insertOne(GreenwaveScenePO greenwaveScenePO);
GreenwaveScenePO selectByGreenwaveId(Integer greenwaveId);
}
......@@ -111,4 +111,16 @@
AND cross_id = #{crossId}
</select>
<select id="selectByCrossIdsAndTimestamp" resultType="net.wanji.databus.po.CrossDataHistPO">
select <include refid="Base_Column_List"></include>
from t_cross_data_hist
where cross_id in
<foreach collection="crossIdList" item="crossId" separator="," open="(" close=")">
#{crossId}
</foreach>
and batch_time <![CDATA[ >= ]]> #{startTimeStamp}
and batch_time <![CDATA[ <= ]]> #{endTimeStamp}
order by batch_time
</select>
</mapper>
\ No newline at end of file
......@@ -2,13 +2,22 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.wanji.databus.dao.mapper.GreenwaveCrossMapper">
<sql id="Base_Column_List">
id,green_id,cross_id,in_dir,out_dir,offset,sort,section_id,next_cross_len,is_key_route,gmt_create,gmt_modified
</sql>
<select id="selectByGreenwaveId" resultType="net.wanji.databus.dao.entity.GreenwaveCrossPO">
select
id,green_id,cross_id,in_dir,out_dir,offset,sort,section_id,next_cross_len,is_key_route,gmt_create,gmt_modified
select <include refid="Base_Column_List"/>
from t_greenwave_cross
where green_id = #{id}
order by sort
</select>
<select id="selectByGreenwaveIdAndKeyRoute" resultType="net.wanji.databus.dao.entity.GreenwaveCrossPO">
select <include refid="Base_Column_List"/>
from t_greenwave_cross
where green_id = #{id} and is_key_route = 1
</select>
</mapper>
......@@ -27,7 +27,7 @@
<select id="selectByTimeSection" resultType="net.wanji.databus.dao.entity.GreenwaveHistPO">
select t1.id,t1.status,t1.type,t1.traffic_index,t1.speed,t1.trval_time,t1.stop_times,t1.queue_length,
t1.cong_rate,t1.delay_time,t1.nopark_pass_rate,t1.cord_reliability,t1.cord_queue_ratio,
t1.uncoordinate_phase_queue,t1.gmt_create,t1.gmt_modified, t2.name as greenwaveName, t2.dir
t1.uncoordinate_phase_queue,t1.gmt_create,t1.gmt_modified, t2.name as greenwaveName, t2.dir, t2.section_id
from t_greenwave_hist t1 join t_greenwave_info t2 on t1.id = t2.id
where t1.gmt_modified <![CDATA[ <= ]]> #{endTimeStr}
and t1.gmt_modified <![CDATA[ >= ]]> #{startTimeStr}
......
......@@ -2,6 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.wanji.databus.dao.mapper.GreenwaveSceneMapper">
<sql id="Base_Column_List">
id,greenwave_id,scene_id,gmt_create,gmt_modified
</sql>
<insert id="insertOne">
insert into t_greenwave_scene(greenwave_id,scene_id)
......@@ -10,7 +13,13 @@
<delete id="deleteByGreenwaveId">
delete from t_greenwave_scene
where greenwave_id = ${greenwaveId}
where greenwave_id = #{greenwaveId}
</delete>
<select id="selectByGreenwaveId" resultType="net.wanji.databus.po.GreenwaveScenePO">
select <include refid="Base_Column_List"/>
from t_greenwave_scene
where greenwave_id = #{greenwaveId}
</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