Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
谢明辉
/
存储配置服务
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 9a899c4e
authored
Jan 13, 2022
by
xmh
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
添加注释
1 parent
9c339ec7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
473 additions
and
173 deletions
src/main/java/com/viontech/storage/entity/Generator.java
src/main/java/com/viontech/storage/entity/Generator.java
View file @
9a899c4
package
com
.
viontech
.
storage
.
entity
;
import
cn.hutool.cache.CacheUtil
;
import
cn.hutool.cache.impl.TimedCache
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.lang.Pair
;
import
cn.hutool.core.util.XmlUtil
;
...
...
@@ -16,9 +14,9 @@ import com.viontech.storage.service.StorageConfigService;
import
com.viontech.storage.vo.CaptionVo
;
import
com.viontech.storage.vo.PicConfigVo
;
import
com.viontech.storage.vo.StorageConfigVo
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.experimental.Accessors
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.Node
;
...
...
@@ -38,8 +36,8 @@ public class Generator {
private
static
final
String
ROOT_ELEMENT_NAME
=
"StorageConfig"
;
private
static
final
String
FILE_VERSION
=
"001-012-000-000"
;
private
static
final
TimedCache
<
Long
,
String
>
STORAGE_CONFIG_ID_RESULT_CACHE
=
CacheUtil
.
newTimedCache
(
20
*
1000
);
private
final
Document
document
=
XmlUtil
.
createXml
(
"StorageConfig"
);
private
final
Document
document
=
XmlUtil
.
createXml
(
ROOT_ELEMENT_NAME
);
/** 来自 StorageConfig, 对应 Solution */
private
final
List
<
Context
>
contexts
;
/** key: picConfigVoId */
private
final
Map
<
Long
,
PicConfigVo
>
picConfigMap
;
...
...
@@ -68,14 +66,13 @@ public class Generator {
captionSetIds
.
add
(
copy
.
getCaptionSetId
());
}
List
<
Caption
>
captions
=
captionService
.
list
(
captionService
.
query
().
in
(
"caption_set_id"
,
captionSetIds
).
getWrapper
()
);
List
<
Caption
>
captions
=
captionService
.
list
(
captionService
.
query
().
in
(
"caption_set_id"
,
captionSetIds
).
getWrapper
());
this
.
captionSetMap
=
captions
.
stream
().
map
(
CaptionVo:
:
copy
).
collect
(
Collectors
.
groupingBy
(
CaptionVo:
:
getCaptionSetId
,
Collectors
.
toList
()));
}
public
String
build
()
{
// 基本上算是固定写法
Node
rootNode
=
document
.
getFirstChild
();
rootNode
.
appendChild
(
createTextNode
(
"FileVersion"
,
FILE_VERSION
));
Element
standard
=
document
.
createElement
(
"Standard"
);
...
...
@@ -88,6 +85,7 @@ public class Generator {
switchPathConfig
.
appendChild
(
createTextNode
(
"CountThreshold"
,
"64"
));
standard
.
appendChild
(
switchPathConfig
);
// 开始组装 Solution
for
(
Context
context
:
contexts
)
{
Node
solution
=
buildSolution
(
context
);
if
(
solution
!=
null
)
{
...
...
@@ -107,6 +105,7 @@ public class Generator {
return
null
;
}
// 基本上算是固定写法
Element
solution
=
document
.
createElement
(
"Solution"
+
order
);
solution
.
appendChild
(
createTextNode
(
"SolutionName"
,
picConfig
.
getName
()));
solution
.
appendChild
(
createTextNode
(
"Conditions"
,
conditions
));
...
...
@@ -121,12 +120,15 @@ public class Generator {
pathConfig
.
appendChild
(
document
.
createTextNode
(
"VideoRelativePath"
));
pathConfig
.
appendChild
(
createTextNode
(
"VideoRootPath"
,
"/kk/video;;;;;"
));
solution
.
appendChild
(
pathConfig
);
// 组装图片属性和字幕
Node
picConfigNode
=
buildPicConfig
(
picConfig
);
solution
.
appendChild
(
picConfigNode
);
return
solution
;
}
private
Node
buildPicConfig
(
PicConfigVo
picConfig
)
{
// 没有自定义的地方,先固定写死
Element
configNode
=
document
.
createElement
(
"PicConfig"
);
configNode
.
appendChild
(
createTextNode
(
"PicCount"
,
"1"
));
configNode
.
appendChild
(
createTextNode
(
"DigPicFlag"
,
"1"
));
...
...
@@ -144,7 +146,6 @@ public class Generator {
denoiser
.
appendChild
(
createTextNode
(
"Param2"
,
"3"
));
denoiser
.
appendChild
(
createTextNode
(
"Param3"
,
"0.000000"
));
denoiser
.
appendChild
(
createTextNode
(
"Param4"
,
"0.000000"
));
Element
fixedSizeQuality
=
XmlUtil
.
appendChild
(
picQuality
,
"FixedSizeQuality"
);
Element
st200wImageQuality
=
XmlUtil
.
appendChild
(
picQuality
,
"st200WImageQuality"
);
Element
st500wImageQuality
=
XmlUtil
.
appendChild
(
picQuality
,
"st500WImageQuality"
);
...
...
@@ -160,69 +161,81 @@ public class Generator {
Element
pic1
=
XmlUtil
.
appendChild
(
configNode
,
"Pic1"
);
pic1
.
appendChild
(
createTextNode
(
"OriPicCount"
,
String
.
valueOf
(
picConfig
.
calPicCount
())));
pic1
.
appendChild
(
createTextNode
(
"DirectSaveFlag"
,
"0"
));
PicConfigCalculator
calculator
=
new
PicConfigCalculator
(
picConfig
);
Coordinate
[]
coordinates
=
calculator
.
coordinates
;
HashMap
<
Integer
,
Coordinate
>
coordinateMap
=
calculator
.
coordinateMap
;
for
(
int
i
=
0
;
i
<
coordinates
.
length
;
i
++)
{
Coordinate
item
=
coordinates
[
i
];
PicConfigGenerator
picConfigGenerator
=
new
PicConfigGenerator
(
picConfig
,
captionSetMap
.
get
(
picConfig
.
getCaptionSetId
()));
PicNode
[]
picNodes
=
picConfigGenerator
.
getPicNodes
();
Element
captionsElement
=
XmlUtil
.
appendChild
(
pic1
,
"Captions"
);
int
captionCount
=
0
;
for
(
int
i
=
0
;
i
<
picNodes
.
length
;
i
++)
{
PicNode
item
=
picNodes
[
i
];
Element
oriPic
=
XmlUtil
.
appendChild
(
pic1
,
"OriPic"
+
(
i
+
1
));
XmlUtil
.
appendChild
(
oriPic
,
"Content"
).
setTextContent
(
item
.
getName
());
XmlUtil
.
appendChild
(
oriPic
,
"Content"
).
setTextContent
(
item
.
get
PicType
Name
());
XmlUtil
.
appendChild
(
oriPic
,
"Type"
).
setTextContent
(
"0"
);
Element
srcCoordinate
=
XmlUtil
.
appendChild
(
oriPic
,
"SrcCoordinate"
);
Element
desCoordinate
=
XmlUtil
.
appendChild
(
oriPic
,
"DesCoordinate"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"left"
).
setTextContent
(
"0"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"top"
).
setTextContent
(
"0"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"width"
).
setTextContent
(
item
.
getName
()
+
"宽"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"height"
).
setTextContent
(
item
.
getName
()
+
"高"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"width"
).
setTextContent
(
item
.
get
PicType
Name
()
+
"宽"
);
XmlUtil
.
appendChild
(
srcCoordinate
,
"height"
).
setTextContent
(
item
.
get
PicType
Name
()
+
"高"
);
XmlUtil
.
appendChild
(
desCoordinate
,
"left"
).
setTextContent
(
item
.
getX
());
XmlUtil
.
appendChild
(
desCoordinate
,
"top"
).
setTextContent
(
item
.
getY
());
XmlUtil
.
appendChild
(
desCoordinate
,
"width"
).
setTextContent
(
"全景1宽"
);
XmlUtil
.
appendChild
(
desCoordinate
,
"height"
).
setTextContent
(
"全景1高"
);
}
// 字幕
Long
captionSetId
=
picConfig
.
getCaptionSetId
();
List
<
CaptionVo
>
captionVos
=
captionSetMap
.
get
(
captionSetId
);
Element
captionsElement
=
XmlUtil
.
appendChild
(
pic1
,
"Captions"
);
int
captionCount
=
0
;
for
(
int
i
=
0
;
i
<
captionVos
.
size
();
i
++)
{
CaptionVo
caption
=
captionVos
.
get
(
i
);
Integer
picType
=
caption
.
getPicType
();
Coordinate
coordinate
=
coordinateMap
.
get
(
picType
);
if
(
coordinate
==
null
)
{
continue
;
}
List
<
Context
>
contexts
=
caption
.
getContexts
();
String
dateFormat
=
(
caption
.
getMillisecond
()
!=
null
&&
caption
.
getMillisecond
())
?
caption
.
getDateFormat
()
+
".xxx"
:
caption
.
getDateFormat
();
Pair
<
String
,
Integer
>
combine
=
combineCaptionContent
(
picType
,
contexts
,
dateFormat
);
String
content
=
combine
.
getKey
();
Integer
wrapCount
=
combine
.
getValue
();
Element
ele
=
XmlUtil
.
appendChild
(
captionsElement
,
"Caption"
+
(
i
+
1
));
XmlUtil
.
appendChild
(
ele
,
"Content"
).
setTextContent
(
content
);
XmlUtil
.
appendChild
(
ele
,
"bgColor"
).
setTextContent
(
caption
.
getBgColor
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"Font"
).
setTextContent
(
caption
.
getFont
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"FontSize"
).
setTextContent
(
caption
.
getFontSize
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"fgColor"
).
setTextContent
(
caption
.
getFgColor
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"ShadowColor"
).
setTextContent
(
"4"
);
XmlUtil
.
appendChild
(
ele
,
"ShadowSize"
).
setTextContent
(
"0"
);
XmlUtil
.
appendChild
(
ele
,
"bgTransparency"
).
setTextContent
(
caption
.
getBgTransparency
().
toString
());
Element
coordinateElement
=
XmlUtil
.
appendChild
(
ele
,
"Coordinate"
);
// 坐标需要根据positionType来搞
Integer
positionType
=
caption
.
getPositionType
();
String
y
=
coordinate
.
getY
();
if
(
positionType
==
1
)
{
y
=
y
+
"+全景1高"
;
}
else
if
(
positionType
==
0
)
{
y
=
y
+
"-80"
;
}
else
if
(
positionType
==
3
)
{
y
=
y
+
"+全景1高-80"
;
// 字幕
CaptionNode
captionNode
=
item
.
getCaptionNode
();
for
(
int
j
=
0
;
j
<
4
;
j
++)
{
CaptionVo
caption
;
String
content
;
String
height
;
if
(
j
==
0
&&
captionNode
.
getTop
()
!=
null
)
{
caption
=
captionNode
.
getTop
();
content
=
captionNode
.
getTopContent
();
height
=
String
.
valueOf
(
captionNode
.
getTopHeight
());
}
else
if
(
j
==
1
&&
captionNode
.
getBottom
()
!=
null
)
{
caption
=
captionNode
.
getBottom
();
content
=
captionNode
.
getBottomContent
();
height
=
String
.
valueOf
(
captionNode
.
getBottomHeight
());
}
else
if
(
j
==
2
&&
captionNode
.
getSecond
()
!=
null
)
{
caption
=
captionNode
.
getSecond
();
content
=
captionNode
.
getSecondContent
();
height
=
String
.
valueOf
(
captionNode
.
getSecondHeight
());
}
else
if
(
j
==
3
&&
captionNode
.
getThird
()
!=
null
)
{
caption
=
captionNode
.
getThird
();
content
=
captionNode
.
getThirdContent
();
height
=
String
.
valueOf
(
captionNode
.
getThirdHeight
());
}
else
{
continue
;
}
captionCount
++;
Element
ele
=
XmlUtil
.
appendChild
(
captionsElement
,
"Caption"
+
captionCount
);
XmlUtil
.
appendChild
(
ele
,
"Content"
).
setTextContent
(
content
);
XmlUtil
.
appendChild
(
ele
,
"bgColor"
).
setTextContent
(
caption
.
getBgColor
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"Font"
).
setTextContent
(
caption
.
getFont
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"FontSize"
).
setTextContent
(
caption
.
getFontSize
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"fgColor"
).
setTextContent
(
caption
.
getFgColor
().
toString
());
XmlUtil
.
appendChild
(
ele
,
"ShadowColor"
).
setTextContent
(
"4"
);
XmlUtil
.
appendChild
(
ele
,
"ShadowSize"
).
setTextContent
(
"0"
);
XmlUtil
.
appendChild
(
ele
,
"bgTransparency"
).
setTextContent
(
caption
.
getBgTransparency
().
toString
());
Element
coordinateElement
=
XmlUtil
.
appendChild
(
ele
,
"Coordinate"
);
// 坐标需要根据 positionType 来算
Integer
positionType
=
caption
.
getPositionType
();
String
y
=
item
.
getY
();
if
(
positionType
==
1
)
{
y
=
y
+
"+全景1高"
;
}
else
if
(
positionType
==
0
)
{
y
=
y
+
"-"
+
height
;
}
else
if
(
positionType
==
3
)
{
y
=
y
+
"+全景1高-"
+
height
;
}
XmlUtil
.
appendChild
(
coordinateElement
,
"left"
).
setTextContent
(
item
.
getX
());
XmlUtil
.
appendChild
(
coordinateElement
,
"top"
).
setTextContent
(
y
);
XmlUtil
.
appendChild
(
coordinateElement
,
"width"
).
setTextContent
(
"全景1宽"
);
XmlUtil
.
appendChild
(
coordinateElement
,
"height"
).
setTextContent
(
height
);
}
XmlUtil
.
appendChild
(
coordinateElement
,
"left"
).
setTextContent
(
coordinate
.
getX
());
XmlUtil
.
appendChild
(
coordinateElement
,
"top"
).
setTextContent
(
y
);
XmlUtil
.
appendChild
(
coordinateElement
,
"width"
).
setTextContent
(
"全景1宽"
);
int
height
=
wrapCount
==
0
?
80
:
caption
.
getFontSize
()
*
wrapCount
;
XmlUtil
.
appendChild
(
coordinateElement
,
"height"
).
setTextContent
(
String
.
valueOf
(
height
));
captionCount
++;
}
XmlUtil
.
appendChild
(
captionsElement
,
"Count"
).
setTextContent
(
String
.
valueOf
(
captionCount
));
return
configNode
;
...
...
@@ -238,153 +251,440 @@ public class Generator {
return
dataTypes
.
stream
().
map
(
x
->
"数据类型="
+
x
).
collect
(
Collectors
.
joining
(
"+"
));
}
private
Pair
<
String
,
Integer
>
combineCaptionContent
(
Integer
picType
,
List
<
Context
>
contexts
,
String
dateFormat
)
{
if
(
CollectionUtil
.
isEmpty
(
contexts
))
{
return
Pair
.
of
(
null
,
null
);
}
String
picTypeName
=
Dict
.
INSTANCE
.
picType
.
get
(
picType
);
StringBuilder
sb
=
new
StringBuilder
();
int
wrapCount
=
0
;
for
(
Context
context
:
contexts
)
{
Integer
type
=
context
.
getType
();
sb
.
append
(
Dict
.
INSTANCE
.
captionType
.
get
(
type
)).
append
(
":+"
);
switch
(
type
)
{
case
1
:
if
(
picTypeName
.
contains
(
"特写"
))
{
picTypeName
=
"特写图"
;
}
sb
.
append
(
"("
).
append
(
picTypeName
).
append
(
"时间:"
).
append
(
dateFormat
).
append
(
")"
);
break
;
case
9
:
sb
.
append
(
"(用户车辆类型1)"
);
break
;
case
10
:
sb
.
append
(
"(用户车身颜色1)"
);
break
;
case
11
:
sb
.
append
(
"(车辆子品牌)"
);
break
;
case
15
:
sb
.
append
(
"(合成图1防伪码)"
);
break
;
case
16
:
sb
.
append
(
context
.
getContent
());
break
;
case
17
:
sb
.
append
(
"(违法类型代码)"
);
break
;
default
:
sb
.
append
(
"("
).
append
(
Dict
.
INSTANCE
.
captionType
.
get
(
type
)).
append
(
")"
);
}
/**
* 一个图片属性会有多个图片节点
* 按照类型不同排列
*/
public
@Getter
@Setter
@Accessors
(
chain
=
true
)
static
class
PicNode
{
private
final
PicConfigGenerator
generator
;
/** 图片类型代码 */
private
final
int
picType
;
/** 图片类型名称 */
private
final
String
picTypeName
;
private
final
int
index
;
private
CaptionNode
captionNode
=
new
CaptionNode
();
private
String
x
;
private
String
y
;
if
(
context
.
getWrap
()
)
{
wrapCount
++
;
sb
.
append
(
"+(换行分隔符)"
);
}
sb
.
append
(
"+"
)
;
public
PicNode
(
PicConfigGenerator
generator
,
int
picType
,
int
index
)
{
this
.
generator
=
generator
;
this
.
picTypeName
=
Dict
.
INSTANCE
.
picType
.
get
(
picType
);
this
.
picType
=
picType
;
this
.
index
=
index
;
}
sb
.
setLength
(
sb
.
length
()
-
1
);
return
Pair
.
of
(
sb
.
toString
(),
wrapCount
);
}
private
static
class
PicConfigCalculator
{
public
final
Coordinate
[]
coordinates
;
/** key : picType */
public
final
HashMap
<
Integer
,
Coordinate
>
coordinateMap
=
new
HashMap
<>();
private
final
int
layoutType
;
public
PicConfigCalculator
(
PicConfigVo
picConfigVo
)
{
List
<
Context
>
contexts
=
picConfigVo
.
getContexts
().
stream
().
sorted
(
Comparator
.
comparingInt
(
Context:
:
getOrder
)).
collect
(
Collectors
.
toList
());
layoutType
=
picConfigVo
.
getType
();
this
.
coordinates
=
new
Coordinate
[
contexts
.
size
()];
for
(
int
i
=
0
;
i
<
contexts
.
size
();
i
++)
{
Context
context
=
contexts
.
get
(
i
);
Integer
picType
=
context
.
getType
();
calCoordinate
(
i
,
picType
);
/**
* 计算该图片在合成图上的 X 坐标
*/
public
String
getX
()
{
if
(
this
.
x
!=
null
)
{
return
this
.
x
;
}
}
private
void
calCoordinate
(
Integer
index
,
Integer
picType
)
{
String
x
=
"0"
;
String
y
=
"80"
;
this
.
x
=
"0"
;
PicNode
left
=
getLeft
();
if
(
index
!=
0
)
{
Coordinate
pre
=
coordinates
[
index
-
1
];
switch
(
layoutType
)
{
switch
(
generator
.
getLayoutType
())
{
case
21
:
case
31
:
case
41
:
case
51
:
case
61
:
x
=
pre
.
x
+
"+"
+
"全景1宽"
;
y
=
"80"
;
this
.
x
=
left
.
x
+
"+"
+
"全景1宽"
;
break
;
case
12
:
case
13
:
case
14
:
case
15
:
case
16
:
x
=
"0"
;
y
=
pre
.
y
+
"+"
+
"全景1高"
;
this
.
x
=
"0"
;
break
;
case
22
:
case
23
:
if
(
index
==
1
)
{
x
=
"全景1宽"
;
y
=
"80"
;
}
else
if
(
index
==
2
)
{
x
=
"0"
;
y
=
"80"
+
"+"
+
"全景1高"
;
}
else
if
(
index
==
3
)
{
x
=
"全景1宽"
;
y
=
"80"
+
"+"
+
"全景1高"
;
}
else
if
(
index
==
4
)
{
x
=
"0"
;
y
=
coordinates
[
2
].
y
+
"+"
+
"全景1高"
;
}
else
if
(
index
==
5
)
{
x
=
"全景1宽"
;
y
=
coordinates
[
3
].
y
+
"+"
+
"全景1高"
;
if
(
index
%
2
==
0
)
{
this
.
x
=
"0"
;
}
else
{
this
.
x
=
"全景1宽"
;
}
break
;
case
32
:
if
(
index
==
1
)
{
x
=
"全景1宽"
;
y
=
"80"
;
}
else
if
(
index
==
2
)
{
x
=
"全景1宽"
+
"+"
+
"全景1宽"
;
y
=
"80"
;
}
else
if
(
index
==
3
)
{
x
=
"0"
;
y
=
"80"
+
"+"
+
"全景1高"
;
}
else
if
(
index
==
4
)
{
x
=
"全景1宽"
;
y
=
"80"
+
"+"
+
"全景1高"
;
}
else
if
(
index
==
5
)
{
x
=
"全景1宽 + 全景1宽"
;
y
=
"80"
+
"+"
+
"全景1高"
;
if
(
index
%
3
==
0
)
{
this
.
x
=
"0"
;
}
else
{
this
.
x
=
left
.
getX
()
+
"+"
+
"全景1宽"
;
}
break
;
default
:
throw
new
RuntimeException
(
"no such type"
);
}
}
Coordinate
coordinate
=
new
Coordinate
(
picType
,
Dict
.
INSTANCE
.
picType
.
get
(
picType
),
x
,
y
);
coordinates
[
index
]
=
coordinate
;
coordinateMap
.
put
(
picType
,
coordinate
);
return
this
.
x
;
}
}
/**
* 计算该图片在合成图上的 Y 坐标
*/
public
String
getY
()
{
if
(
this
.
y
!=
null
)
{
return
this
.
y
;
}
PicNode
upside
=
this
.
getUpside
();
String
paddingTop
=
paddingTop
();
switch
(
generator
.
getLayoutType
())
{
case
11
:
case
21
:
case
31
:
case
41
:
case
51
:
case
61
:
this
.
y
=
paddingTop
;
break
;
case
12
:
case
13
:
case
14
:
case
15
:
case
16
:
if
(
index
==
0
)
{
this
.
y
=
paddingTop
;
}
else
{
this
.
y
=
upside
.
y
+
"+"
+
"全景1高"
+
"+"
+
paddingTop
;
}
break
;
case
22
:
case
23
:
if
(
index
<
2
)
{
this
.
y
=
paddingTop
;
}
else
{
this
.
y
=
upside
.
y
+
"+"
+
"全景1高"
+
"+"
+
paddingTop
;
}
break
;
case
32
:
if
(
index
<
3
)
{
this
.
y
=
paddingTop
;
}
else
{
this
.
y
=
upside
.
y
+
"+"
+
"全景1高"
+
"+"
+
paddingTop
;
}
break
;
default
:
throw
new
RuntimeException
(
"no such type"
);
}
return
this
.
y
;
}
/**
* 计算 Y 坐标时需要的填充值
* 一行内每个图片节点的外上边缘字幕的高度加上该节点上层节点的外下边缘字母的高度的最大值作为结果
* 例如
* <ul>
* <li>A B C</li>
* <li>D E F</li>
* </ul>
* D,E,F 的 paddingTop = {@code max(A外下字幕高度 + D外上字幕高度, B外下字幕高度 + E外上字幕高度, C外下字幕高度 + F外上字幕高度)}
*/
private
String
paddingTop
()
{
PicNode
node
=
this
;
int
maxPaddingTop
=
Integer
.
MIN_VALUE
;
while
(
node
!=
null
)
{
PicNode
upside
=
node
.
getUpside
();
int
bottomHeight
=
Optional
.
ofNullable
(
upside
).
map
(
x
->
x
.
captionNode
).
map
(
CaptionNode:
:
getBottomHeight
).
orElse
(
0
);
int
topHeight
=
node
.
getCaptionNode
().
getTopHeight
()
==
null
?
0
:
node
.
getCaptionNode
().
getTopHeight
();
maxPaddingTop
=
Math
.
max
(
maxPaddingTop
,
bottomHeight
+
topHeight
);
node
=
node
.
getLeft
();
}
node
=
this
;
while
(
node
!=
null
)
{
PicNode
upside
=
node
.
getUpside
();
int
bottomHeight
=
Optional
.
ofNullable
(
upside
).
map
(
x
->
x
.
captionNode
).
map
(
CaptionNode:
:
getBottomHeight
).
orElse
(
0
);
int
topHeight
=
node
.
getCaptionNode
().
getTopHeight
()
==
null
?
0
:
node
.
getCaptionNode
().
getTopHeight
();
maxPaddingTop
=
Math
.
max
(
maxPaddingTop
,
bottomHeight
+
topHeight
);
node
=
node
.
getRight
();
}
return
String
.
valueOf
(
maxPaddingTop
);
}
/**
* 获取一个图片节点的左侧图片节点
*/
public
PicNode
getLeft
()
{
if
(
index
==
0
)
{
return
null
;
}
switch
(
generator
.
getLayoutType
())
{
case
21
:
case
31
:
case
41
:
case
51
:
case
61
:
return
generator
.
getPicNodes
()[
index
-
1
];
case
22
:
case
23
:
if
(
index
%
2
==
0
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
-
1
];
}
case
32
:
if
(
index
%
3
==
0
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
-
1
];
}
case
12
:
case
13
:
case
14
:
case
15
:
case
16
:
default
:
return
null
;
}
}
/**
* 获取一个图片节点的右侧图片节点
*/
public
PicNode
getRight
()
{
if
(
index
==
generator
.
picNodes
.
length
-
1
)
{
return
null
;
}
switch
(
generator
.
getLayoutType
())
{
case
21
:
case
31
:
case
41
:
case
51
:
case
61
:
return
generator
.
getPicNodes
()[
index
+
1
];
case
22
:
case
23
:
if
(
index
%
2
==
1
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
+
1
];
}
case
32
:
if
(
index
%
3
==
2
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
+
1
];
}
case
11
:
case
12
:
case
13
:
case
14
:
case
15
:
case
16
:
default
:
return
null
;
}
}
/**
* 获取一个图片节点的上层图片节点
*/
public
PicNode
getUpside
()
{
if
(
index
==
0
)
{
return
null
;
}
switch
(
generator
.
getLayoutType
())
{
case
12
:
case
13
:
case
14
:
case
15
:
case
16
:
return
generator
.
picNodes
[
index
-
1
];
case
22
:
case
23
:
if
(
index
<
2
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
-
2
];
}
case
32
:
if
(
index
<
3
)
{
return
null
;
}
else
{
return
generator
.
picNodes
[
index
-
3
];
}
case
11
:
case
21
:
case
31
:
case
41
:
case
51
:
case
61
:
default
:
return
null
;
}
}
}
/**
* 字幕属性和图片属性的生成器
* 用来生成图片的坐标,字幕的高度,字幕的内容
*/
public
@Getter
@Setter
@AllArgsConstructor
static
class
Coordinate
{
private
Integer
type
;
private
String
name
;
private
String
x
;
private
String
y
;
@Accessors
(
chain
=
true
)
static
class
PicConfigGenerator
{
private
final
PicNode
[]
picNodes
;
/** 图片排列方式类型 */
private
final
int
layoutType
;
/**
* @param picConfigVo 图片属性
* @param captionVos 图片属性对应的所有字幕
*/
public
PicConfigGenerator
(
PicConfigVo
picConfigVo
,
List
<
CaptionVo
>
captionVos
)
{
List
<
Context
>
contexts
=
picConfigVo
.
getContexts
();
layoutType
=
picConfigVo
.
getType
();
picNodes
=
new
PicNode
[
contexts
.
size
()];
for
(
int
i
=
0
;
i
<
picNodes
.
length
;
i
++)
{
Context
context
=
contexts
.
get
(
i
);
picNodes
[
i
]
=
new
PicNode
(
this
,
context
.
getType
(),
i
);
}
for
(
CaptionVo
captionVo
:
captionVos
)
{
for
(
PicNode
picNode
:
picNodes
)
{
if
(
picNode
.
getPicType
()
==
captionVo
.
getPicType
())
{
picNode
.
getCaptionNode
().
add
(
captionVo
);
}
}
}
}
}
/**
* 字幕节点
* 每个图片节点对应一个字幕节点
*/
public
@Getter
@Setter
static
final
class
CaptionNode
{
/** 图片外上边缘字幕的配置 */
private
CaptionVo
top
;
/** 图片内上边缘字幕的配置 */
private
CaptionVo
second
;
/** 图片内下边缘字幕的配置 */
private
CaptionVo
third
;
/** 图片外下边缘字幕的配置 */
private
CaptionVo
bottom
;
/** 图片外上边缘字幕的内容 */
private
String
topContent
;
/** 图片内上边缘字幕的内容 */
private
String
secondContent
;
/** 图片内下边缘字幕的内容 */
private
String
thirdContent
;
/** 图片外下边缘字幕的内容 */
private
String
bottomContent
;
/** 图片外上边缘字幕的高度 */
private
Integer
topHeight
;
/** 图片内上边缘字幕的高度 */
private
Integer
secondHeight
;
/** 图片内下边缘字幕的高度 */
private
Integer
thirdHeight
;
/** 图片外下边缘字幕的高度 */
private
Integer
bottomHeight
;
/**
* 根据坐标位置类型复制不同的字段,如果是同一类就会覆盖
* 目前没写坐标类型为 自定义 的逻辑,相信自定义坐标也不会用上,如果有的话实现也很简单
*/
public
void
add
(
CaptionVo
vo
)
{
Integer
positionType
=
vo
.
getPositionType
();
Integer
fontSize
=
vo
.
getFontSize
();
String
dateFormat
=
(
vo
.
getMillisecond
()
!=
null
&&
vo
.
getMillisecond
())
?
vo
.
getDateFormat
()
+
".xxx"
:
vo
.
getDateFormat
();
Pair
<
String
,
Integer
>
pair
=
combineCaptionContent
(
vo
.
getPicType
(),
vo
.
getContexts
(),
dateFormat
);
Integer
wrapCount
=
pair
.
getValue
();
int
height
=
wrapCount
==
0
?
fontSize
+
10
:
(
wrapCount
+
1
)
*
(
fontSize
+
10
);
switch
(
positionType
)
{
case
0
:
this
.
top
=
vo
;
this
.
topContent
=
pair
.
getKey
();
this
.
topHeight
=
height
;
break
;
case
1
:
this
.
bottom
=
vo
;
this
.
bottomContent
=
pair
.
getKey
();
this
.
bottomHeight
=
height
;
break
;
case
2
:
this
.
second
=
vo
;
this
.
secondContent
=
pair
.
getKey
();
this
.
secondHeight
=
height
;
break
;
case
3
:
this
.
third
=
vo
;
this
.
thirdContent
=
pair
.
getKey
();
this
.
secondHeight
=
height
;
break
;
default
:
break
;
}
}
/**
* 组合字幕内容
*
* @param picType 图片类型
* @param contexts 内容列表
* @param dateFormat 时间格式
*
* @return key: 字幕内容, value: 换行了多少次,用来计算字幕所占的高度
*/
private
Pair
<
String
,
Integer
>
combineCaptionContent
(
Integer
picType
,
List
<
Context
>
contexts
,
String
dateFormat
)
{
if
(
CollectionUtil
.
isEmpty
(
contexts
))
{
return
Pair
.
of
(
null
,
null
);
}
String
picTypeName
=
Dict
.
INSTANCE
.
picType
.
get
(
picType
);
StringBuilder
sb
=
new
StringBuilder
();
int
wrapCount
=
0
;
for
(
Context
context
:
contexts
)
{
Integer
type
=
context
.
getType
();
sb
.
append
(
Dict
.
INSTANCE
.
captionType
.
get
(
type
)).
append
(
":+"
);
switch
(
type
)
{
case
1
:
if
(
picTypeName
.
contains
(
"特写"
))
{
picTypeName
=
"特写图"
;
}
sb
.
append
(
"("
).
append
(
picTypeName
).
append
(
"时间:"
).
append
(
dateFormat
).
append
(
")"
);
break
;
case
9
:
sb
.
append
(
"(用户车辆类型1)"
);
break
;
case
10
:
sb
.
append
(
"(用户车身颜色1)"
);
break
;
case
11
:
sb
.
append
(
"(车辆子品牌)"
);
break
;
case
15
:
sb
.
append
(
"(合成图1防伪码)"
);
break
;
case
16
:
sb
.
append
(
context
.
getContent
());
break
;
case
17
:
sb
.
append
(
"(违法类型代码)"
);
break
;
default
:
sb
.
append
(
"("
).
append
(
Dict
.
INSTANCE
.
captionType
.
get
(
type
)).
append
(
")"
);
}
if
(
context
.
getWrap
())
{
wrapCount
++;
sb
.
append
(
"+(换行分隔符)"
);
}
sb
.
append
(
"+"
);
}
sb
.
setLength
(
sb
.
length
()
-
1
);
return
Pair
.
of
(
sb
.
toString
(),
wrapCount
);
}
}
}
Write
Preview
Markdown
is supported
Attach a file
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 post a comment