Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
traffic-signal-platform
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
signal
traffic-signal-platform
Commits
d1cee43b
Commit
d1cee43b
authored
Sep 21, 2023
by
hanbing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[add] 新信号评价-干线评价-底部曲线图
parent
7fea895d
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
588 additions
and
9 deletions
+588
-9
BottomCurveBO.java
...service/src/main/java/net/wanji/opt/bo/BottomCurveBO.java
+40
-0
MainlineEvaluateController.java
.../net/wanji/opt/controller/MainlineEvaluateController.java
+14
-0
MainlineEvaluateService.java
...n/java/net/wanji/opt/service/MainlineEvaluateService.java
+5
-0
MainlineEvaluateServiceImpl.java
...t/wanji/opt/service/impl/MainlineEvaluateServiceImpl.java
+465
-9
MainlineEvaluateBottomCurveVO.java
.../java/net/wanji/opt/vo/MainlineEvaluateBottomCurveVO.java
+24
-0
BaseEnum.java
wj-common/src/main/java/net/wanji/common/enums/BaseEnum.java
+10
-0
StrategyAndMetricsEnum.java
...n/java/net/wanji/common/enums/StrategyAndMetricsEnum.java
+9
-0
TurnConvertEnum.java
...src/main/java/net/wanji/common/enums/TurnConvertEnum.java
+9
-0
CrossLaneDataHistMapper.java
...net/wanji/databus/dao/mapper/CrossLaneDataHistMapper.java
+2
-0
CrossLaneDataHistMapper.xml
...bus/src/main/resources/mapper/CrossLaneDataHistMapper.xml
+10
-0
No files found.
signal-optimize-service/src/main/java/net/wanji/opt/bo/BottomCurveBO.java
0 → 100644
View file @
d1cee43b
package
net
.
wanji
.
opt
.
bo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.Date
;
import
java.util.List
;
/**
* @author Kent HAN
* @date 2023/6/9 13:52
*/
@Data
@ApiModel
(
value
=
"BottomCurveBO"
,
description
=
"底部曲线图"
)
public
class
BottomCurveBO
{
@ApiModelProperty
(
value
=
"路口ID"
)
private
String
crossId
;
@ApiModelProperty
(
value
=
"范围 0路口 1进口道 2方向 3车道"
)
private
Integer
scope
;
@ApiModelProperty
(
value
=
"范围列表"
)
List
<
String
>
scopeList
;
@ApiModelProperty
(
value
=
"时间粒度(分钟)"
)
private
Integer
minutes
;
@ApiModelProperty
(
value
=
"指标编号"
)
private
String
metricCode
;
@ApiModelProperty
(
value
=
"开始时间 格式 yyyy-MM-dd HH:mm"
)
@JsonFormat
(
shape
=
JsonFormat
.
Shape
.
STRING
,
pattern
=
"yyyy-MM-dd HH:mm"
,
timezone
=
"GMT+8"
)
private
Date
startTime
;
@ApiModelProperty
(
value
=
"结束时间 格式 yyyy-MM-dd HH:mm"
)
@JsonFormat
(
shape
=
JsonFormat
.
Shape
.
STRING
,
pattern
=
"yyyy-MM-dd HH:mm"
,
timezone
=
"GMT+8"
)
private
Date
endTime
;
}
signal-optimize-service/src/main/java/net/wanji/opt/controller/MainlineEvaluateController.java
View file @
d1cee43b
...
...
@@ -5,14 +5,17 @@ import io.swagger.annotations.ApiOperation;
import
io.swagger.annotations.ApiResponse
;
import
io.swagger.annotations.ApiResponses
;
import
net.wanji.common.framework.rest.JsonViewObject
;
import
net.wanji.opt.bo.BottomCurveBO
;
import
net.wanji.opt.bo.BottomMenuBO
;
import
net.wanji.opt.service.impl.MainlineEvaluateServiceImpl
;
import
net.wanji.opt.vo.MainlineEvaluateBottomCurveVO
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.ws.rs.core.MediaType
;
import
java.text.ParseException
;
import
java.util.List
;
@Api
(
value
=
"MainlineEvaluateController"
,
description
=
"干线评价"
)
...
...
@@ -38,4 +41,15 @@ public class MainlineEvaluateController {
return
JsonViewObject
.
newInstance
().
success
(
res
);
}
@ApiOperation
(
value
=
"底部曲线图"
,
notes
=
"底部曲线图"
,
response
=
JsonViewObject
.
class
,
produces
=
MediaType
.
APPLICATION_JSON
,
consumes
=
MediaType
.
APPLICATION_JSON
)
@PostMapping
(
value
=
"/bottomCurve"
,
produces
=
MediaType
.
APPLICATION_JSON
,
consumes
=
MediaType
.
APPLICATION_JSON
)
@ApiResponses
({
@ApiResponse
(
code
=
200
,
message
=
"OK"
,
response
=
MainlineEvaluateBottomCurveVO
.
class
),
})
public
JsonViewObject
bottomCurve
(
@RequestBody
BottomCurveBO
bo
)
throws
ParseException
{
List
<
MainlineEvaluateBottomCurveVO
>
res
=
mainlineEvaluateService
.
bottomCurve
(
bo
);
return
JsonViewObject
.
newInstance
().
success
(
res
);
}
}
\ No newline at end of file
signal-optimize-service/src/main/java/net/wanji/opt/service/MainlineEvaluateService.java
View file @
d1cee43b
package
net
.
wanji
.
opt
.
service
;
import
net.wanji.opt.bo.BottomCurveBO
;
import
net.wanji.opt.bo.BottomMenuBO
;
import
net.wanji.opt.vo.MainlineEvaluateBottomCurveVO
;
import
java.text.ParseException
;
import
java.util.List
;
public
interface
MainlineEvaluateService
{
List
<
String
>
bottomMenu
(
BottomMenuBO
bo
);
List
<
MainlineEvaluateBottomCurveVO
>
bottomCurve
(
BottomCurveBO
bo
)
throws
ParseException
;
}
signal-optimize-service/src/main/java/net/wanji/opt/service/impl/MainlineEvaluateServiceImpl.java
View file @
d1cee43b
...
...
@@ -2,21 +2,21 @@ package net.wanji.opt.service.impl;
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.mapper.BaseCrossDirInfoMapper
;
import
net.wanji.databus.dao.mapper.BaseCrossTurnInfoMapper
;
import
net.wanji.databus.dao.mapper.CrossBaseLaneInfoMapper
;
import
net.wanji.databus.dao.mapper.LaneInfoMapper
;
import
net.wanji.databus.po.CrossTurnInfoPO
;
import
net.wanji.databus.po.LaneInfoPO
;
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.service.MainlineEvaluateService
;
import
net.wanji.opt.vo.MainlineEvaluateBottomCurveVO
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -29,13 +29,26 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
private
final
BaseCrossDirInfoMapper
baseCrossDirInfoMapper
;
private
final
BaseCrossTurnInfoMapper
baseCrossTurnInfoMapper
;
private
final
LaneInfoMapper
laneInfoMapper
;
private
final
CrossDirDataHistMapper
crossDirDataHistMapper
;
private
final
CrossDataHistMapper
crossDataHistMapper
;
private
final
CrossTurnDataHistMapper
crossTurnDataHistMapper
;
private
final
CrossLaneDataHistMapper
crossLaneDataHistMapper
;
SimpleDateFormat
hourMinuteFormat
=
new
SimpleDateFormat
(
"HH:mm"
);
SimpleDateFormat
dateHourMinuteFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm"
);
public
MainlineEvaluateServiceImpl
(
@Qualifier
(
"baseCrossDirInfoMapper"
)
BaseCrossDirInfoMapper
baseCrossDirInfoMapper
,
@Qualifier
(
"baseCrossTurnInfoMapper"
)
BaseCrossTurnInfoMapper
baseCrossTurnInfoMapper
,
CrossBaseLaneInfoMapper
crossBaseLaneInfoMapper
,
@Qualifier
(
"laneInfoMapper"
)
LaneInfoMapper
laneInfoMapper
)
{
CrossBaseLaneInfoMapper
crossBaseLaneInfoMapper
,
@Qualifier
(
"laneInfoMapper"
)
LaneInfoMapper
laneInfoMapper
,
CrossDirDataHistMapper
crossDirDataHistMapper
,
CrossDataHistMapper
crossDataHistMapper
,
CrossTurnDataHistMapper
crossTurnDataHistMapper
,
CrossLaneDataHistMapper
crossLaneDataHistMapper
)
{
this
.
baseCrossDirInfoMapper
=
baseCrossDirInfoMapper
;
this
.
baseCrossTurnInfoMapper
=
baseCrossTurnInfoMapper
;
this
.
laneInfoMapper
=
laneInfoMapper
;
this
.
crossDirDataHistMapper
=
crossDirDataHistMapper
;
this
.
crossDataHistMapper
=
crossDataHistMapper
;
this
.
crossTurnDataHistMapper
=
crossTurnDataHistMapper
;
this
.
crossLaneDataHistMapper
=
crossLaneDataHistMapper
;
}
@Override
...
...
@@ -54,6 +67,449 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return
null
;
}
@Override
public
List
<
MainlineEvaluateBottomCurveVO
>
bottomCurve
(
BottomCurveBO
bo
)
throws
ParseException
{
String
crossId
=
bo
.
getCrossId
();
Integer
scope
=
bo
.
getScope
();
List
<
String
>
scopeList
=
bo
.
getScopeList
();
Integer
minutes
=
bo
.
getMinutes
();
String
metricCode
=
bo
.
getMetricCode
();
Date
startTime
=
bo
.
getStartTime
();
Date
endTime
=
bo
.
getEndTime
();
if
(
scope
!=
1
&&
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
LOAD_BALANCE
.
getCode
()))
{
throw
new
RuntimeException
(
"只有路口级别可选择负载均衡度"
);
}
List
<
String
>
timeList
=
buildTimeList
(
startTime
,
endTime
,
minutes
);
List
<
MainlineEvaluateBottomCurveVO
>
res
=
new
ArrayList
<>();
int
startTimeStamp
=
(
int
)(
startTime
.
getTime
()
/
1000
);
int
endTimeStamp
=
(
int
)(
endTime
.
getTime
()
/
1000
);
if
(
scope
==
0
)
{
// 路口
// 查询路口该时段内的所有数据
List
<
CrossDataHistPO
>
crossPOList
=
crossDataHistMapper
.
selectByCrossIdAndStartEnd
(
crossId
,
startTimeStamp
,
endTimeStamp
);
for
(
String
timeStr
:
timeList
)
{
Date
startDatetime
=
calcDate
(
timeStr
,
startTime
);
MainlineEvaluateBottomCurveVO
vo
=
new
MainlineEvaluateBottomCurveVO
();
vo
.
setMetricTime
(
timeStr
);
// 计算 endDatetime
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
startDatetime
);
calendar
.
add
(
Calendar
.
MINUTE
,
minutes
);
Date
endDatetime
=
calendar
.
getTime
();
// 转换为 10 位时间戳
int
startTimeStampPart
=
(
int
)(
startDatetime
.
getTime
()
/
1000
);
int
endTimeStampPart
=
(
int
)(
endDatetime
.
getTime
()
/
1000
);
// 使用流式编程进行筛选
List
<
CrossDataHistPO
>
filteredList
=
crossPOList
.
stream
()
.
filter
(
po
->
po
.
getBatchTime
()
>=
startTimeStampPart
&&
po
.
getBatchTime
()
<=
endTimeStampPart
)
.
collect
(
Collectors
.
toList
());
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
NO_STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getNoStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getOneStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_DELAY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToInt
(
CrossDataHistPO:
:
getDelayTime
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
MAX_QUEUE_LENGTH
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getQueueLength
)
.
max
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_TIMES
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getStopTimes
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_SPEED
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getSpeed
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
GREEN_LIGHT_EFFICIENCY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getGreenLightEfficiency
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
SATURATION
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getSturation
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
LOAD_BALANCE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDataHistPO:
:
getLoadBalance
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
res
.
add
(
vo
);
}
}
else
if
(
scope
==
1
)
{
// 进口道
// 查询各进口道该时段内的所有数据
List
<
CrossDirDataHistPO
>
dirPOList
=
crossDirDataHistMapper
.
selectByCrossIdAndStartEnd
(
crossId
,
startTimeStamp
,
endTimeStamp
);
for
(
String
timeStr
:
timeList
)
{
Date
startDatetime
=
calcDate
(
timeStr
,
startTime
);
for
(
String
dirStr
:
scopeList
)
{
int
index
=
dirStr
.
indexOf
(
"进口"
);
String
dirName
=
dirStr
.
substring
(
0
,
index
);
Integer
dirCode
=
BaseEnum
.
SignalDirectionEnum
.
getCodeByName
(
dirName
);
MainlineEvaluateBottomCurveVO
vo
=
new
MainlineEvaluateBottomCurveVO
();
vo
.
setMetricTime
(
timeStr
);
vo
.
setScopeName
(
dirStr
);
// 计算 endDatetime
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
startDatetime
);
calendar
.
add
(
Calendar
.
MINUTE
,
minutes
);
Date
endDatetime
=
calendar
.
getTime
();
// 转换为 10 位时间戳
int
startTimeStampPart
=
(
int
)(
startDatetime
.
getTime
()
/
1000
);
int
endTimeStampPart
=
(
int
)(
endDatetime
.
getTime
()
/
1000
);
// 使用流式编程进行筛选
List
<
CrossDirDataHistPO
>
filteredList
=
dirPOList
.
stream
()
.
filter
(
po
->
po
.
getDirType
().
equals
(
dirCode
))
.
filter
(
po
->
po
.
getInOutType
().
equals
(
1
))
.
filter
(
po
->
po
.
getBatchTime
()
>=
startTimeStampPart
&&
po
.
getBatchTime
()
<=
endTimeStampPart
)
.
collect
(
Collectors
.
toList
());
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
NO_STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getNoStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getOneStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_DELAY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToInt
(
CrossDirDataHistPO:
:
getDelayTime
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
MAX_QUEUE_LENGTH
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getQueueLength
)
.
max
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_TIMES
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getStopTimes
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_SPEED
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getSpeed
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
GREEN_LIGHT_EFFICIENCY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getGreenLightEfficiency
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
SATURATION
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossDirDataHistPO:
:
getSturation
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
res
.
add
(
vo
);
}
}
}
else
if
(
scope
==
2
)
{
// 方向
// 查询各方向该时段内的所有数据
List
<
CrossTurnDataHistPO
>
dirPOList
=
crossTurnDataHistMapper
.
selectByCrossId
(
crossId
,
endTimeStamp
,
startTimeStamp
);
for
(
String
timeStr
:
timeList
)
{
Date
startDatetime
=
calcDate
(
timeStr
,
startTime
);
for
(
String
turnStr
:
scopeList
)
{
int
index
=
turnStr
.
indexOf
(
"进口"
);
String
dirName
=
turnStr
.
substring
(
0
,
index
);
Integer
dirCode
=
BaseEnum
.
SignalDirectionEnum
.
getCodeByName
(
dirName
);
String
turnName
=
turnStr
.
substring
(
index
+
2
);
String
turnCode
=
TurnConvertEnum
.
getCodeByDesc
(
turnName
);
MainlineEvaluateBottomCurveVO
vo
=
new
MainlineEvaluateBottomCurveVO
();
vo
.
setMetricTime
(
timeStr
);
vo
.
setScopeName
(
turnStr
);
// 计算 endDatetime
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
startDatetime
);
calendar
.
add
(
Calendar
.
MINUTE
,
minutes
);
Date
endDatetime
=
calendar
.
getTime
();
// 转换为 10 位时间戳
int
startTimeStampPart
=
(
int
)(
startDatetime
.
getTime
()
/
1000
);
int
endTimeStampPart
=
(
int
)(
endDatetime
.
getTime
()
/
1000
);
// 使用流式编程进行筛选
List
<
CrossTurnDataHistPO
>
filteredList
=
dirPOList
.
stream
()
.
filter
(
po
->
po
.
getInDir
().
equals
(
dirCode
))
.
filter
(
po
->
po
.
getTurnType
().
equals
(
turnCode
))
.
filter
(
po
->
po
.
getBatchTime
()
>=
startTimeStampPart
&&
po
.
getBatchTime
()
<=
endTimeStampPart
)
.
collect
(
Collectors
.
toList
());
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
NO_STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getNoStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getOneStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_DELAY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToInt
(
CrossTurnDataHistPO:
:
getDelayTime
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
MAX_QUEUE_LENGTH
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getQueueLength
)
.
max
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_TIMES
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getStopTimes
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_SPEED
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getSpeed
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
GREEN_LIGHT_EFFICIENCY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getGreenLightEfficiency
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
SATURATION
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossTurnDataHistPO:
:
getSturation
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
res
.
add
(
vo
);
}
}
}
else
if
(
scope
==
3
)
{
// 车道
// 查询各车道该时段内的所有数据
List
<
CrossLaneDataHistPOExt
>
lanePOList
=
crossLaneDataHistMapper
.
selectByCrossId
(
crossId
,
endTimeStamp
,
startTimeStamp
);
for
(
String
timeStr
:
timeList
)
{
Date
startDatetime
=
calcDate
(
timeStr
,
startTime
);
for
(
String
laneStr
:
scopeList
)
{
int
indexOfJinKou
=
laneStr
.
indexOf
(
"进口"
);
int
indexOfCheDao
=
laneStr
.
indexOf
(
"车道"
);
// 截取"进口"之前的部分
String
dirName
=
laneStr
.
substring
(
0
,
indexOfJinKou
);
// 截取"车道"之前的数字部分
String
laneSortStr
=
laneStr
.
substring
(
indexOfCheDao
-
2
,
indexOfCheDao
);
Integer
dirCode
=
BaseEnum
.
SignalDirectionEnum
.
getCodeByName
(
dirName
);
Integer
laneSort
=
Integer
.
parseInt
(
laneSortStr
);
MainlineEvaluateBottomCurveVO
vo
=
new
MainlineEvaluateBottomCurveVO
();
vo
.
setMetricTime
(
timeStr
);
vo
.
setScopeName
(
laneStr
);
// 计算 endDatetime
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
startDatetime
);
calendar
.
add
(
Calendar
.
MINUTE
,
minutes
);
Date
endDatetime
=
calendar
.
getTime
();
// 转换为 10 位时间戳
int
startTimeStampPart
=
(
int
)(
startDatetime
.
getTime
()
/
1000
);
int
endTimeStampPart
=
(
int
)(
endDatetime
.
getTime
()
/
1000
);
// 筛选方向、车道序号
List
<
CrossLaneDataHistPOExt
>
filteredList
=
lanePOList
.
stream
()
.
filter
(
po
->
po
.
getDir
().
equals
(
dirCode
))
.
filter
(
po
->
po
.
getSort
().
equals
(
laneSort
))
.
filter
(
po
->
po
.
getBatchTime
()
>=
startTimeStampPart
&&
po
.
getBatchTime
()
<=
endTimeStampPart
)
.
collect
(
Collectors
.
toList
());
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
NO_STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getNoStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_RATE
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getOneStopRate
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_DELAY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToInt
(
CrossLaneDataHistPOExt:
:
getDelayTime
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
MAX_QUEUE_LENGTH
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getQueueLength
)
.
max
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
STOP_TIMES
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getStopTimes
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
AVERAGE_SPEED
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getSpeed
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
GREEN_LIGHT_EFFICIENCY
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getGreenLightEfficiency
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
else
if
(
Objects
.
equals
(
metricCode
,
StrategyAndMetricsEnum
.
Metrics
.
SATURATION
.
getCode
()))
{
double
v
=
filteredList
.
stream
()
.
mapToDouble
(
CrossLaneDataHistPOExt:
:
getSturation
)
.
average
()
.
orElse
(
0.0
);
int
round
=
(
int
)
(
Math
.
round
(
v
*
100
));
vo
.
setValue
(
round
);
}
res
.
add
(
vo
);
}
}
}
return
res
;
}
private
Date
calcDate
(
String
timeStr
,
Date
startTime
)
throws
ParseException
{
// 使用 Calendar 来获取年、月、日信息
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
startTime
);
// 使用 SimpleDateFormat 来获取时和分
Date
time
=
hourMinuteFormat
.
parse
(
timeStr
);
Calendar
timeCal
=
Calendar
.
getInstance
();
timeCal
.
setTime
(
time
);
// 组合两者
calendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
timeCal
.
get
(
Calendar
.
HOUR_OF_DAY
));
calendar
.
set
(
Calendar
.
MINUTE
,
timeCal
.
get
(
Calendar
.
MINUTE
));
calendar
.
set
(
Calendar
.
SECOND
,
0
);
calendar
.
set
(
Calendar
.
MILLISECOND
,
0
);
// 转换回 Date 对象
Date
startDatetime
=
calendar
.
getTime
();
return
startDatetime
;
}
private
List
<
String
>
buildTimeList
(
Date
startTime
,
Date
endTime
,
Integer
minutes
)
{
// 用于存储时间区间的列表
List
<
String
>
timeList
=
new
ArrayList
<>();
Calendar
cal
=
Calendar
.
getInstance
();
cal
.
setTime
(
startTime
);
while
(
cal
.
getTime
().
before
(
endTime
)
||
cal
.
getTime
().
equals
(
endTime
))
{
String
formattedTime
=
hourMinuteFormat
.
format
(
cal
.
getTime
());
timeList
.
add
(
formattedTime
);
// 增加指定分钟数
cal
.
add
(
Calendar
.
MINUTE
,
minutes
);
}
return
timeList
;
}
public
static
String
formatTime
(
int
totalMinutes
)
{
int
hours
=
totalMinutes
/
60
;
int
minutes
=
totalMinutes
%
60
;
return
String
.
format
(
"%02d:%02d"
,
hours
,
minutes
);
}
private
List
<
String
>
buildLaneMenu
(
String
crossId
)
{
List
<
BaseCrossDirInfoPO
>
poList
=
baseCrossDirInfoMapper
.
selectByCrossId
(
crossId
);
List
<
BaseCrossDirInfoPO
>
dirList
=
poList
.
stream
()
...
...
signal-optimize-service/src/main/java/net/wanji/opt/vo/MainlineEvaluateBottomCurveVO.java
0 → 100644
View file @
d1cee43b
package
net
.
wanji
.
opt
.
vo
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* @author Kent HAN
* @date 2023/2/9 8:38
*/
@Data
@NoArgsConstructor
@ApiModel
(
value
=
"MainlineEvaluateBottomCurveVO"
,
description
=
"底部曲线图"
)
public
class
MainlineEvaluateBottomCurveVO
{
@ApiModelProperty
(
value
=
"时间"
)
private
String
metricTime
;
@ApiModelProperty
(
value
=
"范围名称"
)
private
String
scopeName
;
@ApiModelProperty
(
value
=
"数值"
)
private
Integer
value
;
}
wj-common/src/main/java/net/wanji/common/enums/BaseEnum.java
View file @
d1cee43b
...
...
@@ -152,6 +152,16 @@ public class BaseEnum {
}
return
null
;
}
public
static
Integer
getCodeByName
(
String
name
)
{
for
(
SignalDirectionEnum
signalDirectionEnum
:
SignalDirectionEnum
.
values
())
{
if
(
Objects
.
equals
(
signalDirectionEnum
.
getName
(),
name
))
{
return
signalDirectionEnum
.
getCode
();
}
}
return
null
;
}
}
@Getter
...
...
wj-common/src/main/java/net/wanji/common/enums/StrategyAndMetricsEnum.java
View file @
d1cee43b
...
...
@@ -76,6 +76,15 @@ public class StrategyAndMetricsEnum {
}
return
null
;
}
public
static
Metrics
getEnumByCode
(
String
code
)
{
for
(
Metrics
value
:
Metrics
.
values
())
{
if
(
value
.
code
.
equals
(
code
))
{
return
value
;
}
}
return
null
;
}
}
public
static
final
Map
<
Strategy
,
List
<
Metrics
>>
STRATEGY_METRICS_MAP
;
...
...
wj-common/src/main/java/net/wanji/common/enums/TurnConvertEnum.java
View file @
d1cee43b
...
...
@@ -100,4 +100,13 @@ public enum TurnConvertEnum {
return
res
;
}
public
static
String
getCodeByDesc
(
String
desc
){
for
(
TurnConvertEnum
e
:
TurnConvertEnum
.
values
())
{
if
(
e
.
desc
.
equals
(
desc
)){
return
e
.
code
;
}
}
return
null
;
}
}
wj-databus/src/main/java/net/wanji/databus/dao/mapper/CrossLaneDataHistMapper.java
View file @
d1cee43b
...
...
@@ -20,4 +20,6 @@ public interface CrossLaneDataHistMapper extends BaseMapper<CrossLaneDataHistPO>
void
deleteBatch
(
@Param
(
"list"
)
Collection
<
String
>
crossIds
);
List
<
MetricHistDTO
>
selectMetricHistDTO
(
String
crossId
,
int
startStamp
,
int
endStamp
);
List
<
CrossLaneDataHistPOExt
>
selectByCrossIdAndDir
(
String
crossId
,
Integer
dir
,
int
endTimeStamp
,
int
startTimeStamp
);
List
<
CrossLaneDataHistPOExt
>
selectByCrossId
(
String
crossId
,
int
endTimeStamp
,
int
startTimeStamp
);
}
wj-databus/src/main/resources/mapper/CrossLaneDataHistMapper.xml
View file @
d1cee43b
...
...
@@ -74,4 +74,14 @@
AND batch_time
<![CDATA[ >= ]]>
#{startTimeStamp}
AND batch_time
<![CDATA[ <= ]]>
#{endTimeStamp};
</select>
<select
id=
"selectByCrossId"
resultType=
"net.wanji.databus.po.CrossLaneDataHistPOExt"
>
SELECT *
FROM t_base_lane_info
JOIN t_lane_data_hist ON t_base_lane_info.id = t_lane_data_hist.id
WHERE t_base_lane_info.cross_id = #{crossId}
AND t_base_lane_info.type = 2
AND batch_time
<![CDATA[ >= ]]>
#{startTimeStamp}
AND batch_time
<![CDATA[ <= ]]>
#{endTimeStamp};
</select>
</mapper>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment