浏览代码

锚点计算精确度修正;计算流程修改;输出模式mapper;关联关系过滤

zhaoyk 3 年之前
父节点
当前提交
86e24d213f
共有 23 个文件被更改,包括 662 次插入320 次删除
  1. 3 3
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/TemplateController.java
  2. 44 72
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramBuilder.java
  3. 18 23
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramDataLoader.java
  4. 0 55
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramView.java
  5. 7 7
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/LineLayoutManager.java
  6. 6 3
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/Diagram.java
  7. 21 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/Container.java
  8. 5 5
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/legend/Anchor.java
  9. 2 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/AndFilter.java
  10. 115 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/CalcContext.java
  11. 5 3
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DataFilter.java
  12. 1 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/MatchFilter.java
  13. 2 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/OrFilter.java
  14. 126 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/RelationFilter.java
  15. 2 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/ContainerRefPoint.java
  16. 6 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/DiagramTemplate.java
  17. 166 32
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/MainPipe.java
  18. 8 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/virtual/PackNode.java
  19. 3 4
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/util/GsonUtil.java
  20. 62 15
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/util/MyObjectMapper.java
  21. 2 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/frame/EditRequest.java
  22. 15 25
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DemoDiagramManager.java
  23. 43 66
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/TemplateManager.java

+ 3 - 3
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/TemplateController.java

@@ -63,9 +63,9 @@ public class TemplateController {
         return ResultHelper.single(templateManager.moveCon(params.getCurrentCompId(), params.getTemplateId(), params.getMoveOffset()));
     }
 
