|
@@ -0,0 +1,120 @@
|
|
|
+package cn.com.qmth.stmms.biz.utils;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Map.Entry;
|
|
|
+
|
|
|
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
|
|
|
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 根据裁切图配置与评卷分组拼接配置,将各显示元素坐标转换为原图坐标
|
|
|
+ *
|
|
|
+ * @author luoshi
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class PictureConfigTransform {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换方法
|
|
|
+ *
|
|
|
+ * @param sliceConfigs
|
|
|
+ * - 裁切图配置
|
|
|
+ * @param groups
|
|
|
+ * - 评卷分组与原始元素列表
|
|
|
+ * @return 原图序号与新的显示元素列表,序号从1开始
|
|
|
+ */
|
|
|
+ public static Map<Integer, List<PictureTag>> process(List<PictureConfigItem> sliceConfigs,
|
|
|
+ Map<MarkGroup, List<OriginTag>> groups) {
|
|
|
+ Map<Integer, List<PictureTag>> map = new HashMap<>();
|
|
|
+ if (sliceConfigs.isEmpty()) {
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+ for (Entry<MarkGroup, List<OriginTag>> entry : groups.entrySet()) {
|
|
|
+ MarkGroup group = entry.getKey();
|
|
|
+ List<OriginTag> tags = entry.getValue();
|
|
|
+ List<PictureConfigItem> groupConfigs = group.getPictureConfigList();
|
|
|
+ if (tags.isEmpty() || groupConfigs.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ int maxWidth = 0;
|
|
|
+ int totalHeight = 0;
|
|
|
+ // 计算评卷分组拼接图的总高度与最大宽度
|
|
|
+ for (PictureConfigItem config : groupConfigs) {
|
|
|
+ if (config.getW() == 0 || config.getH() == 0) {
|
|
|
+ // 兼容老数据,宽高未设置时,表示直接使用整张裁切图
|
|
|
+ PictureConfigItem sliceConfig = sliceConfigs.size() >= config.getI()
|
|
|
+ ? sliceConfigs.get(config.getI() - 1)
|
|
|
+ : null;
|
|
|
+ if (sliceConfig != null) {
|
|
|
+ // 直接使用裁切图的宽高
|
|
|
+ config.setW(sliceConfig.getW());
|
|
|
+ config.setH(sliceConfig.getH());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (config.getW() > 0 && config.getH() > 0) {
|
|
|
+ maxWidth = Math.max(maxWidth, config.getW());
|
|
|
+ totalHeight += config.getH();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 遍历所有显示元素
|
|
|
+ for (OriginTag tag : tags) {
|
|
|
+ // 计算显示元素在拼接图内的绝对位置
|
|
|
+ int left = (int) (maxWidth * tag.getPoxitionX());
|
|
|
+ int top = (int) (totalHeight * tag.getPoxitionY());
|
|
|
+ int start = 0;
|
|
|
+ for (PictureConfigItem config : groupConfigs) {
|
|
|
+ if (config.getW() > 0 && config.getH() > 0) {
|
|
|
+ if (top <= (config.getH() + start)) {
|
|
|
+ // 根据绝对高度判断显示元素是否落在当前拼接块
|
|
|
+ buildSheetTag(map, sliceConfigs, config, tag.getContent(), left, top - start);
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ start += config.getH();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据计算出的拼接块,构造新的原图显示元素
|
|
|
+ *
|
|
|
+ * @param tags
|
|
|
+ * - 原图显示元素集合
|
|
|
+ * @param sliceConfigs
|
|
|
+ * - 裁切图配置
|
|
|
+ * @param config
|
|
|
+ * - 当前拼接块配置
|
|
|
+ * @param content
|
|
|
+ * - 显示元素内容
|
|
|
+ * @param left
|
|
|
+ * - 在拼接块内的左偏移
|
|
|
+ * @param top
|
|
|
+ * - 在拼接块内的上偏移
|
|
|
+ */
|
|
|
+ private static void buildSheetTag(Map<Integer, List<PictureTag>> tags, List<PictureConfigItem> sliceConfigs,
|
|
|
+ PictureConfigItem config, String content, int left, int top) {
|
|
|
+ if (sliceConfigs.size() >= config.getI()) {
|
|
|
+ PictureConfigItem sliceConfig = sliceConfigs.get(config.getI() - 1);
|
|
|
+ PictureTag tag = new PictureTag();
|
|
|
+ tag.setContent(content);
|
|
|
+ // 原图内偏移=拼接块内偏移+拼接块在裁切图内偏移+裁切图在原图内偏移
|
|
|
+ tag.setLeft(left + config.getX() + sliceConfig.getX());
|
|
|
+ tag.setTop(top + config.getY() + sliceConfig.getY());
|
|
|
+
|
|
|
+ List<PictureTag> list = tags.get(config.getI());
|
|
|
+ if (list == null) {
|
|
|
+ list = new LinkedList<>();
|
|
|
+ tags.put(config.getI(), list);
|
|
|
+ }
|
|
|
+ list.add(tag);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|