|
@@ -4,17 +4,19 @@ import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
-import com.persagy.adm.diagram.core.model.Diagram;
|
|
|
-import com.persagy.adm.diagram.core.model.EquipmentNode;
|
|
|
-import com.persagy.adm.diagram.core.model.Label;
|
|
|
+import com.persagy.adm.diagram.core.model.*;
|
|
|
import com.persagy.adm.diagram.core.model.base.Container;
|
|
|
import com.persagy.adm.diagram.core.model.base.IComponent;
|
|
|
+import com.persagy.adm.diagram.core.model.base.IEquipHolder;
|
|
|
+import com.persagy.adm.diagram.core.model.legend.Anchor;
|
|
|
import com.persagy.adm.diagram.core.model.legend.Legend;
|
|
|
+import com.persagy.adm.diagram.core.model.logic.DataFilter;
|
|
|
+import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
|
|
|
+import com.persagy.adm.diagram.core.model.template.MainPipe;
|
|
|
import com.persagy.adm.diagram.core.model.virtual.PackNode;
|
|
|
+import com.persagy.dmp.digital.entity.ObjectRelation;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* 处理系统图的计算逻辑
|
|
@@ -22,18 +24,96 @@ import java.util.List;
|
|
|
*/
|
|
|
public class DiagramBuilder {
|
|
|
|
|
|
+ /**
|
|
|
+ * 设备容器限制,避免模板设置不当导致过多节点
|
|
|
+ */
|
|
|
+ public static int equipLimit = 50;
|
|
|
+
|
|
|
private Diagram diagram;
|
|
|
|
|
|
+ private DiagramTemplate template;
|
|
|
+
|
|
|
private DataStrategy dataStrategy;
|
|
|
|
|
|
private HashMap<String, List<Legend>> legendsCache = new HashMap<>();
|
|
|
|
|
|
+ private HashSet<String> refRelTypes = new HashSet<>();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录已经使用的数据id和对应的组件
|
|
|
+ */
|
|
|
+ private HashMap<String, Object> equipMap = new HashMap<>();
|
|
|
+
|
|
|
public DiagramBuilder(Diagram diagram, DataStrategy dataStrategy) {
|
|
|
this.diagram = diagram;
|
|
|
+ this.template = diagram.getTemplate();
|
|
|
this.dataStrategy = dataStrategy;
|
|
|
+
|
|
|
+ init();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void init(){
|
|
|
+ //记录节点中已使用的数据id
|
|
|
+ diagram.getNodes().forEach(node -> {
|
|
|
+ if (EquipmentNode.TYPE.equals(node.getCompType()))
|
|
|
+ equipMap.put(((EquipmentNode) node).getObjId(), node);
|
|
|
+ });
|
|
|
+ //记录干管中已使用的数据id
|
|
|
+ if(template.getMainPipes() != null) {
|
|
|
+ template.getMainPipes().forEach(mainPipe -> {
|
|
|
+ if(StrUtil.isNotBlank(mainPipe.getDataObjectId()))
|
|
|
+ equipMap.put(mainPipe.getDataObjectId(), mainPipe);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //加载设备数据,并进行计算处理
|
|
|
+ public void buildEquipNodeAndContainer(List<Container> containers, List<ObjectNode> optionalObjs){
|
|
|
+ for(Container con : containers) {
|
|
|
+ if(con.isEquipmentBox()) {
|
|
|
+ Iterator<ObjectNode> iter = optionalObjs.iterator();
|
|
|
+ while (iter.hasNext()) {
|
|
|
+ ObjectNode obj = iter.next();
|
|
|
+ if (match(obj, con)) {
|
|
|
+ if(con.getEquipPack() != null)
|
|
|
+ addPackData(con, obj);
|
|
|
+ else
|
|
|
+ addEquipNode(con, obj);
|
|
|
+
|
|
|
+ iter.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(template.getMainPipes() != null) {
|
|
|
+ for(MainPipe mainPipe : template.getMainPipes()) {
|
|
|
+ if (mainPipe.isBindEquipment() && mainPipe.getDataObject() == null){
|
|
|
+ Iterator<ObjectNode> iter = optionalObjs.iterator();
|
|
|
+ while (iter.hasNext()) {
|
|
|
+ ObjectNode obj = iter.next();
|
|
|
+ if(match(obj, mainPipe)) {
|
|
|
+ mainPipe.setDataObject(obj);
|
|
|
+ mainPipe.setDataObjectId(obj.get("id").asText());
|
|
|
+
|
|
|
+ equipMap.put(mainPipe.getDataObjectId(), mainPipe);
|
|
|
+
|
|
|
+ iter.remove();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ handleNodes();
|
|
|
+
|
|
|
+ buildContainers(containers);
|
|
|
}
|
|
|
|
|
|
- public void addEquipNode(Container con, ObjectNode obj){
|
|
|
+ private void addEquipNode(Container con, ObjectNode obj){
|
|
|
+ if(con.getChildren().size() > equipLimit)
|
|
|
+ return;
|
|
|
+
|
|
|
EquipmentNode node = new EquipmentNode();
|
|
|
node.setId(IdUtil.simpleUUID());
|
|
|
node.setObjId(obj.get("id").asText());
|
|
@@ -47,6 +127,8 @@ public class DiagramBuilder {
|
|
|
node.setLegendId(legend.getId());
|
|
|
node.setLegend(legend);
|
|
|
}
|
|
|
+
|
|
|
+ equipMap.put(node.getObjId(), node);
|
|
|
}
|
|
|
|
|
|
private void initNode(EquipmentNode node, String name, Container con){
|
|
@@ -61,7 +143,7 @@ public class DiagramBuilder {
|
|
|
diagram.getNodes().add(node);
|
|
|
}
|
|
|
|
|
|
- public void addPackData(Container con, ObjectNode obj){
|
|
|
+ private void addPackData(Container con, ObjectNode obj){
|
|
|
PackNode pn = null;
|
|
|
String classCode = getClassCode(obj);
|
|
|
Legend legend = null;
|
|
@@ -107,6 +189,51 @@ public class DiagramBuilder {
|
|
|
return pn;
|
|
|
}
|
|
|
|
|
|
+ private boolean match(ObjectNode obj, IEquipHolder equipHolder) {
|
|
|
+ String classCode = DiagramBuilder.getClassCode(obj);
|
|
|
+ if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
|
|
|
+ DataFilter filter = equipHolder.getDataFilter();
|
|
|
+ if(filter != null)
|
|
|
+ return filter.filter(obj);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void buildContainers(List<Container> containers) {
|
|
|
+ for(Container con : containers) {
|
|
|
+ if(con.isEquipmentBox()) {
|
|
|
+ if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren()))
|
|
|
+ con.setHidden(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对节点进行处理,并返回图例锚点会使用到的关系类型
|
|
|
+ */
|
|
|
+ private void handleNodes() {
|
|
|
+ for(DiagramNode node : diagram.getNodes()) {
|
|
|
+ if(PackNode.TYPE.equals(node.getCompType())) {
|
|
|
+ PackNode pn = (PackNode)node;
|
|
|
+ pn.getLabel().setContent(pn.getLabel().getContent() + ":" + pn.totalCount());
|
|
|
+ statRelTypes(pn);
|
|
|
+ } else if(EquipmentNode.TYPE.equals(node.getCompType())) {
|
|
|
+ statRelTypes((EquipmentNode)node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void statRelTypes(EquipmentNode equipmentNode){
|
|
|
+ List<Anchor> anchors = equipmentNode.getLegend().getAnchors();
|
|
|
+ if(anchors != null) {
|
|
|
+ for(Anchor anchor : anchors) {
|
|
|
+ if(anchor.getAcceptRelations() != null)
|
|
|
+ anchor.getAcceptRelations().forEach(rel -> refRelTypes.add(rel));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private String getTypeName(String classCode){
|
|
|
//TODO
|
|
|
return classCode;
|
|
@@ -154,6 +281,154 @@ public class DiagramBuilder {
|
|
|
l.setHeight(100);
|
|
|
return l;
|
|
|
}
|
|
|
+
|
|
|
+ public void buildLines(List<ObjectNode> optionalRels){
|
|
|
+ for(ObjectNode rel : optionalRels) {
|
|
|
+ String from = rel.get(ObjectRelation.OBJ_FROM_HUM).asText();
|
|
|
+ String to = rel.get(ObjectRelation.OBJ_TO_HUM).asText();
|
|
|
+
|
|
|
+ Object fromObj = equipMap.get(from);
|
|
|
+ Object toObj = equipMap.get(to);
|
|
|
+
|
|
|
+ if(fromObj != null && toObj != null) {
|
|
|
+ String relType = rel.get(ObjectRelation.GRAPH_CODE_HUM).asText() + '/' + rel.get(ObjectRelation.REL_CODE_HUM).asText();
|
|
|
+ ConnectPoint p1 = getConnectPoint(fromObj, relType, toObj);
|
|
|
+ if(p1 != null) {
|
|
|
+ ConnectPoint p2 = getConnectPoint(toObj, relType, fromObj);
|
|
|
+ if(p2 != null) {
|
|
|
+ Line line = new Line();
|
|
|
+ line.setFrom(p1);
|
|
|
+ line.setTo(p2);
|
|
|
+ line.setRelType(relType);
|
|
|
+ line.setDataObject(rel);
|
|
|
+
|
|
|
+ addLine(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //test code TODO
|
|
|
+ EquipmentNode n1 = null;
|
|
|
+ EquipmentNode n2 = null;
|
|
|
+ for(Object o : equipMap.values()) {
|
|
|
+ if(o instanceof EquipmentNode){
|
|
|
+ String txt = ((EquipmentNode) o).getLabel().getContent();
|
|
|
+ if("1#进线柜".equals(txt))
|
|
|
+ n1 = (EquipmentNode) o;
|
|
|
+ else if("1#计量柜".equals(txt))
|
|
|
+ n2 = (EquipmentNode) o;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(n1 != null && n2 != null) {
|
|
|
+ ConnectPoint p1 = new ConnectPoint();
|
|
|
+ p1.setHostType(EquipmentNode.TYPE);
|
|
|
+ p1.setHostId(n1.getId());
|
|
|
+ p1.setAnchorCode("T3");
|
|
|
+ p1.setHostObj(n1);
|
|
|
+ ConnectPoint p2 = new ConnectPoint();
|
|
|
+ p2.setHostType(EquipmentNode.TYPE);
|
|
|
+ p2.setHostId(n2.getId());
|
|
|
+ p2.setAnchorCode("B3");
|
|
|
+ p2.setHostObj(n2);
|
|
|
+ Line line = new Line();
|
|
|
+ line.setFrom(p1);
|
|
|
+ line.setTo(p2);
|
|
|
+ addLine(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ConnectPoint getConnectPoint(Object obj, String relType, Object theOtherEnd){
|
|
|
+ ObjectNode theOtherData = null;
|
|
|
+ if(theOtherEnd instanceof EquipmentNode)
|
|
|
+ theOtherData = (ObjectNode) ((EquipmentNode) theOtherEnd).getDataObject();
|
|
|
+ else if(theOtherEnd instanceof MainPipe)
|
|
|
+ theOtherData = (ObjectNode) ((MainPipe) theOtherEnd).getDataObject();
|
|
|
+ String theOtherType = getClassCode(theOtherData);
|
|
|
+
|
|
|
+ if(obj instanceof EquipmentNode) {
|
|
|
+ EquipmentNode en = (EquipmentNode)obj;
|
|
|
+ Anchor anchor = null;
|
|
|
+ List<Anchor> anchors = en.getLegend().getAnchors();
|
|
|
+ if(CollUtil.isNotEmpty(anchors)) {
|
|
|
+ Anchor anchor1 = null; //部分匹配
|
|
|
+ for (Anchor a : anchors) {
|
|
|
+ Boolean relMatch = null; //关系匹配
|
|
|
+ Boolean equipMatch = null; //另一端设备匹配
|
|
|
+
|
|
|
+ if(CollUtil.isNotEmpty(a.getAcceptRelations()))
|
|
|
+ relMatch = a.getAcceptRelations().contains(relType);
|
|
|
+
|
|
|
+ if(!Boolean.FALSE.equals(relMatch)) {
|
|
|
+ if(CollUtil.isNotEmpty(a.getToEquipmentTypes()))
|
|
|
+ equipMatch = a.getToEquipmentTypes().contains(theOtherType);
|
|
|
+ if(!Boolean.FALSE.equals(equipMatch) && a.getToDataFilter() != null)
|
|
|
+ equipMatch = a.getToDataFilter().filter(theOtherData);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!Boolean.FALSE.equals(relMatch) && !Boolean.FALSE.equals(equipMatch)) {
|
|
|
+ if(relMatch == null || equipMatch == null) {
|
|
|
+ //部分匹配
|
|
|
+ if(anchor1 == null)
|
|
|
+ anchor1 = a;
|
|
|
+ else if(CollUtil.isNotEmpty(anchor1.getLines()) && CollUtil.isEmpty(a.getLines()))
|
|
|
+ anchor1 = a;
|
|
|
+ } else {
|
|
|
+ //完全匹配
|
|
|
+ if(CollUtil.isEmpty(a.getLines())) {
|
|
|
+ anchor = a;
|
|
|
+ break;
|
|
|
+ } else if(anchor == null)
|
|
|
+ anchor = a;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(anchor == null && anchor1 != null)
|
|
|
+ anchor = anchor1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(anchor != null) {
|
|
|
+ ConnectPoint cp = new ConnectPoint();
|
|
|
+ cp.setHostType(EquipmentNode.TYPE);
|
|
|
+ cp.setHostId(en.getId());
|
|
|
+ cp.setAnchorCode(anchor.getCode());
|
|
|
+ cp.setHostObj(en);
|
|
|
+ return cp;
|
|
|
+ }
|
|
|
+ } else if(obj instanceof MainPipe) {
|
|
|
+ MainPipe mp = (MainPipe)obj;
|
|
|
+ if(CollUtil.isEmpty(mp.getConnectEquips()) || mp.getConnectEquips().contains(theOtherType)) {
|
|
|
+ ConnectPoint cp = new ConnectPoint();
|
|
|
+ cp.setHostType(MainPipe.TYPE);
|
|
|
+ cp.setHostId(mp.getId());
|
|
|
+ cp.setHostObj(mp);
|
|
|
+ return cp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addLine(Line line) {
|
|
|
+ markAnchorLine(line.getFrom(), line);
|
|
|
+ markAnchorLine(line.getTo(), line);
|
|
|
+ diagram.getLines().add(line);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void markAnchorLine(ConnectPoint p, Line line){
|
|
|
+ if (StrUtil.isNotBlank(p.getAnchorCode())) {
|
|
|
+ EquipmentNode en = (EquipmentNode) p.getHostObj();
|
|
|
+ Anchor anchor = en.getLegend().getAnchor(p.getAnchorCode());
|
|
|
+ anchor.addLine(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public HashMap<String, Object> getEquipMap() {
|
|
|
+ return equipMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ public HashSet<String> getRefRelTypes() {
|
|
|
+ return refRelTypes;
|
|
|
+ }
|
|
|
|
|
|
public static String getName(ObjectNode obj){
|
|
|
String name = null;
|
|
@@ -165,7 +440,7 @@ public class DiagramBuilder {
|
|
|
}
|
|
|
|
|
|
public static String getClassCode(ObjectNode obj){
|
|
|
- if(obj.get("classCode") != null)
|
|
|
+ if(obj != null && obj.get("classCode") != null)
|
|
|
return obj.get("classCode").asText();
|
|
|
return null;
|
|
|
}
|