From 02ecca5e61d2eb17de40cc058be678b414aaad00 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Mon, 15 May 2017 14:06:05 +0300 Subject: [PATCH] Enhancements to district functionalities and code Change-Id: Ia388a879d9624724a66f6ce7c7d7891e553bb172 --- .../META-INF/MANIFEST.MF | 8 +- .../district/imports/ui/CSVImportModel.java | 135 ++++++ .../district/imports/ui/CSVImportWizard.java | 98 ++++- .../imports/ui/CSVImportWizardFirstPage.java | 125 ++++++ .../imports/ui/CSVImportWizardPage.java | 394 ++++++++++++++---- .../imports/ui/ComponentMappingPage.java | 133 ++++++ .../ui/controls/DynamicComboFieldEditor.java | 218 ++++++++++ .../district/imports/DistrictImportUtils.java | 22 +- .../simantics/maps/MapScalingTransform.java | 19 + .../src/org/simantics/maps/sg/MapNode.java | 5 +- .../graph.tg | Bin 2504 -> 2444 bytes .../graph/DistrictNetworkUI.pgraph | 10 +- .../META-INF/MANIFEST.MF | 3 +- .../fragment.e4xmi | 3 + .../district/network/ui/DNEdgeBuilder.java | 45 +- .../network/ui/DistrictDiagramViewer.java | 2 +- .../network/ui/DistrictNetworkEdge.java | 47 ++- .../adapters/DistrictNetworkEdgeElement.java | 2 +- .../DistrictNetworkEdgeElementFactory.java | 7 +- .../ChangeMappingTypeHandler.java | 190 +++++++++ .../network/ui/function/Functions.java | 17 +- .../ui/nodes/DistrictNetworkEdgeNode.java | 8 +- .../ui/nodes/DistrictNetworkVertexNode.java | 2 + .../network/ui/nodes/MapRulerNode.java | 2 + .../network/ui/nodes/NetworkDrawingNode.java | 1 + .../ui/participants/DNTranslateMode.java | 1 + .../META-INF/MANIFEST.MF | 3 +- .../district/network/DistrictNetworkUtil.java | 26 +- .../district/network/ModelledCRS.java | 5 +- .../simantics/maps/server/ui/Activator.java | 8 +- .../district/maps/server/Activator.java | 16 +- 31 files changed, 1393 insertions(+), 162 deletions(-) create mode 100644 org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardFirstPage.java create mode 100644 org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/ComponentMappingPage.java create mode 100644 org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/controls/DynamicComboFieldEditor.java create mode 100644 org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeMappingTypeHandler.java diff --git a/org.simantics.district.imports.ui/META-INF/MANIFEST.MF b/org.simantics.district.imports.ui/META-INF/MANIFEST.MF index 48019c70..b7d0aa63 100644 --- a/org.simantics.district.imports.ui/META-INF/MANIFEST.MF +++ b/org.simantics.district.imports.ui/META-INF/MANIFEST.MF @@ -10,5 +10,11 @@ Require-Bundle: org.eclipse.ui.ide, org.simantics.district.imports;bundle-version="1.0.0", org.simantics.db, org.simantics.district.geotools;bundle-version="1.0.0", - org.simantics.district.network.ui;bundle-version="1.0.0" + org.simantics.district.network.ui;bundle-version="1.0.0", + org.simantics.db.common, + org.simantics, + org.simantics.diagram.ontology, + org.simantics.modeling.ontology, + org.simantics.district.network, + org.simantics.district.network.ontology Bundle-ActivationPolicy: lazy diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java index 1521a926..53de5cfe 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java @@ -3,20 +3,46 @@ package org.simantics.district.imports.ui; import java.io.IOException; import java.nio.file.Path; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.csv.CSVRecord; +import org.simantics.db.Resource; import org.simantics.district.imports.DistrictImportUtils; import org.simantics.district.imports.DistrictImportUtils.CSVHeader; public class CSVImportModel { + // First page fills these + private Resource targetDiagram; private Path source; + + // Second page fills these private char delimiter; private boolean read; private Map delimiters; private Path wktFile; + + // Vertex import + private int xCoordIndex = -1; + private int yCoordIndex = -1; + private int zCoordIndex = -1; + + // Edge import + private int startXCoordIndex = -1; + private int startYCoordIndex = -1; + private int startZCoordIndex = -1; + private int endXCoordIndex = -1; + private int endYCoordIndex = -1; + private int endZCoordIndex = -1; + + // common + private int componentMappingIndex = -1; + private Map componentMappings = new HashMap<>(); + private boolean isVertexImport; + + // Third page public CSVImportModel() { delimiters = DistrictImportUtils.getSupportedCSVDelimiterFormats(); @@ -87,4 +113,113 @@ public class CSVImportModel { public Path getWKTFile() { return wktFile; } + + public int getXCoordIndex() { + return xCoordIndex; + } + + public void setXCoordIndex(int xCoordIndex) { + this.xCoordIndex = xCoordIndex; + } + + public int getYCoordIndex() { + return yCoordIndex; + } + + public void setYCoordIndex(int yCoordIndex) { + this.yCoordIndex = yCoordIndex; + } + + public int getZCoordIndex() { + return zCoordIndex; + } + + public void setZCoordIndex(int zCoordIndex) { + this.zCoordIndex = zCoordIndex; + } + + public int getComponentMappingIndex() { + return componentMappingIndex; + } + + public void setComponentMappingIndex(int componentMappingIndex) { + this.componentMappingIndex = componentMappingIndex; + } + + public void setParentDiagram(Resource diagram) { + this.targetDiagram = diagram; + } + + public Resource getParentDiagram() { + return targetDiagram; + } + + public void setWKTFile(Path wktFile) { + this.wktFile = wktFile; + } + + public void setComponentMappings(String value, Resource resource) { + componentMappings.put(value, resource); + } + + public Map getComponentMappings() { + return componentMappings; + } + + public boolean isVertexImport() { + return isVertexImport; + } + + public void setVertexImport(boolean isVertexImport) { + this.isVertexImport = isVertexImport; + } + + public void setStartXCoordIndex(int parseInt) { + this.startXCoordIndex = parseInt; + } + + public int getStartXCoordIndex() { + return startXCoordIndex; + } + + public void setStartYCoordIndex(int parseInt) { + this.startYCoordIndex = parseInt; + } + + public int getStartYCoordIndex() { + return startYCoordIndex; + } + + public void setStartZCoordIndex(int parseInt) { + this.startZCoordIndex = parseInt; + } + + public int getStartZCoordIndex() { + return startZCoordIndex; + } + + public void setEndXCoordIndex(int parseInt) { + this.endXCoordIndex = parseInt; + } + + public int getEndXCoordIndex() { + return endXCoordIndex; + } + + public void setEndYCoordIndex(int parseInt) { + this.endYCoordIndex = parseInt; + } + + public int getEndYCoordIndex() { + return endYCoordIndex; + } + + public void setEndZCoordIndex(int parseInt) { + this.endZCoordIndex = parseInt; + } + + public int getEndZCoordIndex() { + return endZCoordIndex; + } + } diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java index 7a29e750..58fd168c 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java @@ -9,10 +9,24 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.IImportWizard; import org.eclipse.ui.IWorkbench; +import org.geotools.geometry.DirectPosition2D; import org.geotools.referencing.CRS; +import org.opengis.geometry.DirectPosition; +import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Write; import org.simantics.district.imports.DistrictImportUtils; +import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.district.network.ui.DNEdgeBuilder; public class CSVImportWizard extends Wizard implements IImportWizard { @@ -26,7 +40,9 @@ public class CSVImportWizard extends Wizard implements IImportWizard { @Override public void init(IWorkbench workbench, IStructuredSelection selection) { model = new CSVImportModel(); + addPage(new CSVImportWizardFirstPage(model)); addPage(new CSVImportWizardPage(model)); + addPage(new ComponentMappingPage(model)); } @Override @@ -41,17 +57,87 @@ public class CSVImportWizard extends Wizard implements IImportWizard { Path wktFile = model.getWKTFile(); + int xCoordColumnIndex = model.getXCoordIndex(); + int yCoordColumnIndex = model.getYCoordIndex(); + int zCoordColumnIndex = model.getZCoordIndex(); + + int startXCoordColumnIndex = model.getStartXCoordIndex(); + int startYCoordColumnIndex = model.getStartYCoordIndex(); + int startZValueColumnIndex = model.getStartZCoordIndex(); + int endXCoordColumnIndex = model.getEndXCoordIndex(); + int endYCoordColumnIndex = model.getEndYCoordIndex(); + int endZValueColumnIndex = model.getEndZCoordIndex(); + + int mappingColumn = model.getComponentMappingIndex(); + try { + CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:3879"); + CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326"); + MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true); - - CoordinateReferenceSystem crs = CRS.decode(null); - } catch (FactoryException e) { - // TODO Auto-generated catch block + Simantics.getSession().syncRequest(new Write() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for (int k = 1; k < rows.size(); k++) { + CSVRecord row = rows.get(k); + + String mappingValue = row.get(mappingColumn); + + try { + if (model.isVertexImport()) { + String xCoords = row.get(xCoordColumnIndex); + String yCoords = row.get(yCoordColumnIndex); + double xCoord = Double.parseDouble(xCoords); + double yCoord = Double.parseDouble(yCoords); + + String zs = row.get(zCoordColumnIndex); + double z = Double.parseDouble(zs); + + DirectPosition2D targetPos = new DirectPosition2D(); + DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord); + DirectPosition res = transform.transform(sourcePos, targetPos); + double[] coords = res.getCoordinate(); + Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), new double[] { coords[1], -coords[0]}, model.getComponentMappings().get(mappingValue)); + graph.claimLiteral(vertex, DistrictNetworkResource.getInstance(graph).Vertex_HasElevation, z, Bindings.DOUBLE); + } else { + String startXCoords = row.get(startXCoordColumnIndex); + String startYCoords = row.get(startYCoordColumnIndex); + String endXCoords = row.get(endXCoordColumnIndex); + String endYCoords = row.get(endYCoordColumnIndex); + + double startXCoord = Double.parseDouble(startXCoords); + double startYCoord = Double.parseDouble(startYCoords); + + double endXCoord = Double.parseDouble(endXCoords); + double endYCoord = Double.parseDouble(endYCoords); + + DirectPosition2D startTargetPos = new DirectPosition2D(); + DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord); + DirectPosition startRes = transform.transform(startSourcePos, startTargetPos); + double[] startCoords = startRes.getCoordinate(); + + DirectPosition2D endTargetPos = new DirectPosition2D(); + DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord); + DirectPosition endRes = transform.transform(endSourcePos, endTargetPos); + double[] endCoords = endRes.getCoordinate(); + + Resource edge = DNEdgeBuilder.create(graph, model.getParentDiagram(), new double[] { startCoords[1], -startCoords[0]}, new double[] { endCoords[1], -endCoords[0]}, 0.0000001); + graph.claim(edge, DistrictNetworkResource.getInstance(graph).HasMapping, model.getComponentMappings().get(mappingValue)); +// graph.claimLiteral(edge, DistrictNetworkResource.getInstance(graph).Edge_HasDiameter, value); + } + } catch (MismatchedDimensionException | TransformException | DatabaseException e) { + e.printStackTrace(); + } + + } + } + }); + return true; + } catch (FactoryException | DatabaseException e) { e.printStackTrace(); } - - DistrictImportUtils.importCSVAsLayer(csvFile); } catch (IOException e) { e.printStackTrace(); } diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardFirstPage.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardFirstPage.java new file mode 100644 index 00000000..830b1264 --- /dev/null +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardFirstPage.java @@ -0,0 +1,125 @@ +package org.simantics.district.imports.ui; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.district.network.ui.function.Functions; +import org.simantics.modeling.ModelingResources; +import org.simantics.utils.ui.widgets.FileOrDirectorySelectionWidget; +import org.simantics.utils.ui.widgets.FileSelectionListener; +import org.simantics.utils.ui.widgets.FileSelectionWidget; + +public class CSVImportWizardFirstPage extends WizardPage implements FileSelectionListener { + + private final CSVImportModel model; + + private Map diagrams = new HashMap<>(); + + private Combo diagramCombo; + private FileSelectionWidget csvSelection; + + public CSVImportWizardFirstPage(CSVImportModel model) { + super("Select source for CSV data"); + this.model = model; + setMessage("Select target network diagram and source for CSV-data"); + } + + @Override + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1,false)); + GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite); + + Group parentConfigurationGroup = new Group(composite, SWT.NONE); + parentConfigurationGroup.setText("Select target network diagram"); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(parentConfigurationGroup); + + diagramCombo = new Combo(parentConfigurationGroup, SWT.DROP_DOWN | SWT.READ_ONLY); + diagramCombo.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + String selection = diagramCombo.getItem(diagramCombo.getSelectionIndex()); + model.setParentDiagram(diagrams.get(selection)); + validateComplete(); + } + }); + + GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(parentConfigurationGroup); + + csvSelection = new FileSelectionWidget(composite, "CSV file", SWT.OPEN); + csvSelection.addListener(this); + + updateAvailableParents(); + + validateComplete(); + + setControl(composite); + } + + private void updateAvailableParents() { + try { + Simantics.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Collection diagrams = Functions.getDistrictDiagrams(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + Resource projectResource = Simantics.getProjectResource(); + String projectURI = graph.getURI(projectResource); + for (Resource diagram : diagrams) { + Resource composite = graph.getSingleObject(diagram, MOD.DiagramToComposite); + String compositeURI = graph.getURI(composite); + String path = compositeURI.replace(projectURI, ""); + CSVImportWizardFirstPage.this.diagrams.put(path, diagram); + } + } + }); + diagramCombo.setItems(diagrams.keySet().toArray(new String[diagrams.size()])); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) { + String[] selection = csvSelection.getFilename(); + if (selection != null && selection.length > 0) { + Path csvFile = Paths.get(selection[0]); + if (!Files.exists(csvFile)) { + setErrorMessage("File " + csvFile.toAbsolutePath() + " does not exist"); + } else { + model.setSource(csvFile); + validateComplete(); + } + } + } + + private void validateComplete() { + setPageComplete(model.getSource() != null && model.getParentDiagram() != null); + } +} diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java index e4a0612a..9d1d08c4 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java @@ -4,13 +4,19 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.apache.commons.csv.CSVRecord; +import org.eclipse.jface.dialogs.IPageChangeProvider; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.wizard.IWizardContainer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; @@ -19,144 +25,371 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; -import org.simantics.district.network.ui.function.Functions; +import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor; import org.simantics.utils.ui.widgets.FileOrDirectorySelectionWidget; import org.simantics.utils.ui.widgets.FileSelectionListener; import org.simantics.utils.ui.widgets.FileSelectionWidget; - -public class CSVImportWizardPage extends WizardPage implements FileSelectionListener { +public class CSVImportWizardPage extends WizardPage { private CSVImportModel model; - private FileSelectionWidget csvSelection; + + private Map headerIndexAndValues = new HashMap<>(); + private Table headerTable; private Button firstAsHeader; - - private Combo diagramCombo; - - + private Combo delimiterCombo; - private Combo delimiterdCombo; private TableColumnLayout tableColumnLayout; - private TableViewer tableViewer; private Composite tableComposite; private FileSelectionWidget wktFileSelection; + + // Common for vertex and edge + private DynamicComboFieldEditor componentMappingSelector; + private DynamicComboFieldEditor labelSelector; - private Path wktFile; + // For vertex import + private DynamicComboFieldEditor xCoordSelector; + private DynamicComboFieldEditor yCoordSelector; + private DynamicComboFieldEditor zValueSelector; + + // For edge import + private DynamicComboFieldEditor startXCoordSelector; + private DynamicComboFieldEditor startYCoordSelector; + private DynamicComboFieldEditor startZValueSelector; + private DynamicComboFieldEditor endXCoordSelector; + private DynamicComboFieldEditor endYCoordSelector; + private DynamicComboFieldEditor endZValueSelector; + + private Group indexMappingGroup; + + private Composite composite; + private Button isVertexImport; + protected CSVImportWizardPage(CSVImportModel model) { super("Import CSV Data"); this.model = model; - setMessage("Select CSV file to import"); + setMessage("Select columng index mappings"); } @Override public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout(1,false)); + composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1, false)); GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite); - - diagramCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); - diagramCombo.setItems(getDistrictDiagrams()); - - - csvSelection = new FileSelectionWidget(composite, "CSV file", SWT.OPEN); - csvSelection.addListener(this); - + delimiterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); delimiterCombo.setItems(model.getDelimiterFormats()); delimiterCombo.addSelectionListener(new SelectionListener() { - + @Override public void widgetSelected(SelectionEvent e) { model.setDelimiterByLabel(delimiterCombo.getItem(delimiterCombo.getSelectionIndex())); updateHeaders(); + updateCombos(); } - + @Override public void widgetDefaultSelected(SelectionEvent e) { - + widgetSelected(e); } }); - + firstAsHeader = new Button(composite, SWT.CHECK); firstAsHeader.setText("Read first row as header"); firstAsHeader.setSelection(model.getReadFirstAsHeader()); firstAsHeader.addSelectionListener(new SelectionListener() { - + @Override public void widgetSelected(SelectionEvent e) { model.setReadFirstAsHeader(firstAsHeader.getSelection()); updateHeaders(); + updateCombos(); } - + @Override public void widgetDefaultSelected(SelectionEvent e) { - + } }); - - + tableComposite = new Composite(composite, SWT.BORDER); tableColumnLayout = new TableColumnLayout(); tableComposite.setLayout(tableColumnLayout); - - wktFileSelection = new FileSelectionWidget(composite, "WKT file", SWT.OPEN); wktFileSelection.addListener(new FileSelectionListener() { - + @Override public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) { String[] selection = wktFileSelection.getFilename(); if (selection != null && selection.length > 0) { - Path wktFilee = Paths.get(selection[0]); - if (!Files.exists(wktFilee)) { - setErrorMessage("File " + wktFilee.toAbsolutePath() + " does not exist"); + Path wktFile = Paths.get(selection[0]); + if (!Files.exists(wktFile)) { + setErrorMessage("File " + wktFile.toAbsolutePath() + " does not exist"); } else { - wktFile = wktFilee; - setPageComplete(true); + model.setWKTFile(wktFile); + validatePageComplete(); } - } else { - setPageComplete(false); - } + } + } + }); + + isVertexImport = new Button(composite, SWT.CHECK); + isVertexImport.setText("File contains vertices"); + isVertexImport.setSelection(model.isVertexImport()); + isVertexImport.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + model.setVertexImport(isVertexImport.getSelection()); + updateControls(false); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); } }); + updateControls(true); updateHeaders(); + setControl(composite); + + final IWizardContainer container = getContainer(); + if (container instanceof IPageChangeProvider) { + ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() { + + @Override + public void pageChanged(PageChangedEvent event) { + if (isCurrentPage()) + CSVImportWizardPage.this.updateControls(false); + } + }); + } + + validatePageComplete(); + } + + private void updateControls(boolean initial) { + createIndexMappingGroup(); + updateCombos(); + if (!initial) + composite.layout(true, true); + } + + private void createIndexMappingGroup() { + if (indexMappingGroup != null) + indexMappingGroup.dispose(); + indexMappingGroup = new Group(composite, SWT.NONE); + indexMappingGroup.setText("Column index mapping"); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(indexMappingGroup); - setControl(composite); + if (model.isVertexImport()) + createVertexIndexMappingField(indexMappingGroup); + else + createEdgeIndexMappingField(indexMappingGroup); + createCommonIndexMappingField(indexMappingGroup); + } + + private void createCommonIndexMappingField(Group parent) { + componentMappingSelector = new DynamicComboFieldEditor("componentMapping", "Apros component mapping", parent); + componentMappingSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setComponentMappingIndex(Integer.parseInt(componentMappingSelector.getValue())); + validatePageComplete(); + } + }); - setPageComplete(false); } - private String[] getDistrictDiagrams() { - Functions.getDistrictDiagrams(null); - return null; + private void createVertexIndexMappingField(Group parent) { + xCoordSelector = new DynamicComboFieldEditor("xCoord", "X Coordinate", parent); + xCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setXCoordIndex(Integer.parseInt(xCoordSelector.getValue())); + validatePageComplete(); + } + }); + + yCoordSelector = new DynamicComboFieldEditor("yCoord", "Y Coordinate", parent); + yCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setYCoordIndex(Integer.parseInt(yCoordSelector.getValue())); + validatePageComplete(); + } + }); + zValueSelector = new DynamicComboFieldEditor("zValue", "Z Value", parent); + zValueSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setZCoordIndex(Integer.parseInt(zValueSelector.getValue())); + validatePageComplete(); + } + }); } - @Override - public void fileSelected(FileOrDirectorySelectionWidget source, String[] filename) { - String[] selection = csvSelection.getFilename(); - if (selection != null && selection.length > 0) { - Path csvFile = Paths.get(selection[0]); - if (!Files.exists(csvFile)) { - setErrorMessage("File " + csvFile.toAbsolutePath() + " does not exist"); - } else { - model.setSource(csvFile); - updateHeaders(); - setPageComplete(true); + private void createEdgeIndexMappingField(Group parent) { + startXCoordSelector = new DynamicComboFieldEditor("startxCoord", "Start X Coordinate", parent); + startXCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setStartXCoordIndex(Integer.parseInt(startXCoordSelector.getValue())); + validatePageComplete(); + } + }); + + startYCoordSelector = new DynamicComboFieldEditor("startyCoord", "Start Y Coordinate", parent); + startYCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setStartYCoordIndex(Integer.parseInt(startYCoordSelector.getValue())); + validatePageComplete(); + } + }); + startZValueSelector = new DynamicComboFieldEditor("startzValue", "Start Z Value", parent); + startZValueSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setStartZCoordIndex(Integer.parseInt(startZValueSelector.getValue())); + validatePageComplete(); + } + }); + + endXCoordSelector = new DynamicComboFieldEditor("endxCoord", "End X Coordinate", parent); + endXCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setEndXCoordIndex(Integer.parseInt(endXCoordSelector.getValue())); + validatePageComplete(); + } + }); + + endYCoordSelector = new DynamicComboFieldEditor("endyCoord", "End Y Coordinate", parent); + endYCoordSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setEndYCoordIndex(Integer.parseInt(endYCoordSelector.getValue())); + validatePageComplete(); + } + }); + endZValueSelector = new DynamicComboFieldEditor("endzValue", "End Z Value", parent); + endZValueSelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.setEndZCoordIndex(Integer.parseInt(endZValueSelector.getValue())); + validatePageComplete(); } - } else { - setPageComplete(false); + }); + } + + private void updateCombos() { + String[][] namesAndValues = new String[headerIndexAndValues.size()][]; + + int i = 0; + for (Entry entry : headerIndexAndValues.entrySet()) { + int key = entry.getKey(); + String value = entry.getValue(); + + String[] nameAndValue = new String[2]; + nameAndValue[0] = value; + nameAndValue[1] = Integer.toString(key); + namesAndValues[i++] = nameAndValue; } + + if (model.isVertexImport()) + updateVertexcombos(namesAndValues); + else + updateEdgeCombos(namesAndValues); + + componentMappingSelector.updateCombo(namesAndValues); + } + + private void updateEdgeCombos(String[][] namesAndValues) { + startXCoordSelector.updateCombo(namesAndValues); + endXCoordSelector.updateCombo(namesAndValues); + startYCoordSelector.updateCombo(namesAndValues); + endYCoordSelector.updateCombo(namesAndValues); + startZValueSelector.updateCombo(namesAndValues); + endZValueSelector.updateCombo(namesAndValues); + } + + private void updateVertexcombos(String[][] namesAndValues) { + xCoordSelector.updateCombo(namesAndValues); + yCoordSelector.updateCombo(namesAndValues); + zValueSelector.updateCombo(namesAndValues); } private void updateHeaders() { @@ -174,21 +407,26 @@ public class CSVImportWizardPage extends WizardPage implements FileSelectionList TableItem item = headerTable.getItem(i); item.dispose(); } + + headerIndexAndValues.clear(); + try { List rows = model.getRows(5); - + for (int k = 0; k < rows.size(); k++) { CSVRecord row = rows.get(k); - + int columnCount = row.size(); for (int i = 0; i < columnCount; i++) { String value = row.get(i); if (k == 0) { TableColumn headerCol = new TableColumn(headerTable, SWT.NONE); headerCol.setText(value); - + tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10)); headerCol.pack(); + + headerIndexAndValues.put(i, value); } else { int actualK = k - 1; TableItem item; @@ -202,29 +440,17 @@ public class CSVImportWizardPage extends WizardPage implements FileSelectionList } } } - -// Map> headerAndValues = model.getHeaderAndRows(5); -// -// int coo = headerTable.getColumns().length; -// int count = headerTable.getColumnCount(); -// -// for (Map.Entry> entr : headerAndValues.entrySet()) { -// CSVHeader he = entr.getKey(); -// int index = he.getIndex(); -// TableColumn headerCol = new TableColumn(headerTable, SWT.NONE); -// headerCol.setText(he.getHeader()); -// -// tableColumnLayout.setColumnData(headerCol, new ColumnWeightData(10)); -// headerCol.pack(); -// -// for (String val : entr.getValue()) { -// TableItem item = new TableItem(headerTable, SWT.NONE); -// item.setText(val); -// } -// } + } catch (IOException e) { setErrorMessage(e.getMessage()); } } + protected void validatePageComplete() { + if (model.isVertexImport()) + setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1); + else + setPageComplete(model.getStartXCoordIndex() != 1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1); + } + } diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/ComponentMappingPage.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/ComponentMappingPage.java new file mode 100644 index 00000000..5cf55511 --- /dev/null +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/ComponentMappingPage.java @@ -0,0 +1,133 @@ +package org.simantics.district.imports.ui; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +import org.eclipse.jface.dialogs.IPageChangeProvider; +import org.eclipse.jface.dialogs.IPageChangedListener; +import org.eclipse.jface.dialogs.PageChangedEvent; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.district.imports.DistrictImportUtils; +import org.simantics.district.network.ui.function.Functions; + +public class ComponentMappingPage extends WizardPage { + + private CSVImportModel model; + private Composite composite; + private Composite childComposite; + protected Map componentMappings; + private Collection distinctMappingIvalues; + private Collection distinctMappingIndexColumnValues; + + public ComponentMappingPage(CSVImportModel model) { + super("Select component mappings"); + this.model = model; + setMessage("Select component mappings"); + } + + @Override + public void createControl(Composite parent) { + composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1,false)); + GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite); + + setControl(composite); + + validatePageComplete(); + + IWizardContainer container = getContainer(); + if (container instanceof IPageChangeProvider) { + ((IPageChangeProvider) container).addPageChangedListener(new IPageChangedListener() { + + @Override + public void pageChanged(PageChangedEvent event) { + if (container.getCurrentPage().equals(ComponentMappingPage.this)) { + ComponentMappingPage.this.updateComponentMappings(); + } + } + }); + } + } + + private void updateComponentMappings() { + try { + int mappingIndex = model.getComponentMappingIndex(); + distinctMappingIndexColumnValues = DistrictImportUtils.readDistinctValuesOfColumn(model.getSource(), model.getDelimiter(), mappingIndex); + + try { + Simantics.getSession().sync(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + if (model.isVertexImport()) + componentMappings = Functions.getVertexMappings(graph, model.getParentDiagram()); + else + componentMappings = Functions.getEdgeMappings(graph, model.getParentDiagram()); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + System.out.println(distinctMappingIndexColumnValues); + if (childComposite != null) + childComposite.dispose(); + childComposite = new Composite(composite, SWT.NONE); + childComposite.setLayout(new GridLayout(1,false)); + GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(childComposite); + + for (String value : distinctMappingIndexColumnValues) { + + Composite newCompo = new Composite(childComposite, SWT.NONE); + newCompo.setLayout(new GridLayout(2,false)); + GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(newCompo); + + Label t = new Label(newCompo, SWT.NONE); + t.setText(value); + + Combo c = new Combo(newCompo, SWT.READ_ONLY); + c.setItems(componentMappings.keySet().toArray(new String[componentMappings.size()])); + c.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + model.setComponentMappings(value, componentMappings.get(c.getItem(c.getSelectionIndex()))); + validatePageComplete(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }); + } + composite.layout(true, true); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void validatePageComplete() { + Map currentMappings = model.getComponentMappings(); + if (currentMappings != null && distinctMappingIndexColumnValues != null && currentMappings.keySet().containsAll(distinctMappingIndexColumnValues)) + setPageComplete(true); + else + setPageComplete(false); + } + +} diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/controls/DynamicComboFieldEditor.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/controls/DynamicComboFieldEditor.java new file mode 100644 index 00000000..5fc8cad3 --- /dev/null +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/controls/DynamicComboFieldEditor.java @@ -0,0 +1,218 @@ +package org.simantics.district.imports.ui.controls; + +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * A field editor for a combo box that allows the drop-down selection of one of + * a list of items. + * + * @since 3.3 + */ +public class DynamicComboFieldEditor extends FieldEditor { + + /** + * The Combo widget. + */ + private Combo fCombo; + + /** + * The value (not the name) of the currently selected item in the Combo widget. + */ + private String fValue; + + /** + * The names (labels) and underlying values to populate the combo widget. These should be + * arranged as: { {name1, value1}, {name2, value2}, ...} + */ + private String[][] fEntryNamesAndValues; + + /** + * Create the combo box field editor. + * + * @param name the name of the preference this field editor works on + * @param labelText the label text of the field editor + * @param entryNamesAndValues the names (labels) and underlying values to populate the combo widget. These should be + * arranged as: { {name1, value1}, {name2, value2}, ...} + * @param parent the parent composite + */ + + public DynamicComboFieldEditor(String name, String labelText, Composite parent) { + init(name, labelText); + createControl(parent); + } + + public DynamicComboFieldEditor(String name, String labelText, String[][] entryNamesAndValues, Composite parent) { + init(name, labelText); + fEntryNamesAndValues = entryNamesAndValues; + createControl(parent); + } + + public void updateCombo(String[][] fEntryNamesAndValues) { + this.fEntryNamesAndValues = fEntryNamesAndValues; + updateComboBoxControl(); + } + + /** + * Checks whether given String[][] is of "type" + * String[][2]. + * + * @return true if it is ok, and false otherwise + */ + private boolean checkArray(String[][] table) { + if (table == null) { + return false; + } + for (int i = 0; i < table.length; i++) { + String[] array = table[i]; + if (array == null || array.length != 2) { + return false; + } + } + return true; + } + + @Override + protected void adjustForNumColumns(int numColumns) { + if (numColumns > 1) { + Control control = getLabelControl(); + int left = numColumns; + if (control != null) { + ((GridData)control.getLayoutData()).horizontalSpan = 1; + left = left - 1; + } + ((GridData)fCombo.getLayoutData()).horizontalSpan = left; + } else { + Control control = getLabelControl(); + if (control != null) { + ((GridData)control.getLayoutData()).horizontalSpan = 1; + } + ((GridData)fCombo.getLayoutData()).horizontalSpan = 1; + } + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + int comboC = 1; + if (numColumns > 1) { + comboC = numColumns - 1; + } + Control control = getLabelControl(parent); + GridData gd = new GridData(); + gd.horizontalSpan = 1; + control.setLayoutData(gd); + control = getComboBoxControl(parent); + gd = new GridData(); + gd.horizontalSpan = comboC; + gd.horizontalAlignment = GridData.FILL; + control.setLayoutData(gd); + control.setFont(parent.getFont()); + } + + @Override + protected void doLoad() { + updateComboForValue(getPreferenceStore().getString(getPreferenceName())); + } + + @Override + protected void doLoadDefault() { + updateComboForValue(getPreferenceStore().getDefaultString(getPreferenceName())); + } + + @Override + protected void doStore() { + if (fValue == null) { + getPreferenceStore().setToDefault(getPreferenceName()); + return; + } + getPreferenceStore().setValue(getPreferenceName(), fValue); + } + + @Override + public int getNumberOfControls() { + return 2; + } + + /* + * Lazily create and return the Combo control. + */ + private Combo getComboBoxControl(Composite parent) { + if (fCombo == null) { + fCombo = new Combo(parent, SWT.READ_ONLY); + fCombo.setFont(parent.getFont()); + + fCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent evt) { + String oldValue = fValue; + String name = fCombo.getText(); + fValue = getValueForName(name); + setPresentsDefaultValue(false); + fireValueChanged(VALUE, oldValue, fValue); + } + }); + } + updateComboBoxControl(); + return fCombo; + } + + private void updateComboBoxControl() { + fCombo.removeAll(); + if (fEntryNamesAndValues != null) { + for (int i = 0; i < fEntryNamesAndValues.length; i++) { + fCombo.add(fEntryNamesAndValues[i][0], i); + } + } + } + + /* + * Given the name (label) of an entry, return the corresponding value. + */ + private String getValueForName(String name) { + for (int i = 0; i < fEntryNamesAndValues.length; i++) { + String[] entry = fEntryNamesAndValues[i]; + if (name.equals(entry[0])) { + return entry[1]; + } + } + return fEntryNamesAndValues[0][0]; + } + + /* + * Set the name in the combo widget to match the specified value. + */ + private void updateComboForValue(String value) { + fValue = value; + for (int i = 0; i < fEntryNamesAndValues.length; i++) { + if (value.equals(fEntryNamesAndValues[i][1])) { + fCombo.setText(fEntryNamesAndValues[i][0]); + return; + } + } + if (fEntryNamesAndValues.length > 0) { + fValue = fEntryNamesAndValues[0][1]; + fCombo.setText(fEntryNamesAndValues[0][0]); + } + } + + @Override + public void setEnabled(boolean enabled, Composite parent) { + super.setEnabled(enabled, parent); + getComboBoxControl(parent).setEnabled(enabled); + } + + public void addComboListener(SelectionListener selectionListener) { + fCombo.addSelectionListener(selectionListener); + } + + public String getValue() { + return fValue; + } +} diff --git a/org.simantics.district.imports/src/org/simantics/district/imports/DistrictImportUtils.java b/org.simantics.district.imports/src/org/simantics/district/imports/DistrictImportUtils.java index 1ad5b9a9..100c307e 100644 --- a/org.simantics.district.imports/src/org/simantics/district/imports/DistrictImportUtils.java +++ b/org.simantics.district.imports/src/org/simantics/district/imports/DistrictImportUtils.java @@ -4,10 +4,13 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; @@ -17,8 +20,7 @@ import org.simantics.db.Resource; public class DistrictImportUtils { private DistrictImportUtils() { } - - + public static Resource importCSVAsLayer(Path csvFile) throws IOException { try (CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(Files.newBufferedReader(csvFile))) { @@ -172,4 +174,20 @@ public class DistrictImportUtils { } } + public static Collection readDistinctValuesOfColumn(Path source, char delim, int mappingIndex) throws IOException { + Set results = new HashSet<>(); + CSVFormat format = CSVFormat.newFormat(delim); + try (CSVParser parser = format.parse(Files.newBufferedReader(source))) { + Iterator records = parser.iterator(); + if (records.hasNext()) + records.next(); + while (records.hasNext()) { + CSVRecord row = records.next(); + String value = row.get(mappingIndex); + results.add(value); + } + } + return results; + } + } diff --git a/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java b/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java new file mode 100644 index 00000000..e208be71 --- /dev/null +++ b/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java @@ -0,0 +1,19 @@ +package org.simantics.maps; + +import java.awt.geom.AffineTransform; + +public class MapScalingTransform { + + private MapScalingTransform() { + } + + public static final AffineTransform INSTANCE = new AffineTransform(100000, 0, 0, 100000, 0, 0); + + public static double getScaleX() { + return INSTANCE.getScaleX(); + } + + public static double getScaleY() { + return INSTANCE.getScaleY(); + } +} diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java index e06adcb2..b8b54e31 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java @@ -224,9 +224,8 @@ public class MapNode extends G2DNode implements ITileListener { return; Graphics2D g = (Graphics2D)g2d.create(); - AffineTransform tr = (AffineTransform)g.getTransform().clone(); - + double scaleX = Math.abs(tr.getScaleX()); double scaleY = Math.abs(tr.getScaleY()); if (scaleX <= 0 || scaleY <= 0) { @@ -255,7 +254,7 @@ public class MapNode extends G2DNode implements ITileListener { tileSize *= 0.5; level++; } - + System.out.println("level " + level); /* * To convert y-coordinates to map coordinates in ruler, use: * double val = (y-offsetY)/scaleY; diff --git a/org.simantics.district.network.ui.ontology/graph.tg b/org.simantics.district.network.ui.ontology/graph.tg index a8b273c2bbd091c31327bd5e5e903aff3a130594..2815e2f3f9098a21d7acc6cade172ca3768bb810 100644 GIT binary patch literal 2444 zcmai0{Z|u56eW;v0um4b(Mmy~pai5^rG7$!5JlmD@cSegCuP~`&KXU(&-ap!W(gEPj$46kq$4r zQ7^xT5`0g&HTzmCcubva6;&E)Ieb!4U(geue>1Vsf)X!eJ4d;dR!jL2l( zDE>=4fod`nET*hxx!>x>8f8+SN@Kckbx^S$+L!8c<$4kFURza$VcKTT@CqFHK3gk zcGhOA#zXE#k99#YBBhS8!me?=5Jhf*&Inz;3Zy@F-JvTpbFO?xHC&B>22##ZaA)*D z1;@T)d?&mFu9BR~)x96u4>bBSqRK(V+#qTsW-LXSMCRUC?26WZk2XnFnRzHge~-kZ zl_yOiRp2l|Jcngc=|a_Xx+ZW!hOLlV&bsQ-^g?vs6R%ilo=8kiCTmTi5fkLkJ;Ht9fBp2i(H|E2i_sMWQ9JEP@ILXYkcj)yFli_Si?8{04Ek( z{eq>gimZ2UW3++P^sO8A-l zrX^e>u{zo`Zm;9X^#S~jHkI0jh+k zAh=lfaFD&GKKcgkwQv|B)NNUnq7eBbFEp-cbF-Dm6tivDG!);|K5@ya>XU?IkCh)v z&ff&{g>bRrjr1lGo#ME7Jk>7*mmoU!bqi}K`(|6%+>VsYGkic|+Zt?K6r67IwyQ2? z2-OFA#x3bfkru922JVkSP1&Pfuh*zJM?5(|&jb{)F9O^jflTaqlrX9;I`Q*D<&p4E zH8huJm(09X#w(HJc8zhh;w_OQk(wH~m+(4yD^1gx%heo(?@R~%heC|)4s6rgLZ|my zZJxI&LD_S>Xng_vH|%#<;U7F`pU3zmTArDoWBdZ`N7w@FS6HHdg+8xW8&`mNn;pWa zC1%B+Vbl^Q`VI6STlh8lzgT!R#%pNb!Ki%%TZg@cF&A-?Z#l**Xy3z_i*rc)i!ok8 zy90X&yAMnJvoYRAdjR9w+=C_lH|XEBFzcOwO~UqIQv>++0G^IUX) zuqupW5zoMCFxGbqmc+B3F$?p3@L$3>>;sHi;u35hMlEp?UySiHw4Y!ci~a<2ZEVc7 zPFa5Xa4*q%6QWsQ#{$IxHVf85^t zB!O^FPj$}q=-#)?n^jJ>T-EtDFfcF(45axJKFLv6d#39)bjfrbe~5BUU-{bcEaP}t z@)Upa{K;8O?f8~&X)i+_&oq>YG6hMR`m5!@)i@(`4WC5f%ozVpT*6UpEqx^X>rU{N zsh|YcQT83rR7bh!U-I8ZWojMv68I)FRp&M`ne%+*>o$Udf+aNdUD@6LA3;*wWZWqJ zG#o%B8VM#-W^=OF>lHn#tuQeSuV~yBJW@0b7S6S;8!Yb9(!Go7##V6)`h6NxQ|G>N zn#ygSx~8LD&MD-~Fau}Gmgl=x!#~k}&$xd|=nGgL)0~+ML@Gh7|Zcdvhqp18XYHJy4VQD*5w(?j%>~duvxU##B zsqVyj-4?g8ZiJ>|G??G-BeG+l2V?BD&dqBo~t^z1e}JheTDW;G<4zXmdr{{giOuxjcr=oEqN-r zRLeGX#g+O%o{v>^Bq6C&<@%EIH{o0mPFA>O-v>_TIBE`WgxA9JvN3fNb13^}SJd>L zl+5#ArLY_8Y)m{j+-S8+Hbw}qLt4gSu5ZLOdowdIe-^0_@AY=RM#MPm$Ps-hB!_+B z;qLKdV6TFNL3P1xu^>_g36E4=b9%~D7Gh<*6_@nBF}7B`VbT-^3w?JQmXkNyJsQ*L zvZe5iYUBNx2&4Ob+jK_cM5Wo{d7BoNy2L{3EAYR8-+}Buc+kEI`5UyKfS*GC8trG` zDex;0`M<^cFMXWV@g_V8ZRC+ZuW|An;22=84Ir|=!~4%Mz83Ozw0i)3p97mf4PY+v zD1Ig6t7!KD=HeJ4`%=i4(UyQ`z+)h?-w*jNTHYC)n@2!oe~8p)?4lEV ov5Q@+hzn5elw#k`zo85uc}Anzl|I~9K0pWOMlb8o`yUuCl4qyPW_ diff --git a/org.simantics.district.network.ui.ontology/graph/DistrictNetworkUI.pgraph b/org.simantics.district.network.ui.ontology/graph/DistrictNetworkUI.pgraph index c03c89c5..26d246fb 100644 --- a/org.simantics.district.network.ui.ontology/graph/DistrictNetworkUI.pgraph +++ b/org.simantics.district.network.ui.ontology/graph/DistrictNetworkUI.pgraph @@ -10,12 +10,12 @@ DNUI = : L0.Ontology L0.Ontology.global true L0.HasResourceClass "org.simantics.district.network.ui.ontology.DistrictNetworkUIResource" -DNUI.SelectionTabContribution : SEL.MultiTypedVariableTabContribution - SEL.TypedTabContribution.HasType DN.Vertex - SEL.TypedTabContribution.HasType DN.Edge - SEL.TypedTabContribution.HasType DN.Diagram +DNUI.SelectionTabContribution : SEL.TypedVariableTabContribution + SEL.TypedVariableTabContribution.HasType DN.Vertex + SEL.TypedVariableTabContribution.HasType DN.Edge + SEL.TypedVariableTabContribution.HasType DN.Diagram SEL.VariableTabContribution.HasView SEL_UI.StandardProperties - SEL.TabContribution.HasPriority 10 + SEL.VariableTabContribution.HasPriority 10 L0.HasLabel "Network Properties" DNUI.NetworkProperties : SEL_UI.StandardProperties diff --git a/org.simantics.district.network.ui/META-INF/MANIFEST.MF b/org.simantics.district.network.ui/META-INF/MANIFEST.MF index b3aef540..8db22872 100644 --- a/org.simantics.district.network.ui/META-INF/MANIFEST.MF +++ b/org.simantics.district.network.ui/META-INF/MANIFEST.MF @@ -4,7 +4,8 @@ Bundle-Name: Simantics District Network UI Bundle-SymbolicName: org.simantics.district.network.ui;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.simantics.district.network.ui.internal.Activator -Export-Package: org.simantics.district.network.ui.adapters, +Export-Package: org.simantics.district.network.ui, + org.simantics.district.network.ui.adapters, org.simantics.district.network.ui.function Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100.v20150407-1430", org.eclipse.swt, diff --git a/org.simantics.district.network.ui/fragment.e4xmi b/org.simantics.district.network.ui/fragment.e4xmi index f0c705c8..6271c820 100644 --- a/org.simantics.district.network.ui/fragment.e4xmi +++ b/org.simantics.district.network.ui/fragment.e4xmi @@ -8,6 +8,7 @@ + @@ -17,10 +18,12 @@ + + diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java index ebdb9e87..eb081445 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java @@ -12,9 +12,11 @@ import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; import org.simantics.diagram.synchronization.SynchronizationHints; -import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; +import org.simantics.diagram.synchronization.graph.layer.GraphLayer; import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; +import org.simantics.diagram.synchronization.graph.layer.IGraphLayerUtil; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.g2d.diagram.IDiagram; @@ -34,29 +36,40 @@ public class DNEdgeBuilder { glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); } - public void create(WriteGraph graph, double[] start, double[] end, double padding) throws DatabaseException { + public static Resource create(WriteGraph graph, Resource diagramResource, double[] start, double[] end, double padding) throws DatabaseException { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); // 1. Get diagram edge to construct - Resource edge = getOrCreateEdge(graph); - - // 1.1 Give running name to connection and increment the counter attached to the diagram. - AddElement.claimFreshElementName(graph, diagramResource, edge); + Resource edge = getOrCreateEdge(graph, diagramResource); // 2. Add vertices Collection vertices = graph.syncRequest(new ObjectsWithType(diagramResource, Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex)); - Resource startVertex = getOrCreateVertex(graph, vertices, start, padding); - Resource endVertex = getOrCreateVertex(graph, vertices, end, padding); + Resource startVertex = getOrCreateVertex(graph, diagramResource, vertices, start, padding); + Resource endVertex = getOrCreateVertex(graph, diagramResource, vertices, end, padding); graph.claim(edge, DN.HasStartVertex, startVertex); graph.claim(edge, DN.HasEndVertex, endVertex); + // We need to put GraphLayer to newLayers so... + for (Resource layer : graph.getObjects(diagramResource, DiagramResource.getInstance(graph).HasLayer)) { + IGraphLayerUtil layerUtil = graph.adapt(graph.getSingleObject(layer, Layer0.getInstance(graph).InstanceOf), IGraphLayerUtil.class); + + GraphLayer gl = layerUtil.loadLayer(graph, layer); + gl.forEachTag(tag -> { + DiagramGraphUtil.tag(graph, startVertex, tag, true); + DiagramGraphUtil.tag(graph, endVertex, tag, true); + }); + } + + return edge; + } + public void create(WriteGraph graph, double[] start, double[] end, double padding) throws DatabaseException { + + Resource edge = create(graph, diagramResource, start, end, padding); // 7. Put the element on all the currently active layers if possible. if (glm != null) { putOnActiveLayer(graph, edge); - putOnActiveLayer(graph, startVertex); - putOnActiveLayer(graph, endVertex); } Layer0Utils.addCommentMetadata(graph, "Added edge " + edge); @@ -68,26 +81,28 @@ public class DNEdgeBuilder { glm.putElementOnVisibleLayers(diagram, graph, res); } - private Resource getOrCreateVertex(WriteGraph graph, Collection vertices, double[] coords, double padding) throws DatabaseException { + private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Collection vertices, double[] coords, double padding) throws DatabaseException { Resource vertex = null; double halfPadding = padding / 2; + double maxDistance = Double.MAX_VALUE; for (Resource vertx : vertices) { double[] existingCoords = graph.getRelatedValue2(vertx, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY); Rectangle2D existing = new Rectangle2D.Double(existingCoords[0] - halfPadding, existingCoords[1] - halfPadding, padding, padding); Rectangle2D tobecreated = new Rectangle2D.Double(coords[0] - halfPadding, coords[1] - halfPadding, padding, padding); if (existing.intersects(tobecreated)) { - vertex = vertx; - break; + double dist = Math.sqrt((Math.pow(coords[0] - existingCoords[0], 2) + (Math.pow(coords[1] - existingCoords[1], 2)))); + if (dist <= maxDistance) { + vertex = vertx; + } } } if (vertex == null) { vertex = DistrictNetworkUtil.createVertex(graph, diagramResource, coords); - AddElement.claimFreshElementName(graph, diagramResource, vertex); } return vertex; } - private Resource getOrCreateEdge(WriteGraph graph) throws DatabaseException { + private static Resource getOrCreateEdge(WriteGraph graph, Resource diagramResource) throws DatabaseException { return DistrictNetworkUtil.createEdge(graph, diagramResource); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java index 486f8759..47a7bc5f 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java @@ -41,7 +41,7 @@ public class DistrictDiagramViewer extends DiagramViewer { public void initializeCanvasContext(CanvasContext ctx) { super.initializeCanvasContext(ctx); IHintContext h = ctx.getDefaultHintContext(); - h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 10000.0); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 1000000.0); h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 0.01); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java index e30b4cb0..c5021ff1 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java @@ -1,22 +1,25 @@ -package org.simantics.district.network.ui; - -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; - -public class DistrictNetworkEdge { - - private Path2D path; - - public DistrictNetworkEdge(Path2D path) { - this.path = path; - } - - public Path2D getPath() { - return path; - } - - public Rectangle2D getBounds(Rectangle2D rect) { - rect.setFrame(path.getBounds2D()); - return rect; - } -} +package org.simantics.district.network.ui; + +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Point2D.Double; +import java.awt.geom.Rectangle2D; + +public class DistrictNetworkEdge { + + private Path2D path; + + public DistrictNetworkEdge(Path2D path) { + this.path = path; + } + + public Path2D getPath() { + return path; + } + + public Rectangle2D getBounds(Rectangle2D rect) { + rect.setFrame(path.getBounds2D()); + return rect; + } + +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index cf10ffab..a7cd09ac 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -1,6 +1,7 @@ package org.simantics.district.network.ui.adapters; import java.awt.Color; +import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.util.Collection; import java.util.Collections; @@ -89,7 +90,6 @@ public class DistrictNetworkEdgeElement { return size; } - } static class DNEdgeConnectionHandler implements ConnectionHandler { diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java index 2899a0e7..c3058a0e 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java @@ -1,6 +1,7 @@ package org.simantics.district.network.ui.adapters; import java.awt.geom.Path2D; +import java.awt.geom.Point2D; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; @@ -20,9 +21,11 @@ import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; import org.simantics.g2d.layers.ILayersEditor; +import org.simantics.maps.MapScalingTransform; public class DistrictNetworkEdgeElementFactory extends SyncElementFactory { @@ -51,7 +54,7 @@ public class DistrictNetworkEdgeElementFactory extends SyncElementFactory { Resource startVertex = graph.getSingleObject(edgeResource, DN.HasStartVertex); Resource endVertex = graph.getSingleObject(edgeResource, DN.HasEndVertex); - + // TODO: fix scale.. double scale = 100000; @@ -61,7 +64,7 @@ public class DistrictNetworkEdgeElementFactory extends SyncElementFactory { double startLat = ModelledCRS.latitudeToY(startCoords[1]) * scale; double[] endCoords = graph.getRelatedValue2(endVertex, DIA.HasLocation); - + double endLon = ModelledCRS.longitudeToX(endCoords[0]) * scale; double endLat = ModelledCRS.latitudeToY(endCoords[1]) * scale; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeMappingTypeHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeMappingTypeHandler.java new file mode 100644 index 00000000..2f3aae45 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeMappingTypeHandler.java @@ -0,0 +1,190 @@ +package org.simantics.district.network.ui.contributions; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Named; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +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.PlatformUI; +import org.eclipse.ui.dialogs.SelectionStatusDialog; +import org.simantics.DatabaseJob; +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.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.SelectionHints; +import org.simantics.db.request.Read; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.district.network.ui.function.Functions; +import org.simantics.district.network.ui.internal.Activator; +import org.simantics.layer0.Layer0; +import org.simantics.utils.ui.ISelectionUtils; + +public class ChangeMappingTypeHandler { + + + @CanExecute + public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) { + List elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class); + if (elements.size() < 1) + return false; + try { + return Simantics.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource instanceOf = null; + for (Resource element : elements) { + if (instanceOf == null) { + instanceOf = graph.getSingleObject(element, L0.InstanceOf); + } else { + Resource currentInstanceOf = graph.getSingleObject(element, L0.InstanceOf); + if (!currentInstanceOf.equals(instanceOf)) { + return false; + } + } + } + return true; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + return false; + } + } + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection) { + final List elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class); + if (elements.size() < 1) + return; + + SelectMappingDialog dialog = new SelectMappingDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), elements); + if (dialog.open() != Dialog.OK) + return; + + Resource mapping = dialog.getDefaultVertexMapping(); + Job job = new DatabaseJob("Join selected vertices") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + Simantics.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + for (Resource element : elements) { + graph.deny(element, DN.HasMapping); + graph.claim(element, DN.HasMapping, mapping); + } + } + }); + } catch (DatabaseException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, getName() + " failed.", e); + } + return Status.OK_STATUS; + } + }; + job.setUser(true); + job.schedule(); + } + + private static class SelectMappingDialog extends SelectionStatusDialog { + + private Combo vertexMappingCombo; + + private Composite composite; + + private List elements; + private Map vertexMappings = new HashMap<>(); + + private Resource defaultVertexMapping; + + protected SelectMappingDialog(Shell parentShell, List elements) { + super(parentShell); + this.elements = elements; + setTitle("Select mappings for new DN diagram"); + } + + public Resource getDefaultVertexMapping() { + return defaultVertexMapping; + } + + @Override + protected Control createDialogArea(Composite parent) { + composite = (Composite) super.createDialogArea(parent); + + createMappingsGroup(composite); + + // compute default values + Simantics.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Resource element = elements.get(0); + if (graph.isInstanceOf(element, DN.Vertex)) { + vertexMappings = Functions.getVertexMappings(graph, element); + } else if (graph.isInstanceOf(element, DN.Edge)) { + vertexMappings = Functions.getEdgeMappings(graph, element); + } + composite.getDisplay().asyncExec(() -> { + vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()])); + vertexMappingCombo.select(0); + }); + + } + }); + return composite; + } + + @Override + protected void computeResult() { + defaultVertexMapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex())); + } + + private void createMappingsGroup(Composite parent) { + Group group= new Group(parent, SWT.NONE); + group.setFont(parent.getFont()); + group.setText("Default mappings"); + 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("Default vertex mapping"); + + vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo); + + } + } +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java index 4fc40dbb..627de3a6 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java @@ -1,9 +1,12 @@ package org.simantics.district.network.ui.function; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.eclipse.jface.dialogs.Dialog; @@ -32,6 +35,7 @@ import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.IndexRoot; +import org.simantics.db.common.request.IndexRoots; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; @@ -49,7 +53,6 @@ import org.simantics.modeling.ModelingUtils; import org.simantics.modeling.adapters.NewCompositeActionFactory; import org.simantics.modeling.typicals.TypicalUtil; import org.simantics.scl.reflection.annotations.SCLValue; -import org.simantics.structural.stubs.StructuralResource2; import org.simantics.ui.workbench.action.DefaultActions; import org.simantics.utils.ui.SWTUtils; import org.slf4j.Logger; @@ -446,7 +449,15 @@ public class Functions { }); } - public static void getDistrictDiagrams(ReadGraph graph) { - + public static Collection getDistrictDiagrams(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Collection indexRoots = graph.sync(new ObjectsWithType(Simantics.getProjectResource(), L0.ConsistsOf, L0.IndexRoot)); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Set results = new HashSet<>(); + for (Resource indexRoot : indexRoots) { + Collection diagrams = ModelingUtils.searchByType(graph, indexRoot, DN.Diagram); + results.addAll(diagrams); + } + return results; } } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java index 11d883e9..9170fa15 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java @@ -6,8 +6,12 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import org.simantics.district.network.ModelledCRS; +import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.district.network.ui.DistrictNetworkEdge; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.GeometryUtils; @@ -67,7 +71,7 @@ public class DistrictNetworkEdgeNode extends G2DNode { } // render g2d.draw(edge.getPath()); - + // Reset g2d.setStroke(oldStroke); g2d.setColor(oldColor); @@ -76,7 +80,7 @@ public class DistrictNetworkEdgeNode extends G2DNode { if (ot != null) g2d.setTransform(ot); } - + private boolean isSelected() { return NodeUtil.isSelected(this, 1); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java index 86c71857..e9d0713d 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java @@ -6,8 +6,10 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.adapters.DistrictNetworkVertex; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.GeometryUtils; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/MapRulerNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/MapRulerNode.java index 078c8ebb..ba22aa42 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/MapRulerNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/MapRulerNode.java @@ -11,6 +11,7 @@ public class MapRulerNode extends RulerNode { protected double modifyHorizontalValue(double value) { // TODO: fix scale! double scale = 100000; +// double scale = 1; return ModelledCRS.xToLongitude(value / scale); } @@ -18,6 +19,7 @@ public class MapRulerNode extends RulerNode { protected double modifyVerticalValue(double value) { // TODO: fix scale! double scale = 100000; +// double scale = 1; return ModelledCRS.yToLatitude(value / scale); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java index 13bd2cbe..b2c15718 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java @@ -164,6 +164,7 @@ public class NetworkDrawingNode extends G2DNode { */ // TODO: fix scale double scale = 100000; +// double scale = 1; double startLat = ModelledCRS.yToLatitude(start.getY() / scale); double startLon = ModelledCRS.xToLongitude(start.getX() / scale); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java index 12caba47..7bec07dc 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java @@ -55,6 +55,7 @@ public class DNTranslateMode extends TranslateMode { double y = at.getTranslateY(); // TODO: Fix scale! double scale = 100000; +// double scale = 1; double lat = ModelledCRS.yToLatitude(y / scale); double lon = ModelledCRS.xToLongitude(x / scale); diff --git a/org.simantics.district.network/META-INF/MANIFEST.MF b/org.simantics.district.network/META-INF/MANIFEST.MF index 51580d23..47d74d8e 100644 --- a/org.simantics.district.network/META-INF/MANIFEST.MF +++ b/org.simantics.district.network/META-INF/MANIFEST.MF @@ -11,5 +11,6 @@ Require-Bundle: org.simantics.db, org.simantics.db.common, org.simantics.db.layer0, org.simantics.district.maps, - org.simantics.district.geotools;bundle-version="1.0.0" + org.simantics.district.geotools;bundle-version="1.0.0", + org.simantics.diagram Export-Package: org.simantics.district.network diff --git a/org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java b/org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java index 94799a97..6155bf6f 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java +++ b/org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java @@ -10,6 +10,10 @@ import org.simantics.db.WriteGraph; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.diagram.synchronization.graph.layer.GraphLayer; +import org.simantics.diagram.synchronization.graph.layer.IGraphLayerUtil; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; @@ -27,10 +31,17 @@ public class DistrictNetworkUtil { OrderedSetUtils.add(graph, composite, edge); graph.claim(composite, L0.ConsistsOf, L0.PartOf, edge); + + AddElement.claimFreshElementName(graph, composite, edge); return edge; } public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords) throws DatabaseException { + Resource defaultVertexMapping = graph.getPossibleObject(composite, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping); + return createVertex(graph, composite, coords, defaultVertexMapping); + } + + public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords, Resource mapping) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); @@ -38,12 +49,23 @@ public class DistrictNetworkUtil { graph.claim(vertex, L0.InstanceOf, DN.Vertex); graph.claimLiteral(vertex, DIA.HasLocation, coords); - Resource defaultVertexMapping = graph.getPossibleObject(composite, DN.VertexDefaultMapping); - graph.claim(vertex, DN.HasMapping, defaultVertexMapping); + graph.claim(vertex, DN.HasMapping, mapping); OrderedSetUtils.add(graph, composite, vertex); graph.claim(composite, L0.ConsistsOf, L0.PartOf, vertex); + AddElement.claimFreshElementName(graph, composite, vertex); + + // We need to put GraphLayer to newLayers so... + for (Resource layer : graph.getObjects(composite, DiagramResource.getInstance(graph).HasLayer)) { + IGraphLayerUtil layerUtil = graph.adapt(graph.getSingleObject(layer, Layer0.getInstance(graph).InstanceOf), IGraphLayerUtil.class); + + GraphLayer gl = layerUtil.loadLayer(graph, layer); + gl.forEachTag(tag -> { + DiagramGraphUtil.tag(graph, vertex, tag, true); + }); + } + return vertex; } diff --git a/org.simantics.district.network/src/org/simantics/district/network/ModelledCRS.java b/org.simantics.district.network/src/org/simantics/district/network/ModelledCRS.java index 23e68f2b..55d850e5 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/ModelledCRS.java +++ b/org.simantics.district.network/src/org/simantics/district/network/ModelledCRS.java @@ -28,12 +28,11 @@ public class ModelledCRS implements CRS { return dist; } - // TODO: these only work with Spherical Mercator public static double xToLongitude(double x) { return x; } - + public static double yToLatitude(double y) { double rad = Math.toRadians(y); double sinh = Math.sinh(rad); @@ -41,7 +40,7 @@ public class ModelledCRS implements CRS { double finald = Math.toDegrees(atan); return finald; } - + public static double longitudeToX(double lon) { return lon; } diff --git a/org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/Activator.java b/org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/Activator.java index cd46e1a5..4c1c9637 100644 --- a/org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/Activator.java +++ b/org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/Activator.java @@ -4,9 +4,13 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.simantics.district.maps.server.TileserverMapnikInstance; import org.simantics.district.maps.server.prefs.MapsServerPreferences; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Activator implements BundleActivator { + private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class); + public static final String PLUGIN_ID = "org.simantics.maps.server.ui"; private static BundleContext context; @@ -30,8 +34,8 @@ public class Activator implements BundleActivator { new Thread(() -> { try { TileserverMapnikInstance.get().start(); - } catch (Exception e) { - e.printStackTrace(); + } catch (Throwable t) { + LOGGER.error("Could not start integrated tile server", t); } }).start(); } diff --git a/org.simantics.maps.server/src/org/simantics/district/maps/server/Activator.java b/org.simantics.maps.server/src/org/simantics/district/maps/server/Activator.java index eaeda86a..a09545fb 100644 --- a/org.simantics.maps.server/src/org/simantics/district/maps/server/Activator.java +++ b/org.simantics.maps.server/src/org/simantics/district/maps/server/Activator.java @@ -1,6 +1,7 @@ package org.simantics.district.maps.server; import java.io.IOException; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; @@ -40,15 +41,18 @@ public class Activator implements BundleActivator { } public static Path getNodeJSRoot() throws IOException, URISyntaxException { - URL nodeURL = getContext().getBundle().getEntry("/node"); - URL nodeFileURL = FileLocator.toFileURL(nodeURL); - return Paths.get(nodeFileURL.toURI()); + return resolvePath("/node"); } public static Path getTileserverMapnikRoot() throws IOException, URISyntaxException { - URL serverURL = getContext().getBundle().getEntry("/server"); - URL serverFileURL = FileLocator.toFileURL(serverURL); - return Paths.get(serverFileURL.toURI()); + return resolvePath("/server"); + } + + private static Path resolvePath(String entry) throws IOException, URISyntaxException { + URL entryURL = getContext().getBundle().getEntry(entry); + URL entryFileURL = FileLocator.toFileURL(entryURL); + URI encodedUri = new URI(entryFileURL.getProtocol(), entryFileURL.getPath(), null).normalize(); + return Paths.get(encodedUri); } } -- 2.45.1