]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.region/src/org/simantics/district/region/DiagramRegions.java
Improved Routes view functionality
[simantics/district.git] / org.simantics.district.region / src / org / simantics / district / region / DiagramRegions.java
1 package org.simantics.district.region;
2
3 import java.awt.Shape;
4 import java.awt.geom.FlatteningPathIterator;
5 import java.awt.geom.Path2D;
6 import java.awt.geom.PathIterator;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.Collection;
10 import java.util.Collections;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import org.simantics.Simantics;
17 import org.simantics.databoard.Bindings;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Resource;
20 import org.simantics.db.WriteGraph;
21 import org.simantics.db.common.request.UniqueRead;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.db.layer0.QueryIndexUtils;
24 import org.simantics.db.layer0.request.PossibleActiveModel;
25 import org.simantics.db.layer0.util.RemoverUtil;
26 import org.simantics.diagram.stubs.DiagramResource;
27 import org.simantics.district.region.ontology.DiagramRegionsResource;
28 import org.simantics.layer0.Layer0;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public final class DiagramRegions {
33
34     private static final Logger LOGGER = LoggerFactory.getLogger(DiagramRegions.class);
35
36     public static Resource createRegionForDiagram(WriteGraph graph, Resource diagram, String label, double[] coordinates) throws DatabaseException {
37         if (coordinates == null || coordinates.length < 6 || coordinates.length % 2 != 0)
38             throw new IllegalArgumentException("Provided coordinates are not valid : " + Arrays.toString(coordinates));
39         Path2D path = new Path2D.Double();
40         double startX = coordinates[0];
41         double startY = coordinates[1];
42         path.moveTo(startX, startY);
43         for (int i = 2; i < coordinates.length; i++)
44             path.lineTo(coordinates[i], coordinates[++i]);
45
46         path.closePath(); // might not be needed
47         DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph);
48         Layer0 L0 = Layer0.getInstance(graph);
49         Resource region = graph.newResource();
50         graph.claim(region, L0.InstanceOf, DRR.Region);
51         graph.claim(diagram, DRR.hasRegion, region);
52         graph.claim(region, DRR.regionOf, diagram);
53         graph.claimLiteral(region, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING);
54         graph.claimLiteral(region, L0.HasLabel, label, Bindings.STRING);
55         graph.claimLiteral(region, DRR.Region_area, coordinates, Bindings.DOUBLE_ARRAY);
56         if (LOGGER.isDebugEnabled())
57             LOGGER.debug("Created region for diagram {} with label {} and area {}", diagram, label, Arrays.toString(coordinates));
58         return region;
59     }
60
61     public static void removeRegion(WriteGraph graph, Resource region) throws DatabaseException {
62         RemoverUtil.remove(graph, region);
63     }
64
65     public static class DiagramRegion {
66         
67         private Resource resource;
68         private String label;
69         private Shape shape;
70         
71         public DiagramRegion(Resource resource, String label, Shape coordinatesToShape) {
72             this.resource = resource;
73             this.label = label;
74             this.shape = coordinatesToShape;
75         }
76         
77         public Resource getResource() {
78             return resource;
79         }
80         
81         public String getLabel() {
82             return label;
83         }
84         
85         public Shape getShape() {
86             return shape;
87         }
88     }
89     
90     public static Collection<DiagramRegion> findRegions(ReadGraph graph, Resource model) throws DatabaseException {
91         if (model == null)
92             return Collections.emptyList();
93
94         List<Resource> diagrams = QueryIndexUtils.searchByType(graph, model, DiagramResource.getInstance(graph).Diagram);
95         Set<DiagramRegion> regions = new HashSet<>();
96         
97         Layer0 L0 = Layer0.getInstance(graph);
98         
99         for (Resource diagram : diagrams) {
100             Collection<Resource> region = graph.getObjects(diagram, DiagramRegionsResource.getInstance(graph).hasRegion);
101             for (Resource r : region) {
102                 String label = graph.getRelatedValue(r, L0.HasLabel, Bindings.STRING);
103                 Shape coordinatesToShape = DiagramRegions.coordinatesToShape(graph, r);
104                 regions.add(new DiagramRegion(r, label, coordinatesToShape));
105             }
106         }
107         return regions;
108     }
109     
110     public static class DiagramRegionsRequest extends UniqueRead<Collection<DiagramRegion>> {
111
112         @Override
113         public Collection<DiagramRegion> perform(ReadGraph graph) throws DatabaseException {
114             return findRegions(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource())));
115         }
116     }
117
118     public static Shape coordinatesToShape(ReadGraph graph, Resource region) throws DatabaseException {
119         DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph);
120         double[] coordinates = graph.getRelatedValue(region, DRR.Region_area, Bindings.DOUBLE_ARRAY);
121         Path2D path = new Path2D.Double();
122         double startX = coordinates[0];
123         double startY = coordinates[1];
124         path.moveTo(startX, startY);
125         for (int i = 2; i < coordinates.length; i++)
126             path.lineTo(coordinates[i], coordinates[++i]);
127
128         path.closePath(); // might not be needed
129         return path;
130     }
131
132     public static double[] shapeToCoordinates(Shape shape) {
133         PathIterator it = new FlatteningPathIterator(shape.getPathIterator(null), 1);
134         double points[] = new double[6];
135         double moveX = 0, moveY = 0;
136         double thisX = 0, thisY = 0;
137         int type = 0;
138
139         List<Double> coords = new ArrayList<>();
140         // float factor = 1;
141
142         while (!it.isDone()) {
143             type = it.currentSegment(points);
144             switch (type) {
145             case PathIterator.SEG_MOVETO:
146                 moveX = points[0];
147                 moveY = points[1];
148                 coords.add(moveX);
149                 coords.add(moveY);
150                 break;
151
152             case PathIterator.SEG_CLOSE:
153                 points[0] = moveX;
154                 points[1] = moveY;
155                 // Fall into....
156                 break;
157             case PathIterator.SEG_LINETO:
158                 thisX = points[0];
159                 thisY = points[1];
160                 coords.add(thisX);
161                 coords.add(thisY);
162                 break;
163             }
164             it.next();
165         }
166         double[] finalCoords = new double[coords.size()];
167         for (int i = 0; i < coords.size(); i++) {
168             double d = coords.get(i);
169             finalCoords[i] = d;
170         }
171         return finalCoords;
172     }
173
174     public static Resource getDiagramForRegion(ReadGraph graph, Resource region) throws DatabaseException {
175         DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph);
176         Resource diagram = graph.getSingleObject(region, DRR.regionOf);
177         return diagram;
178     }
179 }