package org.simantics.district.network.ui.table; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.inject.Inject; import javax.inject.Named; 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.e4.ui.workbench.modeling.EPartService; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.SelectionStatusDialog; import org.geotools.geometry.DirectPosition2D; import org.geotools.referencing.CRS; import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.IndexRoot; 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.request.PossibleActiveModel; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ui.function.Functions; import org.simantics.modeling.ModelingResources; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ImportCSVHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ImportCSVHandler.class); @Inject EPartService partService; @Execute public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell s) { // here we can import based on the current CSV table data MPart activePart = partService.getActivePart(); Object object = activePart.getObject(); // this object is the part wrapped by e4part DistrictCSVTableView view = (DistrictCSVTableView) object; String[][] data = view.getCurrentData(); SelectionDialog d = new SelectionDialog(s); if (d.open() == Dialog.CANCEL) return; String sourceEPSGCRS = d.getSourceCRS();//"EPSG:3067"; Resource targetDiagram = d.getTargetDiagram(); Resource mappingType = d.getMappingType(); try { MathTransform transform = null; boolean doTransform = false; // if sourceEPSGCRS is empty || null then ignore transformation if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) { CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS); CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326"); transform = CRS.findMathTransform(sourceCRS, targetCRS, false); doTransform = true; } final MathTransform finalTransform = transform; int x = xColumn(data); int y = yColumn(data); int z = zColumn(data); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { for (int i = 1; i < data.length; i++) { try { String[] rows = data[i]; String xCoords = rows[x]; String yCoords = rows[y]; double xCoord = Double.parseDouble(xCoords); double yCoord = Double.parseDouble(yCoords); DirectPosition2D targetPos = new DirectPosition2D(); DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord); DirectPosition res = finalTransform.transform(sourcePos, targetPos); double[] coords = res.getCoordinate(); flipAxes(coords); Resource vertex = DistrictNetworkUtil.createVertex(graph, targetDiagram, coords, z, mappingType); } catch (Exception e) { LOGGER.error("", e); } } } }); } catch (Exception e) { LOGGER.error("", e); } } private static void flipAxes(double[] coords) { double tmp = coords[0]; coords[0] = coords[1]; coords[1] = tmp; } private int zColumn(String[][] data) { return column("z", data); } private int yColumn(String[][] data) { return column("y", data); } private int xColumn(String[][] data) { return column("x", data); } private int column(String expected, String[][] data) { String[] columns = data[0]; // first row should be headers for (int i = 0; i < columns.length; i++) { String col = columns[i]; if (col.equals(expected)) { return i; } } return -1; } private static class SelectionDialog extends SelectionStatusDialog { private Map diagrams = new HashMap<>(); private Map vertexMappings = new HashMap<>(); private Composite composite; private Combo networkDiagramSelectionCombo; private Combo sourceCRSCombo; private Combo vertexMappingCombo; private String sourceCRS; private Resource diagram; private Resource mapping; public SelectionDialog(Shell parent) { super(parent); } public Resource getMappingType() { return mapping; } public Resource getTargetDiagram() { return diagram; } public String getSourceCRS() { return "EPSG:" + sourceCRS; } @Override protected Control createDialogArea(Composite parent) { composite = (Composite) super.createDialogArea(parent); createMappingsGroup(composite); computeContent(); return composite; } private void computeContent() { Simantics.getSession().asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { Resource indexRoot = graph.sync(new IndexRoot(graph.sync(new PossibleActiveModel(Simantics.getProjectResource())))); vertexMappings = Functions.getVertexMappings(graph, indexRoot); Collection diagramss = Functions.getDistrictDiagrams(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Resource projectResource = Simantics.getProjectResource(); String projectURI = graph.getURI(projectResource); for (Resource diagram : diagramss) { Resource composite = graph.getSingleObject(diagram, MOD.DiagramToComposite); String compositeURI = graph.getURI(composite); String path = compositeURI.replace(projectURI, ""); diagrams.put(path, diagram); } composite.getDisplay().asyncExec(() -> { vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()])); networkDiagramSelectionCombo.setItems(diagrams.keySet().toArray(new String[diagrams.size()])); if (diagrams.size() > 0) { networkDiagramSelectionCombo.select(0); } Set codes = CRS.getSupportedCodes("EPSG"); sourceCRSCombo.setItems(codes.toArray(new String[codes.size()])); sourceCRSCombo.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { String currentText = sourceCRSCombo.getText(); if (codes.contains(currentText)) { // Select this String[] items = sourceCRSCombo.getItems(); int i; for (i = 0; i < items.length; i++) { String item = items[i]; if (currentText.equals(item)) { break; } } if (i != 0) { sourceCRSCombo.select(i); } else { System.err.println("Should not happen"); } } } }); }); } }); } private void createMappingsGroup(Composite parent) { Group group= new Group(parent, SWT.NONE); group.setFont(parent.getFont()); group.setText("Select Diagram & CRS"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); group.setLayout(new GridLayout(1, false)); Composite cmposite = new Composite(group, SWT.NONE); cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); cmposite.setLayout(new GridLayout(2, false)); Label vertexMappingLabel = new Label(cmposite, SWT.NONE); vertexMappingLabel.setText("Select Vertex Mapping"); vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo); Label selectNetworkDiagramLabel = new Label(cmposite, SWT.NONE); selectNetworkDiagramLabel.setText("Select Network Diagram"); networkDiagramSelectionCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).applyTo(networkDiagramSelectionCombo); Label label = new Label(cmposite, SWT.NONE); label.setText("Select Source Coordinate Reference System"); sourceCRSCombo = new Combo(cmposite, SWT.NONE); sourceCRSCombo.setToolTipText("Select the coordinate reference system that is used in the source material for possible transformation to target coordinate reference system (EPSG:4326)"); GridDataFactory.fillDefaults().grab(true, false).applyTo(sourceCRSCombo); } @Override protected void computeResult() { mapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex())); diagram = diagrams.get(networkDiagramSelectionCombo.getItem(networkDiagramSelectionCombo.getSelectionIndex())); sourceCRS = sourceCRSCombo.getItem(sourceCRSCombo.getSelectionIndex()); } } }