From 29914be09d4a237840e5c793bdb562ec83093b8d Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Fri, 28 Sep 2018 16:33:33 +0300 Subject: [PATCH] First draft of vertex size adjusting district network diagram profiles * Non-scaling edge/vertex rendering is now limited to view scale range [1,5] which supports seems to work well for current models. * View zooming is now limited to range [0.01, 10000]. * Vertices and edges can be separately hidden with respective profile entries gitlab #2 Change-Id: If8015fc4d65db88abb8c307b14be9139a4450c0d --- .../DistrictNetworkDiagramSettings.pgraph | 91 +- .../graph/DistrictNetworkProfiles.pgraph | 27 +- .../ontology/DistrictNetworkResource.java | 790 ++++++++++++++++++ .../ontology/DistrictNetworkUIResource.java | 64 ++ .../network/ui/DistrictDiagramViewer.java | 4 +- .../network/ui/NetworkDrawingParticipant.java | 1 - .../adapters/DistrictNetworkEdgeElement.java | 104 ++- .../network/ui/function/Functions.java | 111 ++- .../ui/nodes/DistrictNetworkEdgeNode.java | 100 ++- .../ui/nodes/DistrictNetworkVertexNode.java | 84 +- .../META-INF/MANIFEST.MF | 6 +- org.simantics.district.network/adapters.xml | 21 +- .../network/profile/DiagramSettings.java | 48 +- .../profile/DiagramSettingsRequest.java | 58 +- .../network/profile/DistrictNodeGroup.java | 143 ++++ ...EdgeStyle.java => EdgeThicknessStyle.java} | 12 +- .../district/network/profile/HideStyle.java | 38 + .../network/profile/VertexSizeStyle.java | 60 ++ .../district/network/profile/VertexStyle.java | 30 - 19 files changed, 1555 insertions(+), 237 deletions(-) create mode 100644 org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java create mode 100644 org.simantics.district.network.ui.ontology/src/org/simantics/district/network/ui/ontology/DistrictNetworkUIResource.java create mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/DistrictNodeGroup.java rename org.simantics.district.network/src/org/simantics/district/network/profile/{EdgeStyle.java => EdgeThicknessStyle.java} (83%) create mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/HideStyle.java create mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java delete mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/VertexStyle.java diff --git a/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph index f01546e3..10744ea1 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph @@ -17,47 +17,88 @@ DN.EdgeThicknessPropertyParameterType -- DN.Vertex.ScaleProperty.value --> L0.Relation -- DN.Edge.ThicknessProperty.value ==> "Resource -> Maybe Double" -- DN.Edge.ThicknessProperty.gain --> L0.Double -- DN.Vertex.ScaleProperty.scale ==> "Double" -- DN.Edge.ThicknessProperty.bias --> L0.Double -- DN.Edge.ThicknessProperty.scale --> L0.Double -- DN.Vertex.ScaleProperty.value ==> "Resource -> Maybe Double" -- DN.Vertex.ScaleProperty.gain ==> "Double" -- DN.Edge.ThicknessProperty.value --> L0.Relation -- DN.Vertex.ScaleProperty.bias ==> "Double" -- DN.Diagram.nodeScale ==> "Double" -- DN.Diagram.nodeScalingProperty --> DN.Vertex.ScaleProperty -- DN.Diagram.edgeThicknessScale ==> "Double" -- DN.Diagram.edgeThicknessGain ==> "Double" -- DN.Diagram.edgeThicknessBias ==> "Double" -- DN.Diagram.edgeThicknessProperty --> DN.Edge.ThicknessProperty -- DN.Diagram.nodeScaleGain ==> "Double" -- DN.Diagram.nodeScaleBias ==> "Double" -- DN.Diagram.nodeScaleProperty --> DN.Vertex.ScaleProperty Maybe Double" DN.Edge.ThicknessProperty.Diameter : DN.Edge.ThicknessProperty L0.HasLabel "Diameter" - DN.Edge.ThicknessProperty.value DN.Edge.HasDiameter - DN.Edge.ThicknessProperty.scale 0.001 + DN.Edge.ThicknessProperty.value + DN.Functions.hasDiameterValue : L0.Function + L0.HasValueType "Resource -> Maybe Double" + DN.Edge.ThicknessProperty.gain 0.001 + + +DN.Vertex.ScaleProperty.OnlyGainAndBias: DN.Vertex.ScaleProperty + L0.HasLabel "Only Gain and Bias" + DN.Vertex.ScaleProperty.value + DN.Functions.constantOne : L0.Function + L0.HasValueType "Resource -> Maybe Double" -DN.Edge.ThicknessProperty.NominalMassFlow : DN.Edge.ThicknessProperty - L0.HasLabel "Nominal Mass Flow" - DN.Edge.ThicknessProperty.value DN.Edge.HasNominalMassFlow - DN.Edge.ThicknessProperty.scale 1.0 +DN.Vertex.ScaleProperty.NominalSupplyPressure : DN.Vertex.ScaleProperty + L0.HasLabel "Nominal Supply Pressure" + DN.Vertex.ScaleProperty.value + DN.Functions.hasNominalSupplyPressure : L0.Function + L0.HasValueType "Resource -> Maybe Double" + DN.Vertex.ScaleProperty.gain 0.001 +DN.Vertex.ScaleProperty.Elevation : DN.Vertex.ScaleProperty + L0.HasLabel "Elevation" + DN.Vertex.ScaleProperty.value + DN.Functions.hasElevation : L0.Function + L0.HasValueType "Resource -> Maybe Double" + DN.Vertex.ScaleProperty.gain 0.1 + DN.Vertex.ScaleProperty.bias 0.001 diff --git a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph index d00bf422..773ddd30 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph @@ -9,27 +9,16 @@ SEL_UI = G2D = DN = -/* -DN.DistrictProfile : DIA.Profile - L0.HasLabel "District Network Profile" - DIA.Profile.priority 0.0 - DIA.HasEntries - _ : DIA.Profile - @L0.list - DN.DistrictProfile.entry1 - L0.HasLabel "Node Coloring" - @DIA.groupStyleProfileEntry DN.VertexStyle DN.Groups.VertexGroup - DN.DistrictProfile.entry2 - L0.HasLabel "Edge Styling" - @DIA.groupStyleProfileEntry DN.EdgeStyle DN.Groups.EdgeGroup -*/ - DN.Groups : L0.Library +DN.DistrictNodeGroup -- DN.DistrictNodeGroup.hasComponentTypeName ==> "String" () { + public DistrictNetworkResource perform(ReadGraph graph) throws DatabaseException { + QueryControl qc = graph.getService(QueryControl.class); + return new DistrictNetworkResource(qc.getIndependentGraph(graph)); + } + }); + session.registerService(DistrictNetworkResource.class, ret); + } + return ret; + } + +} + diff --git a/org.simantics.district.network.ui.ontology/src/org/simantics/district/network/ui/ontology/DistrictNetworkUIResource.java b/org.simantics.district.network.ui.ontology/src/org/simantics/district/network/ui/ontology/DistrictNetworkUIResource.java new file mode 100644 index 00000000..d6ae2f61 --- /dev/null +++ b/org.simantics.district.network.ui.ontology/src/org/simantics/district/network/ui/ontology/DistrictNetworkUIResource.java @@ -0,0 +1,64 @@ +package org.simantics.district.network.ui.ontology; + +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.ReadGraph; +import org.simantics.db.request.Read; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.QueryControl; + +public class DistrictNetworkUIResource { + + public final Resource NetworkProperties; + public final Resource SelectionTab; + public final Resource SelectionTabContribution; + + public static class URIs { + public static final String NetworkProperties = "http://www.simantics.org/DistrictNetworkUI-1.0/NetworkProperties"; + public static final String SelectionTab = "http://www.simantics.org/DistrictNetworkUI-1.0/SelectionTab"; + public static final String SelectionTabContribution = "http://www.simantics.org/DistrictNetworkUI-1.0/SelectionTabContribution"; + } + + public static Resource getResourceOrNull(ReadGraph graph, String uri) { + try { + return graph.getResource(uri); + } catch(DatabaseException e) { + System.err.println(e.getMessage()); + return null; + } + } + + public DistrictNetworkUIResource(ReadGraph graph) { + NetworkProperties = getResourceOrNull(graph, URIs.NetworkProperties); + SelectionTab = getResourceOrNull(graph, URIs.SelectionTab); + SelectionTabContribution = getResourceOrNull(graph, URIs.SelectionTabContribution); + } + + public static DistrictNetworkUIResource getInstance(ReadGraph graph) { + Session session = graph.getSession(); + DistrictNetworkUIResource ret = session.peekService(DistrictNetworkUIResource.class); + if(ret == null) { + QueryControl qc = graph.getService(QueryControl.class); + ret = new DistrictNetworkUIResource(qc.getIndependentGraph(graph)); + session.registerService(DistrictNetworkUIResource.class, ret); + } + return ret; + } + + public static DistrictNetworkUIResource getInstance(RequestProcessor session) throws DatabaseException { + DistrictNetworkUIResource ret = session.peekService(DistrictNetworkUIResource.class); + if(ret == null) { + ret = session.syncRequest(new Read() { + public DistrictNetworkUIResource perform(ReadGraph graph) throws DatabaseException { + QueryControl qc = graph.getService(QueryControl.class); + return new DistrictNetworkUIResource(qc.getIndependentGraph(graph)); + } + }); + session.registerService(DistrictNetworkUIResource.class, ret); + } + return ret; + } + +} + diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java index 9d07f037..f3e55671 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java @@ -43,8 +43,8 @@ public class DistrictDiagramViewer extends DiagramViewer { public void initializeCanvasContext(CanvasContext ctx) { super.initializeCanvasContext(ctx); IHintContext h = ctx.getDefaultHintContext(); - h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 1000000.0); - h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 0.003); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 10000.0); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 0.01); } @Override diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java index aa11d6bb..b29f1876 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java @@ -16,7 +16,6 @@ import org.simantics.g2d.diagram.handler.PickContext; import org.simantics.g2d.diagram.handler.PickRequest; import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; import org.simantics.g2d.element.IElement; -import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.utils.datastructures.hints.IHintContext.Key; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index db730b1e..cbc6a578 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -1,23 +1,32 @@ package org.simantics.district.network.ui.adapters; import java.awt.Color; +import java.awt.Shape; import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.util.Collection; import java.util.Collections; +import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.DistrictNetworkEdge; import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeNode; import org.simantics.g2d.connection.handler.ConnectionHandler; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; import org.simantics.g2d.diagram.handler.Topology.Connection; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.Outline; +import org.simantics.g2d.element.handler.Pick; import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.SelectionOutline; +import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.element.handler.impl.DefaultTransform; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; @@ -28,7 +37,7 @@ public class DistrictNetworkEdgeElement { public static final Key KEY_DN_EDGE = new KeyOf(DistrictNetworkEdge.class, "DN_EDGE"); public static final Key KEY_DN_EDGE_NODE = new SceneGraphNodeKey(DistrictNetworkEdgeNode.class, "DN_EDGE_NODE"); - + public static final ElementClass CLASS = ElementClass.compile( DefaultTransform.INSTANCE, @@ -36,14 +45,16 @@ public class DistrictNetworkEdgeElement { DNEdgeSceneGraph.INSTANCE, DNEdgeConnectionHandler.INSTANCE, SimpleElementLayers.INSTANCE, + // TODO: do we need this and does it work? + ConnectionSelectionOutline.INSTANCE, DistrictNetworkAdditionalColor.INSTANCE ).setId(DistrictNetworkEdgeElement.class.getSimpleName()); - + static final class DNEdgeSceneGraph implements SceneGraph { - + public static final DNEdgeSceneGraph INSTANCE = new DNEdgeSceneGraph(); - private static final long serialVersionUID = 8894367073815556871L; + private static final long serialVersionUID = 68135568495835923L; @Override public void init(IElement edgeElement, G2DParentNode parent) { @@ -72,13 +83,13 @@ public class DistrictNetworkEdgeElement { edge.removeHint(KEY_DN_EDGE_NODE); } } - - static final class DNEdgeInternalSize implements InternalSize { + + static final class DNEdgeInternalSize implements InternalSize, Outline, Pick { private static final Logger LOGGER = LoggerFactory.getLogger(DNEdgeInternalSize.class); - - private static final long serialVersionUID = -2725017034692179676L; - + + private static final long serialVersionUID = -7346653820911240628L; + public static final DNEdgeInternalSize INSTANCE = new DNEdgeInternalSize(); @Override @@ -87,18 +98,84 @@ public class DistrictNetworkEdgeElement { if (size == null) size = new Rectangle2D.Double(); if (edge != null) - size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge).getBounds2D()); + size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge, null).getBounds2D()); else LOGGER.debug("Element {} does not have edge!", e); return size; } + + @Override + public Shape getElementShape(IElement e) { + DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE); + if (edge != null) { + return DistrictNetworkEdgeNode.calculatePath(edge, null); + } else { + return getBounds(e, null); + } + } + + private Shape getSelectionShape(IElement e) { + for (SelectionOutline so : e.getElementClass().getItemsByClass(SelectionOutline.class)) { + Shape shape = so.getSelectionShape(e); + if (shape != null) + return shape; + } + // Using on-diagram coordinates because neither connections nor + // edges have a non-identity transform which means that + // coordinates are always absolute. Therefore branch point + // shape also needs to be calculated in absolute coordinates. + Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(e); + return shape; + } + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE); + if (edge != null) { + Rectangle2D bounds = getBounds(s); + + switch (policy) { + case PICK_CONTAINED_OBJECTS: + Shape selectionShape = getSelectionShape(e); + return bounds.contains(selectionShape.getBounds2D()); + + case PICK_INTERSECTING_OBJECTS: + double tolerance = (bounds.getHeight() + bounds.getHeight()) * 0.25 / MapScalingTransform.getScaleX(); + Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint()); + double sx = bounds.getCenterX() / MapScalingTransform.getScaleX(); + double sy = bounds.getCenterY() / MapScalingTransform.getScaleY(); + double ssx = ModelledCRS.xToLongitude(sx); + double ssy = ModelledCRS.yToLatitude(-sy); // Invert for Simantics diagram coordinate system + double distSq = line.ptSegDistSq(ssx, ssy); +// System.out.println("s: " + sx + ", " + sy); +// System.out.println("ss: " + ssx + ", " + ssy); +// System.out.println("p1: " + edge.getStartPoint()); +// System.out.println("p2: " + edge.getEndPoint()); +// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")"); +// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance); + if (distSq <= tolerance * tolerance) { + return true; + } + } + return false; + } + + return false; + } + + private Rectangle2D getBounds(Shape shape) { + if (shape instanceof Rectangle2D) + return (Rectangle2D) shape; + return shape.getBounds2D(); + } + } - + static class DNEdgeConnectionHandler implements ConnectionHandler { - private static final long serialVersionUID = -410377314637446238L; - + private static final long serialVersionUID = -6882671891381761687L; + public static final DNEdgeConnectionHandler INSTANCE = new DNEdgeConnectionHandler(); @Override @@ -121,4 +198,5 @@ public class DistrictNetworkEdgeElement { return Collections.emptyList(); } } + } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java index 9748f87c..04cd94cf 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java @@ -41,18 +41,21 @@ import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.QueryIndexUtils; import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; import org.simantics.db.layer0.variable.Variables.Role; import org.simantics.db.procedure.Procedure; -import org.simantics.diagram.stubs.DiagramResource; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; -import org.simantics.modeling.ModelingUtils; import org.simantics.modeling.adapters.NewCompositeActionFactory; import org.simantics.modeling.typicals.TypicalUtil; import org.simantics.operation.Layer0X; import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.function.FunctionImpl1; import org.simantics.ui.workbench.action.DefaultActions; import org.simantics.utils.ui.SWTUtils; import org.slf4j.Logger; @@ -116,7 +119,7 @@ public class Functions { public static Map getNetworkMappingsByType(ReadGraph graph, Resource element, Resource mappingType) throws DatabaseException { Resource indexRoot = graph.sync(new IndexRoot(element)); - List mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType); + List mappings = QueryIndexUtils.searchByType(graph, indexRoot, mappingType); Map result = new HashMap<>(mappings.size()); Layer0 L0 = Layer0.getInstance(graph); mappings.forEach(mapping -> { @@ -135,7 +138,7 @@ public class Functions { private static Object baseMappingModifier(ReadGraph graph, Resource element, Resource property, Resource mappingType, Variable context) throws DatabaseException { Resource indexRoot = graph.sync(new IndexRoot(element)); - List mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType); + List mappings = QueryIndexUtils.searchByType(graph, indexRoot, mappingType); Enumeration enums = Enumeration .make(mappings.stream().map(m -> createEnumeratedValue(graph, m)).collect(Collectors.toList())); @@ -180,8 +183,11 @@ public class Functions { @SCLValue(type = "ReadGraph -> Resource -> a -> b") public static Object convertToValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException { - return graph.getRelatedValue2(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); -// return null; + Layer0 L0 = Layer0.getInstance(graph); + String label = graph.getPossibleRelatedValue2(resource, L0.HasLabel, Bindings.STRING); + if (label == null) + label = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING); + return label; } @@ -213,7 +219,6 @@ public class Functions { private Map edgeMappings = new HashMap<>(); private Map composites = new HashMap<>(); private Map crss = new HashMap<>(); - private Map> components = new HashMap<>(); private Resource defaultVertexMapping; private Resource defaultEdgeMapping; @@ -254,10 +259,7 @@ public class Functions { edgeMappings = getEdgeMappings(graph, configuration); composites = getComposites(graph, configuration); - if (composites.size() > 0) { - components = getComponents(graph, composites.get(0)); - } - + crss = getCRSs(graph, configuration); composite.getDisplay().asyncExec(() -> { @@ -282,16 +284,7 @@ public class Functions { return composite; } - protected Map> getComponents(ReadGraph graph, Resource resource) { - // TODO Auto-generated method stub - return null; - } - protected Map getComposites(ReadGraph graph, Resource element) throws DatabaseException { - - Resource indexRoot = graph.sync(new IndexRoot(element)); - List diagrams = ModelingUtils.searchByType(graph, indexRoot, DiagramResource.getInstance(graph).Diagram); - List nonDistrictComposites = composites.values().stream().filter(comp -> { try { return !graph.isInstanceOf(comp, DistrictNetworkResource.getInstance(graph).Composite); @@ -462,15 +455,32 @@ public class Functions { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); Set results = new HashSet<>(); for (Resource indexRoot : indexRoots) { - Collection diagrams = ModelingUtils.searchByType(graph, indexRoot, DN.Diagram); + Collection diagrams = QueryIndexUtils.searchByType(graph, indexRoot, DN.Diagram); results.addAll(diagrams); } return results; } + private static List listInstanceNames(ReadGraph graph, Variable context, Resource type) throws DatabaseException { + Resource indexRoot = Variables.getIndexRoot(graph, context); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + List properties = QueryIndexUtils.searchByType(graph, indexRoot, DN.Vertex_ScaleProperty); + return properties.stream() + .map(m -> createEnumeratedValue(graph, m)) + .map(EnumeratedValue::getName) + .collect(Collectors.toList()); + } + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") public static Object edgeThicknessPropertyEnumerationValues(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { - return Collections.emptyList(); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return listInstanceNames(graph, context, DN.Edge_ThicknessProperty); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Object nodeScalePropertyEnumerationValues(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return listInstanceNames(graph, context, DN.Vertex_ScaleProperty); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") @@ -480,4 +490,61 @@ public class Functions { return baseMappingModifier(graph, diagram, DN.Diagram_edgeThicknessProperty, DN.Edge_ThicknessProperty, context); } + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Object nodeScalePropertyModifier(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + Resource diagram = resolveElement(graph, context); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return baseMappingModifier(graph, diagram, DN.Diagram_nodeScaleProperty, DN.Vertex_ScaleProperty, context); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Function1 hasDiameterValue(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + return directPropertyValueFunction(DistrictNetworkResource.getInstance(graph).Edge_HasDiameter, 0); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Function1 hasNominalMassFlowValue(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + return directPropertyValueFunction(DistrictNetworkResource.getInstance(graph).Edge_HasNominalMassFlow, 0); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Function1 hasNominalSupplyPressure(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + return directPropertyValueFunction(DistrictNetworkResource.getInstance(graph).Vertex_HasSupplyPressure, 0); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Function1 hasElevation(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + return directPropertyValueFunction(DistrictNetworkResource.getInstance(graph).Vertex_HasElevation, 0); + } + + private static final Function1 ONE = new FunctionImpl1() { + private final Double ONE = 1.0; + @Override + public Double apply(Resource edge) { + return ONE; + } + }; + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Function1 constantOne(ReadGraph graph, Resource resource, Variable context) throws DatabaseException { + return ONE; + } + + private static Function1 directPropertyValueFunction(Resource property, double defaultValue) throws DatabaseException { + Double def = defaultValue; + return new FunctionImpl1() { + @Override + public Double apply(Resource edge) { + ReadGraph graph = (ReadGraph) SCLContext.getCurrent().get("graph"); + try { + Double d = graph.getPossibleRelatedValue(edge, property, Bindings.DOUBLE); + return d != null ? d : def; + } catch (DatabaseException e) { + LOGGER.error("Failed to evaluate property value", e); + return def; + } + } + }; + } + } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java index 92299324..1e577e97 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java @@ -6,26 +6,29 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.DistrictNetworkEdge; +import org.simantics.scenegraph.ISelectionPainterNode; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.NodeUtil; -public class DistrictNetworkEdgeNode extends G2DNode { +public class DistrictNetworkEdgeNode extends G2DNode implements ISelectionPainterNode { private static final long serialVersionUID = 8049769475036519806L; - + private static final Stroke SELECTION_STROKE = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96); - + private DistrictNetworkEdge edge; private Rectangle2D bounds; - - private static final Stroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); + private Line2D path; + + private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); private boolean scaleStroke = true; private Color color; @@ -35,68 +38,81 @@ public class DistrictNetworkEdgeNode extends G2DNode { @Override public void init() { } - + @Override public void render(Graphics2D g2d) { - AffineTransform ot = null; AffineTransform t = getTransform(); if (t != null && !t.isIdentity()) { ot = g2d.getTransform(); g2d.transform(getTransform()); } - + Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Color oldColor = g2d.getColor(); BasicStroke oldStroke = (BasicStroke) g2d.getStroke(); -// boolean selected = isSelected(); -// if (selected) { -// Path2D selectionPath = edge.getPath(); -// Shape selectionShape = SELECTION_STROKE.createStrokedShape(selectionPath); -// g2d.setColor(SELECTION_COLOR); -// g2d.fill(selectionShape); -// } -// + g2d.setColor(color); - if (STROKE != null) { - if (scaleStroke && STROKE instanceof BasicStroke) { - double str; - if (stroke != null) - str = Math.abs(stroke); - else - str = 1.0; - BasicStroke bs = GeometryUtils.scaleStroke(STROKE, (float) (str / GeometryUtils.getScale(g2d.getTransform()))); - g2d.setStroke(bs); - } else { - g2d.setStroke(STROKE); - } + BasicStroke bs = null; + if (scaleStroke) { + double scale = GeometryUtils.getScale(g2d.getTransform()); + scale = Math.max(10000, Math.min(scale, 50000)); + double str = stroke != null ? Math.abs(stroke) : 1.0; + bs = GeometryUtils.scaleStroke(STROKE, (float) (str / scale)); + } else { + bs = STROKE; } - g2d.draw(calculatePath(edge)); - + path = calculateLine(edge, path); + + if (isSelected()) { + g2d.setColor(SELECTION_COLOR); + g2d.setStroke(GeometryUtils.scaleStroke(bs, 4f)); + g2d.draw(path); + } + + g2d.setStroke(bs); + g2d.draw(path); + // Reset g2d.setStroke(oldStroke); g2d.setColor(oldColor); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); - + if (ot != null) g2d.setTransform(ot); } - - public static Path2D calculatePath(DistrictNetworkEdge edge) { + + public static Line2D calculateLine(DistrictNetworkEdge edge, Line2D result) { + // Convert to screen coordinates + double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); + double startY = ModelledCRS.latitudeToY(-edge.getStartPoint().getY()); // Invert for Simantics + double endX = ModelledCRS.longitudeToX(edge.getEndPoint().getX()); + double endY = ModelledCRS.latitudeToY(-edge.getEndPoint().getY());// Invert for Simantics + + if (result == null) + result = new Line2D.Double(); + result.setLine(startX, startY, endX, endY); + return result; + } + + public static Path2D calculatePath(DistrictNetworkEdge edge, Path2D result) { // Convert to screen coordinates double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); double startY = ModelledCRS.latitudeToY(-edge.getStartPoint().getY()); // Invert for Simantics double endX = ModelledCRS.longitudeToX(edge.getEndPoint().getX()); double endY = ModelledCRS.latitudeToY(-edge.getEndPoint().getY());// Invert for Simantics - - // render - Path2D path = new Path2D.Double(); - path.moveTo(startX, startY); - path.lineTo(endX, endY); - return path; + + if (result == null) { + result = new Path2D.Double(); + } else { + result.reset(); + } + result.moveTo(startX, startY); + result.lineTo(endX, endY); + return result; } private boolean isSelected() { @@ -107,7 +123,7 @@ public class DistrictNetworkEdgeNode extends G2DNode { public Rectangle2D getBoundsInLocal() { return bounds; } - + private void updateBounds() { Rectangle2D oldBounds = bounds; if (oldBounds == null) @@ -116,7 +132,7 @@ public class DistrictNetworkEdgeNode extends G2DNode { } private Rectangle2D calculateBounds(Rectangle2D rect) { - return calculatePath(edge).getBounds2D(); + return calculatePath(edge, null).getBounds2D(); } public void setDNEdge(DistrictNetworkEdge edge) { @@ -127,7 +143,7 @@ public class DistrictNetworkEdgeNode extends G2DNode { public void setColor(Color color) { this.color = color; } - + public Color getColor() { return color; } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java index 99eb3cc1..1dd0afe5 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java @@ -1,17 +1,14 @@ package org.simantics.district.network.ui.nodes; -import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; -import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.adapters.DistrictNetworkVertex; -import org.simantics.scenegraph.ParentNode; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.GeometryUtils; import org.slf4j.Logger; @@ -20,7 +17,7 @@ import org.slf4j.LoggerFactory; public class DistrictNetworkVertexNode extends G2DNode { private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkVertexNode.class); - + private static final long serialVersionUID = -2641639101400236719L; private DistrictNetworkVertex vertex; @@ -28,11 +25,10 @@ public class DistrictNetworkVertexNode extends G2DNode { private static final double top = -0.25; private static final double width = 0.5; private static final double height = 0.5; - + private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height); private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 3, top * 3, width * 3, height * 3); - - private Stroke stroke = new BasicStroke(2); + private boolean scaleStroke = true; private boolean hover; @@ -40,46 +36,46 @@ public class DistrictNetworkVertexNode extends G2DNode { private Rectangle2D bounds; - private Double strokee; + private double nodeSize = 1; @Override public void init() { setZIndex(2); } - + @Override public void render(Graphics2D g2d) { + if (nodeSize <= 0.0) + return; + AffineTransform ot = null; AffineTransform t = getTransform(); if (t != null && !t.isIdentity()) { ot = g2d.getTransform(); g2d.transform(getTransform()); } - + + Object oaaHint = null; Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - + if (aaHint != RenderingHints.VALUE_ANTIALIAS_OFF) { + oaaHint = aaHint; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + Color oldColor = g2d.getColor(); - Stroke oldStroke = g2d.getStroke(); - g2d.setColor(color); - + double scaleRecip = 1; if (scaleStroke) { double scale = GeometryUtils.getScale(g2d.getTransform()); - double str; - if (strokee != null) - str = strokee; - else - str = 1.0; - //System.out.println("scale: " + scale); + scale = Math.max(10000, Math.min(scale, 50000)); scaleRecip = 1.0 / scale; } - scaleRecip = 8.0 * scaleRecip; - + scaleRecip = scaleRecip * nodeSize; + // Translate lat and lon to X and Y Point2D res = calculatePoint2D(vertex); - + Rectangle2D toDraw; if (hover) { toDraw = new Rectangle2D.Double(res.getX() - (HOVERED.getWidth() / 2 * scaleRecip), res.getY() - (HOVERED.getHeight() / 2 * scaleRecip), HOVERED.getWidth() * scaleRecip, HOVERED.getHeight() * scaleRecip); @@ -88,13 +84,11 @@ public class DistrictNetworkVertexNode extends G2DNode { } // render g2d.fill(toDraw); - - // Reset stats + + // Reset settings g2d.setColor(oldColor); - g2d.setStroke(oldStroke); - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); - + if (oaaHint != null) + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); if (ot != null) g2d.setTransform(ot); } @@ -103,12 +97,12 @@ public class DistrictNetworkVertexNode extends G2DNode { public Rectangle2D getBounds() { return super.getBounds(); } - + @Override public Rectangle2D getBoundsInLocal() { return bounds; } - + private void updateBounds() { Rectangle2D oldBounds = bounds; if (oldBounds == null) @@ -122,16 +116,16 @@ public class DistrictNetworkVertexNode extends G2DNode { // Update bounds updateBounds(); } - + @Override public AffineTransform getTransform() { return super.getTransform(); } - + private Rectangle2D calculateBounds(Rectangle2D rect) { Point2D calcPoint = calculatePoint2D(vertex); AffineTransform at = getTransform(); - return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), 1 / at.getScaleX(), 1 / at.getScaleY()).getBounds2D(); + return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), width / at.getScaleX(), height / at.getScaleY()).getBounds2D(); } private static Point2D calculatePoint2D(DistrictNetworkVertex vertex) { @@ -148,7 +142,7 @@ public class DistrictNetworkVertexNode extends G2DNode { this.vertex = vertex; updateBounds(); } - + public boolean hover(boolean hover) { // if (hover && LOGGER.isDebugEnabled()) // LOGGER.debug("Hovering " + this); @@ -163,13 +157,23 @@ public class DistrictNetworkVertexNode extends G2DNode { public void setColor(Color color) { this.color = color; } - + public Color getColor() { return color; } - @PropertySetter(value = "stroke") - public void setStroke(Double stroke) { - this.strokee = stroke / 10; + @PropertySetter(value = "size") + public void setSize(Double size) { + boolean changed = false; + if (size != null) { + changed = size != this.nodeSize; + this.nodeSize = size; + } else { + changed = this.nodeSize != 1.0; + this.nodeSize = 1.0; + } + if (changed) + updateBounds(); } + } diff --git a/org.simantics.district.network/META-INF/MANIFEST.MF b/org.simantics.district.network/META-INF/MANIFEST.MF index 2d1fe771..8fb9329f 100644 --- a/org.simantics.district.network/META-INF/MANIFEST.MF +++ b/org.simantics.district.network/META-INF/MANIFEST.MF @@ -13,5 +13,7 @@ Require-Bundle: org.simantics.db, org.simantics.district.maps, org.simantics.district.geotools;bundle-version="1.0.0", org.simantics.diagram, - org.simantics.scenegraph.profile;bundle-version="1.0.0" -Export-Package: org.simantics.district.network + org.simantics.scenegraph.profile;bundle-version="1.0.0", + org.simantics;bundle-version="1.0.0" +Export-Package: org.simantics.district.network, + org.simantics.district.network.profile diff --git a/org.simantics.district.network/adapters.xml b/org.simantics.district.network/adapters.xml index a6463cd7..cd7b4337 100644 --- a/org.simantics.district.network/adapters.xml +++ b/org.simantics.district.network/adapters.xml @@ -9,11 +9,22 @@ - + - + - + + + + + + + + + \ No newline at end of file diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettings.java b/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettings.java index 8136b19c..071489de 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettings.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettings.java @@ -3,22 +3,27 @@ package org.simantics.district.network.profile; import java.util.Optional; import org.simantics.db.Resource; +import org.simantics.scl.runtime.function.Function1; /** * @author Tuukka Lehtonen */ public class DiagramSettings { - public final Optional vertexScalingProperty; - public final double vertexScalingScale; - public final Optional edgeThicknessProperty; - public final double edgeThicknessScale; + public final Optional> vertexScaleProperty; + public final double vertexScaleGain; + public final double vertexScaleBias; + public final Optional> edgeThicknessProperty; + public final double edgeThicknessGain; + public final double edgeThicknessBias; - public DiagramSettings(Resource vertexScalingProperty, double vertexScalingScale, Resource edgeThicknessProperty, double edgeThicknessScale) { - this.vertexScalingProperty = Optional.ofNullable(vertexScalingProperty); - this.vertexScalingScale = vertexScalingScale; + public DiagramSettings(Function1 vertexScaleProperty, double vertexScaleGain, double vertexScaleBias, Function1 edgeThicknessProperty, double edgeThicknessGain, double edgeThicknessBias) { + this.vertexScaleProperty = Optional.ofNullable(vertexScaleProperty); + this.vertexScaleGain = vertexScaleGain; + this.vertexScaleBias = vertexScaleBias; this.edgeThicknessProperty = Optional.ofNullable(edgeThicknessProperty); - this.edgeThicknessScale = edgeThicknessScale; + this.edgeThicknessGain = edgeThicknessGain; + this.edgeThicknessBias = edgeThicknessBias; } @Override @@ -27,10 +32,14 @@ public class DiagramSettings { int result = 1; result = prime * result + edgeThicknessProperty.hashCode(); long temp; - temp = Double.doubleToLongBits(edgeThicknessScale); + temp = Double.doubleToLongBits(edgeThicknessGain); result = prime * result + (int) (temp ^ (temp >>> 32)); -// result = prime * result + vertexScalingProperty.hashCode(); - temp = Double.doubleToLongBits(vertexScalingScale); + temp = Double.doubleToLongBits(edgeThicknessBias); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + vertexScaleProperty.hashCode(); + temp = Double.doubleToLongBits(vertexScaleGain); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(vertexScaleBias); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @@ -46,14 +55,23 @@ public class DiagramSettings { DiagramSettings other = (DiagramSettings) obj; if (!edgeThicknessProperty.equals(other.edgeThicknessProperty)) return false; - if (Double.doubleToLongBits(edgeThicknessScale) != Double.doubleToLongBits(other.edgeThicknessScale)) + if (Double.doubleToLongBits(edgeThicknessGain) != Double.doubleToLongBits(other.edgeThicknessGain)) + return false; + if (Double.doubleToLongBits(edgeThicknessBias) != Double.doubleToLongBits(other.edgeThicknessBias)) + return false; + if (!vertexScaleProperty.equals(other.vertexScaleProperty)) return false; - if (!vertexScalingProperty.equals(other.vertexScalingProperty)) + if (Double.doubleToLongBits(vertexScaleGain) != Double.doubleToLongBits(other.vertexScaleGain)) return false; - if (Double.doubleToLongBits(vertexScalingScale) != Double.doubleToLongBits(other.vertexScalingScale)) + if (Double.doubleToLongBits(vertexScaleBias) != Double.doubleToLongBits(other.vertexScaleBias)) return false; return true; } - + @Override + public String toString() { + return String.format("DiagramSettings[%s * %f + %f - %s * %f + %f]", vertexScaleProperty.toString(), + vertexScaleGain, vertexScaleBias, edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias); + } + } diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettingsRequest.java b/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettingsRequest.java index 726005ee..6fdb9721 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettingsRequest.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/DiagramSettingsRequest.java @@ -5,15 +5,18 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.scl.runtime.function.Function1; /** * @author Tuukka Lehtonen */ public class DiagramSettingsRequest extends ResourceRead { - protected DiagramSettingsRequest(Resource runtimeDiagram) { + public DiagramSettingsRequest(Resource runtimeDiagram) { super(runtimeDiagram); } @@ -22,28 +25,53 @@ public class DiagramSettingsRequest extends ResourceRead { DiagramResource DIA = DiagramResource.getInstance(graph); DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - Resource edgeThicknessProperty = null; - Resource nodeScalingProperty = null; - double edgeThicknessScale = 1; - double nodeScalingScale = 1; + Function1 edgeThicknessProperty = null; + Function1 nodeScaleProperty = null; + double edgeThicknessGain = 1; + double edgeThicknessBias = 0; + double nodeScaleGain = 1; + double nodeScaleBias = 0; Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration); if (diagram != null) { Resource etp = graph.getPossibleObject(diagram, DN.Diagram_edgeThicknessProperty); - edgeThicknessProperty = graph.getPossibleObject(etp, DN.Edge_ThicknessProperty_value); -// Resource nsp = graph.getPossibleObject(diagram, DN.Diagram_nodeScalingProperty); -// nodeScalingProperty = graph.getPossibleObject(nsp, DN.Vertex_ScaleProperty_value); + //System.out.println("etp: " + NameUtils.getURIOrSafeNameInternal(graph, etp)); + if (etp != null) { + Variable etpv = Variables.getPossibleVariable(graph, etp); + if (etpv != null) { + //System.out.println("etpv: " + etpv.getURI(graph)); + edgeThicknessProperty = etpv.getPropertyValue(graph, DN.Edge_ThicknessProperty_value); + } - edgeThicknessScale = - safeDoubleProperty(graph, etp, DN.Edge_ThicknessProperty_scale, 1) - * safeDoubleProperty(graph, diagram, DN.Diagram_edgeThicknessScale, 1); + edgeThicknessGain = + safeDoubleProperty(graph, etp, DN.Edge_ThicknessProperty_gain, 1) + * safeDoubleProperty(graph, diagram, DN.Diagram_edgeThicknessGain, 1); + edgeThicknessBias = + safeDoubleProperty(graph, etp, DN.Edge_ThicknessProperty_bias, 0) + + safeDoubleProperty(graph, diagram, DN.Diagram_edgeThicknessBias, 0); + } + Resource nsp = graph.getPossibleObject(diagram, DN.Diagram_nodeScaleProperty); + if (nsp != null) { + Variable nspv = Variables.getPossibleVariable(graph, nsp); + if (nspv != null) { + //System.out.println("nspv: " + nspv.getURI(graph)); + nodeScaleProperty = nspv.getPropertyValue(graph, DN.Vertex_ScaleProperty_value); + } -// nodeScalingScale = -// safeDoubleProperty(graph, nsp, DN.Vertex_ScaleProperty_scale, 1) -// * safeDoubleProperty(graph, diagram, DN.Diagram_nodeScale, 1); + nodeScaleGain = + safeDoubleProperty(graph, nsp, DN.Vertex_ScaleProperty_gain, 1) + * safeDoubleProperty(graph, diagram, DN.Diagram_nodeScaleGain, 1); + nodeScaleBias = + safeDoubleProperty(graph, nsp, DN.Vertex_ScaleProperty_bias, 0) + + safeDoubleProperty(graph, diagram, DN.Diagram_nodeScaleBias, 0); + } } - return new DiagramSettings(nodeScalingProperty, nodeScalingScale, edgeThicknessProperty, edgeThicknessScale); + DiagramSettings ds = new DiagramSettings( + nodeScaleProperty, nodeScaleGain, nodeScaleBias, + edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias); + //System.out.println("new diagram settings: " + ds); + return ds; } private static double safeDoubleProperty(ReadGraph graph, Resource r, Resource property, double defaultValue) throws DatabaseException { diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/DistrictNodeGroup.java b/org.simantics.district.network/src/org/simantics/district/network/profile/DistrictNodeGroup.java new file mode 100644 index 00000000..fff235ac --- /dev/null +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/DistrictNodeGroup.java @@ -0,0 +1,143 @@ +package org.simantics.district.network.profile; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.OrderedSet; +import org.simantics.db.common.procedure.wrapper.SetListenerToSingleSetListener; +import org.simantics.db.common.request.BinaryRead; +import org.simantics.db.common.request.TernaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.SetListener; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.layer0.Layer0; +import org.simantics.scenegraph.profile.Group; +import org.simantics.utils.strings.StringUtils; + +/** + * @author Tuukka Lehtonen + */ +public class DistrictNodeGroup implements Group { + + private final String name; + private final Collection types; + private final Set mappedComponentTypeNames; + + public DistrictNodeGroup(ReadGraph graph, Resource group) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + this.name = StringUtils.safeString( graph.getPossibleRelatedValue(group, L0.HasName, Bindings.STRING) ); + this.types = graph.getObjects(group, DIA.TypeGroup_HasType); + Collection names = graph.getObjects(group, DN.DistrictNodeGroup_hasComponentTypeName); + this.mappedComponentTypeNames = new HashSet<>(names.size()); + for (Resource name : names) { + mappedComponentTypeNames.add( graph.getValue(name, Bindings.STRING) ); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + name.hashCode(); + result = prime * result + types.hashCode(); + result = prime * result + mappedComponentTypeNames.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DistrictNodeGroup other = (DistrictNodeGroup) obj; + return name.equals(other.name) && types.equals(other.types) && mappedComponentTypeNames.equals(other.mappedComponentTypeNames); + } + + @Override + public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) { + if (types.isEmpty()) { + System.out.println("DistrictNodeGroup has no types!"); + return; + } + processor.asyncRequest(new TernaryRead, Set, Collection>(runtimeDiagram, types, mappedComponentTypeNames) { + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + return graph.syncRequest(new ElementsMappedToComponentTypes(parameter, parameter2, parameter3)); + } + }, new SetListenerToSingleSetListener(listener)); + } + + @Override + public String toString() { + return "every '" + name + "' of mapped type " + mappedComponentTypeNames; + } + + private static class ElementsMappedToComponentTypes extends TernaryRead, Set, Set> { + + public ElementsMappedToComponentTypes(Resource runtimeDiagram, Collection elementTypes, Set componentTypeNames) { + super(runtimeDiagram, elementTypes, componentTypeNames); + } + + @Override + public Set perform(ReadGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Set result = new HashSet<>(); + Set elementsOfType = graph.syncRequest(new ElementsOfType(parameter, parameter2)); + for (Resource e : elementsOfType) { + Resource mapping = graph.getPossibleObject(e, DN.HasMapping); + if (mapping != null) { + String ct = graph.getPossibleRelatedValue(mapping, DN.Mapping_ComponentType, Bindings.STRING); + if (ct != null) { + if (parameter3.contains(ct)) { + //System.out.println("GROUP: added element " + NameUtils.getSafeName(graph, e) + " of type " + ct); + result.add(e); + } + } + } + } + return result; + } + + } + + private static class ElementsOfType extends BinaryRead, Set> { + + public ElementsOfType(Resource runtimeDiagram, Collection types) { + super(runtimeDiagram, types); + } + + @Override + public Set perform(ReadGraph graph) throws DatabaseException { + HashSet result = new HashSet<>(); + + Resource realDiagram = graph.getPossibleObject(parameter, DiagramResource.getInstance(graph).RuntimeDiagram_HasConfiguration); + if (realDiagram == null) + return result; + + Collection elements = graph.syncRequest(new OrderedSet(realDiagram)); + for (Resource element : elements) { + Collection elementTypes = graph.getTypes(element); + if (!Collections.disjoint(parameter2, elementTypes)) { + result.add(element); + } + } + + return result; + } + + } + +} diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java similarity index 83% rename from org.simantics.district.network/src/org/simantics/district/network/profile/EdgeStyle.java rename to org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java index 4ee26ad4..45b55549 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java @@ -1,6 +1,6 @@ package org.simantics.district.network.profile; -import org.simantics.databoard.Bindings; +import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; @@ -12,7 +12,7 @@ import org.simantics.scenegraph.g2d.nodes.ConnectionNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; -public class EdgeStyle extends StyleBase { +public class EdgeThicknessStyle extends StyleBase { private static final Double PENDING = Double.NaN; private static final Double ONE = 1.0; @@ -22,12 +22,12 @@ public class EdgeStyle extends StyleBase { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); Double thickness = ONE; if (ds.edgeThicknessProperty.isPresent()) { - thickness = graph.getPossibleRelatedValue2(groupItem, ds.edgeThicknessProperty.get(), Bindings.DOUBLE); - //System.out.println("read thickness: " + thickness + " : " + ds.edgeThicknessProperty); + thickness = Simantics.applySCLRead(graph, ds.edgeThicknessProperty.get(), groupItem); +// System.out.println("read thickness: " + thickness + " : " + ds.edgeThicknessProperty); if (thickness == null) { thickness = ONE; } else { - thickness = thickness * ds.edgeThicknessScale; + thickness = thickness * ds.edgeThicknessGain + ds.edgeThicknessBias; } } return thickness; @@ -35,7 +35,7 @@ public class EdgeStyle extends StyleBase { @Override public void applyStyleForNode(EvaluationContext observer, INode node, Double value) { - //System.out.println("apply: " + node + " : " + value); +// System.out.println("apply: " + node + " : " + value); ConnectionNode n = (ConnectionNode) node; if (value == PENDING) { ((G2DSceneGraph)node.getRootNode()).setPending(node); diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/HideStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/HideStyle.java new file mode 100644 index 00000000..8e053a06 --- /dev/null +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/HideStyle.java @@ -0,0 +1,38 @@ +package org.simantics.district.network.profile; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.profile.EvaluationContext; + +/** + * @author Tuukka Lehtonen + */ +public class HideStyle extends StyleBase { + + @Override + public Boolean calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + return Boolean.TRUE; + } + + @Override + public void applyStyleForNode(EvaluationContext observer, INode node, Boolean result) { + SingleElementNode n = (SingleElementNode) node; + n.setVisible(false); + } + + @Override + protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) { + SingleElementNode n = (SingleElementNode) node; + n.setVisible(true); + } + + @Override + public String toString() { + return "Hide"; + } + +} diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java new file mode 100644 index 00000000..b33cd1c0 --- /dev/null +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java @@ -0,0 +1,60 @@ +package org.simantics.district.network.profile; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.G2DSceneGraph; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.common.ProfileVariables; + +public class VertexSizeStyle extends StyleBase { + + private static final Double PENDING = Double.NaN; + private static final Double ONE = 1.0; + + @Override + public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); + Double scaling = ONE; + if (ds.vertexScaleProperty.isPresent()) { + scaling = Simantics.applySCLRead(graph, ds.vertexScaleProperty.get(), groupItem); + if (scaling == null) { + scaling = ONE; + } else { +// System.out.println("read vertex scaling: " + scaling + " : " + ds.vertexScaleProperty); + scaling = scaling * ds.vertexScaleGain + ds.vertexScaleBias; +// System.out.println("RESULT: " + scaling); + } + } + return scaling; + } + + @Override + public void applyStyleForNode(EvaluationContext observer, INode node, Double value) { + //System.out.println("apply: " + node + " : " + value); + SingleElementNode n = (SingleElementNode) node; + if (value == PENDING) { + ((G2DSceneGraph)node.getRootNode()).setPending(node); + } else { + ((G2DSceneGraph)node.getRootNode()).clearPending(node); + } + if (value == null) + value = ONE; + for (INode nn : n.getNodes()) + ProfileVariables.claimNodeProperty(nn, "size", value, observer); + } + + @Override + protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) { + ((G2DSceneGraph)node.getRootNode()).clearPending(node); + SingleElementNode n = (SingleElementNode) node; + for (INode nn : n.getNodes()) + ProfileVariables.claimNodeProperty(nn, "size", ONE, evaluationContext); + } + +} diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexStyle.java deleted file mode 100644 index 6fc5dfcc..00000000 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexStyle.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.simantics.district.network.profile; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.profile.StyleBase; -import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.scenegraph.INode; -import org.simantics.scenegraph.g2d.nodes.ConnectionNode; -import org.simantics.scenegraph.profile.EvaluationContext; -import org.simantics.scenegraph.profile.common.ProfileVariables; - -public class VertexStyle extends StyleBase { - - @Override - public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { - return 1.0; - } - - @Override - public void applyStyleForNode(EvaluationContext observer, INode node, Double result) { -// if (result != null) { -// ConnectionNode n = (ConnectionNode) node; -// for (INode nn : n.getNodes()) { -// ProfileVariables.claimNodeProperty(nn, "stroke", result, observer); -// } -// } - } - -} -- 2.45.1