]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Change route point to Vertex 68/2868/1
authorjsimomaa <jani.simomaa@gmail.com>
Mon, 29 Apr 2019 14:10:37 +0000 (17:10 +0300)
committerjsimomaa <jani.simomaa@gmail.com>
Mon, 29 Apr 2019 14:10:37 +0000 (17:10 +0300)
gitlab #42
APROS-15325

Change-Id: I29598bb700ddc9aa53674b0387f1e72b62d735e1

org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java [new file with mode: 0644]

index 92a6187b59c7975fb70d4789c0e14eb88bcc686a..b937ed2a7bdcfacec77dd8839ee202a10bf0f9a4 100644 (file)
@@ -59,7 +59,7 @@ public class DNEdgeBuilder {
             Envelope e = new Envelope(x1, x2, y1, y2);
             vv.insert(e, new ResourceVertex(vertex, coords, false));
         }
-        return create(graph, vv, diagramResource, null, start, startElevation, end, endElevation, detailedGeometryCoords, padding, false);
+        return create(graph, vv, diagramResource, null, start, startElevation, end, endElevation, detailedGeometryCoords, padding, true);
     }
     
     public static Optional<Resource> create(WriteGraph graph, Quadtree vertices, Resource diagramResource, Resource mapping, double[] start, double startElevation, double[] end, double endElevation, double[] detailedGeometryCoords, double padding, boolean writeElevationToEdgeFromPoints) throws DatabaseException {
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java
new file mode 100644 (file)
index 0000000..5179627
--- /dev/null
@@ -0,0 +1,211 @@
+package org.simantics.district.network.ui.contributions;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ModelledCRS;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.DNEdgeBuilder;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.district.network.ui.NetworkDrawingParticipant;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ChangeRoutePointToVertexHandler {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ChangeRoutePointToVertexHandler.class);
+    static List<Resource> elements;
+    static boolean cut = true;
+
+    @CanExecute
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+        List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+        if (elements.size() != 1)
+            return false;
+        try {
+            return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+                @Override
+                public Boolean perform(ReadGraph graph) throws DatabaseException {
+                    DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+                    for (Resource selection : elements) {
+                        if (!graph.isInstanceOf(selection, DN.Edge)) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            });
+        } catch (DatabaseException e) {
+            LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
+            return false;
+        }
+    }
+
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart mActiveEditorPart, @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, ParameterizedCommand command) {
+        final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+        
+        Resource edge = elements.get(0);
+        try {
+            Point2D mouseClicked = mouseClickedOnEditor(mActiveEditorPart);
+            if (mouseClicked != null) {
+                
+                IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+                if (activeEditorPart == null)
+                    return;
+                if (!(activeEditorPart instanceof DistrictDiagramEditor))
+                    return;
+                DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+                Resource diagram = editor.getInputResource();
+                
+                Simantics.getSession().asyncRequest(new ReadRequest() {
+                    
+                    @Override
+                    public void run(ReadGraph graph) throws DatabaseException {
+                        DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+                        double[] detailedGeom = graph.getPossibleRelatedValue(edge, DN.Edge_HasGeometry, Bindings.DOUBLE_ARRAY);
+                        if (detailedGeom != null) {
+                            double closestDistance = Double.MAX_VALUE;
+                            Point2D closestPoint = null;
+                            int j = 0;
+                            for (int i = 0; i < detailedGeom.length; i += 2) {
+                                double x = detailedGeom[i];
+                                double y = detailedGeom[i + 1];
+                                Point2D currentPoint = new Point2D.Double(x, y);
+                                double currentDistance = mouseClicked.distance(currentPoint);
+                                if (currentDistance < closestDistance) {
+                                    closestDistance = currentDistance;
+                                    closestPoint = currentPoint;
+                                    j = i;
+                                }
+                            }
+                            
+                            final Point2D finalClosestPoint = closestPoint;
+                            
+                            DiagramResource DIA = DiagramResource.getInstance(graph);
+                            Resource currentStartVertex = graph.getSingleObject(edge, DN.HasStartVertex);
+                            double[] currentStartVertexCoords = graph.getRelatedValue(currentStartVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+                            Resource currentEndVertex = graph.getSingleObject(edge, DN.HasEndVertex);
+                            double[] currentEndVertexCoords = graph.getRelatedValue(currentEndVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+                            
+                            double[] detailedLeftEdgeGeometryCoords = new double[j];
+                            for (int k = 0; k < j; k += 2) {
+                                double x = detailedGeom[k];
+                                double y = detailedGeom[k + 1];
+                                detailedLeftEdgeGeometryCoords[k] = x;
+                                detailedLeftEdgeGeometryCoords[k + 1] = y;
+                            }
+                            
+                            double[] detailedRightEdgeGeometryCoords = new double[detailedGeom.length - j - 2];
+                            int i = 0;
+                            for (int k = j + 2; k < detailedGeom.length; k += 2) {
+                                double x = detailedGeom[k];
+                                double y = detailedGeom[k + 1];
+                                detailedRightEdgeGeometryCoords[i++] = x;
+                                detailedRightEdgeGeometryCoords[i++] = y;
+                            }
+                            
+                            Simantics.getSession().asyncRequest(new WriteRequest() {
+                                
+                                @Override
+                                public void perform(WriteGraph graph) throws DatabaseException {
+                                    RemoverUtil.remove(graph, edge);
+                                    
+                                    ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+                                        Simantics.getSession().asyncRequest(new WriteRequest() {
+                                            
+                                            @Override
+                                            public void perform(WriteGraph graph) throws DatabaseException {
+                                                // we might have closest point
+                                                if (finalClosestPoint != null) {
+                                                    Resource mapping = graph.getSingleObject(diagram, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
+                                                    double[] midVertexCoords = new double[] { finalClosestPoint.getX(), finalClosestPoint.getY() };
+                                                    Resource createdVertex = DistrictNetworkUtil.createVertex(graph, diagram, midVertexCoords, 0, mapping);
+
+                                                    Optional<Resource> leftEdge = DNEdgeBuilder.create(graph, diagram, currentStartVertexCoords, 0, midVertexCoords, 0, detailedLeftEdgeGeometryCoords, 0.001);
+                                                    Optional<Resource> rightEdge = DNEdgeBuilder.create(graph, diagram, midVertexCoords, 0, currentEndVertexCoords, 0, detailedRightEdgeGeometryCoords, 0.001);
+                                                    
+                                                }
+                                            }
+                                        });
+                                    }, 500, TimeUnit.MILLISECONDS);
+                                    
+                                }
+                            });
+                            
+                        } else {
+                            // no can do - or it would be possible to split the edge here in to two different edges
+                        }
+                    }
+                });
+            } else {
+                LOGGER.warn("No mouseClicked for editor {}", mActiveEditorPart);
+            }
+        } catch (InvocationTargetException e) {
+            LOGGER.error("Could not change route point to vertex", e);
+        }
+    }
+
+    private static Point2D mouseClickedOnEditor(MPart mActiveEditorPart) throws InvocationTargetException {
+        IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+        if (activeEditorPart == null)
+            return null;
+        if (!(activeEditorPart instanceof DistrictDiagramEditor))
+            return null;
+        DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+       
+        ICanvasContext ctx = editor.getAdapter(ICanvasContext.class);
+        NetworkDrawingParticipant drawingParticipant = ctx.getAtMostOneItemOfClass(NetworkDrawingParticipant.class);
+        AffineTransform drawingTransform = drawingParticipant.getTransform();
+        MouseUtil util = ctx.getAtMostOneItemOfClass(MouseUtil.class);
+        MouseInfo mouseInfo = util.getMousePressedInfo(0);
+        if (mouseInfo == null) {
+            return null;
+        }
+        Point2D canvasPosition = mouseInfo.canvasPosition;
+        Point2D transformed = null;
+        try {
+            transformed = drawingTransform.inverseTransform(canvasPosition, new Point2D.Double());
+        } catch (NoninvertibleTransformException e) {
+            LOGGER.error("Could not create inverse transform of {}", drawingTransform, e);
+            throw new InvocationTargetException(e);
+        }
+        double x = ModelledCRS.xToLongitude(transformed.getX());
+        double y = ModelledCRS.yToLatitude(-transformed.getY());
+        return new Point2D.Double(x, y);
+    }
+}