]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java
Fixed most warnings from district codebase after JavaSE-11 switch
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / contributions / ChangeRoutePointToVertexHandler.java
1 package org.simantics.district.network.ui.contributions;
2
3 import java.awt.geom.AffineTransform;
4 import java.awt.geom.NoninvertibleTransformException;
5 import java.awt.geom.Point2D;
6 import java.lang.reflect.InvocationTargetException;
7 import java.util.List;
8 import java.util.Optional;
9 import java.util.concurrent.TimeUnit;
10
11 import javax.inject.Named;
12
13 import org.eclipse.core.commands.ParameterizedCommand;
14 import org.eclipse.e4.core.di.annotations.CanExecute;
15 import org.eclipse.e4.core.di.annotations.Execute;
16 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
17 import org.eclipse.e4.ui.services.IServiceConstants;
18 import org.eclipse.jface.viewers.ISelection;
19 import org.eclipse.ui.IEditorPart;
20 import org.simantics.Simantics;
21 import org.simantics.databoard.Bindings;
22 import org.simantics.db.ReadGraph;
23 import org.simantics.db.Resource;
24 import org.simantics.db.WriteGraph;
25 import org.simantics.db.common.request.ReadRequest;
26 import org.simantics.db.common.request.WriteRequest;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.layer0.SelectionHints;
29 import org.simantics.db.layer0.util.RemoverUtil;
30 import org.simantics.db.request.Read;
31 import org.simantics.diagram.stubs.DiagramResource;
32 import org.simantics.district.network.DNEdgeBuilder;
33 import org.simantics.district.network.DistrictNetworkUtil;
34 import org.simantics.district.network.ModelledCRS;
35 import org.simantics.district.network.ontology.DistrictNetworkResource;
36 import org.simantics.district.network.ui.DistrictDiagramEditor;
37 import org.simantics.district.network.ui.NetworkDrawingParticipant;
38 import org.simantics.g2d.canvas.ICanvasContext;
39 import org.simantics.g2d.participant.MouseUtil;
40 import org.simantics.g2d.participant.MouseUtil.MouseInfo;
41 import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
42 import org.simantics.utils.threads.ThreadUtils;
43 import org.simantics.utils.ui.ISelectionUtils;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class ChangeRoutePointToVertexHandler {
48
49     private static final Logger LOGGER = LoggerFactory.getLogger(ChangeRoutePointToVertexHandler.class);
50     static List<Resource> elements;
51     static boolean cut = true;
52
53     @CanExecute
54     public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
55         List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
56         if (elements.size() != 1)
57             return false;
58         try {
59             return Simantics.getSession().syncRequest(new Read<Boolean>() {
60
61                 @Override
62                 public Boolean perform(ReadGraph graph) throws DatabaseException {
63                     DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
64                     for (Resource selection : elements) {
65                         if (!graph.isInstanceOf(selection, DN.Edge)) {
66                             return false;
67                         }
68                     }
69                     return true;
70                 }
71             });
72         } catch (DatabaseException e) {
73             LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
74             return false;
75         }
76     }
77
78     @Execute
79     public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart mActiveEditorPart, @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, ParameterizedCommand command) {
80         final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
81         
82         Resource edge = elements.get(0);
83         try {
84             Point2D mouseClicked = mouseClickedOnEditor(mActiveEditorPart);
85             if (mouseClicked != null) {
86                 
87                 IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
88                 if (activeEditorPart == null)
89                     return;
90                 if (!(activeEditorPart instanceof DistrictDiagramEditor))
91                     return;
92                 DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
93                 Resource diagram = editor.getInputResource();
94                 
95                 Simantics.getSession().asyncRequest(new ReadRequest() {
96                     
97                     @Override
98                     public void run(ReadGraph graph) throws DatabaseException {
99                         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
100                         double[] detailedGeom = graph.getPossibleRelatedValue(edge, DN.Edge_HasGeometry, Bindings.DOUBLE_ARRAY);
101                         if (detailedGeom != null) {
102                             double closestDistance = Double.MAX_VALUE;
103                             Point2D closestPoint = null;
104                             int j = 0;
105                             for (int i = 0; i < detailedGeom.length; i += 2) {
106                                 double x = detailedGeom[i];
107                                 double y = detailedGeom[i + 1];
108                                 Point2D currentPoint = new Point2D.Double(x, y);
109                                 double currentDistance = mouseClicked.distance(currentPoint);
110                                 if (currentDistance < closestDistance) {
111                                     closestDistance = currentDistance;
112                                     closestPoint = currentPoint;
113                                     j = i;
114                                 }
115                             }
116                             
117                             final Point2D finalClosestPoint = closestPoint;
118                             
119                             DiagramResource DIA = DiagramResource.getInstance(graph);
120                             Resource currentStartVertex = graph.getSingleObject(edge, DN.HasStartVertex);
121                             double[] currentStartVertexCoords = graph.getRelatedValue(currentStartVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
122                             Resource currentEndVertex = graph.getSingleObject(edge, DN.HasEndVertex);
123                             double[] currentEndVertexCoords = graph.getRelatedValue(currentEndVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
124                             
125                             double[] detailedLeftEdgeGeometryCoords = new double[j];
126                             for (int k = 0; k < j; k += 2) {
127                                 double x = detailedGeom[k];
128                                 double y = detailedGeom[k + 1];
129                                 detailedLeftEdgeGeometryCoords[k] = x;
130                                 detailedLeftEdgeGeometryCoords[k + 1] = y;
131                             }
132                             
133                             double[] detailedRightEdgeGeometryCoords = new double[detailedGeom.length - j - 2];
134                             int i = 0;
135                             for (int k = j + 2; k < detailedGeom.length; k += 2) {
136                                 double x = detailedGeom[k];
137                                 double y = detailedGeom[k + 1];
138                                 detailedRightEdgeGeometryCoords[i++] = x;
139                                 detailedRightEdgeGeometryCoords[i++] = y;
140                             }
141                             
142                             Simantics.getSession().asyncRequest(new WriteRequest() {
143                                 
144                                 @Override
145                                 public void perform(WriteGraph graph) throws DatabaseException {
146                                     RemoverUtil.remove(graph, edge);
147                                     
148                                     ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
149                                         Simantics.getSession().asyncRequest(new WriteRequest() {
150                                             
151                                             @Override
152                                             public void perform(WriteGraph graph) throws DatabaseException {
153                                                 // we might have closest point
154                                                 if (finalClosestPoint != null) {
155                                                     Resource mapping = graph.getSingleObject(diagram, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
156                                                     double x = finalClosestPoint.getX();
157                                                     double y = finalClosestPoint.getY();
158                                                     double[] midVertexCoords = new double[] { x, y };
159                                                     
160                                                     @SuppressWarnings("unused")
161                                                     Resource createdVertex = DistrictNetworkUtil.createVertex(graph, diagram, midVertexCoords, Double.MAX_VALUE, mapping);
162
163                                                     @SuppressWarnings("unused")
164                                                     Optional<Resource> leftEdge = DNEdgeBuilder.create(graph, diagram, currentStartVertexCoords, Double.MAX_VALUE, midVertexCoords, Double.MAX_VALUE, detailedLeftEdgeGeometryCoords, 0.001);
165                                                     @SuppressWarnings("unused")
166                                                     Optional<Resource> rightEdge = DNEdgeBuilder.create(graph, diagram, midVertexCoords, Double.MAX_VALUE, currentEndVertexCoords, Double.MAX_VALUE, detailedRightEdgeGeometryCoords, 0.001);
167                                                 }
168                                             }
169                                         });
170                                     }, 500, TimeUnit.MILLISECONDS);
171                                     
172                                 }
173                             });
174                             
175                         } else {
176                             // no can do - or it would be possible to split the edge here in to two different edges
177                         }
178                     }
179                 });
180             } else {
181                 LOGGER.warn("No mouseClicked for editor {}", mActiveEditorPart);
182             }
183         } catch (InvocationTargetException e) {
184             LOGGER.error("Could not change route point to vertex", e);
185         }
186     }
187
188     private static Point2D mouseClickedOnEditor(MPart mActiveEditorPart) throws InvocationTargetException {
189         IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
190         if (activeEditorPart == null)
191             return null;
192         if (!(activeEditorPart instanceof DistrictDiagramEditor))
193             return null;
194         DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
195        
196         ICanvasContext ctx = editor.getAdapter(ICanvasContext.class);
197         NetworkDrawingParticipant drawingParticipant = ctx.getAtMostOneItemOfClass(NetworkDrawingParticipant.class);
198         AffineTransform drawingTransform = drawingParticipant.getTransform();
199         MouseUtil util = ctx.getAtMostOneItemOfClass(MouseUtil.class);
200         MouseInfo mouseInfo = util.getMousePressedInfo(0);
201         if (mouseInfo == null) {
202             return null;
203         }
204         Point2D canvasPosition = mouseInfo.canvasPosition;
205         Point2D transformed = null;
206         try {
207             transformed = drawingTransform.inverseTransform(canvasPosition, new Point2D.Double());
208         } catch (NoninvertibleTransformException e) {
209             LOGGER.error("Could not create inverse transform of {}", drawingTransform, e);
210             throw new InvocationTargetException(e);
211         }
212         double x = ModelledCRS.xToLongitude(transformed.getX());
213         double y = ModelledCRS.yToLatitude(-transformed.getY());
214         return new Point2D.Double(x, y);
215     }
216 }