-    @PostMapping("addMainPipe")
-    public CommonResult<DiagramTemplate> addMainPipe(@RequestBody EditRequest params){
-        return ResultHelper.single(templateManager.addMainPipe(params.getLines(), params.getTemplateId()));
+    @PostMapping("drawMainPipe")
+    public CommonResult<DiagramTemplate> drawMainPipe(@RequestBody EditRequest params){
+        return ResultHelper.single(templateManager.drawMainPipe(params.getLines(), params.getCurrentCompId(), params.getTemplateId()));
     }
 
     @PostMapping("delLine")

+ 44 - 72
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramBuilder.java

@@ -10,6 +10,7 @@ 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.CalcContext;
 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;
@@ -17,6 +18,7 @@ import com.persagy.adm.diagram.core.model.virtual.PackNode;
 import com.persagy.dmp.digital.entity.ObjectRelation;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 处理系统图的计算逻辑
@@ -29,6 +31,8 @@ public class DiagramBuilder {
 	 */
 	public static int equipLimit = 50;
 
+	private CalcContext context;
+
 	private Diagram diagram;
 
 	private DiagramTemplate template;
@@ -39,66 +43,24 @@ public class DiagramBuilder {
 
 	private HashSet<String> refRelTypes = new HashSet<>();
 
-	/**
-	 * 记录已经使用的数据id和对应的组件
-	 */
-	private HashMap<String, Object> equipMap = new HashMap<>();
-
-	/**
-	 * 记录已经使用的关系id和对应的连线
-	 */
-	private HashMap<String, Line> lineMap = new HashMap<>();
-
-	public DiagramBuilder(Diagram diagram, DataStrategy dataStrategy) {
-		this.diagram = diagram;
-		this.template = diagram.getTemplate();
+	public DiagramBuilder(CalcContext context, DataStrategy dataStrategy) {
+		this.context = context;
+		this.diagram = context.getDiagram();
+		this.template = context.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 != null && template.getMainPipes() != null) {
-			template.getMainPipes().forEach(mainPipe -> {
-				if(StrUtil.isNotBlank(mainPipe.getDataObjectId())) {
-					equipMap.put(mainPipe.getDataObjectId(), mainPipe);
-				}
-			});
-		}
-
-		diagram.getLines().forEach(line -> {
-			if (StrUtil.isNotBlank(line.getDataObjectId())){
-				lineMap.put(line.getDataObjectId(), line);
-			}
-		});
+		this.context.setDataStrategy(dataStrategy);
 	}
 
 	//加载设备数据,并进行计算处理
 	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(context.getEquipMap().size() > 0) {
+			optionalObjs = optionalObjs.stream().filter(obj -> !context.getEquipMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
+		} else {
+			optionalObjs = new ArrayList<>(optionalObjs);
 		}
+
 		if(template.getMainPipes() != null) {
 			for(MainPipe mainPipe : template.getMainPipes()) {
 				if (mainPipe.isBindEquipment() && mainPipe.getDataObject() == null){
@@ -109,7 +71,7 @@ public class DiagramBuilder {
 							mainPipe.setDataObject(obj);
 							mainPipe.setDataObjectId(obj.get("id").asText());
 
-							equipMap.put(mainPipe.getDataObjectId(), mainPipe);
+							context.getEquipMap().put(mainPipe.getDataObjectId(), mainPipe);
 
 							iter.remove();
 							break;
@@ -118,6 +80,23 @@ public class DiagramBuilder {
 				}
 			}
 		}
+		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();
+					}
+				}
+			}
+		}
 
 		handleNodes();
 
@@ -140,8 +119,6 @@ public class DiagramBuilder {
 		Legend legend = findLegend(node.getObjClassCode(), obj);
 		node.setLegendId(legend.getId());
 		node.setLegend(legend);
-
-		equipMap.put(node.getObjId(), node);
 	}
 
 	private void initNode(EquipmentNode node, String name, Container con){
@@ -154,6 +131,7 @@ public class DiagramBuilder {
 		node.setLabel(label);
 
 		diagram.getNodes().add(node);
+		context.getEquipMap().put(node.getObjId(), node);
 	}
 
 	private void addPackData(Container con, ObjectNode obj){
@@ -171,9 +149,6 @@ public class DiagramBuilder {
 			} else {
 				pn = (PackNode) con.getChildren().get(0);
 			}
-			if(con.getEquipPack().getLegendId() != null) {
-				legend = dataStrategy.getLegend(con.getEquipPack().getLegendId(), classCode.substring(0, 4));
-			}
 		} else { //group
 			for(IComponent comp : con.getChildren()) {
 				PackNode item = (PackNode) comp;
@@ -217,7 +192,7 @@ public class DiagramBuilder {
 		if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
 			DataFilter filter = equipHolder.getDataFilter();
 			if(filter != null) {
-				return filter.filter(obj);
+				return filter.filter(obj, context);
 			}
 			return true;
 		}
@@ -282,7 +257,7 @@ public class DiagramBuilder {
 				//过滤条件匹配
 				boolean filterMatch;
 				if(obj != null && legend.getDataFilter() != null) {
-					filterMatch = legend.getDataFilter().filter(obj);
+					filterMatch = legend.getDataFilter().filter(obj, context);
 				} else {
 					filterMatch = true;
 				}
@@ -313,9 +288,14 @@ public class DiagramBuilder {
 	}
 	
 	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) {
-			Object fromObj = equipMap.get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
-			Object toObj = equipMap.get(rel.get(ObjectRelation.OBJ_TO_HUM).asText());
+			Object fromObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
+			Object 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();
@@ -366,7 +346,7 @@ public class DiagramBuilder {
 							equipMatch = a.getToEquipmentTypes().contains(theOtherType);
 						}
 						if(!Boolean.FALSE.equals(equipMatch) && a.getToDataFilter() != null) {
-							equipMatch = a.getToDataFilter().filter(theOtherData);
+							equipMatch = a.getToDataFilter().filter(theOtherData, context);
 						}
 					}
 
@@ -429,14 +409,6 @@ public class DiagramBuilder {
 		}
 	}
 
-	public HashMap<String, Object> getEquipMap() {
-		return equipMap;
-	}
-
-	public HashMap<String, Line> getLineMap() {
-		return lineMap;
-	}
-
 	public HashSet<String> getRefRelTypes() {
 		return refRelTypes;
 	}

+ 18 - 23
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramDataLoader.java

@@ -1,11 +1,13 @@
 package com.persagy.adm.diagram.core;
 
+import cn.hutool.core.collection.CollUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.adm.diagram.core.model.Diagram;
 import com.persagy.adm.diagram.core.model.DiagramNode;
 import com.persagy.adm.diagram.core.model.EquipmentNode;
 import com.persagy.adm.diagram.core.model.Line;
 import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.logic.CalcContext;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.digital.entity.ObjectRelation;
@@ -26,10 +28,6 @@ public class DiagramDataLoader {
 
 	private DataStrategy dataStrategy;
 
-	private List<ObjectNode> optionalObjs;
-
-	private List<ObjectNode> optionalRels;
-
 	public DiagramDataLoader(Diagram diagram, DataStrategy dataStrategy) {
 		this.diagram = diagram;
 		this.dataStrategy = dataStrategy;
@@ -110,7 +108,10 @@ public class DiagramDataLoader {
 	/**
 	 * 搜索数据并自动加载
 	 */
-	public void autoLoad(DiagramBuilder builder) {
+	public void autoLoad(CalcContext context) {
+		List<ObjectNode> optionalObjs = null;
+		List<ObjectNode> optionalRels = null;
+
 		//查询备选数据
 		HashSet<String> equipTypes = new HashSet<>();
 		List<Container> containers = diagram.getTemplate().getContainers();
@@ -121,7 +122,7 @@ public class DiagramDataLoader {
 		}
 		if(diagram.getTemplate().getMainPipes() != null) {
 			for(MainPipe mainPipe : diagram.getTemplate().getMainPipes()) {
-				if(mainPipe.getEquipmentTypes() != null) { //TODO 过滤已经初始化加载数据的干管
+				if(mainPipe.getEquipmentTypes() != null) {
 					equipTypes.addAll(mainPipe.getEquipmentTypes());
 				}
 			}
@@ -131,41 +132,35 @@ public class DiagramDataLoader {
 		if(equipTypes.size() > 0) {
 			optionalObjs = dataStrategy.loadObjectsByType(new ArrayList<>(equipTypes), diagram.getProjectId(), diagram.getSystemId(), diagram.getGroupCode());
 			optionalObjs = filterValid(optionalObjs);
-		} else {
-			optionalObjs = new ArrayList<>();
 		}
-		//记录备选对象id列表
-		List<String> objIds = optionalObjs.stream().map(obj -> obj.get("id").asText()).collect(Collectors.toList());
-
-		//去掉已经使用的数据项
-		HashMap<String, Object> equipMap = builder.getEquipMap();
-		if(equipMap.size() > 0) {
-			optionalObjs = optionalObjs.stream().filter(obj -> !equipMap.containsKey(obj.get("id").asText())).collect(Collectors.toList());
+		if(optionalObjs == null){
+			optionalObjs = new ArrayList<>();
 		}
 
+		DiagramBuilder builder = new DiagramBuilder(context, dataStrategy);
 		builder.buildEquipNodeAndContainer(containers, optionalObjs);
 		List<String[]> relTypes = builder.getRefRelTypes().stream().map(type -> type.split("/")).collect(Collectors.toList());
 
+		List<String> objIds = optionalObjs.stream().map(obj -> obj.get("id").asText()).collect(Collectors.toList());
 		//TODO 关系查询,需要区分打包设备
 		if(objIds.size() > 0 && relTypes.size() > 0) {
 			optionalRels = dataStrategy.loadRelationsByType(relTypes, objIds, diagram.getProjectId(), diagram.getGroupCode());
 			optionalRels = filterValid(optionalRels);
-		} else {
-			optionalRels = new ArrayList<>();
 		}
-
-		//去掉已经使用的关系项
-		HashMap<String, Line> lineMap = builder.getLineMap();
-		if(lineMap.size() > 0) {
-			optionalRels = optionalRels.stream().filter(obj -> !lineMap.containsKey(obj.get("id").asText())).collect(Collectors.toList());
+		if(optionalRels == null){
+			optionalRels = new ArrayList<>();
 		}
 
 		builder.buildLines(optionalRels);
 	}
 
 	private List<ObjectNode> filterValid(List<ObjectNode> list){
+		if(CollUtil.isEmpty(list))
+			return list;
+
 		return list.stream().filter(obj ->
-				obj.get(ObjectRelation.PROP_VALID) == null || obj.get(ObjectRelation.PROP_VALID).asInt() == ValidEnum.TRUE.getType()).collect(Collectors.toList());
+				obj.get(ObjectRelation.PROP_VALID) == null || obj.get(ObjectRelation.PROP_VALID).asInt() == ValidEnum.TRUE.getType())
+				.collect(Collectors.toList());
 	}
 
 }

+ 0 - 55
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramView.java

@@ -1,55 +0,0 @@
-package com.persagy.adm.diagram.core;
-
-import com.persagy.adm.diagram.core.model.Diagram;
-import com.persagy.adm.diagram.core.model.base.XY;
-import com.persagy.adm.diagram.core.model.template.MainPipe;
-import com.persagy.adm.diagram.core.model.DiagramNode;
-import lombok.Data;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 系统图展现层结构
- * @author zhaoyk
- */
-@Data
-public class DiagramView {
-
-	private String id;
-
-	private String name;
-
-	private String type;
-
-	private String system;
-
-	private String templateId;
-
-	private List<DiagramNode> nodes = new ArrayList<>();
-
-	private List lines = new ArrayList();
-
-	private List<MainPipe> mainPipes = new ArrayList<>();
-
-	private String projectId;
-
-	private String systemId;
-
-	private XY size;
-
-	public DiagramView(Diagram diagram) {
-		this.id = diagram.getId();
-		this.name = diagram.getName();
-		this.type = diagram.getType();
-		this.system = diagram.getSystem();
-		this.templateId = diagram.getTemplateId();
-		this.nodes = diagram.getNodes();
-		this.lines = diagram.getLines();
-		this.mainPipes = diagram.getTemplate().getMainPipes();
-		this.projectId = diagram.getProjectId();
-		this.systemId = diagram.getSystemId();
-		this.size = diagram.getTemplate().getFrame().getSize();
-	}
-
-}

+ 7 - 7
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/LineLayoutManager.java

@@ -1,11 +1,11 @@
 package com.persagy.adm.diagram.core.line;
 
-import com.persagy.adm.diagram.core.DiagramBuilder;
 import com.persagy.adm.diagram.core.model.ConnectPoint;
 import com.persagy.adm.diagram.core.model.DiagramNode;
 import com.persagy.adm.diagram.core.model.EquipmentNode;
 import com.persagy.adm.diagram.core.model.Line;
 import com.persagy.adm.diagram.core.model.base.XY;
+import com.persagy.adm.diagram.core.model.logic.CalcContext;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 import com.persagy.adm.diagram.core.util.GeomUtil;
 import org.locationtech.jts.geom.Point;
@@ -21,19 +21,19 @@ import java.util.Map;
  */
 public class LineLayoutManager {
 
-	private DiagramBuilder diagramBuilder;
+	private CalcContext context;
 
 	private List<Block> blocks = new ArrayList<>();
 
 	private Map<Line, ConnectPoint[]> lines = new HashMap<>();
 
-	public LineLayoutManager(DiagramBuilder diagramBuilder) {
-		this.diagramBuilder = diagramBuilder;
+	public LineLayoutManager(CalcContext context) {
+		this.context = context;
 		initBlocks();
 	}
 
 	private void initBlocks(){
-		for(Object o : diagramBuilder.getEquipMap().values()){
+		for(Object o : context.getEquipMap().values()){
 			if (o instanceof DiagramNode) {
 				blocks.add(new Block((DiagramNode)o));
 			}
@@ -172,8 +172,8 @@ public class LineLayoutManager {
 		return blocks;
 	}
 
-	public DiagramBuilder getDiagramBuilder() {
-		return diagramBuilder;
+	public CalcContext getContext() {
+		return context;
 	}
 
 }

+ 6 - 3
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/Diagram.java

@@ -2,10 +2,10 @@ package com.persagy.adm.diagram.core.model;
 
 import cn.hutool.core.util.StrUtil;
 import com.google.gson.annotations.Expose;
-import com.persagy.adm.diagram.core.DiagramBuilder;
 import com.persagy.adm.diagram.core.line.LineLayoutManager;
 import com.persagy.adm.diagram.core.model.base.Container;
 import com.persagy.adm.diagram.core.model.base.XY;
+import com.persagy.adm.diagram.core.model.logic.CalcContext;
 import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 
@@ -90,6 +90,7 @@ public class Diagram {
 	@Expose(serialize = false)
 	private DiagramTemplate template;
 
+	private XY size;
 
 	public void init(){
 		if (template != null) {
@@ -110,15 +111,17 @@ public class Diagram {
 		}
 	}
 
-	public void layout(DiagramBuilder builder){
+	public void layout(CalcContext context){
 		if(template != null) {
 			template.layout(new XY(0, 0));
 		}
 
-		LineLayoutManager lineLayoutManager = new LineLayoutManager(builder);
+		LineLayoutManager lineLayoutManager = new LineLayoutManager(context);
 		for(Line line : lines) {
 			line.layout(lineLayoutManager);
 		}
+
+		this.size = template.getFrame().getSize();
 	}
 
 	public void toAbsoluteLocation(){

+ 21 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/Container.java

@@ -1,11 +1,13 @@
 package com.persagy.adm.diagram.core.model.base;
 
 import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.gson.annotations.Expose;
 import com.persagy.adm.diagram.core.model.Label;
 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.EquipPack;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -59,6 +61,12 @@ public class Container extends AbstractComponent implements IContainer {
 	 */
 	private Label groupLabel;
 
+	/**
+	 * 直接包含的干管
+	 */
+	@JsonIgnore
+	private List<MainPipe> childMainPipes;
+
 	public Container() {
 		this.compType = TYPE;
 	}
@@ -271,6 +279,19 @@ public class Container extends AbstractComponent implements IContainer {
 		return null;
 	}
 
+	public void addChildMainPipe(MainPipe mainPipe) {
+		if(childMainPipes == null) {
+			childMainPipes = new ArrayList<>();
+		}
+		childMainPipes.add(mainPipe);
+	}
+
+	public void removeChildMainPipe(MainPipe mainPipe) {
+		if(childMainPipes != null) {
+			childMainPipes.remove(mainPipe);
+		}
+	}
+
 	@Override
 	public PositionData defaultPosition() {
 		PositionData data = new PositionData();

+ 5 - 5
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/legend/Anchor.java

@@ -157,7 +157,7 @@ public class Anchor {
 		char c1 = code.charAt(0);
 		char c2 = code.charAt(1);
 		int idx = (int)c2 - 48;
-		int part = 6;
+		float part = 6;
 		switch (c1){
 			case 'T':
 				if(c2 == 'L') {
@@ -166,7 +166,7 @@ public class Anchor {
 				if(c2 == 'R') {
 					return new XY(legendLocation.x + legendSize.x, legendLocation.y);
 				}
-				return new XY(legendLocation.x + legendSize.x / part * idx, legendLocation.y);
+				return new XY(legendLocation.x + Math.round(legendSize.x / part * idx), legendLocation.y);
 			case 'B':
 				if(c2 == 'L') {
 					return new XY(legendLocation.x, legendLocation.y + legendSize.y);
@@ -174,11 +174,11 @@ public class Anchor {
 				if(c2 == 'R') {
 					return new XY(legendLocation.x + legendSize.x, legendLocation.y + legendSize.y);
 				}
-				return new XY(legendLocation.x + legendSize.x / part * idx, legendLocation.y + legendSize.y);
+				return new XY(legendLocation.x + Math.round(legendSize.x / part * idx), legendLocation.y + legendSize.y);
 			case 'L':
-				return new XY(legendLocation.x, legendLocation.y + legendSize.y / part * idx);
+				return new XY(legendLocation.x, legendLocation.y + Math.round(legendSize.y / part * idx));
 			case 'R':
-				return new XY(legendLocation.x + legendSize.x, legendLocation.y + legendSize.y / part * idx);
+				return new XY(legendLocation.x + legendSize.x, legendLocation.y + Math.round(legendSize.y / part * idx));
 			default:
 				return null;
 		}

+ 2 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/AndFilter.java

@@ -11,9 +11,9 @@ public class AndFilter extends LogicFilter {
 	}
 
 	@Override
-	protected boolean judge(Object data) {
+	protected boolean judge(Object data, CalcContext context) {
 		for(DataFilter item : items) {
-			if(!item.filter(data)) {
+			if(!item.filter(data, context)) {
 				return false;
 			}
 		}

+ 115 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/CalcContext.java

@@ -0,0 +1,115 @@
+package com.persagy.adm.diagram.core.model.logic;
+
+import cn.hutool.core.util.StrUtil;
+import com.persagy.adm.diagram.core.DataStrategy;
+import com.persagy.adm.diagram.core.model.Diagram;
+import com.persagy.adm.diagram.core.model.EquipmentNode;
+import com.persagy.adm.diagram.core.model.Line;
+import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
+
+import java.util.HashMap;
+
+/**
+ * 系统图计算上下文
+ * @author zhaoyk
+ */
+public class CalcContext {
+
+	private Diagram diagram;
+
+	private DiagramTemplate template;
+
+	private DataStrategy dataStrategy;
+
+	/**
+	 * 当前动态组
+	 */
+	private Object currentGroup;
+
+	/**
+	 * 记录已经使用的数据id和对应的组件
+	 */
+	private HashMap<String, Object> equipMap = new HashMap<>();
+
+	/**
+	 * 记录已经使用的关系id和对应的连线
+	 */
+	private HashMap<String, Line> lineMap = new HashMap<>();
+
+	public CalcContext(Diagram diagram) {
+		this.diagram = diagram;
+		this.template = diagram.getTemplate();
+
+		init();
+	}
+
+	private void init() {
+		//记录节点中已使用的数据id
+		diagram.getNodes().forEach(node -> {
+			if (EquipmentNode.TYPE.equals(node.getCompType())) {
+				equipMap.put(((EquipmentNode) node).getObjId(), node);
+			}
+		});
+		//记录干管中已使用的数据id
+		if(template != null && template.getMainPipes() != null) {
+			template.getMainPipes().forEach(mainPipe -> {
+				if(StrUtil.isNotBlank(mainPipe.getDataObjectId())) {
+					equipMap.put(mainPipe.getDataObjectId(), mainPipe);
+				}
+			});
+		}
+
+		diagram.getLines().forEach(line -> {
+			if (StrUtil.isNotBlank(line.getDataObjectId())){
+				lineMap.put(line.getDataObjectId(), line);
+			}
+		});
+	}
+
+	public <T> T getComp(String id, String type) {
+		//TODO 按动态组获取
+		if(MainPipe.TYPE.equals(type)) {
+			return (T)template.getMainPipeById(id);
+		} else if(Container.TYPE.equals(type)) {
+			return (T)template.getContainerById(id);
+		} else {
+			//TODO 其他类型
+		}
+		return null;
+	}
+
+	public DataStrategy getDataStrategy() {
+		return dataStrategy;
+	}
+
+	public void setDataStrategy(DataStrategy dataStrategy) {
+		this.dataStrategy = dataStrategy;
+	}
+
+	public Diagram getDiagram() {
+		return diagram;
+	}
+
+	public DiagramTemplate getTemplate() {
+		return template;
+	}
+
+	public HashMap<String, Object> getEquipMap() {
+		return equipMap;
+	}
+
+	public HashMap<String, Line> getLineMap() {
+		return lineMap;
+	}
+
+	public String getProjectId() {
+		return diagram.getProjectId();
+	}
+
+	public String getGroupCode() {
+		return diagram.getGroupCode();
+	}
+
+}

+ 5 - 3
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DataFilter.java

@@ -14,6 +14,8 @@ abstract public class DataFilter {
 
 	public static final int TYPE_OR = 3;
 
+	public static final int TYPE_RELATION = 9;
+
 	/**
 	 * 过滤器类型
 	 */
@@ -45,14 +47,14 @@ abstract public class DataFilter {
 	/**
 	 * 过滤操作,返回true时通过
 	 */
-	public boolean filter(Object data) {
-		boolean rtn = judge(data);
+	public boolean filter(Object data, CalcContext context) {
+		boolean rtn = judge(data, context);
 		return not ? !rtn : rtn;
 	}
 
 	/**
 	 * 子类实现具体的判断逻辑
 	 */
-	abstract protected boolean judge(Object data);
+	abstract protected boolean judge(Object data, CalcContext context);
 
 }

+ 1 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/MatchFilter.java

@@ -37,7 +37,7 @@ public class MatchFilter extends DataFilter {
 	}
 
 	@Override
-	protected boolean judge(Object data) {
+	protected boolean judge(Object data, CalcContext context) {
 		Object param = null;
 		if (data instanceof ObjectNode) {
 			if(object.equals(MatchFilter.OBJ_NAME)) {

+ 2 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/OrFilter.java

@@ -11,9 +11,9 @@ public class OrFilter extends LogicFilter {
 	}
 
 	@Override
-	protected boolean judge(Object data) {
+	protected boolean judge(Object data, CalcContext context) {
 		for(DataFilter item : items) {
-			if(!item.filter(data)) {
+			if(!item.filter(data, context)) {
 				return true;
 			}
 		}

+ 126 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/RelationFilter.java

@@ -0,0 +1,126 @@
+package com.persagy.adm.diagram.core.model.logic;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.gson.annotations.Expose;
+import com.persagy.adm.diagram.core.model.EquipmentNode;
+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.template.MainPipe;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 关系过滤器
+ * @author zhaoyk
+ */
+public class RelationFilter extends DataFilter {
+
+	@Expose
+	private String relObjType; //关联对象类型
+
+	@Expose
+	private String relObjId; //关联对象id
+
+	@Expose
+	private List<String> relTypes; //关联关系类型,格式: graphCode/relCode
+
+	/**
+	 * 关系列表,运行时
+	 */
+	@JsonIgnore
+	private List<ObjectNode> relations;
+
+	public RelationFilter(){
+		this.type = TYPE_RELATION;
+	}
+
+	@Override
+	protected boolean judge(Object data, CalcContext context) {
+		if(relations == null) {
+			initRelations(context);
+		}
+
+		String paramDataId = getDataId(data);
+		if(paramDataId != null) {
+			for(ObjectNode rel : relations) {
+				if(paramDataId.equals(rel.get(ObjectRelation.OBJ_FROM_HUM).asText()) || paramDataId.equals(rel.get(ObjectRelation.OBJ_TO_HUM).asText())){
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private void initRelations(CalcContext context) {
+		List<String> dataIds = new ArrayList<>();
+		Object o = context.getComp(relObjId, relObjType);
+		if(o instanceof MainPipe) {
+			String dataId = getDataId(((MainPipe) o).getDataObject());
+			if(dataId != null) {
+				dataIds.add(dataId);
+			}
+		} else if(o instanceof Container) {
+			Container con = (Container) o;
+			if(con.isEquipmentBox()) {
+				for(IComponent comp : con.getChildren()) {
+					if(comp instanceof EquipmentNode) {
+						String dataId = getDataId(((EquipmentNode) comp).getDataObject());
+						if(dataId != null) {
+							dataIds.add(dataId);
+						}
+					}
+				}
+			}
+		}
+
+		if(dataIds.size() > 0) {
+			List<String[]> types;
+			if (relTypes != null) {
+				types = relTypes.stream().map(type -> type.split("/")).collect(Collectors.toList());
+			} else {
+				types = new ArrayList<>();
+			}
+			relations = context.getDataStrategy().loadRelationsByType(types, dataIds, context.getProjectId(), context.getGroupCode());
+		}
+
+		if(relations == null){
+			relations = new ArrayList<>();
+		}
+	}
+
+	private String getDataId(Object obj){
+		if(obj instanceof ObjectNode){
+			return ((ObjectNode) obj).get("id").asText();
+		}
+		return null;
+	}
+
+	public String getRelObjType() {
+		return relObjType;
+	}
+
+	public void setRelObjType(String relObjType) {
+		this.relObjType = relObjType;
+	}
+
+	public String getRelObjId() {
+		return relObjId;
+	}
+
+	public void setRelObjId(String relObjId) {
+		this.relObjId = relObjId;
+	}
+
+	public List<String> getRelTypes() {
+		return relTypes;
+	}
+
+	public void setRelTypes(List<String> relTypes) {
+		this.relTypes = relTypes;
+	}
+
+}

+ 2 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/ContainerRefPoint.java

@@ -56,12 +56,12 @@ public class ContainerRefPoint {
 		addPoint(container.getId(), BR, new XY(conLocation.x + size.x, conLocation.y + size.y), points);
 		addPoint(container.getId(), BL, new XY(conLocation.x, conLocation.y + size.y), points);
 
-		int len = size.x / 4;
+		int len = Math.round(size.x / 4f);
 		for (int i = 1; i <= 3; i++) {
 			addPoint(container.getId(), "T" + i, new XY(conLocation.x + len * i, conLocation.y), points);
 			addPoint(container.getId(), "B" + i, new XY(conLocation.x + len * i, conLocation.y + size.y), points);
 		}
-		len = size.y / 4;
+		len = Math.round(size.y / 4f);
 		for (int i = 1; i <= 3; i++) {
 			addPoint(container.getId(), "L" + i, new XY(conLocation.x, conLocation.y + len * i), points);
 			addPoint(container.getId(), "R" + i, new XY(conLocation.x + size.x, conLocation.y + len * i), points);

+ 6 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/DiagramTemplate.java

@@ -133,6 +133,12 @@ public class DiagramTemplate {
 	public void init() {
 		frame.initParent();
 		initScattered(frame);
+
+		if(mainPipes != null) {
+			for (MainPipe mainPipe : mainPipes) {
+				mainPipe.init(this);
+			}
+		}
 	}
 
 	private void initScattered(Container con){

+ 166 - 32
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/MainPipe.java

@@ -1,8 +1,11 @@
 package com.persagy.adm.diagram.core.model.template;
 
+import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.gson.annotations.Expose;
-import com.persagy.adm.diagram.core.model.base.Container;
 import com.persagy.adm.diagram.core.model.AbstractLine;
+import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.base.IContainer;
 import com.persagy.adm.diagram.core.model.base.IEquipHolder;
 import com.persagy.adm.diagram.core.model.base.XY;
 import com.persagy.adm.diagram.core.model.logic.DataFilter;
@@ -43,17 +46,162 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 	private DataFilter dataFilter;
 
 	@Expose
-	private List<List<MainPipePoint>> path = new ArrayList<>();
+	private List<List<MainPipePoint>> path;
+
+	/**
+	 * 关联的容器id
+	 */
+	@Expose
+	private List<String> relatedContainers;
 
 	/**
 	 * 连线的坐标点序列,多条线
 	 */
 	private List<List<XY>> locationPath;
 
+	/**
+	 * 关联的容器对象,运行时
+	 */
+	@JsonIgnore
+	private List<Container> relatedContainerList;
+
+	@JsonIgnore
+	private Container parentContainer;
+
 	public MainPipe() {
 		this.compType = TYPE;
 	}
 
+	public void init(DiagramTemplate template) {
+		if(CollUtil.isNotEmpty(relatedContainers)) {
+			relatedContainerList = new ArrayList<>(relatedContainers.size());
+			for(String conId : relatedContainers) {
+				Container con = template.getContainerById(conId);
+				if(con != null)
+					relatedContainerList.add(con);
+			}
+
+			calcParentContainer();
+		}
+	}
+
+	private void calcParentContainer(){
+		IContainer p = null;
+		for(Container con : relatedContainerList) {
+			if (p == null) {
+				p = con.getParent();
+			} else {
+				p = getCommonParent(p, con.getParent());
+				if(p == null){
+					break;
+				}
+			}
+		}
+		if(p instanceof Container && !DiagramTemplate.FRAME_ID.equals(p.getId())) {
+			parentContainer = (Container) p;
+			parentContainer.addChildMainPipe(this);
+		}
+	}
+
+	private IContainer getCommonParent(IContainer p1, IContainer p2){
+		IContainer cp = p1;
+		while (true){
+			IContainer tmp = p2;
+			while (true) {
+				if(cp == tmp){
+					return cp;
+				}
+				tmp = tmp.getParent();
+				if(tmp == null){
+					break;
+				}
+			}
+			cp = cp.getParent();
+			if(cp == null){
+				break;
+			}
+		}
+		return null;
+	}
+
+	public void resetRelatedCons() {
+		if(parentContainer != null) {
+			parentContainer.removeChildMainPipe(this);
+		}
+		parentContainer = null;
+		relatedContainerList = null;
+	}
+
+	public void parseLines(List<List<XY>> lines, DiagramTemplate template) {
+		List<Container> refContainers = relatedContainerList;
+		if(CollUtil.isEmpty(refContainers)) {
+			refContainers = template.getContainers();
+		}
+		List<ContainerRefPoint> allRefPoints = new ArrayList<>();
+		for(Container con : refContainers) {
+			if (!DiagramTemplate.FRAME_ID.equals(con.getId()) && !con.isAbsolutePosition()) {
+				allRefPoints.addAll(ContainerRefPoint.getRefPoints(con, con.locationToRoot()));
+			}
+		}
+
+		path = new ArrayList<>();
+		for (List<XY> line : lines) {
+			List<MainPipePoint> ps = new ArrayList<>();
+			path.add(ps);
+
+			for (XY point : line) {
+				double min = Double.MAX_VALUE;
+				ContainerRefPoint targetRp = null;
+				for (ContainerRefPoint rp : allRefPoints) {
+					double d = distance(point, rp.getLocation());
+					if (d < min) {
+						min = d;
+						targetRp = rp;
+					}
+				}
+				MainPipePoint mp = new MainPipePoint();
+				mp.setContainerId(targetRp.getContainerId());
+				mp.setRefPointName(targetRp.getName());
+				mp.setOffset(new XY(point.x - targetRp.getLocation().x, point.y - targetRp.getLocation().y));
+				ps.add(mp);
+			}
+		}
+	}
+
+	private double distance(XY p1, XY p2) {
+		return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+	}
+
+	@Override
+	public void layout(Object layoutContext) {
+		DiagramTemplate template = (DiagramTemplate)layoutContext;
+		locationPath = new ArrayList<>(path.size());
+		for (List<MainPipePoint> line : path) {
+			ArrayList<XY> list = new ArrayList<>();
+			locationPath.add(list);
+
+			for(MainPipePoint p : line) {
+				Container container = template.getContainerById(p.getContainerId());
+				if(container != null && !container.isAbsolutePosition()) {
+					ContainerRefPoint rp = ContainerRefPoint.getRefPoint(container, p.getRefPointName(), container.locationToRoot());
+					list.add(new XY(rp.getLocation().x + p.getOffset().x , rp.getLocation().y + p.getOffset().y));
+				} else {
+					//参考点丢失,给出指示线
+					if(list.size() > 0) {
+						XY mark = new XY(list.get(list.size() - 1));
+						if(mark.y != -10) {
+							mark.y = -10;
+						} else {
+							mark.x += 50;
+						}
+						list.add(mark);
+					} else
+						list.add(new XY(-10, -10));
+				}
+			}
+		}
+	}
+
 	@Override
 	public String getId() {
 		return id;
@@ -140,6 +288,22 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 		this.path = path;
 	}
 
+	public List<String> getRelatedContainers() {
+		return relatedContainers;
+	}
+
+	public void setRelatedContainers(List<String> relatedContainers) {
+		this.relatedContainers = relatedContainers;
+	}
+
+	public List<Container> getRelatedContainerList() {
+		return relatedContainerList;
+	}
+
+	public Container getParentContainer() {
+		return parentContainer;
+	}
+
 	public List<List<XY>> getLocationPath() {
 		return locationPath;
 	}
@@ -148,34 +312,4 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 		this.locationPath = locationPath;
 	}
 
-	@Override
-	public void layout(Object layoutContext) {
-		DiagramTemplate template = (DiagramTemplate)layoutContext;
-		locationPath = new ArrayList<>(path.size());
-		for (List<MainPipePoint> line : path) {
-			ArrayList<XY> list = new ArrayList<>();
-			locationPath.add(list);
-
-			for(MainPipePoint p : line) {
-				Container container = template.getContainerById(p.getContainerId());
-				if(container != null && !container.isAbsolutePosition()) {
-					ContainerRefPoint rp = ContainerRefPoint.getRefPoint(container, p.getRefPointName(), container.locationToRoot());
-					list.add(new XY(rp.getLocation().x + p.getOffset().x , rp.getLocation().y + p.getOffset().y));
-				} else {
-					//参考点丢失,给出指示线
-					if(list.size() > 0) {
-						XY mark = new XY(list.get(list.size() - 1));
-						if(mark.y != -10) {
-							mark.y = -10;
-						} else {
-							mark.x += 50;
-						}
-						list.add(mark);
-					} else
-						list.add(new XY(-10, -10));
-				}
-			}
-		}
-	}
-
 }

+ 8 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/virtual/PackNode.java

@@ -26,6 +26,14 @@ public class PackNode extends EquipmentNode {
 		this.compType = TYPE;
 	}
 
+	/**
+	 * 重写getObjId方法,返回节点id
+	 */
+	@Override
+	public String getObjId() {
+		return id;
+	}
+
 	public Map<String, Integer> getStatInfo() {
 		return statInfo;
 	}

+ 3 - 4
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/util/GsonUtil.java

@@ -7,10 +7,7 @@ import com.persagy.adm.diagram.core.model.EquipmentNode;
 import com.persagy.adm.diagram.core.model.Label;
 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.logic.AndFilter;
-import com.persagy.adm.diagram.core.model.logic.DataFilter;
-import com.persagy.adm.diagram.core.model.logic.MatchFilter;
-import com.persagy.adm.diagram.core.model.logic.OrFilter;
+import com.persagy.adm.diagram.core.model.logic.*;
 import com.persagy.adm.diagram.core.model.virtual.PackNode;
 import org.springframework.stereotype.Component;
 
@@ -87,6 +84,8 @@ public class GsonUtil {
 				target = AndFilter.class;
 			} else if(fType == OrFilter.TYPE_OR) {
 				target = OrFilter.class;
+			} else if(fType == OrFilter.TYPE_RELATION) {
+				target = RelationFilter.class;
 			} else {
 				//TODO 其他类型
 			}

+ 62 - 15
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/util/MyObjectMapper.java

@@ -5,12 +5,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.persagy.adm.diagram.core.model.Diagram;
+import com.persagy.adm.diagram.core.model.Line;
 import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
  * 自定义ObjectMapper,为jackson定义不同场景下的处理逻辑
+ *
  * @author zhaoyk
  */
 @Component
@@ -18,36 +22,79 @@ public class MyObjectMapper {
 
 	private final ObjectMapper objectMapper;
 
-	private ObjectMapper mapper4Save;
+	private ObjectMapper mapper4Edit;
+
+	private ObjectMapper mapper4View;
 
 	@Autowired
 	public MyObjectMapper(ObjectMapper objectMapper) {
-		this.objectMapper = objectMapper;
-		configCommonMapper();
+		this.objectMapper = getCommonMapper();
 
-		this.mapper4Save = buildMapper4Save();
+		this.mapper4Edit = buildMapper4Edit();
+		this.mapper4View = buildMapper4View();
 	}
 
-	private void configCommonMapper(){
-		//objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
-		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-		objectMapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
-		objectMapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
-		objectMapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
-		objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+	public ObjectMapper mapper4Edit() {
+		return mapper4Edit;
+	}
+
+	public ObjectMapper mapper4View() {
+		return mapper4View;
 	}
 
-	private ObjectMapper buildMapper4Save(){
+	private ObjectMapper getCommonMapper() {
 		ObjectMapper mapper = new ObjectMapper();
-		mapper.addMixIn(DiagramTemplate.class, Template4Save.class);
-		//TODO
+
+		//objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
+		mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
+		mapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
+		mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+
+		return mapper;
+	}
+
+	private ObjectMapper buildMapper4Edit() {
+		ObjectMapper mapper = getCommonMapper();
+		mapper.addMixIn(Diagram.class, Diagram4Edit.class);
+		mapper.addMixIn(DiagramTemplate.class, Template4Edit.class);
+
+		return mapper;
+	}
+
+	private ObjectMapper buildMapper4View() {
+		ObjectMapper mapper = getCommonMapper();
+		mapper.addMixIn(Diagram.class, Diagram4View.class);
+		mapper.addMixIn(DiagramTemplate.class, Template4View.class);
+		mapper.addMixIn(MainPipe.class, MainPipe4View.class);
+		mapper.addMixIn(Line.class, Line4View.class);
+
 		return mapper;
 	}
 
+	@JsonIgnoreProperties({"nodes"})
+	public interface Diagram4Edit {
+	}
+
+	@JsonIgnoreProperties({})
+	public interface Template4Edit {
+	}
 
 	@JsonIgnoreProperties({})
-	public interface Template4Save {
+	public interface Diagram4View {
+	}
+
+	@JsonIgnoreProperties({"diagramType", "id", "frame", "scatteredContainers"})
+	public interface Template4View {
+	}
+
+	@JsonIgnoreProperties({"passbyRels", "connectEquips", "equipmentTypes", "dataFilter", "path", "relatedContainers"})
+	public interface MainPipe4View {
+	}
 
+	@JsonIgnoreProperties({"passingPoints"})
+	public interface Line4View {
 	}
 
 }

+ 2 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/frame/EditRequest.java

@@ -72,6 +72,8 @@ public class EditRequest {
 
 		private List<String> connectEquips;
 
+		private List<String> relatedContainers;
+
 		private Map<String, Object> props;
 
 	}

+ 15 - 25
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DemoDiagramManager.java

@@ -1,13 +1,13 @@
 package com.persagy.adm.diagram.manage;
 
 import cn.hutool.core.util.IdUtil;
-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.DataStrategy;
-import com.persagy.adm.diagram.core.DiagramBuilder;
 import com.persagy.adm.diagram.core.DiagramDataLoader;
 import com.persagy.adm.diagram.core.model.Diagram;
+import com.persagy.adm.diagram.core.model.logic.CalcContext;
+import com.persagy.adm.diagram.core.util.MyObjectMapper;
 import com.persagy.adm.diagram.entity.DiagramType;
 import com.persagy.adm.diagram.frame.BdtpRequest;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -85,7 +85,7 @@ public class DemoDiagramManager {
 		new DiagramDataLoader(diagram, dataStrategy).initLoad();
 
 		if(layout) {
-			diagram.layout(new DiagramBuilder(diagram, dataStrategy));
+			diagram.layout(new CalcContext(diagram));
 		}
 	}
 
@@ -135,7 +135,7 @@ public class DemoDiagramManager {
 	}
 
 	@Autowired
-	private ObjectMapper objectMapper;
+	private MyObjectMapper myObjectMapper;
 	/**
 	 * 加载数据
 	 */
@@ -143,31 +143,21 @@ public class DemoDiagramManager {
 		Diagram diagram = dataStrategy.getDiagram(diagramId);
 		buildDiagram(diagram, false);
 
-		DiagramBuilder builder = new DiagramBuilder(diagram, dataStrategy);
-		new DiagramDataLoader(diagram, dataStrategy).autoLoad(builder);
+		CalcContext context = new CalcContext(diagram);
+		new DiagramDataLoader(diagram, dataStrategy).autoLoad(context);
 
-		diagram.layout(builder);
+		diagram.layout(context);
 
-//		//test 输出数据结构
+		//test 输出数据结构
 //		try {
-//			Diagram d = dataStrategy.getDiagram(diagramId);
-//			buildDiagram(d, false);
-//			loadData(d, autoLoad);
-//			d.layout(new XY(0, 0), true);
-//			if(d.getLines().size() == 0) {
-//				Line line = new Line();
-//				line.setFrom(new ConnectPoint());
-//				line.setTo(new ConnectPoint());
-//				line.setLineStyle(new LineStyle());
-//				Label label = new Label();
-//				label.setStyle(new BaseStyle());
-//				line.setLabel(label);
-//				d.getLines().add(line);
-//			}
-//			DiagramView dv = new DiagramView(d);
+//			System.out.println("----------------------------------------------");
+//			System.out.println("edit json : ");
+//			System.out.println(myObjectMapper.mapper4Edit().writeValueAsString(diagram));
 //
-//			System.out.println("-----------------------------------------------------");
-//			System.out.println(objectMapper.writeValueAsString(dv));
+//			System.out.println("----------------------------------------------");
+//			System.out.println("view json : ");
+//			diagram.toAbsoluteLocation();
+//			System.out.println(myObjectMapper.mapper4View().writeValueAsString(diagram));
 //		}catch (Exception e){
 //			e.printStackTrace();
 //		}

+ 43 - 66
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/TemplateManager.java

@@ -4,25 +4,24 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.IdUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.adm.diagram.core.ContentParser;
+import com.persagy.adm.diagram.core.DataStrategy;
 import com.persagy.adm.diagram.core.model.base.*;
-import com.persagy.adm.diagram.core.model.logic.*;
+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.EquipPack;
+import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
 import com.persagy.adm.diagram.dao.TemplateMapper;
 import com.persagy.adm.diagram.entity.DiagramType;
 import com.persagy.adm.diagram.entity.TemplateEntity;
-import com.persagy.adm.diagram.frame.EditRequest;
-import com.persagy.adm.diagram.core.DataStrategy;
-import com.persagy.adm.diagram.core.model.template.ContainerRefPoint;
-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.frame.BdtpRequest;
+import com.persagy.adm.diagram.frame.EditRequest;
 import com.persagy.adm.diagram.service.BdtpDataService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -244,7 +243,35 @@ public class TemplateManager {
     /**
      * 绘制新的干管
      */
-    public DiagramTemplate addMainPipe(List<List<XY>> lines, String templateId) {
+    public DiagramTemplate drawMainPipe(List<List<XY>> lines, String mainPipeId, String templateId) {
+        lines = fixMainPipePath(lines);
+
+        DiagramTemplate template = dataStrategy.getTemplate(templateId);
+        buildTemplate(template);
+
+        MainPipe mainPipe = null;
+        if(mainPipeId != null){
+            mainPipe = template.getMainPipeById(mainPipeId);
+        }
+        if (mainPipe == null) {
+            mainPipe = new MainPipe();
+            mainPipe.setId(IdUtil.simpleUUID());
+
+            if (template.getMainPipes() == null) {
+                template.setMainPipes(new ArrayList<>());
+            }
+            template.getMainPipes().add(mainPipe);
+        }
+
+        mainPipe.parseLines(lines, template);
+
+        return saveTemplate(template);
+    }
+
+    /**
+     * 对前端传入的路径进行修正处理
+     */
+    private List<List<XY>> fixMainPipePath(List<List<XY>> lines){
         //合并同一条线上的多个点
         List<List<XY>> fixed = new ArrayList<>();
         for (List<XY> line : lines) {
@@ -271,63 +298,7 @@ public class TemplateManager {
                 fixedLine.add(point);
             }
         }
-
-        DiagramTemplate template = dataStrategy.getTemplate(templateId);
-        buildTemplate(template);
-
-        List<ContainerRefPoint> allRefPoints = new ArrayList<>();
-
-        LinkedList<Container> cons = new LinkedList<>();
-        cons.add(template.getFrame());
-        while (cons.size() > 0) {
-            Container con = cons.removeFirst();
-            //不使用frame和自由定位容器做定位
-            if (con.getParent() != null && !con.isAbsolutePosition()) {
-                allRefPoints.addAll(ContainerRefPoint.getRefPoints(con, con.locationToRoot()));
-            }
-
-            for (IComponent comp : con.getChildren()) {
-                if (comp instanceof Container) {
-                    cons.add((Container) comp);
-                }
-            }
-        }
-
-        MainPipe mainPipe = new MainPipe();
-        //TODO
-        mainPipe.setId(IdUtil.simpleUUID());
-
-        for (List<XY> line : fixed) {
-            List<MainPipePoint> ps = new ArrayList<>();
-            mainPipe.getPath().add(ps);
-
-            for (XY point : line) {
-                double min = Double.MAX_VALUE;
-                ContainerRefPoint targetRp = null;
-                for (ContainerRefPoint rp : allRefPoints) {
-                    double d = distance(point, rp.getLocation());
-                    if (d < min) {
-                        min = d;
-                        targetRp = rp;
-                    }
-                }
-                MainPipePoint mp = new MainPipePoint();
-                mp.setContainerId(targetRp.getContainerId());
-                mp.setRefPointName(targetRp.getName());
-                mp.setOffset(new XY(point.x - targetRp.getLocation().x, point.y - targetRp.getLocation().y));
-                ps.add(mp);
-            }
-        }
-        if (template.getMainPipes() == null) {
-            template.setMainPipes(new ArrayList<>());
-        }
-        template.getMainPipes().add(mainPipe);
-
-        return saveTemplate(template);
-    }
-
-    private double distance(XY p1, XY p2) {
-        return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+        return fixed;
     }
 
     /**
@@ -353,6 +324,7 @@ public class TemplateManager {
      */
     public DiagramTemplate modifyMainPipe(EditRequest.TemplatePropsData propsData, String mainPipeId, String templateId) {
         DiagramTemplate template = dataStrategy.getTemplate(templateId);
+        buildTemplate(template);
 
         MainPipe mainPipe = template.getMainPipeById(mainPipeId);
         if (mainPipe != null) {
@@ -364,8 +336,13 @@ public class TemplateManager {
             mainPipe.setEquipmentTypes(propsData.getEquipTypes());
             mainPipe.setPassbyRels(propsData.getPassbyRels());
             mainPipe.setConnectEquips(propsData.getConnectEquips());
+            mainPipe.setRelatedContainers(propsData.getRelatedContainers());
         }
 
+        mainPipe.resetRelatedCons();
+        mainPipe.init(template);
+        mainPipe.parseLines(mainPipe.getLocationPath(), template);
+
         return saveTemplate(template);
     }