blob: 9df56a65a9d70145c408befbab03fa06f8d1f752 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Bundesinstitut für Risikobewertung.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bundesinstitut für Risikobewertung - initial API and implementation
*******************************************************************************/
package org.eclipse.stem.ui.grapheditor;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.stem.core.STEMURI;
import org.eclipse.stem.core.Utility;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.Edge;
import org.eclipse.stem.core.graph.EdgeLabel;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.graph.impl.EdgeImpl;
import org.eclipse.stem.core.model.Model;
import org.eclipse.stem.definitions.adapters.spatial.SpatialProviderAdapter;
import org.eclipse.stem.definitions.adapters.spatial.geo.InlineLatLongDataProvider;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.Segment;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.SegmentBuilder;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProvider;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProviderAdapterFactory;
import org.eclipse.stem.definitions.edges.EdgesFactory;
import org.eclipse.stem.definitions.edges.EdgesPackage;
import org.eclipse.stem.definitions.edges.MigrationEdge;
import org.eclipse.stem.definitions.edges.MigrationEdgeLabel;
import org.eclipse.stem.definitions.edges.MigrationEdgeLabelValue;
import org.eclipse.stem.definitions.labels.AreaLabel;
import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabel;
import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabelValue;
import org.eclipse.stem.definitions.labels.LabelsFactory;
import org.eclipse.stem.definitions.labels.LabelsPackage;
import org.eclipse.stem.definitions.labels.PopulationLabel;
import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabel;
import org.eclipse.stem.definitions.labels.RoadTransportRelationshipLabel;
import org.eclipse.stem.definitions.labels.RoadTransportRelationshipLabelValue;
import org.eclipse.stem.definitions.labels.impl.RoadTransportRelationshipLabelImpl;
import org.eclipse.stem.definitions.nodes.NodesFactory;
import org.eclipse.stem.definitions.nodes.Region;
import org.eclipse.stem.definitions.transport.PipeTransportEdge;
import org.eclipse.stem.definitions.transport.PipeTransportEdgeLabel;
import org.eclipse.stem.definitions.transport.PipeTransportEdgeLabelValue;
import org.eclipse.stem.definitions.transport.TransportFactory;
import org.eclipse.stem.definitions.transport.TransportPackage;
import org.eclipse.stem.definitions.transport.impl.PipeTransportEdgeImpl;
import org.eclipse.stem.ui.Activator;
import org.eclipse.stem.ui.grapheditor.handlers.NewNodeDialog;
import org.eclipse.stem.ui.grapheditor.handlers.SaveInProjectDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.zest.core.widgets.GraphConnection;
import org.eclipse.zest.core.widgets.GraphItem;
import org.eclipse.zest.core.widgets.GraphNode;
public class GraphCanvas {
private final int NODE_SIZE = 10;
private final double INITIAL_SCALE_FACTOR = 0.95;
private IProject project;
private List<Graph> graphList;
private List<Model> modelList;
private Shell shell;
private Graph stemGraph;
private org.eclipse.zest.core.widgets.Graph zestGraph;
private double scaleX;
private double scaleY;
private double xTranslation;
private double yTranslation;
private double zoomFactor;
private int lastCursorX;
private int lastCursorY;
private boolean mouseButtonPressed;
private Map<URI, GraphNode> graphNodes;
private Map<URI, GraphConnection> graphConnections;
private Map<URI, Set<Polygon>> graphPolygons;
private DynamicText nodeXY_edit;
private DynamicText coordinate_trans;
private DynamicText zoomEdit;
public GraphCanvas(String title, IProject project, List<Graph> graphList,
List<Model> modelList) {
this.project = project;
this.graphList = new ArrayList<Graph>();
this.modelList = modelList;
stemGraph = null;
zoomFactor = 1.0;
mouseButtonPressed = false;
graphNodes = new HashMap<URI, GraphNode>();
graphConnections = new HashMap<URI, GraphConnection>();
graphPolygons = new HashMap<URI, Set<Polygon>>();
for (Graph graph : graphList) {
this.graphList.add((Graph) EcoreUtil.copy(graph));
}
for (Graph graph : graphList) {
if (stemGraph == null) {
stemGraph = (Graph) EcoreUtil.copy(graph);
} else {
stemGraph.addGraph((Graph) EcoreUtil.copy(graph), null);
}
}
for (NodeLabel nodeLabel : stemGraph.getNodeLabels().values()) {
Node node = stemGraph.getNode(nodeLabel
.getURIOfIdentifiableToBeLabeled());
if (!node.getLabels().contains(nodeLabel)) {
node.getLabels().add(nodeLabel);
}
}
createShell(title);
for (Node node : stemGraph.getNodes().values()) {
processNode(node);
}
for (Edge edge : stemGraph.getEdges().values()) {
processEdge(edge);
}
if (graphNodes.isEmpty()) {
return;
}
setInitialTransform();
redraw();
shell.open();
while (!shell.isDisposed()) {
while (!Activator.getDefault().getWorkbench().getDisplay()
.readAndDispatch()) {
Activator.getDefault().getWorkbench().getDisplay().sleep();
}
}
}
private void createShell(String title) {
shell = new Shell(Activator.getDefault().getWorkbench().getDisplay());
shell.setText(title);
shell.setLayout(new GridLayout(1, true));
zestGraph = new org.eclipse.zest.core.widgets.Graph(shell, SWT.NONE);
zestGraph.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
zestGraph
.setVerticalScrollBarVisibility(org.eclipse.zest.core.widgets.Graph.NEVER);
zestGraph
.setHorizontalScrollBarVisibility(org.eclipse.zest.core.widgets.Graph.NEVER);
zestGraph.getViewport().setIgnoreScroll(true);
zestGraph.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setLineWidth(0);
e.gc.setClipping(zestGraph.getBounds());
e.gc.setForeground(ColorConstants.lightGray);
for (Set<Polygon> polySet : graphPolygons.values()) {
for (Polygon displayPolygon : polySet) {
e.gc.drawPolygon(polygon2IntArray(displayPolygon));
}
}
}
});
for (Listener l : zestGraph.getVerticalBar()
.getListeners(SWT.Selection)) {
zestGraph.getVerticalBar().removeListener(SWT.Selection, l);
zestGraph.getVerticalBar().removeListener(SWT.Selection, l);
}
for (Listener l : zestGraph.getHorizontalBar().getListeners(
SWT.Selection)) {
zestGraph.getHorizontalBar().removeListener(SWT.Selection, l);
zestGraph.getHorizontalBar().removeListener(SWT.Selection, l);
}
Composite dataComposite = new Composite(shell, SWT.CENTER);
Composite infoComposite = createInfoComposite(dataComposite);
Composite bottomComposite = createButtonsComposite(dataComposite);
dataComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
false));
dataComposite.setLayout(new GridLayout(1, true));
infoComposite
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
addZestGraphListeners();
addZestGraphContextMenu();
shell.pack();
shell.setSize(800, 600);
}
private void updateShell() {
updateShell(0);
}
private void updateShell(int selectedNodeLabel) {
boolean showNodeComposite = false;
boolean showEdgeComposite = false;
if (zestGraph.getSelection().size() == 1) {
if (zestGraph.getSelection().get(0) instanceof GraphNode) {
showNodeComposite = true;
} else if (zestGraph.getSelection().get(0) instanceof GraphConnection) {
showEdgeComposite = true;
}
}
shell.getChildren()[1].dispose();
Composite dataComposite = new Composite(shell, SWT.CENTER);
dataComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
false));
dataComposite.setLayout(new GridLayout(1, true));
if (showNodeComposite) {
GraphNode selectedNode = (GraphNode) zestGraph.getSelection()
.get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
Composite propertiesComposite_nodes = createNodeDataComposite(dataComposite);
nodeData.setActiveLabel(selectedNodeLabel);
propertiesComposite_nodes.setLayoutData(new GridData(SWT.FILL,
SWT.FILL, true, true));
if (!nodeData.getNodeLabels().isEmpty()) {
Composite propertiesComposite_labels = createNodeLabelComposite(dataComposite);
propertiesComposite_labels.setLayoutData(new GridData(SWT.FILL,
SWT.FILL, true, true));
}
}
if (showEdgeComposite) {
Composite propertiesComposite_edges = createEdgeComposite(dataComposite);
Composite edgeLabelComposite = createEdgeLabelComposite(dataComposite);
propertiesComposite_edges.setLayoutData(new GridData(SWT.FILL,
SWT.FILL, true, true));
edgeLabelComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
true, true));
}
Composite infoComposite = createInfoComposite(dataComposite);
Composite bottomComposite = createButtonsComposite(dataComposite);
infoComposite
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
addZestGraphContextMenu();
shell.layout(true);
if (showNodeComposite || showEdgeComposite) {
checkSelectionVisible();
}
}
private Composite createNodeDataComposite(Composite parent) {
GraphNode selectedNode = (GraphNode) zestGraph.getSelection().get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
Group propertiesComposite_nodes = new Group(parent, SWT.CENTER);
propertiesComposite_nodes
.setText(GraphEditorMessages.getString("node"));
propertiesComposite_nodes.setLayout(new RowLayout(SWT.HORIZONTAL));
Label nodeTitle = new Label(propertiesComposite_nodes, SWT.NONE);
nodeTitle.setText(GraphEditorMessages.getString("title") + ":");
DynamicText nodeTitle_edit = new DynamicText(propertiesComposite_nodes,
true);
nodeTitle_edit.setText(nodeData.getNodeTitle());
nodeTitle_edit.addModifyListener(new TextAndButtonModifyListener(
zestGraph, TextAndButtonModifyListener.NODE_TITLE));
Label nodeURI = new Label(propertiesComposite_nodes, SWT.NONE);
nodeURI.setText(GraphEditorMessages.getString("uri") + ":");
DynamicText nodeURI_edit = new DynamicText(propertiesComposite_nodes,
false);
nodeURI_edit.setText(nodeData.getNodeURI().toString());
Label nodeXY = new Label(propertiesComposite_nodes, SWT.NONE);
nodeXY.setText(GraphEditorMessages.getString("coordinates") + ":");
nodeXY_edit = new DynamicText(propertiesComposite_nodes, false);
nodeXY_edit.setText(formatLatLon(nodeData.getOrigY(),
nodeData.getOrigX()));
return propertiesComposite_nodes;
}
private Composite createNodeLabelComposite(Composite parent) {
GraphNode selectedNode = (GraphNode) zestGraph.getSelection().get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
List<NodeLabel> nodeLabels = nodeData.getNodeLabels();
NodeLabel nodeLabel = nodeLabels.get(nodeData.getActiveLabel());
Group nodeLabelComposite = new Group(parent, SWT.CENTER);
nodeLabelComposite.setText(GraphEditorMessages.getString("nodeLabel"));
nodeLabelComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
Label nodeLabelType = new Label(nodeLabelComposite, SWT.NONE);
nodeLabelType.setText(GraphEditorMessages.getString("labelType") + ":");
Combo nodeLabelType_edit = new Combo(nodeLabelComposite, SWT.READ_ONLY);
nodeLabelType_edit.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
updateShell(((Combo) e.getSource()).getSelectionIndex());
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
for (NodeLabel label : nodeLabels) {
if (label instanceof AreaLabel) {
nodeLabelType_edit.add(GraphEditorMessages
.getString("areaLabel"));
} else if (label instanceof PopulationLabel) {
nodeLabelType_edit.add(GraphEditorMessages
.getString("populationLabel"));
}
}
nodeLabelType_edit.select(nodeData.getActiveLabel());
if (nodeLabel instanceof AreaLabel) {
AreaLabel areaLabel = (AreaLabel) nodeLabel;
Label labelArea = new Label(nodeLabelComposite, SWT.NONE);
labelArea.setText(GraphEditorMessages.getString("areaKM") + ":");
DynamicText labelAreaEdit = new DynamicText(nodeLabelComposite,
true);
labelAreaEdit.setText(""
+ areaLabel.getCurrentAreaValue().getArea());
labelAreaEdit.addModifyListener(new TextAndButtonModifyListener(
zestGraph, TextAndButtonModifyListener.AREA_LABEL_VALUE));
} else if (nodeLabel instanceof PopulationLabel) {
PopulationLabel populationLabel = (PopulationLabel) nodeLabel;
Label labelPopulation = new Label(nodeLabelComposite, SWT.NONE);
labelPopulation.setText(GraphEditorMessages.getString("population")
+ ":");
DynamicText labelPopulationEdit = new DynamicText(
nodeLabelComposite, true);
labelPopulationEdit.setText(populationLabel
.getPopulationIdentifier());
labelPopulationEdit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.POPULATION_LABEL_POPULATION));
Label labelPopulationCount = new Label(nodeLabelComposite, SWT.NONE);
labelPopulationCount.setText(GraphEditorMessages
.getString("populationCount") + ":");
DynamicText labelPopulationCountEdit = new DynamicText(
nodeLabelComposite, true);
labelPopulationCountEdit.setText(""
+ populationLabel.getCurrentPopulationValue().getCount());
labelPopulationCountEdit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.POPULATION_LABEL_COUNT));
Label labelPopulatedArea = new Label(nodeLabelComposite, SWT.NONE);
labelPopulatedArea.setText(GraphEditorMessages
.getString("populatedArea") + ":");
DynamicText labelPopulatedAreaEdit = new DynamicText(
nodeLabelComposite, true);
labelPopulatedAreaEdit.setText(""
+ populationLabel.getPopulatedArea());
labelPopulatedAreaEdit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.POPULATION_LABEL_AREA));
}
return nodeLabelComposite;
}
private Composite createEdgeComposite(Composite parent) {
GraphConnection selectedEdge = (GraphConnection) zestGraph
.getSelection().get(0);
ConnectionData edgeData = (ConnectionData) selectedEdge.getData();
Group propertiesComposite_edges = new Group(parent, SWT.CENTER);
propertiesComposite_edges
.setText(GraphEditorMessages.getString("edge"));
propertiesComposite_edges.setLayout(new RowLayout(SWT.HORIZONTAL));
Label edgeTitle = new Label(propertiesComposite_edges, SWT.NONE);
edgeTitle.setText(GraphEditorMessages.getString("title") + ":");
DynamicText edgeTitle_edit = new DynamicText(propertiesComposite_edges,
true);
edgeTitle_edit.setText(edgeData.getEdgeTitle());
edgeTitle_edit.addModifyListener(new TextAndButtonModifyListener(
zestGraph, TextAndButtonModifyListener.EDGE_TITLE));
Label nodeAURI = new Label(propertiesComposite_edges, SWT.NONE);
nodeAURI.setText(GraphEditorMessages.getString("nodeA") + ":");
DynamicText nodeAURI_edit = new DynamicText(propertiesComposite_edges,
false);
nodeAURI_edit.setText(edgeData.getNodeAURI().lastSegment());
Label nodeBURI = new Label(propertiesComposite_edges, SWT.NONE);
nodeBURI.setText(GraphEditorMessages.getString("nodeB") + ":");
DynamicText nodeBURI_edit = new DynamicText(propertiesComposite_edges,
false);
nodeBURI_edit.setText(edgeData.getNodeBURI().lastSegment());
return propertiesComposite_edges;
}
private Composite createEdgeLabelComposite(Composite parent) {
GraphConnection selectedEdge = (GraphConnection) zestGraph
.getSelection().get(0);
ConnectionData edgeData = (ConnectionData) selectedEdge.getData();
EdgeLabel edgeLabel = edgeData.getEdgeLabel();
Group edgeLabelComposite = new Group(parent, SWT.CENTER);
edgeLabelComposite.setText(GraphEditorMessages.getString("edgeLabel"));
edgeLabelComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
if (edgeLabel instanceof MigrationEdgeLabel) {
Label edgeLabelType = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelType.setText(GraphEditorMessages.getString("edgeType")
+ ":");
DynamicText edgeLabelType_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelType_edit.setText(GraphEditorMessages
.getString("migrationEdge"));
edgeLabelType_edit.setEditable(false);
edgeLabelType_edit.setBackground(ColorConstants.white);
Label edgeLabelValue = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelValue.setText(GraphEditorMessages
.getString("migrationRate") + ":");
DynamicText edgeLabelValue_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelValue_edit.setText("" + edgeData.getMigrationRate());
edgeLabelValue_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.MIGRATION_LABEL_RATE));
Label edgeLabelPeriod = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelPeriod.setText(GraphEditorMessages.getString("period")
+ ":");
DynamicText edgeLabelPeriod_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelPeriod_edit.setText("" + edgeData.getMigrationPeriod());
edgeLabelPeriod_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.MIGRATION_LABEL_PERIOD));
Label edgePop = new Label(edgeLabelComposite, SWT.NONE);
edgePop.setText(GraphEditorMessages.getString("population") + ":");
DynamicText edgePop_edit = new DynamicText(edgeLabelComposite, true);
edgePop_edit.setText(edgeData.getMigrationPopulation());
edgePop_edit.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.MIGRATION_LABEL_POPULATION));
Button edgeAbsolute_edit = new Button(edgeLabelComposite, SWT.CHECK);
edgeAbsolute_edit.setText(GraphEditorMessages
.getString("migrationAbsolute"));
edgeAbsolute_edit.setSelection(edgeData.getMigrationAbsolute());
edgeAbsolute_edit
.addSelectionListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.MIGRATION_LABEL_ABSOLUTE));
} else if (edgeLabel instanceof CommonBorderRelationshipLabel) {
Label edgeLabelType = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelType.setText(GraphEditorMessages.getString("edgeType")
+ ":");
DynamicText edgeLabelType_edit = new DynamicText(
edgeLabelComposite, false);
edgeLabelType_edit.setText(GraphEditorMessages
.getString("commonBorderEdge"));
Label edgeLabelValue = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelValue.setText(GraphEditorMessages
.getString("borderLength") + ":");
DynamicText edgeLabelValue_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelValue_edit.setText("" + edgeData.getCommonBorderLength());
edgeLabelValue_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.COMMON_BORDER_LABEL_LENGTH));
} else if (edgeLabel instanceof RoadTransportRelationshipLabel) {
Label edgeLabelType = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelType.setText(GraphEditorMessages.getString("edgeType")
+ ":");
DynamicText edgeLabelType_edit = new DynamicText(
edgeLabelComposite, false);
edgeLabelType_edit.setText(GraphEditorMessages
.getString("roadEdge"));
Label edgeLabelName = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelName.setText(GraphEditorMessages.getString("roadName")
+ ":");
DynamicText edgeLabelName_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelName_edit.setText(edgeData.getRoadName());
edgeLabelName_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.ROAD_LABEL_NAME));
Label edgeLabelClass = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelClass.setText(GraphEditorMessages.getString("roadClass")
+ ":");
DynamicText edgeLabelClass_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelClass_edit.setText(edgeData.getRoadClass());
edgeLabelClass_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.ROAD_LABEL_CLASS));
Label edgeLabelCrossings = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelCrossings.setText(GraphEditorMessages
.getString("numberCrossing") + ":");
DynamicText edgeLabelCrossings_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelCrossings_edit.setText("" + edgeData.getRoadCrossings());
edgeLabelCrossings_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.ROAD_LABEL_CROSSINGS));
} else if (edgeLabel instanceof PipeTransportEdgeLabel) {
Label edgeLabelType = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelType.setText(GraphEditorMessages.getString("edgeType")
+ ":");
DynamicText edgeLabelType_edit = new DynamicText(
edgeLabelComposite, false);
edgeLabelType_edit.setText(GraphEditorMessages
.getString("pipeEdge"));
Label edgePop = new Label(edgeLabelComposite, SWT.NONE);
edgePop.setText(GraphEditorMessages.getString("population") + ":");
DynamicText edgePop_edit = new DynamicText(edgeLabelComposite, true);
edgePop_edit.setText(edgeData.getPipePopulation());
edgePop_edit.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.PIPE_LABEL_POPULATION));
Label edgeLabelFlow = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelFlow.setText(GraphEditorMessages.getString("pipeFlow")
+ ":");
DynamicText edgeLabelFlow_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelFlow_edit.setText("" + edgeData.getPipeFlow());
edgeLabelFlow_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.PIPE_LABEL_FLOW));
Label edgeLabelPeriod = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelPeriod.setText(GraphEditorMessages.getString("period")
+ ":");
DynamicText edgeLabelPeriod_edit = new DynamicText(
edgeLabelComposite, true);
edgeLabelPeriod_edit.setText("" + edgeData.getPipePeriod());
edgeLabelPeriod_edit
.addModifyListener(new TextAndButtonModifyListener(
zestGraph,
TextAndButtonModifyListener.PIPE_LABEL_PERIOD));
} else if (edgeLabel instanceof RelativePhysicalRelationshipLabel) {
Label edgeLabelType = new Label(edgeLabelComposite, SWT.NONE);
edgeLabelType.setText(GraphEditorMessages.getString("edgeType")
+ ":");
DynamicText edgeLabelType_edit = new DynamicText(
edgeLabelComposite, false);
edgeLabelType_edit.setText(GraphEditorMessages
.getString("containmentEdge") + ":");
}
return edgeLabelComposite;
}
private Composite createInfoComposite(Composite parent) {
Group infoComposite = new Group(parent, SWT.CENTER);
Point2D.Double xy_trans = getCoordinatesFromCursorLocation(zestGraph
.toControl(Display.getCurrent().getCursorLocation()));
infoComposite.setText(GraphEditorMessages
.getString("displayInformation"));
infoComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
Label coordinate = new Label(infoComposite, SWT.NONE);
coordinate.setText(GraphEditorMessages.getString("coordinates") + ":");
coordinate_trans = new DynamicText(infoComposite, false);
coordinate_trans.setText(formatLatLon(xy_trans.y, xy_trans.x));
Label zoom = new Label(infoComposite, SWT.NONE);
zoom.setText(GraphEditorMessages.getString("zoom") + ":");
zoomEdit = new DynamicText(infoComposite, false);
zoomEdit.setText(formatDouble(zoomFactor));
return infoComposite;
}
private Composite createButtonsComposite(Composite parent) {
Composite toolBar = new Composite(parent, SWT.NONE);
Button saveButton = new Button(toolBar, SWT.PUSH);
Button saveAsButton = new Button(toolBar, SWT.PUSH);
Button quitButton = new Button(toolBar, SWT.PUSH);
toolBar.setLayout(new RowLayout(SWT.HORIZONTAL));
saveButton.setText(GraphEditorMessages.getString("saveAndQuit"));
saveAsButton.setText(GraphEditorMessages.getString("saveGraphAs"));
quitButton.setText(GraphEditorMessages.getString("quit"));
saveButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
saveGraphList();
Activator.getDefault().getWorkbench().getDisplay()
.getActiveShell().dispose();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
saveAsButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
saveStemGraphAs();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
quitButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Activator.getDefault().getWorkbench().getDisplay()
.getActiveShell().dispose();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
return toolBar;
}
private void addZestGraphListeners() {
zestGraph.getLightweightSystem().getRootFigure()
.addMouseListener(new org.eclipse.draw2d.MouseListener() {
@Override
public void mousePressed(org.eclipse.draw2d.MouseEvent me) {
org.eclipse.draw2d.geometry.Point mousePoint = new org.eclipse.draw2d.geometry.Point(
me.x, me.y);
zestGraph.getRootLayer()
.translateToRelative(mousePoint);
IFigure figureUnderMouse = zestGraph.getFigureAt(
mousePoint.x, mousePoint.y);
if (figureUnderMouse == null && me.button == 1) {
zestGraph.setSelection(new GraphItem[0]);
zestGraph.notifyListeners(SWT.Selection,
new Event());
}
}
@Override
public void mouseReleased(org.eclipse.draw2d.MouseEvent me) {
}
@Override
public void mouseDoubleClicked(
org.eclipse.draw2d.MouseEvent me) {
}
});
zestGraph.addMouseListener(new MouseListener() {
public void mouseDown(MouseEvent e) {
lastCursorX = Display.getCurrent().getCursorLocation().x;
lastCursorY = Display.getCurrent().getCursorLocation().y;
mouseButtonPressed = true;
}
public void mouseUp(MouseEvent e) {
mouseButtonPressed = false;
}
public void mouseDoubleClick(MouseEvent e) {
}
});
zestGraph.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
Point xy = zestGraph.toControl(Display.getCurrent()
.getCursorLocation());
Point2D.Double xy_trans = getCoordinatesFromCursorLocation(xy);
coordinate_trans.setText(formatLatLon(xy_trans.y, xy_trans.x));
if (!mouseButtonPressed) {
return;
}
int x = Display.getCurrent().getCursorLocation().x;
int y = Display.getCurrent().getCursorLocation().y;
int diffX = x - lastCursorX;
int diffY = y - lastCursorY;
lastCursorX = x;
lastCursorY = y;
if (zestGraph.getSelection().isEmpty()) {
if (diffX != 0 || diffY != 0) {
xTranslation += diffX;
yTranslation += diffY;
zestGraph.redraw();
redraw();
}
} else {
for (Object selectedItem : zestGraph.getSelection()) {
if (!(selectedItem instanceof GraphNode)) {
continue;
}
GraphNode selectedNode = (GraphNode) selectedItem;
NodeData nodeData = (NodeData) selectedNode.getData();
if (diffX != 0 || diffY != 0) {
addTranslationToNode(nodeData, diffX, diffY);
zestGraph.redraw();
}
}
if (zestGraph.getSelection().size() == 1
&& zestGraph.getSelection().get(0) instanceof GraphNode) {
GraphNode selectedNode = (GraphNode) zestGraph
.getSelection().get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
nodeXY_edit.setText(formatLatLon(nodeData.getOrigY(),
nodeData.getOrigX()));
}
}
}
});
zestGraph.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
updateShell();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
zestGraph.addMouseWheelListener(new MouseWheelListener() {
public void mouseScrolled(MouseEvent e) {
Point2D.Double p = getCoordinatesFromCursorLocation(zestGraph
.toControl(Display.getCurrent().getCursorLocation()));
if (e.count >= 0) {
xTranslation -= 0.1 * scaleX * p.x;
yTranslation -= 0.1 * scaleY * p.y;
scaleX *= 1.1;
scaleY *= 1.1;
zoomFactor *= 1.1;
} else {
scaleX /= 1.1;
scaleY /= 1.1;
xTranslation += 0.1 * scaleX * p.x;
yTranslation += 0.1 * scaleY * p.y;
zoomFactor /= 1.1;
}
Point xy = zestGraph.toControl(Display.getCurrent()
.getCursorLocation());
Point2D.Double xy_trans = getCoordinatesFromCursorLocation(xy);
coordinate_trans.setText(formatLatLon(xy_trans.y, xy_trans.x));
zoomEdit.setText(formatDouble(zoomFactor));
zestGraph.redraw();
redraw();
}
});
}
private void addZestGraphContextMenu() {
List<?> selection = zestGraph.getSelection();
Menu menu = new Menu(zestGraph.getShell(), SWT.POP_UP);
if (selection.isEmpty()) {
createAddNodeItem(menu);
}
if (selection.size() == 1 && selection.get(0) instanceof GraphNode) {
createRemoveNodeItem(menu);
createAddLabelItem(menu);
createRemoveLabelItem(menu);
}
if (selection.size() == 2 && selection.get(0) instanceof GraphNode
&& selection.get(1) instanceof GraphNode) {
createAddEdgeItem(menu);
}
if (selection.size() == 1
&& selection.get(0) instanceof GraphConnection) {
createRemoveEdgeItem(menu);
}
zestGraph.setMenu(menu);
}
private void createAddNodeItem(Menu menu) {
MenuItem addNode = new MenuItem(menu, SWT.PUSH);
addNode.setText(GraphEditorMessages.getString("addNode"));
addNode.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Point2D.Double p = getCoordinatesFromCursorLocation(zestGraph
.toControl(Display.getCurrent().getCursorLocation()));
NewNodeDialog dialog = new NewNodeDialog(shell);
if (!dialog.hasResult()) {
return;
}
String identifier = dialog.getIdentifier();
double size = dialog.getSize();
Node node = NodesFactory.eINSTANCE.createRegion();
LatLong latlon = new LatLong();
SegmentBuilder builder = new SegmentBuilder();
builder.add(p.y - size / 2, p.x - size / 2);
builder.add(p.y + size / 2, p.x - size / 2);
builder.add(p.y + size / 2, p.x + size / 2);
builder.add(p.y - size / 2, p.x + size / 2);
builder.add(p.y - size / 2, p.x - size / 2);
latlon.add(builder.toSegment());
node.getDublinCore().setTitle("");
node.setURI(STEMURI
.createURI(Region.URI_TYPE_REGION_NODE_SEGMENT + "/"
+ identifier));
node.getDublinCore().setSpatial(
InlineLatLongDataProvider
.createSpatialInlineURIString(latlon));
GraphNode gn = processNode(node);
addNodeToStemGraph(node);
zestGraph.setSelection(new GraphItem[] { gn });
zestGraph.redraw();
redraw();
updateShell();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private void createAddLabelItem(Menu menu) {
MenuItem addLabelItem = new MenuItem(menu, SWT.CASCADE);
Menu addLabelMenu = new Menu(zestGraph.getShell(), SWT.DROP_DOWN);
MenuItem addAreaLabelItem = new MenuItem(addLabelMenu, SWT.PUSH);
MenuItem addPopulationLabelItem = new MenuItem(addLabelMenu, SWT.PUSH);
addLabelItem.setText(GraphEditorMessages.getString("addLabel"));
addAreaLabelItem.setText(GraphEditorMessages.getString("addAreaLabel"));
addPopulationLabelItem.setText(GraphEditorMessages
.getString("addPopulationLabel"));
addLabelItem.setMenu(addLabelMenu);
addAreaLabelItem.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addNodeLabel(LabelsPackage.Literals.AREA_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
addPopulationLabelItem.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addNodeLabel(LabelsPackage.Literals.POPULATION_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private void createAddEdgeItem(Menu menu) {
MenuItem addEdgeItem = new MenuItem(menu, SWT.CASCADE);
Menu addEdgeMenu = new Menu(zestGraph.getShell(), SWT.DROP_DOWN);
MenuItem addMigrationEdge = new MenuItem(addEdgeMenu, SWT.PUSH);
MenuItem addCommonBorderEdge = new MenuItem(addEdgeMenu, SWT.PUSH);
MenuItem addRoadTransportEdge = new MenuItem(addEdgeMenu, SWT.PUSH);
MenuItem addPipeTransportEdge = new MenuItem(addEdgeMenu, SWT.PUSH);
addEdgeItem.setText(GraphEditorMessages.getString("addEdge"));
addMigrationEdge.setText(GraphEditorMessages
.getString("addMigrationEdge"));
addCommonBorderEdge.setText(GraphEditorMessages
.getString("addCommonBorderEdge"));
addRoadTransportEdge.setText(GraphEditorMessages
.getString("addRoadEdge"));
addPipeTransportEdge.setText(GraphEditorMessages
.getString("addPipeEdge"));
addEdgeItem.setMenu(addEdgeMenu);
addCommonBorderEdge.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addEdge(LabelsPackage.Literals.COMMON_BORDER_RELATIONSHIP_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
addMigrationEdge.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addEdge(EdgesPackage.Literals.MIGRATION_EDGE_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
addRoadTransportEdge.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addEdge(LabelsPackage.Literals.ROAD_TRANSPORT_RELATIONSHIP_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
addPipeTransportEdge.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
addEdge(TransportPackage.Literals.PIPE_TRANSPORT_EDGE_LABEL);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private void createRemoveNodeItem(Menu menu) {
MenuItem removeNode = new MenuItem(menu, SWT.PUSH);
removeNode.setText(GraphEditorMessages.getString("removeNode"));
removeNode.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
GraphNode selectedNode = (GraphNode) zestGraph.getSelection()
.get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
List<URI> edgesToRemove = new ArrayList<URI>();
for (Map.Entry<URI, GraphConnection> entry : graphConnections
.entrySet()) {
if (selectedNode == entry.getValue().getSource()
|| selectedNode == entry.getValue()
.getDestination()) {
entry.getValue().dispose();
edgesToRemove.add(entry.getKey());
}
}
for (URI edgeURI : edgesToRemove) {
graphConnections.remove(edgeURI);
}
zestGraph.setSelection(new GraphItem[] {});
graphNodes.remove(nodeData.getNodeURI());
graphPolygons.remove(nodeData.getNodeURI());
selectedNode.dispose();
removeNodeFromStemGraph(nodeData.getNode());
updateShell();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private void createRemoveLabelItem(Menu menu) {
MenuItem removeLabelItem = new MenuItem(menu, SWT.CASCADE);
Menu removeLabelMenu = new Menu(zestGraph.getShell(), SWT.DROP_DOWN);
GraphNode selectedNode = (GraphNode) zestGraph.getSelection().get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
removeLabelItem.setText(GraphEditorMessages.getString("removeLabel"));
removeLabelItem.setMenu(removeLabelMenu);
for (NodeLabel label : nodeData.getNodeLabels()) {
MenuItem item = new MenuItem(removeLabelMenu, SWT.PUSH);
if (label instanceof AreaLabel) {
item.setText(GraphEditorMessages.getString("areaLabel"));
} else if (label instanceof PopulationLabel) {
item.setText(GraphEditorMessages.getString("populationLabel"));
}
item.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
MenuItem item = (MenuItem) e.getSource();
Menu menu = item.getParent();
List<MenuItem> allItems = Arrays.asList(menu.getItems());
int index = allItems.indexOf(item);
List<?> selection = zestGraph.getSelection();
GraphNode selectedNode = (GraphNode) selection.get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
NodeLabel label = nodeData.getNodeLabels().get(index);
removeNodeLabelFromStemGraph(label);
updateShell();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
}
private void createRemoveEdgeItem(Menu menu) {
MenuItem removeEdge = new MenuItem(menu, SWT.PUSH);
removeEdge.setText(GraphEditorMessages.getString("removeEdge"));
removeEdge.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
List<?> selectedItems = zestGraph.getSelection();
GraphConnection selectedEdge = (GraphConnection) selectedItems
.get(0);
ConnectionData edgeData = (ConnectionData) selectedEdge
.getData();
zestGraph.setSelection(new GraphItem[] {});
selectedEdge.dispose();
removeEdgeFromStemGraph(edgeData.getEdge());
updateShell();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private GraphNode processNode(Node node) {
LatLongProvider latLongProvider = (LatLongProvider) LatLongProviderAdapterFactory.INSTANCE
.adaptNew(node, LatLongProvider.class);
List<Segment> segments = latLongProvider.getLatLong().getSegments();
Set<Polygon> displayPolys = new HashSet<Polygon>();
int graphListIndex = 0;
double largestPolygonArea = 0.0;
Point2D.Double center = null;
for (int i = 0; i < graphList.size(); i++) {
if (graphList.get(i).getNodes().get(node.getURI()) != null) {
graphListIndex = i;
break;
}
}
for (Segment segment_tmp : segments) {
Polygon dPolygon = new Polygon(segment_tmp);
displayPolys.add(dPolygon);
if (dPolygon.getArea() > largestPolygonArea) {
largestPolygonArea = dPolygon.getArea();
center = dPolygon.getCentroid();
}
}
node.eAdapters().remove(latLongProvider);
if (center != null) {
GraphNode graphCenterNode = new GraphNode(zestGraph, SWT.NONE, "");
graphCenterNode.setData(new NodeData(node, center.x, center.y, 0,
graphListIndex));
setNodeColor(graphCenterNode);
graphPolygons.put(node.getURI(), displayPolys);
graphNodes.put(node.getURI(), graphCenterNode);
return graphCenterNode;
}
return null;
}
private GraphConnection processEdge(Edge edge) {
URI nodeAURI = edge.getNodeAURI();
URI nodeBURI = edge.getNodeBURI();
URI edgeURI = edge.getURI();
if (nodeAURI.toString().compareTo(nodeBURI.toString()) > 0) {
URI mem = nodeAURI;
nodeAURI = nodeBURI;
nodeBURI = mem;
}
if ((graphNodes.get(nodeAURI) != null)
&& (graphNodes.get(nodeBURI) != null)) {
GraphConnection gc = new GraphConnection(zestGraph, SWT.NONE,
graphNodes.get(nodeAURI), graphNodes.get(nodeBURI));
gc.setData(new ConnectionData(edge, 0));
setEdgeColor(gc);
preventOverlay(gc);
graphConnections.put(edgeURI, gc);
return gc;
}
return null;
}
private void addNodeLabel(EClass labelClass) {
List<?> selectedItems = zestGraph.getSelection();
GraphItem selectedNode = (GraphItem) selectedItems.get(0);
NodeData nodeData = (NodeData) selectedNode.getData();
NodeLabel label = null;
if (labelClass == LabelsPackage.Literals.AREA_LABEL) {
label = LabelsFactory.eINSTANCE.createAreaLabel();
((AreaLabel) label).getCurrentAreaValue().setArea(0.0);
label.setURIOfIdentifiableToBeLabeled(nodeData.getNodeURI());
label.setNode(nodeData.getNode());
} else if (labelClass == LabelsPackage.Literals.POPULATION_LABEL) {
label = LabelsFactory.eINSTANCE.createPopulationLabel();
((PopulationLabel) label).setPopulationIdentifier("");
((PopulationLabel) label).setPopulatedArea(0.0);
((PopulationLabel) label).getCurrentPopulationValue().setCount(0);
label.setURIOfIdentifiableToBeLabeled(nodeData.getNodeURI());
label.setNode(nodeData.getNode());
}
addNodeLabelToStemGraph(label);
updateShell(nodeData.getNodeLabels().size() - 1);
}
private void addEdge(EClass labelClass) {
List<?> selectedItems = zestGraph.getSelection();
GraphNode selectedNodeA = (GraphNode) selectedItems.get(0);
GraphNode selectedNodeB = (GraphNode) selectedItems.get(1);
NodeData nodeDataA = (NodeData) selectedNodeA.getData();
NodeData nodeDataB = (NodeData) selectedNodeB.getData();
Node nodeA = nodeDataA.getNode();
Node nodeB = nodeDataB.getNode();
Edge edge = null;
if (labelClass == EdgesPackage.Literals.MIGRATION_EDGE_LABEL) {
edge = createMigrationEdge(nodeA, nodeB);
} else if (labelClass == LabelsPackage.Literals.COMMON_BORDER_RELATIONSHIP_LABEL) {
edge = createCommonBorderEdge(nodeA, nodeB);
} else if (labelClass == LabelsPackage.Literals.ROAD_TRANSPORT_RELATIONSHIP_LABEL) {
edge = createRoadTransportEdge(nodeA, nodeB);
} else if (labelClass == TransportPackage.Literals.PIPE_TRANSPORT_EDGE_LABEL) {
edge = createPipeTransportEdge(nodeA, nodeB);
}
GraphConnection gc = processEdge(edge);
addEdgeToStemGraph(edge);
zestGraph.setSelection(new GraphItem[] { gc });
updateShell();
}
private Edge createCommonBorderEdge(Node nodeA, Node nodeB) {
Edge cbrEdge = EdgeImpl.createEdge(nodeA, nodeB);
CommonBorderRelationshipLabel cbrLabel = LabelsFactory.eINSTANCE
.createCommonBorderRelationshipLabel();
CommonBorderRelationshipLabelValue cbrLabelValue = (CommonBorderRelationshipLabelValue) cbrLabel
.getCurrentValue();
cbrEdge.setURI(getRandomURI(Edge.URI_TYPE_EDGE_SEGMENT
+ "/relationship/commonborder"));
cbrEdge.setLabel(cbrLabel);
cbrEdge.getDublinCore().setTitle(
createEdgeTitle(nodeA, nodeB, "Edge", false));
cbrLabel.setURIOfIdentifiableToBeLabeled(cbrEdge.getURI());
cbrLabelValue.setBorderLength(0.0);
return cbrEdge;
}
private MigrationEdge createMigrationEdge(Node nodeA, Node nodeB) {
MigrationEdge mEdge = EdgesFactory.eINSTANCE.createMigrationEdge();
mEdge.setURI(getRandomURI(MigrationEdge.URI_TYPE_MIGRATION_EDGE_SEGMENT));
mEdge.setNodeAURI(nodeA.getURI());
mEdge.setNodeBURI(nodeB.getURI());
mEdge.getLabel().setURIOfIdentifiableToBeLabeled(mEdge.getURI());
mEdge.getLabel().getCurrentValue().setMigrationRate(0.0);
mEdge.getDublinCore().setTitle(
createEdgeTitle(nodeA, nodeB, "MigrationEdge", true));
mEdge.setPopulationIdentifier("");
return mEdge;
}
private Edge createRoadTransportEdge(Node nodeA, Node nodeB) {
Edge edge = RoadTransportRelationshipLabelImpl
.createRoadTransportRelationship(nodeA, nodeB, "", "", 0);
edge.setURI(getRandomURI(Edge.URI_TYPE_EDGE_SEGMENT + "/road"));
edge.getLabel().setURIOfIdentifiableToBeLabeled(edge.getURI());
edge.getDublinCore().setTitle(
createEdgeTitle(nodeA, nodeB, "RoadEdge", false));
return edge;
}
private Edge createPipeTransportEdge(Node nodeA, Node nodeB) {
PipeTransportEdge edge = TransportFactory.eINSTANCE
.createPipeTransportEdge();
PipeTransportEdgeLabelValue edgeValue = TransportFactory.eINSTANCE
.createPipeTransportEdgeLabelValue();
edge.setURI(getRandomURI(PipeTransportEdgeImpl.URI_TYPE_PIPE_TRANSPORT_EDGE_SEGMENT));
edge.setA(nodeA);
edge.setB(nodeB);
edge.setNodeAURI(nodeA.getURI());
edge.setNodeBURI(nodeB.getURI());
edge.getLabel().setURIOfIdentifiableToBeLabeled(edge.getURI());
edge.getLabel().setCurrentValue(edgeValue);
edge.getDublinCore().setTitle(
createEdgeTitle(nodeA, nodeB, "Pipe", true));
edge.setPopulationIdentifier("");
edgeValue.setMaxFlow(0.0);
edgeValue.setTimePeriod(86400000);
return edge;
}
private void addNodeToStemGraph(Node node) {
stemGraph.getNodes().put(node.getURI(), node);
graphList.get(0).getNodes()
.put(node.getURI(), (Node) EcoreUtil.copy(node));
}
private void addEdgeToStemGraph(Edge edge) {
stemGraph.getEdges().put(edge.getURI(), edge);
for (Graph graph : graphList) {
if (graph.getNode(edge.getNodeAURI()) != null) {
graph.getEdges().put(edge.getURI(), EcoreUtil.copy(edge));
}
}
}
private void addNodeLabelToStemGraph(NodeLabel nodeLabel) {
NodeLabel nodeLabelCopy = EcoreUtil.copy(nodeLabel);
URI nodeURI = nodeLabel.getURIOfIdentifiableToBeLabeled();
stemGraph.getNodeLabels().put(nodeLabel.getURI(), nodeLabel);
stemGraph.getNode(nodeURI).getLabels().add(nodeLabel);
for (Graph graph : graphList) {
if (graph.getNode(nodeURI) != null) {
graph.getNodeLabels().put(nodeLabel.getURI(), nodeLabelCopy);
graph.getNode(nodeURI).getLabels().add(nodeLabelCopy);
}
}
}
private void removeNodeFromStemGraph(Node node) {
URI nodeURI = node.getURI();
List<URI> nodeLabelsToRemove = new ArrayList<URI>();
List<URI> edgesToRemove = new ArrayList<URI>();
for (NodeLabel nodeLabel : node.getLabels()) {
nodeLabelsToRemove.add(nodeLabel.getURI());
}
for (Edge edge : stemGraph.getEdges().values()) {
if (edge.getNodeAURI().equals(nodeURI)
|| edge.getNodeBURI().equals(nodeURI)) {
edgesToRemove.add(edge.getURI());
}
}
for (URI nodeLabelURI : nodeLabelsToRemove) {
stemGraph.getNodeLabels().removeKey(nodeLabelURI);
}
for (URI edgeURI : edgesToRemove) {
stemGraph.getEdges().removeKey(edgeURI);
}
stemGraph.getNodes().removeKey(nodeURI);
for (Graph graph : graphList) {
for (URI nodeLabelURI : nodeLabelsToRemove) {
graph.getNodeLabels().removeKey(nodeLabelURI);
}
for (URI edgeURI : edgesToRemove) {
graph.getEdges().removeKey(edgeURI);
}
graph.getNodes().removeKey(nodeURI);
}
}
private void removeEdgeFromStemGraph(Edge edge) {
URI edgeURI = edge.getURI();
stemGraph.getEdges().removeKey(edgeURI);
for (Graph graph : graphList) {
graph.getEdges().removeKey(edgeURI);
}
}
private void removeNodeLabelFromStemGraph(NodeLabel nodeLabel) {
URI labelURI = nodeLabel.getURI();
URI nodeURI = nodeLabel.getURIOfIdentifiableToBeLabeled();
stemGraph.getNode(nodeURI).getLabels()
.remove(stemGraph.getNodeLabel(labelURI));
stemGraph.getNodeLabels().removeKey(labelURI);
NodeLabel labelToRemove = null;
for (Graph graph : graphList) {
labelToRemove = graph.getNodeLabels().removeKey(labelURI);
}
for (Graph graph : graphList) {
if (graph.getNodes().containsKey(nodeURI)) {
graph.getNode(nodeURI).getLabels().remove(labelToRemove);
}
}
}
private void saveStemGraphAs() {
SaveInProjectDialog saveAsDialog = new SaveInProjectDialog(Activator
.getDefault().getWorkbench().getDisplay().getActiveShell());
saveAsDialog.open();
if (saveAsDialog.getResult() == null) {
return;
}
IFile saveAsFile = ResourcesPlugin.getWorkspace().getRoot()
.getFile(saveAsDialog.getResult());
saveGraph(stemGraph, saveAsFile.getProject(),
URI.createPlatformResourceURI(saveAsFile.getFullPath()
.toString(), false));
try {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
Activator.logError(e.getMessage(), e);
}
}
private void saveGraphList() {
for (Model model : modelList) {
EList<Graph> modelGraphs = model.getGraphs();
for (int i = 0; i < modelGraphs.size(); i++) {
URI graphURI = modelGraphs.get(i).getURI();
for (Graph graph : graphList) {
if (graph.getURI().equals(graphURI)) {
modelGraphs.set(i, graph);
break;
}
}
}
}
for (Graph graph : graphList) {
saveGraph(graph, project, graph.getURI());
}
for (Model model : modelList) {
if (model.getURI().isPlatformResource()) {
List<Identifiable> identifiables = new ArrayList<Identifiable>();
URI uri = model.getURI();
identifiables.add(model);
addContainments(identifiables, model);
try {
Utility.serializeIdentifiables(identifiables, uri);
} catch (IOException e) {
Activator.logError(e.getMessage(), e);
}
}
}
try {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
Activator.logError(e.getMessage(), e);
}
}
private void addContainments(List<Identifiable> identifiables, Model model) {
for (Graph subGraph : model.getGraphs()) {
if (!subGraph.getURI().isPlatformResource()) {
identifiables.add(subGraph);
}
}
for (Model subModel : model.getModels()) {
if (!subModel.getURI().isPlatformResource()) {
identifiables.add(subModel);
addContainments(identifiables, subModel);
}
}
}
private void saveGraph(Graph graph, IProject project, URI newURI) {
graph.setURI(newURI);
updateGraph(graph);
graph.getDublinCore().setTitle("");
String fileBaseName = graph.getURI().lastSegment()
.substring(0, graph.getURI().lastSegment().lastIndexOf("."));
String tail = project.getName() + "/.gml/" + fileBaseName + "_MAP.xml";
Map<URI, Set<Polygon>> currentGraphPolygons = new HashMap<URI, Set<Polygon>>();
if (!project.getFolder(".gml").exists()) {
IProgressMonitor monitor = new NullProgressMonitor();
try {
project.getFolder(".gml").create(false, true, monitor);
} catch (CoreException e) {
Activator.logError(e.getMessage(), e);
} finally {
monitor.done();
}
}
for (Node n : graph.getNodes().values()) {
Set<Polygon> displayPolygons = graphPolygons.get(n.getURI());
String spatialString = n.getDublinCore().getSpatial();
if (spatialString
.contains(SpatialProviderAdapter.STEM_SPATIAL_SCHEME_PREFIX
+ "inline")) {
LatLong latlon = new LatLong();
for (Polygon p : displayPolygons) {
SegmentBuilder sb = new SegmentBuilder();
for (int i = 0; i < p.npoints; i++) {
sb.add(p.y[i], p.x[i]);
}
latlon.add(sb.toSegment());
}
n.getDublinCore().setSpatial(
InlineLatLongDataProvider
.createSpatialInlineURIString(latlon));
} else if (spatialString
.contains(SpatialProviderAdapter.STEM_SPATIAL_SCHEME_PREFIX
+ "platform")) {
String newSpatialString = SpatialProviderAdapter.STEM_SPATIAL_SCHEME_PREFIX
+ "platform:/resource/"
+ tail
+ "#"
+ n.getURI().lastSegment();
n.getDublinCore().setSpatial(newSpatialString);
currentGraphPolygons.put(n.getURI(),
graphPolygons.get(n.getURI()));
}
}
if (!currentGraphPolygons.isEmpty()) {
String spatialString = SpatialProviderAdapter.STEM_SPATIAL_SCHEME_PREFIX
+ "platform:/resource/" + tail;
String fileName = ResourcesPlugin.getWorkspace().getRoot()
.getLocation().toString().concat("/" + tail);
SpatialGmlExporter.writeGML(fileName, graph.getURI(),
currentGraphPolygons);
graph.getDublinCore().setSpatial(spatialString);
}
if (graph.getURI().isPlatformResource()) {
try {
Utility.serializeIdentifiable(graph, graph.getURI());
} catch (IOException e) {
Activator.logError(e.getMessage(), e);
}
}
}
private void redraw() {
for (GraphNode gn : graphNodes.values()) {
NodeData nodeData = (NodeData) gn.getData();
double origX = nodeData.getOrigX();
double origY = nodeData.getOrigY();
double displayX = origX * scaleX + xTranslation;
double displayY = origY * scaleY + yTranslation;
gn.setSize(NODE_SIZE, NODE_SIZE);
gn.setLocation(displayX - NODE_SIZE / 2, displayY - NODE_SIZE / 2);
}
}
private void setInitialTransform() {
Rectangle zestBounds = zestGraph.getClientArea();
Rectangle2D.Double stemBounds = null;
for (Set<Polygon> polygons : graphPolygons.values()) {
for (Polygon p : polygons) {
if (stemBounds == null) {
stemBounds = p.getBounds();
} else {
stemBounds = (Rectangle2D.Double) stemBounds.createUnion(p
.getBounds());
}
}
}
double scaleFactor = Math.min(zestBounds.width / stemBounds.width,
zestBounds.height / stemBounds.height) * INITIAL_SCALE_FACTOR;
double zestCenterX = zestBounds.x + zestBounds.width / 2;
double zestCenterY = zestBounds.y + zestBounds.height / 2;
double stemCenterX = stemBounds.getCenterX();
double stemCenterY = stemBounds.getCenterY();
scaleX = scaleFactor;
scaleY = -scaleFactor; // y-axis points in opposite direction
xTranslation = zestCenterX - scaleX * stemCenterX;
yTranslation = zestCenterY - scaleY * stemCenterY;
}
private void updateGraph(Graph graph) {
for (Node graphNode : graph.getNodes().values()) {
Node stemGraphNode = stemGraph.getNode(graphNode.getURI());
graphNode.getDublinCore().setTitle(
stemGraphNode.getDublinCore().getTitle());
}
for (Edge graphEdge : graph.getEdges().values()) {
Edge stemGraphEdge = stemGraph.getEdge(graphEdge.getURI());
EdgeLabel graphLabel = graphEdge.getLabel();
EdgeLabel stemGraphLabel = stemGraphEdge.getLabel();
graphEdge.getDublinCore().setTitle(
stemGraphEdge.getDublinCore().getTitle());
if (graphLabel instanceof CommonBorderRelationshipLabel) {
CommonBorderRelationshipLabelValue graphLabelValue = (CommonBorderRelationshipLabelValue) graphLabel
.getCurrentValue();
CommonBorderRelationshipLabelValue stemGraphLabelValue = (CommonBorderRelationshipLabelValue) stemGraphLabel
.getCurrentValue();
graphLabelValue.setBorderLength(stemGraphLabelValue
.getBorderLength());
} else if (graphLabel instanceof MigrationEdgeLabel) {
MigrationEdge graphMigration = (MigrationEdge) graphEdge;
MigrationEdge stemGraphMigration = (MigrationEdge) stemGraphEdge;
MigrationEdgeLabelValue graphLabelValue = (MigrationEdgeLabelValue) graphEdge
.getLabel().getCurrentValue();
MigrationEdgeLabelValue stemGraphLabelValue = (MigrationEdgeLabelValue) stemGraphEdge
.getLabel().getCurrentValue();
graphMigration.setPopulationIdentifier(stemGraphMigration
.getPopulationIdentifier());
graphMigration.setUseAbsoluteValues(stemGraphMigration
.isUseAbsoluteValues());
graphLabelValue.setMigrationRate(stemGraphLabelValue
.getMigrationRate());
graphLabelValue.setTimePeriod(stemGraphLabelValue
.getTimePeriod());
} else if (graphLabel instanceof RoadTransportRelationshipLabel) {
RoadTransportRelationshipLabelValue graphLabelValue = (RoadTransportRelationshipLabelValue) graphLabel
.getCurrentValue();
RoadTransportRelationshipLabelValue stemGraphLabelValue = (RoadTransportRelationshipLabelValue) stemGraphLabel
.getCurrentValue();
graphLabelValue.setRoadName(stemGraphLabelValue.getRoadName());
graphLabelValue
.setRoadClass(stemGraphLabelValue.getRoadClass());
graphLabelValue.setNumberCrossings(stemGraphLabelValue
.getNumberCrossings());
} else if (graphLabel instanceof PipeTransportEdgeLabel) {
PipeTransportEdge graphPipe = (PipeTransportEdge) graphEdge;
PipeTransportEdge stemGraphPipe = (PipeTransportEdge) stemGraphEdge;
PipeTransportEdgeLabelValue graphLabelValue = (PipeTransportEdgeLabelValue) graphEdge
.getLabel().getCurrentValue();
PipeTransportEdgeLabelValue stemGraphLabelValue = (PipeTransportEdgeLabelValue) stemGraphEdge
.getLabel().getCurrentValue();
graphPipe.setPopulationIdentifier(stemGraphPipe
.getPopulationIdentifier());
graphLabelValue.setMaxFlow(stemGraphLabelValue.getMaxFlow());
graphLabelValue.setTimePeriod(stemGraphLabelValue
.getTimePeriod());
}
}
for (NodeLabel graphLabel : graph.getNodeLabels().values()) {
NodeLabel stemGraphLabel = stemGraph.getNodeLabel(graphLabel
.getURI());
if (graphLabel instanceof PopulationLabel) {
PopulationLabel graphPopLabel = (PopulationLabel) graphLabel;
PopulationLabel stemGraphPopLabel = (PopulationLabel) stemGraphLabel;
graphPopLabel.setPopulationIdentifier(stemGraphPopLabel
.getPopulationIdentifier());
graphPopLabel.getCurrentPopulationValue().setCount(
stemGraphPopLabel.getCurrentPopulationValue()
.getCount());
graphPopLabel.setPopulatedArea(stemGraphPopLabel
.getPopulatedArea());
} else if (graphLabel instanceof AreaLabel) {
AreaLabel graphAreaLabel = (AreaLabel) graphLabel;
AreaLabel stemGraphAreaLabel = (AreaLabel) stemGraphLabel;
graphAreaLabel.getCurrentAreaValue().setArea(
stemGraphAreaLabel.getCurrentAreaValue().getArea());
}
}
}
private void addTranslationToNode(NodeData nodeData, int xTranslation,
int yTranslation) {
Set<Polygon> displayPolygons = graphPolygons.get(nodeData.getNodeURI());
double dx = xTranslation / scaleX;
double dy = yTranslation / scaleY;
nodeData.setOrigX(nodeData.getOrigX() + dx);
nodeData.setOrigY(nodeData.getOrigY() + dy);
for (Polygon polygon : displayPolygons) {
for (int i = 0; i < polygon.npoints; i++) {
polygon.x[i] += dx;
polygon.y[i] += dy;
}
}
}
private int[] polygon2IntArray(Polygon poly) {
if (poly.npoints == 0) {
return new int[] { 0, 0 };
}
int[] points = new int[poly.npoints * 2];
for (int i = 0; i < poly.npoints; i++) {
points[i * 2] = (int) Math.round(poly.x[i] * scaleX + xTranslation);
points[i * 2 + 1] = (int) Math.round(poly.y[i] * scaleY
+ yTranslation);
}
return points;
}
private String createEdgeTitle(Node nodeA, Node nodeB, String typeName,
boolean directed) {
String nA = nodeA.getDublinCore().getTitle();
String nB = nodeB.getDublinCore().getTitle();
String title = null;
if (directed) {
title = typeName + "[(" + nA + ")->(" + nB + ")]";
} else {
title = typeName + "[(" + nA + ")<->(" + nB + ")]";
}
return title;
}
private URI getRandomURI(String segment) {
URI uri = null;
boolean isDuplicate = true;
while (isDuplicate) {
uri = STEMURI.createURI(segment + "/"
+ STEMURI.generateUniquePart());
isDuplicate = stemGraph.getNodes().containsKey(uri)
|| stemGraph.getEdges().contains(uri);
}
return uri;
}
private void preventOverlay(GraphConnection connection) {
ConnectionData edgeData = (ConnectionData) connection.getData();
List<GraphConnection> sameConnections = new ArrayList<GraphConnection>();
int curveDepth = 0;
for (GraphConnection c : graphConnections.values()) {
GraphNode source1 = connection.getSource();
GraphNode destination1 = connection.getDestination();
GraphNode source2 = c.getSource();
GraphNode destination2 = c.getDestination();
if (source1 == source2 && destination1 == destination2) {
if (!(c.equals(connection))) {
sameConnections.add(c);
}
}
}
for (int i = 0; i < sameConnections.size(); i++) {
boolean exists = false;
for (GraphConnection c : sameConnections) {
if (((ConnectionData) c.getData()).getCurveDepth() == curveDepth) {
exists = true;
break;
}
}
if (!exists) {
break;
}
curveDepth = NODE_SIZE * (int) Math.ceil((i + 1.0) / 2.0)
* (int) Math.pow(-1, i);
}
edgeData.setCurveDepth(curveDepth);
connection.setCurveDepth(curveDepth);
}
private Point2D.Double getCoordinatesFromCursorLocation(Point xy) {
double x_back = (xy.x - xTranslation) / scaleX;
double y_back = (xy.y - yTranslation) / scaleY;
return new Point2D.Double(x_back, y_back);
}
private String formatLatLon(double lat, double lon) {
DecimalFormat df = new DecimalFormat("0.00",
DecimalFormatSymbols.getInstance(Locale.US));
return df.format(lat) + " " + df.format(lon);
}
private String formatDouble(double value) {
DecimalFormat df = new DecimalFormat("0.00",
DecimalFormatSymbols.getInstance(Locale.US));
return df.format(value);
}
private void checkSelectionVisible() {
Object selectedItem = zestGraph.getSelection().get(0);
int yMax = zestGraph.getSize().y;
int yPos = 0;
if (selectedItem instanceof GraphNode) {
GraphNode node = (GraphNode) selectedItem;
yPos = node.getLocation().y;
} else if (selectedItem instanceof GraphConnection) {
GraphConnection connection = (GraphConnection) selectedItem;
GraphNode node1 = connection.getSource();
GraphNode node2 = connection.getDestination();
yPos = (node1.getLocation().y + node2.getLocation().y) / 2;
}
if (yPos + NODE_SIZE > yMax) {
yTranslation += (yMax - NODE_SIZE - yPos);
zestGraph.redraw();
redraw();
}
}
private void setNodeColor(GraphNode gn) {
NodeData data = (NodeData) gn.getData();
switch (data.getGraphListIndex()) {
case 0:
gn.setBackgroundColor(ColorConstants.black);
return;
case 1:
gn.setBackgroundColor(ColorConstants.red);
return;
case 2:
gn.setBackgroundColor(ColorConstants.green);
return;
case 3:
gn.setBackgroundColor(ColorConstants.blue);
return;
case 4:
gn.setBackgroundColor(ColorConstants.yellow);
return;
case 5:
gn.setBackgroundColor(ColorConstants.orange);
return;
case 6:
gn.setBackgroundColor(ColorConstants.cyan);
return;
}
gn.setBackgroundColor(ColorConstants.black);
}
private void setEdgeColor(GraphConnection gc) {
ConnectionData cd = (ConnectionData) gc.getData();
EdgeLabel label = cd.getEdgeLabel();
if (label instanceof MigrationEdgeLabel) {
gc.setLineStyle(SWT.LINE_SOLID);
} else if (label instanceof CommonBorderRelationshipLabel) {
gc.setLineStyle(SWT.LINE_DOT);
} else if (label instanceof RoadTransportRelationshipLabel) {
gc.setLineStyle(SWT.LINE_DASH);
} else if (label instanceof PipeTransportEdgeLabel) {
gc.setLineStyle(SWT.LINE_DASHDOT);
}
}
}