|
@@ -0,0 +1,722 @@
|
|
|
|
+package com.persagy.adm.diagram.core.build;
|
|
|
|
+
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
|
+import cn.hutool.extra.spring.SpringUtil;
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
+import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
|
+import com.persagy.adm.diagram.core.ContentParser;
|
|
|
|
+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.IDataBind;
|
|
|
|
+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.logic.DynGroup;
|
|
|
|
+import com.persagy.adm.diagram.core.model.logic.LogicFilter;
|
|
|
|
+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.template.MainPipePoint;
|
|
|
|
+import com.persagy.adm.diagram.core.model.virtual.PackNode;
|
|
|
|
+import com.persagy.dmp.digital.entity.ObjectRelation;
|
|
|
|
+
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 处理系统图的计算逻辑
|
|
|
|
+ * @author zhaoyk
|
|
|
|
+ */
|
|
|
|
+public class DiagramBuilder {
|
|
|
|
+
|
|
|
|
+ public static final Object DATA_NULL = new Object();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设备容器限制,避免模板设置不当导致过多节点
|
|
|
|
+ */
|
|
|
|
+ public static int equipLimit = 50;
|
|
|
|
+
|
|
|
|
+ private CalcContext context;
|
|
|
|
+
|
|
|
|
+ private Diagram diagram;
|
|
|
|
+
|
|
|
|
+ private DiagramTemplate template;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * template.mainPipes引用,避免空指针
|
|
|
|
+ */
|
|
|
|
+ private List<MainPipe> mainPipes;
|
|
|
|
+
|
|
|
|
+ private LegendLoader legendLoader;
|
|
|
|
+
|
|
|
|
+ private ContentParser contentParser;
|
|
|
|
+
|
|
|
|
+ private HashSet<String> refRelTypes = new HashSet<>();
|
|
|
|
+
|
|
|
|
+ public DiagramBuilder(CalcContext context, LegendLoader legendLoader) {
|
|
|
|
+ this.context = context;
|
|
|
|
+ this.legendLoader = legendLoader;
|
|
|
|
+
|
|
|
|
+ this.diagram = context.getDiagram();
|
|
|
|
+ this.template = context.getTemplate();
|
|
|
|
+ this.mainPipes = template.getMainPipes() != null ? template.getMainPipes() : new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ this.context.setDiagramBuilder(this);
|
|
|
|
+
|
|
|
|
+ this.contentParser = SpringUtil.getBean("diagramContentParser");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 加载设备数据,构建系统图结构
|
|
|
|
+ */
|
|
|
|
+ public void buildStructure(){
|
|
|
|
+ calcContainerAndMainPipes(template.getFrame());
|
|
|
|
+
|
|
|
|
+ buildMainPipeAndNodes();
|
|
|
|
+
|
|
|
|
+ handleNodes();
|
|
|
|
+ handleContainers();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 对容器和相关的干管进行计算和数据加载
|
|
|
|
+ */
|
|
|
|
+ private void calcContainerAndMainPipes(Container container){
|
|
|
|
+ List<Container> subEquipBoxes = new ArrayList<>();
|
|
|
|
+ List<Container> subDynCons = new ArrayList<>();
|
|
|
|
+ container.readSubContainers(subEquipBoxes, subDynCons);
|
|
|
|
+
|
|
|
|
+ List<MainPipe> relMainPipes = getRelMainPipes(container, subEquipBoxes);
|
|
|
|
+
|
|
|
|
+ DynGroup dynGroup = container.getDynGroup();
|
|
|
|
+ if (dynGroup != null) {
|
|
|
|
+ List<ObjectNode> dynData;
|
|
|
|
+ CalcGroup group;
|
|
|
|
+ int pos = container.getParent().getChildren().indexOf(container);
|
|
|
|
+
|
|
|
|
+ boolean isCompSrc = dynGroup.isCompSrc();
|
|
|
|
+ boolean isBuildingSrc = DynGroup.SRC_BUILDING.equals(dynGroup.getDynSource());
|
|
|
|
+ boolean isFloorSrc = DynGroup.SRC_FLOOR.equals(dynGroup.getDynSource());
|
|
|
|
+ if(isCompSrc) {
|
|
|
|
+ IEquipHolder srcComp = context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType());
|
|
|
|
+ dynData = findMatchedData(srcComp);
|
|
|
|
+ } else {
|
|
|
|
+ dynData = getGroupList(dynGroup);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (CollUtil.isEmpty(dynData)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ group = new CalcGroup();
|
|
|
|
+ context.setCurrentGroup(group);
|
|
|
|
+
|
|
|
|
+ String containerJson = null;
|
|
|
|
+ String mainPipesJson = null;
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < dynData.size(); i++) {
|
|
|
|
+ group.setCurrentIdx(i);
|
|
|
|
+
|
|
|
|
+ if(i == 0){
|
|
|
|
+ setGroupContainer(container, group);
|
|
|
|
+ setGroupMainPipes(relMainPipes, group);
|
|
|
|
+
|
|
|
|
+ if(isCompSrc) {
|
|
|
|
+ group.setDynSrcComp(context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType()), dynData.get(i));
|
|
|
|
+ } else if(isFloorSrc) {
|
|
|
|
+ group.setFloor(dynData.get(i));
|
|
|
|
+ } else if(isBuildingSrc) {
|
|
|
|
+ group.setBuilding(dynData.get(i));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ loadEquipsData(subEquipBoxes, subDynCons, relMainPipes);
|
|
|
|
+ } else {
|
|
|
|
+ if(containerJson == null) {
|
|
|
|
+ containerJson = contentParser.toJson(container);
|
|
|
|
+ }
|
|
|
|
+ if(mainPipesJson == null) {
|
|
|
|
+ mainPipesJson = contentParser.toJson(relMainPipes);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String idLabel = StrUtil.join("_", group.getIdx());
|
|
|
|
+
|
|
|
|
+ Container newCon = copyContainer(containerJson, idLabel);
|
|
|
|
+ container.getParent().addComp(newCon, pos + i);
|
|
|
|
+ setGroupContainer(newCon, group);
|
|
|
|
+
|
|
|
|
+ List<MainPipe> newMps = copyRelMainPipes(mainPipesJson, idLabel);
|
|
|
|
+ mainPipes.addAll(newMps);
|
|
|
|
+ setGroupMainPipes(newMps, group);
|
|
|
|
+
|
|
|
|
+ List<Container> newSubEquipBoxes = new ArrayList<>();
|
|
|
|
+ List<Container> newSubDynCons = new ArrayList<>();
|
|
|
|
+ newCon.readSubContainers(newSubEquipBoxes, newSubDynCons);
|
|
|
|
+
|
|
|
|
+ if(isCompSrc) {
|
|
|
|
+ group.setDynSrcComp(context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType()), dynData.get(i));
|
|
|
|
+ } else if(isFloorSrc) {
|
|
|
|
+ group.setFloor(dynData.get(i));
|
|
|
|
+ } else if(isBuildingSrc) {
|
|
|
|
+ group.setBuilding(dynData.get(i));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ loadEquipsData(newSubEquipBoxes, newSubDynCons, newMps);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //清除当前计算组
|
|
|
|
+ context.clearCurrentGroup();
|
|
|
|
+ } else {
|
|
|
|
+ loadEquipsData(subEquipBoxes, subDynCons, relMainPipes);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<ObjectNode> getGroupList(DynGroup dynGroup){
|
|
|
|
+ if(DynGroup.SRC_TYPE_GROUP.equals(dynGroup.getDynSourceType())) {
|
|
|
|
+ //按设备统计
|
|
|
|
+ return getGroupList(dynGroup.getDynSource());
|
|
|
|
+ } else if(DynGroup.SRC_TYPE_DATA.equals(dynGroup.getDynSourceType())) {
|
|
|
|
+ //TODO 数据查询
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<ObjectNode> getGroupList(String group){
|
|
|
|
+ ObjectMapper mapper = new ObjectMapper();
|
|
|
|
+ HashMap<String, ObjectNode> map = new HashMap<>();
|
|
|
|
+ //TODO 楼层和建筑对象
|
|
|
|
+ for(ObjectNode obj : context.getOptionalObjs()) {
|
|
|
|
+ if(DynGroup.SRC_FLOOR.equals(group)) {
|
|
|
|
+ String key = getFloorId(obj);
|
|
|
|
+ if(StrUtil.isNotBlank(key) && !map.containsKey(key)){
|
|
|
|
+ map.put(key, mapper.createObjectNode().put("id", key));
|
|
|
|
+ }
|
|
|
|
+ } else if(DynGroup.SRC_BUILDING.equals(group)) {
|
|
|
|
+ String key = getBuildingId(obj);
|
|
|
|
+ if(StrUtil.isNotBlank(key) && !map.containsKey(key)){
|
|
|
|
+ map.put(key, mapper.createObjectNode().put("id", key));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<ObjectNode> list = new ArrayList<>(map.values());
|
|
|
|
+ sortBdFlList(list);
|
|
|
|
+
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void sortBdFlList(List<ObjectNode> list){
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void setGroupContainer(Container con, CalcGroup currentGroup) {
|
|
|
|
+ for (Container item : con.listContainers()) {
|
|
|
|
+ currentGroup.addComp(getSrcId(item.getId()), item);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void setGroupMainPipes(List<MainPipe> mps, CalcGroup currentGroup){
|
|
|
|
+ for(MainPipe mp : mps){
|
|
|
|
+ currentGroup.addComp(getSrcId(mp.getId()), mp);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Container copyContainer(String containerJson, String idLabel) {
|
|
|
|
+ Container container = contentParser.parseContent(containerJson, Container.class);
|
|
|
|
+ for (Container con : container.listContainers()) {
|
|
|
|
+ con.setId(getSrcId(con.getId()) + ":" + idLabel);
|
|
|
|
+ }
|
|
|
|
+ container.initParent();
|
|
|
|
+
|
|
|
|
+ return container;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<MainPipe> copyRelMainPipes(String mainPipesJson, String idLabel){
|
|
|
|
+ List<MainPipe> mainPipes = new ArrayList<>();
|
|
|
|
+ Collections.addAll(mainPipes, contentParser.parseContent(mainPipesJson, MainPipe[].class));
|
|
|
|
+ for(MainPipe mp : mainPipes){
|
|
|
|
+ mp.setId(getSrcId(mp.getId()) + ":" + idLabel);
|
|
|
|
+ changeMainPipeRefIds(mp);
|
|
|
|
+
|
|
|
|
+ mp.init(template);
|
|
|
|
+ }
|
|
|
|
+ return mainPipes;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void changeMainPipeRefIds(MainPipe mp){
|
|
|
|
+ List<String> relConIds = mp.getRelatedContainers();
|
|
|
|
+ if(relConIds != null){
|
|
|
|
+ for (int i = 0; i < relConIds.size(); i++) {
|
|
|
|
+ Container con = context.getComp(relConIds.get(i), Container.TYPE);
|
|
|
|
+ if(con != null) {
|
|
|
|
+ relConIds.set(i, con.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(List<MainPipePoint> line : mp.getPath()){
|
|
|
|
+ for (MainPipePoint p : line) {
|
|
|
|
+ Container con = context.getComp(p.getContainerId(), Container.TYPE);
|
|
|
|
+ if(con != null) {
|
|
|
|
+ p.setContainerId(con.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String getSrcId(String id){
|
|
|
|
+ int pos = id.indexOf(':');
|
|
|
|
+ if(pos > 0){
|
|
|
|
+ return id.substring(0, pos);
|
|
|
|
+ }
|
|
|
|
+ return id;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<MainPipe> getRelMainPipes(Container container, List<Container> subEquipBoxes){
|
|
|
|
+ List<MainPipe> relMainPipes = new ArrayList<>();
|
|
|
|
+ boolean isFrame = template.isFrameContainer(container);
|
|
|
|
+ for(MainPipe mainPipe : mainPipes) {
|
|
|
|
+ List<Container> relCons = mainPipe.getRelatedContainerList();
|
|
|
|
+ boolean relWithMe;
|
|
|
|
+ if(isFrame){
|
|
|
|
+ relWithMe = CollUtil.isEmpty(relCons);
|
|
|
|
+ } else {
|
|
|
|
+ relWithMe = relCons != null && relCons.contains(container);
|
|
|
|
+ }
|
|
|
|
+ if(relWithMe){
|
|
|
|
+ relMainPipes.add(mainPipe);
|
|
|
|
+ } else {
|
|
|
|
+ for(Container subEq : subEquipBoxes) {
|
|
|
|
+ if(relCons != null && relCons.contains(subEq)){
|
|
|
|
+ relMainPipes.add(mainPipe);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return relMainPipes;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void loadEquipsData(List<Container> subEquipBoxes, List<Container> subDynCons, List<MainPipe> relMainPipes){
|
|
|
|
+ for(MainPipe mainPipe : relMainPipes) {
|
|
|
|
+ if (mainPipe.isBindEquipment()){
|
|
|
|
+ loadMatchedData(mainPipe);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for(Container subCon : subEquipBoxes) {
|
|
|
|
+ loadMatchedData(subCon);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subDynCons.size() > 0) {
|
|
|
|
+ for(Container subDyn : subDynCons) {
|
|
|
|
+ calcContainerAndMainPipes(subDyn);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<ObjectNode> loadMatchedData(IEquipHolder equipHolder){
|
|
|
|
+ List<ObjectNode> matchedData = equipHolder.getMatchedData();
|
|
|
|
+ if(matchedData == null){
|
|
|
|
+ matchedData = findMatchedData(equipHolder);
|
|
|
|
+ if(matchedData == null) {
|
|
|
|
+ matchedData = Collections.EMPTY_LIST;
|
|
|
|
+ }
|
|
|
|
+ equipHolder.setMatchedData(matchedData);
|
|
|
|
+ }
|
|
|
|
+ return matchedData;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<ObjectNode> findMatchedData(IEquipHolder equipHolder){
|
|
|
|
+ ArrayList<ObjectNode> data = null;
|
|
|
|
+ for(ObjectNode obj : context.getOptionalObjs()) {
|
|
|
|
+ if (match(obj, equipHolder)){
|
|
|
|
+ if(data == null){
|
|
|
|
+ data = new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ data.add(obj);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return data;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void buildMainPipeAndNodes(){
|
|
|
|
+ for(MainPipe mainPipe : mainPipes) {
|
|
|
|
+ if (mainPipe.isBindEquipment()) {
|
|
|
|
+ List<ObjectNode> matchedData = mainPipe.getMatchedData();
|
|
|
|
+ if(CollUtil.isNotEmpty(matchedData)) {
|
|
|
|
+ sortDataList(matchedData);
|
|
|
|
+
|
|
|
|
+ ObjectNode obj = (ObjectNode)mainPipe.getMatchedData().get(0);
|
|
|
|
+ mainPipe.setDataObject(obj);
|
|
|
|
+ mainPipe.setDataObjectId(obj.get("id").asText());
|
|
|
|
+
|
|
|
|
+ context.getEquipMap().put(mainPipe.getDataObjectId(), mainPipe);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for(Container con : template.getContainers()) {
|
|
|
|
+ if(con.isEquipmentBox()) {
|
|
|
|
+ List<ObjectNode> matchedData = con.getMatchedData();
|
|
|
|
+ if(CollUtil.isNotEmpty(matchedData)) {
|
|
|
|
+ sortDataList(matchedData);
|
|
|
|
+
|
|
|
|
+ for(ObjectNode obj : matchedData) {
|
|
|
|
+ if(con.getEquipPack() != null) {
|
|
|
|
+ addPackData(con, obj);
|
|
|
|
+ } else {
|
|
|
|
+ addEquipNode(con, obj);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void sortDataList(List<ObjectNode> dataList){
|
|
|
|
+ //TODO 对设备数据进行排序操作
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void addEquipNode(Container con, ObjectNode obj){
|
|
|
|
+ if(con.getChildren().size() > equipLimit) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ EquipmentNode node = new EquipmentNode();
|
|
|
|
+ node.setId(IdUtil.fastSimpleUUID());
|
|
|
|
+ node.setDataObjectId(obj.get("id").asText());
|
|
|
|
+ node.setObjClassCode(DiagramBuilder.getClassCode(obj));
|
|
|
|
+ node.setDataObject(obj);
|
|
|
|
+
|
|
|
|
+ initNode(node, DiagramBuilder.getName(obj), con);
|
|
|
|
+
|
|
|
|
+ Legend legend = legendLoader.findLegend(node.getObjClassCode(), obj);
|
|
|
|
+ node.setLegendId(legend.getId());
|
|
|
|
+ node.setLegend(legend);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void initNode(EquipmentNode node, String name, Container con){
|
|
|
|
+ con.addComp(node);
|
|
|
|
+ node.setContainerId(con.getId());
|
|
|
|
+ node.setLayoutIndex(con.getChildren().size() - 1);
|
|
|
|
+
|
|
|
|
+ Label label = new Label();
|
|
|
|
+ label.setId(IdUtil.fastSimpleUUID());
|
|
|
|
+ label.setContent(name);
|
|
|
|
+ node.setLabel(label);
|
|
|
|
+
|
|
|
|
+ diagram.getNodes().add(node);
|
|
|
|
+ context.getEquipMap().put(node.getDataObjectId(), node);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void addPackData(Container con, ObjectNode obj){
|
|
|
|
+ PackNode pn = null;
|
|
|
|
+ String classCode = getClassCode(obj);
|
|
|
|
+ Legend legend = null;
|
|
|
|
+ //single
|
|
|
|
+ if(!con.getEquipPack().isPackByType()) {
|
|
|
|
+ String packName = con.getEquipPack().getPackName();
|
|
|
|
+ if(StrUtil.isBlank(packName)) {
|
|
|
|
+ packName = getTypeName(classCode);
|
|
|
|
+ }
|
|
|
|
+ if(con.getChildren().size() == 0) {
|
|
|
|
+ pn = newPackNode(PackNode.SINGLE_PACK, con, packName);
|
|
|
|
+ } else {
|
|
|
|
+ pn = (PackNode) con.getChildren().get(0);
|
|
|
|
+ }
|
|
|
|
+ } else { //group
|
|
|
|
+ for(IComponent comp : con.getChildren()) {
|
|
|
|
+ PackNode item = (PackNode) comp;
|
|
|
|
+ if(item.getObjClassCode().equals(classCode)){
|
|
|
|
+ pn = item;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(pn == null) {
|
|
|
|
+ pn = newPackNode(classCode, con, getTypeName(classCode));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pn.getLegend() == null) {
|
|
|
|
+ if(con.getEquipPack().getLegendId() != null) {
|
|
|
|
+ legend = legendLoader.findLegendById(con.getEquipPack().getLegendId(), classCode.substring(0, 4));
|
|
|
|
+ }
|
|
|
|
+ if(legend == null) {
|
|
|
|
+ legend = legendLoader.findLegend(classCode, null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pn.setLegendId(legend.getId());
|
|
|
|
+ pn.setLegend(legend);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pn.add(classCode);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private PackNode newPackNode(String objClsCode, Container con, String packName){
|
|
|
|
+ PackNode pn = new PackNode();
|
|
|
|
+ pn.setId(IdUtil.fastSimpleUUID());
|
|
|
|
+ pn.setObjClassCode(objClsCode);
|
|
|
|
+
|
|
|
|
+ initNode(pn, packName, con);
|
|
|
|
+
|
|
|
|
+ return pn;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean match(ObjectNode obj, IEquipHolder equipHolder) {
|
|
|
|
+ String classCode = DiagramBuilder.getClassCode(obj);
|
|
|
|
+ if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
|
|
|
|
+ if(checkBdFl(obj)){
|
|
|
|
+ DataFilter filter = equipHolder.getDataFilter();
|
|
|
|
+ if(filter != null) {
|
|
|
|
+ return filter.filter(obj, context);
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean checkBdFl(ObjectNode obj){
|
|
|
|
+ ObjectNode bd = context.getBuilding();
|
|
|
|
+ ObjectNode fl = context.getFloor();
|
|
|
|
+ if(bd != null){
|
|
|
|
+ String bdId = getBuildingId(obj);
|
|
|
|
+ if(!bd.get("id").asText().equals(bdId)){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(fl != null){
|
|
|
|
+ String flId = getFloorId(obj);
|
|
|
|
+ if(!fl.get("id").asText().equals(flId)){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 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 void handleContainers() {
|
|
|
|
+ for(Container con : template.getContainers()) {
|
|
|
|
+ if(con.isEquipmentBox()) {
|
|
|
|
+ if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren())) {
|
|
|
|
+ con.setHidden(true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String getTypeName(String classCode){
|
|
|
|
+ //TODO
|
|
|
|
+ return classCode;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void buildLines(List<ObjectNode> optionalRels){
|
|
|
|
+ //去掉已经使用的关系项
|
|
|
|
+ if(context.getLineMap().size() > 0) {
|
|
|
|
+ optionalRels = optionalRels.stream().filter(obj -> !context.getLineMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(ObjectNode rel : optionalRels) {
|
|
|
|
+ IDataBind fromObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
|
|
|
|
+ IDataBind toObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_TO_HUM).asText());
|
|
|
|
+
|
|
|
|
+ if(fromObj != null && toObj != null) {
|
|
|
|
+ String relType = rel.get(ObjectRelation.GRAPH_CODE_HUM).asText() + '/' + rel.get(ObjectRelation.REL_CODE_HUM).asText();
|
|
|
|
+ ConnectPoint from = getConnectPoint(fromObj, relType, toObj);
|
|
|
|
+ if(from != null) {
|
|
|
|
+ ConnectPoint to = getConnectPoint(toObj, relType, fromObj);
|
|
|
|
+ if(to != null) {
|
|
|
|
+ Line line = new Line();
|
|
|
|
+ line.setFrom(from);
|
|
|
|
+ line.setTo(to);
|
|
|
|
+ line.setRelType(relType);
|
|
|
|
+ line.setDataObject(rel);
|
|
|
|
+ line.setDataObjectId(rel.get("id").asText());
|
|
|
|
+
|
|
|
|
+ addLine(line);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private ConnectPoint getConnectPoint(IDataBind obj, String relType, IDataBind theOtherEnd){
|
|
|
|
+ ObjectNode theOtherData = (ObjectNode) 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, context);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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) {
|
|
|
|
+ line.setId(IdUtil.fastSimpleUUID());
|
|
|
|
+ markAnchorLine(line.getFrom(), line);
|
|
|
|
+ markAnchorLine(line.getTo(), line);
|
|
|
|
+ diagram.getLines().add(line);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void markAnchorLine(ConnectPoint p, Line line){
|
|
|
|
+ EquipmentNode en = p.getEquipmentNode();
|
|
|
|
+ if (en != null) {
|
|
|
|
+ Anchor anchor = en.getLegend().getAnchor(p.getAnchorCode());
|
|
|
|
+ anchor.addLine(line);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public HashSet<String> getRefRelTypes() {
|
|
|
|
+ return refRelTypes;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Diagram getDiagram() {
|
|
|
|
+ return diagram;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static boolean hasRelationFilter(IEquipHolder equipHolder) {
|
|
|
|
+ DataFilter filter = equipHolder.getDataFilter();
|
|
|
|
+ if(filter != null) {
|
|
|
|
+ if (filter.getType() == DataFilter.TYPE_RELATION) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ if (filter instanceof LogicFilter) {
|
|
|
|
+ LinkedList<DataFilter> list = new LinkedList<>();
|
|
|
|
+ list.addAll(((LogicFilter) filter).getItems());
|
|
|
|
+
|
|
|
|
+ while (list.size() > 0) {
|
|
|
|
+ DataFilter item = list.removeFirst();
|
|
|
|
+ if(item.getType() == DataFilter.TYPE_RELATION){
|
|
|
|
+ return true;
|
|
|
|
+ } else if(item instanceof LogicFilter) {
|
|
|
|
+ list.addAll(((LogicFilter) item).getItems());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String getName(ObjectNode obj){
|
|
|
|
+ String name = null;
|
|
|
|
+ if(obj.get("localName") != null) {
|
|
|
|
+ name = obj.get("localName").asText();
|
|
|
|
+ }
|
|
|
|
+ if(StrUtil.isBlank(name) && obj.get("name") != null) {
|
|
|
|
+ name = obj.get("name").asText();
|
|
|
|
+ }
|
|
|
|
+ return name;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String getClassCode(ObjectNode obj){
|
|
|
|
+ return getInfo(obj, "classCode");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String getInfo(ObjectNode obj, String infoCode){
|
|
|
|
+ if(obj != null && obj.get(infoCode) != null) {
|
|
|
|
+ return obj.get(infoCode).asText();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String getBuildingId(ObjectNode obj){
|
|
|
|
+ return getInfo(obj, "buildingId");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String getFloorId(ObjectNode obj){
|
|
|
|
+ return getInfo(obj, "floorId");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|