Commit 46a110ce authored by hanbing's avatar hanbing

[update] 微观大数据平台-路段行程时间改为根据轨迹计算

parent a1495534
package net.wanji.web.common.util;
import net.wanji.web.common.constant.Constant;
import net.wanji.web.common.util.date.DateStyle;
import net.wanji.web.common.util.date.DateUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @description: redis工具类
* @author wanji
* @version 1.0
* Created on 2019/4/29 20:34
*/
@Component
public class RedisUtils {
/**
* 注入redisTemplate
*/
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* @description: 判断是否存在Key
* @param key redis的Key
* @return boolean true:有 false:无
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* @description: 添加字符串
* @param key redis的Key
* @param value 添加redis的value
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* @description: 添加对象
* @param key redis的Key
* @param object 添加redis的value
*/
public void set(String key, Object object) {
redisTemplate.opsForValue().set(key, object);
}
/**
* @description: 添加带生命周期的对象
* @param key redis的Key
* @param object 添加redis的value
* @param seconds 失效时间
*/
public void setAndExpire(String key, Object object, int seconds) {
redisTemplate.opsForValue().set(key, object);
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
/**
* @description: 添加带生命周期的对象
* @param key redis的Key
* @param value 添加redis的value
* @param seconds 失效时间
*/
public void setAndExpire(String key, String value, int seconds) {
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
/**
* @description: 获取对象
* @param key redis的Key
* @return Object 返回对象
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* @description: 存入redis的hash
* @param key redis的Key
* @param field 字段值
* @param value 存入的值
*/
public void setHash(String key, String field, String value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* @description: 存入redis的hash
* @param key redis的Key
* @param field 字段值
* @param value 存入的值
*/
public void setHash(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* @description: 根据key和字段值获取内容值
* @param key redis的Key
* @param field 字段值
* @return String 返回字符串
*/
public String getHash(String key, String field) {
return (String)redisTemplate.opsForHash().get(key, field);
}
/**
* @description: 根据field删除值
* @param key redis的Key
* @param field 字段值
*/
public void delHashMap(String key, String field) {
redisTemplate.boundHashOps(key).delete(field);
}
/**
* @description: 存入hash集合
* @param key redis的Key
* @param hashmap 存入的Map集合
*/
public void setHashMap(String key, Map<String, Object> hashmap){
redisTemplate.opsForHash().putAll(key, hashmap);
}
/**
* @description: 取出hash集合
* @param key redis的Key
* @return Map<Object, Object> 返回Map集合
*/
public Map<Object, Object> getHashMap(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* @description: 存入redis的Set
* @param key redis的Key
* @param object 对象
*/
public void setSet(String key,Object object){
redisTemplate.opsForSet().add(key, object);
}
/**
* @description: 获取redis的Set
* @param key redis的Key
* @return Set<Object> Set集合
*/
public Set<Object> getSet(String key){
return redisTemplate.opsForSet().members(key);
}
/**
* @discription: 查看值是否是set成员
* @param key set的key
* @param value set的成员
* @return 是否是set成员
*/
public Boolean isSetMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* @description:设置key的过期时间,endTime格式:yyyy-MM-dd hh:mm:ss
* @param key redis的Key
* @param endTime 结束时间
*/
public void setExpire(String key, Date endTime) {
long seconds = endTime.getTime() - System.currentTimeMillis();
redisTemplate.expire(key, (int) (seconds / 1000), TimeUnit.SECONDS);
}
/**
* @description: 设置key的过期时间
* @param key redis的Key
* @param time 过期时间(秒)
*/
public void setExpire(String key, int time) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* <p>Discription:获取key的过期时间
* @param key redis的Key
* @return 过期时间(秒)
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* @description: 在redis消息队列队尾插入数据
* @param key redis的Key
* @param object 添加的对象
*/
public void tailPush(String key, Object object){
redisTemplate.opsForList().rightPush(key, object);
}
/**
* @description: 在redis消息队列对头插入数据
* @param key redis的Key
* @param object 添加的对象
*/
public void headPush(String key,Object object){
redisTemplate.opsForList().leftPush(key, object);
}
/**
* @description: 在redis消息队列队尾删除数据
* @param key redis的Key
* @return Object 删除的对象
*/
public Object tailPop(String key){
return redisTemplate.opsForList().rightPop(key);
}
/**
* @description: 在redis消息队列队头删除数据
* @param key redis的Key
* @return Object 删除的对象
*/
public Object headPop(String key){
return redisTemplate.opsForList().leftPop(key);
}
/**
* @description: 删除redis的值
* @param key redis的Key
*/
public void del(String key) {
if (hasKey(key)) {
redisTemplate.delete(key);
}
}
/**
* @description: 清理redis缓存
*/
public void flushDB(){
redisTemplate.getConnectionFactory().getConnection().flushDb();
}
/**
* @description: 根据类型生成版本号
* @param type 类型key区分
* @return 版本号
* @author wanji
* @date 2019/5/5 19:26
*/
public String getVersion(String type) {
String formatDate = DateUtils.dateToString(new Date(), DateStyle.YYYYMMDD);
String key = Constant.KEY_PREFIX + type + formatDate;
//当前时间到第二天还剩多少时间
Date newDate = DateUtils.dateForMat(DateUtils.addDay(new Date(), 1), DateStyle.YYYY_MM_DD);
int liveTime = DateUtils.dayDiff(newDate, new Date(), Calendar.MILLISECOND);
//获取自增号
Long incr = getIncr(key, liveTime);
if(incr == 0) {
incr = getIncr(key, liveTime);//从001开始
}
DecimalFormat df = new DecimalFormat("000");//三位序列号
return formatDate + Constant.SEPARATOR_MINUS + df.format(incr);
}
/**
* 自增ID
* @param key 建
* @param liveTime 过期时间
* @return 自增结果
*/
public Long getIncr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
entityIdCounter.expire(liveTime, TimeUnit.MILLISECONDS);//单位毫秒
}
return increment;
}
/**
* 获取全部Redis的key
* @return
*/
public Set<String> keys() {
return redisTemplate.keys("*");
}
}
package net.wanji.opt.common;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
/**
* @description: redis工具类
* @author wanji
* @version 1.0
* Created on 2019/4/29 20:34
*/
@Component
public class RedisUtils {
@Resource
private RedisTemplate<String, Object> redis7Template;
/**
* 7号库获取最大 score zset 元素
*/
public Object getMaxScoreElement(String redisKey) {
ZSetOperations<String, Object> zSetOps = redis7Template.opsForZSet();
Set<Object> result = zSetOps.reverseRange(redisKey, 0, 0);
if (result != null && !result.isEmpty()) {
return result.iterator().next();
} else {
return null;
}
}
}
package net.wanji.opt.config; package net.wanji.opt.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.client.RestTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.nio.charset.StandardCharsets;
@Configuration @Configuration
public class RestTemplateConfig { public class RestTemplateConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.database}")
private int redisDatabase;
@Value("${spring.redis.password}")
private String redisPassword;
// 默认使用配置的数据库
@Bean @Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) { public RedisConnectionFactory redisConnectionFactory() {
RestTemplate restTemplate = new RestTemplate(factory); LettuceConnectionFactory factory = new LettuceConnectionFactory(redisHost, redisPort);
restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8)); factory.setPassword(redisPassword);
return restTemplate; factory.setDatabase(redisDatabase);
return factory;
} }
@Bean @Bean(name = "redisTemplate")
public ClientHttpRequestFactory simpleClientHttpRequestFactory() { public RedisTemplate<String, Object> redisTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); RedisTemplate<String, Object> template = new RedisTemplate<>();
factory.setConnectTimeout(30000); template.setConnectionFactory(redisConnectionFactory());
factory.setReadTimeout(30000); template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
// 使用7号数据库
@Bean(name = "redis7ConnectionFactory")
public RedisConnectionFactory redis7ConnectionFactory() {
LettuceConnectionFactory factory = new LettuceConnectionFactory(redisHost, redisPort);
factory.setPassword(redisPassword);
factory.setDatabase(7);
return factory; return factory;
} }
@Bean(name = "redis7Template")
public RedisTemplate<String, Object> redis7Template() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redis7ConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
} }
\ No newline at end of file
package net.wanji.opt.controller; package net.wanji.opt.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponse;
...@@ -107,7 +108,8 @@ public class TrendController { ...@@ -107,7 +108,8 @@ public class TrendController {
@ApiResponses({ @ApiResponses({
@ApiResponse(code = 200, message = "OK", response = GreenwaveCrossMetricsVO.class), @ApiResponse(code = 200, message = "OK", response = GreenwaveCrossMetricsVO.class),
}) })
public JsonViewObject greenwaveCrossMetrics(@RequestBody GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO) { public JsonViewObject greenwaveCrossMetrics(@RequestBody GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO)
throws JsonProcessingException {
List<GreenwaveCrossMetricsVO> res = trendService.greenwaveCrossMetrics(greenwaveIdAndTimeStampBO); List<GreenwaveCrossMetricsVO> res = trendService.greenwaveCrossMetrics(greenwaveIdAndTimeStampBO);
return JsonViewObject.newInstance().success(res); return JsonViewObject.newInstance().success(res);
} }
......
package net.wanji.opt.dao.cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisDao {
/**
* 注入redisTemplate
*/
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* @description: 判断是否存在Key
* @param key redis的Key
* @return boolean true:有 false:无
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* @description: 添加字符串
* @param key redis的Key
* @param value 添加redis的value
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* @description: 添加对象
* @param key redis的Key
* @param object 添加redis的value
*/
public void set(String key, Object object) {
redisTemplate.opsForValue().set(key, object);
}
/**
* @description: 添加带生命周期的对象
* @param key redis的Key
* @param object 添加redis的value
* @param seconds 失效时间
*/
public void setAndExpire(String key, Object object, int seconds) {
redisTemplate.opsForValue().set(key, object);
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
/**
* @description: 添加带生命周期的对象
* @param key redis的Key
* @param value 添加redis的value
* @param seconds 失效时间
*/
public void setAndExpire(String key, String value, int seconds) {
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
/**
* @description: 获取对象
* @param key redis的Key
* @return Object 返回对象
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* @description: 存入redis的hash
* @param key redis的Key
* @param field 字段值
* @param value 存入的值
*/
public void setHash(String key, String field, String value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* @description: 存入redis的hash
* @param key redis的Key
* @param field 字段值
* @param value 存入的值
*/
public void setHash(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* @description: 根据key和字段值获取内容值
* @param key redis的Key
* @param field 字段值
* @return String 返回字符串
*/
public String getHash(String key, String field) {
return (String)redisTemplate.opsForHash().get(key, field);
}
/**
* @description: 根据field删除值
* @param key redis的Key
* @param field 字段值
*/
public void delHashMap(String key, String field) {
redisTemplate.boundHashOps(key).delete(field);
}
/**
* @description: 存入hash集合
* @param key redis的Key
* @param hashmap 存入的Map集合
*/
public void setHashMap(String key, Map<String, Object> hashmap){
redisTemplate.opsForHash().putAll(key, hashmap);
}
/**
* @description: 取出hash集合
* @param key redis的Key
* @return Map<Object, Object> 返回Map集合
*/
public Map<Object, Object> getHashMap(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* @description: 存入redis的Set
* @param key redis的Key
* @param object 对象
*/
public void setSet(String key,Object object){
redisTemplate.opsForSet().add(key, object);
}
/**
* @description: 获取redis的Set
* @param key redis的Key
* @return Set<Object> Set集合
*/
public Set<Object> getSet(String key){
return redisTemplate.opsForSet().members(key);
}
/**
* @discription: 查看值是否是set成员
* @param key set的key
* @param value set的成员
* @return 是否是set成员
*/
public Boolean isSetMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* @description:设置key的过期时间,endTime格式:yyyy-MM-dd hh:mm:ss
* @param key redis的Key
* @param endTime 结束时间
*/
public void setExpire(String key, Date endTime) {
long seconds = endTime.getTime() - System.currentTimeMillis();
redisTemplate.expire(key, (int) (seconds / 1000), TimeUnit.SECONDS);
}
/**
* @description: 设置key的过期时间
* @param key redis的Key
* @param time 过期时间(秒)
*/
public void setExpire(String key, int time) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* <p>Discription:获取key的过期时间
* @param key redis的Key
* @return 过期时间(秒)
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* @description: 在redis消息队列队尾插入数据
* @param key redis的Key
* @param object 添加的对象
*/
public void tailPush(String key, Object object){
redisTemplate.opsForList().rightPush(key, object);
}
/**
* @description: 在redis消息队列对头插入数据
* @param key redis的Key
* @param object 添加的对象
*/
public void headPush(String key,Object object){
redisTemplate.opsForList().leftPush(key, object);
}
/**
* @description: 在redis消息队列队尾删除数据
* @param key redis的Key
* @return Object 删除的对象
*/
public Object tailPop(String key){
return redisTemplate.opsForList().rightPop(key);
}
/**
* @description: 在redis消息队列队头删除数据
* @param key redis的Key
* @return Object 删除的对象
*/
public Object headPop(String key){
return redisTemplate.opsForList().leftPop(key);
}
/**
* @description: 删除redis的值
* @param key redis的Key
*/
public void del(String key) {
if (hasKey(key)) {
redisTemplate.delete(key);
}
}
/**
* @description: 清理redis缓存
*/
public void flushDB(){
redisTemplate.getConnectionFactory().getConnection().flushDb();
}
/**
* 自增ID
* @param key 建
* @param liveTime 过期时间
* @return 自增结果
*/
public Long getIncr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
entityIdCounter.expire(liveTime, TimeUnit.MILLISECONDS);//单位毫秒
}
return increment;
}
/**
* 获取全部Redis的key
* @return
*/
public Set<String> keys() {
return redisTemplate.keys("*");
}
}
package net.wanji.opt.dto;
import lombok.Data;
import java.util.List;
@Data
public class CrossEventDTO {
private Integer dir;
private String rid;
//该路段的结束路口
private String crossId;
private Double index;
private String indexName;
// 501畅通 502轻微拥堵 503中度拥堵 504重度拥堵
private String congestionCode;
private String timestamp;
private Long globalTimeStamp;
private Long startTime;
private Long endTime;
private Integer duration;
// 事件序列号
private String eventSerialNumber;
// 检测时间
private Long detectTime;
private List<CrossEventDTO> details;
private String msgType;
// 失衡方向
private Integer unbalanceDir;
// 路灯结束时排队长度
private Double greenEndQueueLength;
// 非协调方向饱和度
private Double noCoordSaturation;
// 协调方向行程时间
private Double transitTime;
// 协调方向自由流时间
private Double freeTime;
}
package net.wanji.opt.service; package net.wanji.opt.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import net.wanji.databus.bo.CrossIdBO; import net.wanji.databus.bo.CrossIdBO;
import net.wanji.databus.vo.GreenwaveListVO; import net.wanji.databus.vo.GreenwaveListVO;
import net.wanji.opt.bo.*; import net.wanji.opt.bo.*;
...@@ -35,7 +36,7 @@ public interface TrendService { ...@@ -35,7 +36,7 @@ public interface TrendService {
GreenwaveDetailVO greenwaveDetail(GreenwaveDetailBO greenwaveDetailBO); GreenwaveDetailVO greenwaveDetail(GreenwaveDetailBO greenwaveDetailBO);
List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO); List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO) throws JsonProcessingException;
void saveGreenwaveStrategy(SaveGreenwaveStrategyBO saveGreenwaveStrategyBO); void saveGreenwaveStrategy(SaveGreenwaveStrategyBO saveGreenwaveStrategyBO);
......
...@@ -5,6 +5,8 @@ import cn.hutool.core.date.DateUnit; ...@@ -5,6 +5,8 @@ import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.wanji.common.enums.*; import net.wanji.common.enums.*;
import net.wanji.common.framework.Constants; import net.wanji.common.framework.Constants;
...@@ -17,6 +19,7 @@ import net.wanji.databus.po.*; ...@@ -17,6 +19,7 @@ import net.wanji.databus.po.*;
import net.wanji.databus.vo.AbnormalCrossListVO; import net.wanji.databus.vo.AbnormalCrossListVO;
import net.wanji.databus.vo.GreenwaveListVO; import net.wanji.databus.vo.GreenwaveListVO;
import net.wanji.opt.bo.*; import net.wanji.opt.bo.*;
import net.wanji.opt.common.RedisUtils;
import net.wanji.opt.config.DirectionMappingsConfig; import net.wanji.opt.config.DirectionMappingsConfig;
import net.wanji.opt.dao.mapper.CrossSchemeOptLogMapper; import net.wanji.opt.dao.mapper.CrossSchemeOptLogMapper;
import net.wanji.opt.dao.mapper.HoloEventMapper; import net.wanji.opt.dao.mapper.HoloEventMapper;
...@@ -26,6 +29,7 @@ import net.wanji.opt.dao.mapper.strategy.SceneStrategyMapper; ...@@ -26,6 +29,7 @@ import net.wanji.opt.dao.mapper.strategy.SceneStrategyMapper;
import net.wanji.opt.dao.mapper.strategy.StrategyMapper; import net.wanji.opt.dao.mapper.strategy.StrategyMapper;
import net.wanji.opt.dao.mapper.trend.AnalysisRidTurnIndicatorsMapper; import net.wanji.opt.dao.mapper.trend.AnalysisRidTurnIndicatorsMapper;
import net.wanji.opt.dao.mapper.trend.EventAlarmMapper; import net.wanji.opt.dao.mapper.trend.EventAlarmMapper;
import net.wanji.opt.dto.CrossEventDTO;
import net.wanji.opt.dto.CrossLaneSnapshotDataDTO; import net.wanji.opt.dto.CrossLaneSnapshotDataDTO;
import net.wanji.opt.dto.LineSchemeDTO; import net.wanji.opt.dto.LineSchemeDTO;
import net.wanji.opt.dto.trend.AbnormalCrossListDTO; import net.wanji.opt.dto.trend.AbnormalCrossListDTO;
...@@ -40,6 +44,7 @@ import net.wanji.opt.service.TrendService; ...@@ -40,6 +44,7 @@ import net.wanji.opt.service.TrendService;
import net.wanji.opt.service.es.LaneSnapshotDataQueryService; import net.wanji.opt.service.es.LaneSnapshotDataQueryService;
import net.wanji.opt.vo.*; import net.wanji.opt.vo.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -121,6 +126,9 @@ public class TrendServiceImpl implements TrendService { ...@@ -121,6 +126,9 @@ public class TrendServiceImpl implements TrendService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
RedisUtils redisUtils;
public TrendServiceImpl(GreenwaveInfoMapper greenwaveInfoMapper, BaseCrossInfoMapper baseCrossInfoMapper, public TrendServiceImpl(GreenwaveInfoMapper greenwaveInfoMapper, BaseCrossInfoMapper baseCrossInfoMapper,
CrossDataRealtimeMapper crossDataRealtimeMapper, CrossDataRealtimeMapper crossDataRealtimeMapper,
CrossTurnDataRealtimeMapper crossTurnDataRealtimeMapper, CrossTurnDataRealtimeMapper crossTurnDataRealtimeMapper,
...@@ -996,7 +1004,9 @@ public class TrendServiceImpl implements TrendService { ...@@ -996,7 +1004,9 @@ public class TrendServiceImpl implements TrendService {
} }
@Override @Override
public List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO) { public List<GreenwaveCrossMetricsVO> greenwaveCrossMetrics(GreenwaveIdAndTimeStampBO greenwaveIdAndTimeStampBO)
throws JsonProcessingException {
List<GreenwaveCrossMetricsVO> res = new ArrayList<>(); List<GreenwaveCrossMetricsVO> res = new ArrayList<>();
Long timeStamp = greenwaveIdAndTimeStampBO.getTimeStamp(); Long timeStamp = greenwaveIdAndTimeStampBO.getTimeStamp();
...@@ -1054,26 +1064,20 @@ public class TrendServiceImpl implements TrendService { ...@@ -1054,26 +1064,20 @@ public class TrendServiceImpl implements TrendService {
greenwaveCrossMetricsVO.setNoparkPassRate(calcNoparkPassRate(crossDirDataHistPOList, coordDirList)); greenwaveCrossMetricsVO.setNoparkPassRate(calcNoparkPassRate(crossDirDataHistPOList, coordDirList));
greenwaveCrossMetricsVO.setUncoordinatePhaseQueue( greenwaveCrossMetricsVO.setUncoordinatePhaseQueue(
calcUncoordinatePhaseQueue(crossDirDataHistPOList, coordDirList)); calcUncoordinatePhaseQueue(crossDirDataHistPOList, coordDirList));
Double nextCrossLen = greenwaveCrossPO.getNextCrossLen(); greenwaveCrossMetricsVO.setTrvalTime(calcTravelTime(crossId, greenwaveCrossPO.getInDir()));
greenwaveCrossMetricsVO.setTrvalTime(calcTravelTime(crossDirDataHistPOList, coordDirList, nextCrossLen));
res.add(greenwaveCrossMetricsVO); res.add(greenwaveCrossMetricsVO);
} }
return res; return res;
} }
private Integer calcTravelTime(List<CrossDirDataHistPO> crossDirDataHistPOList, List<Integer> coordDirList, private Integer calcTravelTime(String crossId, Integer inDir) throws JsonProcessingException {
Double nextCrossLen) { // 从 Redis 中获取路段行程时间
double average = crossDirDataHistPOList.stream() String redisKey = crossId + ":" + inDir;
.filter(po -> po.getInOutType() == 1 && coordDirList.contains(po.getDirType())) Object element = redisUtils.getMaxScoreElement(redisKey);
.mapToDouble(CrossDirDataHistPO::getSpeed) ObjectMapper objectMapper = new ObjectMapper();
.average() CrossEventDTO dto = objectMapper.readValue(element.toString(), CrossEventDTO.class);
.orElse(0.0); return dto.getTransitTime().intValue();
if (average != 0.0) {
return (int) (nextCrossLen / average);
} else {
return 0;
}
} }
private Integer calcUncoordinatePhaseQueue( private Integer calcUncoordinatePhaseQueue(
...@@ -1112,23 +1116,6 @@ public class TrendServiceImpl implements TrendService { ...@@ -1112,23 +1116,6 @@ public class TrendServiceImpl implements TrendService {
return dirCode; return dirCode;
} }
private List<CrossTurnDataHistPO> getPhaseQueueList(
List<CrossTurnDataHistPO> listForNoPark, List<CrossTurnDataHistPO> allPO) {
// 去除协调相位,用于计算非协调相位二次排队
Iterator<CrossTurnDataHistPO> iterator = allPO.iterator();
while (iterator.hasNext()) {
CrossTurnDataHistPO next = iterator.next();
for (CrossTurnDataHistPO crossTurnDataHistPO : listForNoPark) {
if (Objects.equals(next.getTurnType(), crossTurnDataHistPO.getTurnType())
&& Objects.equals(next.getInDir(), crossTurnDataHistPO.getInDir())) {
iterator.remove();
break;
}
}
}
return allPO;
}
@Override @Override
@Transactional @Transactional
public void saveGreenwaveStrategy(SaveGreenwaveStrategyBO saveGreenwaveStrategyBO) { public void saveGreenwaveStrategy(SaveGreenwaveStrategyBO saveGreenwaveStrategyBO) {
...@@ -1454,52 +1441,6 @@ public class TrendServiceImpl implements TrendService { ...@@ -1454,52 +1441,6 @@ public class TrendServiceImpl implements TrendService {
return null; return null;
} }
private void setMetrics(GreenwaveCrossMetricsVO greenwaveCrossMetricsVO, GreenwaveCrossPO greenwaveCrossPO,
List<CrossTurnDataHistPO> listForNoPark, List<CrossTurnDataHistPO> listForPhaseQueue) {
if (CollectionUtil.isNotEmpty(listForNoPark) && CollectionUtil.isNotEmpty(listForPhaseQueue)) {
Integer noparkPassRate = getAveRate(listForNoPark);
greenwaveCrossMetricsVO.setNoparkPassRate(noparkPassRate);
Integer uncoordinatePhaseQueue = getPhaseQueue(listForPhaseQueue);
greenwaveCrossMetricsVO.setUncoordinatePhaseQueue(uncoordinatePhaseQueue);
Double length = greenwaveCrossPO.getNextCrossLen();
Double speed = getSpeed(listForNoPark);
double travelTime = length / speed;
greenwaveCrossMetricsVO.setTrvalTime((int) travelTime);
}
}
private Double getSpeed(List<CrossTurnDataHistPO> listForNoPark) {
Double total = 0.0;
for (CrossTurnDataHistPO crossDirDataHistPO : listForNoPark) {
Double speed = crossDirDataHistPO.getSpeed();
total += speed;
}
double avgSpeed = total / listForNoPark.size();
return avgSpeed;
}
private Integer getPhaseQueue(List<CrossTurnDataHistPO> listForPhaseQueue) {
double maxQueue = 0.0;
for (CrossTurnDataHistPO crossDirDataHistPO : listForPhaseQueue) {
double queueLength = crossDirDataHistPO.getQueueLength();
if (queueLength > maxQueue) {
maxQueue = queueLength;
}
}
return (int) maxQueue;
}
private Integer getAveRate(List<CrossTurnDataHistPO> crossDirDataHistPOList) {
Double total = 0.0;
for (CrossTurnDataHistPO 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) { private List<GreenWaveCrossMonitorVO> buildRes(List<GreenwaveCrossPO> greenwaveCrossPOList) {
List<GreenWaveCrossMonitorVO> res = new ArrayList<>(); List<GreenWaveCrossMonitorVO> res = new ArrayList<>();
......
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