From 8ceba7214150309c1bfae4b8213d1e6eb51f5934 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Fri, 14 Jun 2019 12:22:59 +0300 Subject: [PATCH] Make it possible to import CSV data via SCL & create models gitlab #52 Change-Id: I84968442a4956f008b7b5604a258f4d60e00ffd0 --- .../district/imports/ui/CSVImportWizard.java | 325 +-------------- .../imports/ui/CSVImportWizardFirstPage.java | 1 + .../imports/ui/CSVImportWizardPage.java | 3 +- .../imports/ui/ComponentMappingPage.java | 1 + .../META-INF/MANIFEST.MF | 8 +- .../build.properties | 11 +- .../scl/Simantics/District/Import.scl | 45 +++ .../district/imports}/CSVImportModel.java | 11 +- .../district/imports/DistrictImportUtils.java | 375 ++++++++++++++++++ .../ChangeRoutePointToVertexHandler.java | 2 +- .../ChangeVertexToRoutePointHandler.java | 2 +- .../network/ui/function/Functions.java | 102 +++-- .../network/ui/nodes/NetworkDrawingNode.java | 2 +- .../META-INF/MANIFEST.MF | 3 +- .../scl/Simantics/District.scl | 4 + .../district/network}/DNEdgeBuilder.java | 24 +- .../district/network/DistrictNetworkUtil.java | 31 ++ 17 files changed, 543 insertions(+), 407 deletions(-) create mode 100644 org.simantics.district.imports/scl/Simantics/District/Import.scl rename {org.simantics.district.imports.ui/src/org/simantics/district/imports/ui => org.simantics.district.imports/src/org/simantics/district/imports}/CSVImportModel.java (98%) rename {org.simantics.district.network.ui/src/org/simantics/district/network/ui => org.simantics.district.network/src/org/simantics/district/network}/DNEdgeBuilder.java (92%) 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 8b0a377b..a4d29fe1 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 @@ -1,13 +1,7 @@ package org.simantics.district.imports.ui; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; -import org.apache.commons.csv.CSVRecord; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; @@ -15,35 +9,10 @@ import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardPage; 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.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.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.util.Layer0Utils; -import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.imports.CSVImportModel; 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; -import org.simantics.district.network.ui.DNEdgeBuilder.ResourceVertex; -import org.simantics.layer0.Layer0; import org.simantics.utils.ui.ExceptionUtils; -import com.vividsolutions.jts.geom.Envelope; -import com.vividsolutions.jts.index.quadtree.Quadtree; - public class CSVImportWizard extends Wizard implements IImportWizard { private CSVImportModel model; @@ -70,228 +39,13 @@ public class CSVImportWizard extends Wizard implements IImportWizard { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { - Path csvFile = model.getSource(); - char delim = model.getDelimiter(); - monitor.beginTask("Importing CSV", 1); - // Path wktFile = model.getWKTFile(); - - int xCoordColumnIndex = model.getXCoordIndex(); - int yCoordColumnIndex = model.getYCoordIndex(); - int zCoordColumnIndex = model.getZCoordIndex(); - int supplyTempColumnIndex = model.getSupplyTempIndex(); - int returnTempColumnIndex = model.getReturnTempIndex(); - int supplyPressureColumnIndex = model.getSupplyPressureIndex(); - int returnPressureColumnIndex = model.getReturnPressureIndex(); - int dpIndex = model.getDeltaPressureIndex(); - int dtIndex = model.getDeltaTemperatureIndex(); - int heatPowerIndex = model.getHeatPowerIndex(); - int valvePositionIndex = model.getValvePositionIndx(); - int nominalHeadMIndex = model.getNominalHeadMIndex(); - int nominalHeadBIndex = model.getNominalHeadBIndex(); - int nominalFlowIndex = model.getNominalFlowIndex(); - int maximumHeadMIndex = model.getMaximumHeadMIndex(); - int heatLoadDsIndex = model.getHeatLoadDsIndex(); - int massFlowIndex = model.getMassFlowIndex(); - int volFlowIndex = model.getVolFlowIndex(); - int velocityIndex = model.getVelocityIndex(); - int flowAreaIndex = model.getFlowAreaIndex(); - int nominalPressureLossIndex = model.getNominalPressureLossIndex(); - int addressIndex = model.getAddressIndex(); - - 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 diameterColumnIndex= model.getDiameterIndex(); - int outerDiameterColumnIndex = model.getOuterDiamterIndex(); - int nominalMassFlowIndex = model.getNominalMassFlowIndex(); - int tGroundIndex = model.gettGroundIndex(); - int edgeFlowAreaIndex = model.getEdgeFlowAreaIndex(); - int kReturnIndex = model.getkReturnIndex(); - int kSupplyIndex = model.getkSupplyIndex(); - int lengthIndex = model.getLengthIndex(); - int detailedGeometryIndex = model.getDetailedGeometryIndex(); - - int mappingColumn = model.getComponentMappingIndex(); - int idColumn = model.getIdIndex(); - - double padding = model.getEdgePadding(); - - String sourceEPSGCRS = model.getSourceCRS(); - - 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, true); - doTransform = true; + if (model.isVertexImport()) { + DistrictImportUtils.importVertices(model); + } else { + DistrictImportUtils.importEdges(model); } - final boolean actualDoTransform = doTransform; - final MathTransform actualTransform = transform; - - double halfPadding = padding / 2; - - Quadtree vv = Simantics.getSession().syncRequest(new UniqueRead() { - - @Override - public Quadtree perform(ReadGraph graph) throws DatabaseException { - Collection vertices = graph.syncRequest(new ObjectsWithType(model.getParentDiagram(), Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex)); - Quadtree vv = new Quadtree(); - for (Resource vertex : vertices) { - double[] coords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY); - double x1 = coords[0] - halfPadding; - double y1= coords[1] - halfPadding; - double x2 = coords[0] + halfPadding; - double y2= coords[1] + halfPadding; - Envelope e = new Envelope(x1, x2, y1, y2); - vv.insert(e, new ResourceVertex(vertex, coords, true)); - } - return vv; - } - }); - - Simantics.getSession().syncRequest(new WriteRequest() { - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - try { - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - graph.markUndoPoint(); - - DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - - DistrictImportUtils.consumeCSV(csvFile, delim, true, row -> { - 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); - - double z = 0; - if (zCoordColumnIndex != -1) { - String zs = row.get(zCoordColumnIndex); - - if (!zs.isEmpty()) { - try { - z = Double.parseDouble(zs); - } catch (NumberFormatException e1) { - throw new DatabaseException(e1); - } - } - } - - double[] coords; - if (actualDoTransform) { - DirectPosition2D targetPos = new DirectPosition2D(); - DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord); - DirectPosition res = actualTransform.transform(sourcePos, targetPos); - coords = res.getCoordinate(); - } else { - coords = new double[] { xCoord, yCoord }; - } - - // Switch to (longitude, latitude) - flipAxes(coords); - - Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, z, model.getComponentMappings().get(mappingValue)); - - writeStringValue(graph, row, idColumn, vertex, DN.HasId); - - writeValue(graph, row, supplyTempColumnIndex, vertex, DN.Vertex_HasSupplyTemperature); - writeValue(graph, row, returnTempColumnIndex, vertex, DN.Vertex_HasReturnTemperature); - writeValue(graph, row, supplyPressureColumnIndex, vertex, DN.Vertex_HasSupplyPressure); - writeValue(graph, row, returnPressureColumnIndex, vertex, DN.Vertex_HasReturnPressure); - writeValue(graph, row, dpIndex, vertex, DN.Vertex_HasDeltaPressure); - writeValue(graph, row, dtIndex, vertex, DN.Vertex_HasDeltaTemperature); - writeValue(graph, row, heatPowerIndex, vertex, DN.Vertex_HasHeatPower); - writeValue(graph, row, valvePositionIndex, vertex, DN.Vertex_HasValvePosition); - writeValue(graph, row, nominalHeadMIndex, vertex, DN.Vertex_HasNominalHeadM); - writeValue(graph, row, nominalHeadBIndex, vertex, DN.Vertex_HasNominalHeadB); - writeValue(graph, row, nominalFlowIndex, vertex, DN.Vertex_HasNominalFlow); - writeValue(graph, row, maximumHeadMIndex, vertex, DN.Vertex_HasMaximumHeadM); - writeValue(graph, row, heatLoadDsIndex, vertex, DN.Vertex_HasHeatLoadDs); - writeValue(graph, row, massFlowIndex, vertex, DN.Vertex_HasMassFlow); - writeValue(graph, row, volFlowIndex, vertex, DN.Vertex_HasVolFlow); - writeValue(graph, row, velocityIndex, vertex, DN.Vertex_HasVelocity); - writeValue(graph, row, flowAreaIndex, vertex, DN.Vertex_HasFlowArea); - writeValue(graph, row, nominalPressureLossIndex, vertex, DN.Vertex_HasNominalPressureLoss); - writeStringValue(graph, row, addressIndex, vertex, DN.Vertex_HasAddress); - - } else { - String startXCoords = row.get(startXCoordColumnIndex); - String startYCoords = row.get(startYCoordColumnIndex); - String startZCoords = row.get(startZValueColumnIndex); - String endXCoords = row.get(endXCoordColumnIndex); - String endYCoords = row.get(endYCoordColumnIndex); - String endZCoords = row.get(endZValueColumnIndex); - - double startXCoord = Double.parseDouble(startXCoords); // make negative - double startYCoord = Double.parseDouble(startYCoords); - double startZCoord = Double.parseDouble(startZCoords); - - double endXCoord = Double.parseDouble(endXCoords); // make negative - double endYCoord = Double.parseDouble(endYCoords); - double endZCoord = Double.parseDouble(endZCoords); - - double[] startCoords; - double[] endCoords; - if (actualDoTransform) { - DirectPosition2D startTargetPos = new DirectPosition2D(); - DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord); - DirectPosition startRes = actualTransform.transform(startSourcePos, startTargetPos); - startCoords = startRes.getCoordinate(); - - DirectPosition2D endTargetPos = new DirectPosition2D(); - DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord); - DirectPosition endRes = actualTransform.transform(endSourcePos, endTargetPos); - endCoords = endRes.getCoordinate(); - } else { - startCoords = new double[] { startXCoord , startYCoord }; - endCoords = new double[] { endXCoord , endYCoord }; - } - - // Switch to (longitude, latitude) - flipAxes(startCoords); - flipAxes(endCoords); - - Optional oedge = DNEdgeBuilder.create(graph, vv, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, startZCoord, endCoords, endZCoord, new double[0], padding, true); - if (oedge.isPresent()) { - Resource edge = oedge.get(); - writeStringValue(graph, row, idColumn, edge, DN.HasId); - - writeValue(graph, row, diameterColumnIndex, edge, DN.Edge_HasDiameter); - writeValue(graph, row, outerDiameterColumnIndex, edge, DN.Edge_HasOuterDiameter); - writeValue(graph, row, nominalMassFlowIndex, edge, DN.Edge_HasNominalMassFlow); - writeValue(graph, row, tGroundIndex, edge, DN.Edge_HasTGround); - writeValue(graph, row, kReturnIndex, edge, DN.Edge_HasKReturn); - writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply); - writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea); - writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength); - writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform); - } - } - } catch (MismatchedDimensionException | TransformException | DatabaseException e2) { - throw new RuntimeException(e2); - } - monitor.worked(1); - return true; - }); - } catch (IOException e) { - e.printStackTrace(); - } finally { - Layer0Utils.setDependenciesIndexingDisabled(graph, false); - } - } - }); } catch (Exception e) { throw new InvocationTargetException(e); } @@ -310,74 +64,5 @@ public class CSVImportWizard extends Wizard implements IImportWizard { } } - private static void flipAxes(double[] coords) { - double tmp = coords[0]; - coords[0] = coords[1]; - coords[1] = tmp; - } - - private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException { - if (index != -1) { - String stringValue = row.get(index); - if (!stringValue.isEmpty()) { - try { - graph.claimLiteral(subject, relation, Double.parseDouble(stringValue), Bindings.DOUBLE); - } catch (NumberFormatException e) { - throw new DatabaseException(e); - } - } - } - } - - private static void writeStringValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException { - if (index != -1) { - String stringValue = row.get(index); - if (!stringValue.isEmpty()) { - try { - graph.claimLiteral(subject, relation, stringValue, Bindings.STRING); - } catch (NumberFormatException e) { - throw new DatabaseException(e); - } - } - } - } - private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException { - if (index != -1) { - String stringValue = row.get(index); - if (!stringValue.isEmpty()) { - if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) { - stringValue = stringValue.substring(1, stringValue.length() - 1); - } - String[] coordPairs = stringValue.split(";"); - ArrayList dd = new ArrayList<>(coordPairs.length * 2); - for (int i = 0; i < coordPairs.length; i++) { - String coordPair = coordPairs[i]; - String[] p = coordPair.split(" "); - double x = Double.parseDouble(p[0]); - double y = Double.parseDouble(p[1]); - if (actualTransform != null) { - DirectPosition2D targetPos = new DirectPosition2D(); - DirectPosition2D sourcePos = new DirectPosition2D(y, x); - DirectPosition res = actualTransform.transform(sourcePos, targetPos); - double[] coords = res.getCoordinate(); - x = coords[1]; - y = coords[0]; - } - dd.add(x); - dd.add(y); - } - double[] detailedGeometryCoords = new double[dd.size()]; - for (int i = 0; i < dd.size(); i++) { - double d = dd.get(i); - detailedGeometryCoords[i] = d; - } - try { - graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY); - } catch (NumberFormatException e) { - throw new DatabaseException(e); - } - } - } - } } 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 index 9ba7e2da..a0cc023c 100644 --- 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 @@ -22,6 +22,7 @@ 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.CSVImportModel; import org.simantics.district.network.ui.function.Functions; import org.simantics.modeling.ModelingResources; import org.simantics.utils.ui.widgets.FileOrDirectorySelectionWidget; 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 3d121e7a..c6e1b516 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 @@ -33,6 +33,7 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.geotools.referencing.CRS; +import org.simantics.district.imports.CSVImportModel; import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor; public class CSVImportWizardPage extends WizardPage { @@ -300,7 +301,7 @@ public class CSVImportWizardPage extends WizardPage { public void modifyText(ModifyEvent e) { try { double padding = Double.parseDouble(edgeConnectionPadding.getText()); - model.setEdgePapping(padding); + model.setEdgePadding(padding); } catch (NumberFormatException ee) { // ignore } 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 index 8bdf26dc..7b87b29f 100644 --- 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 @@ -23,6 +23,7 @@ import org.simantics.db.Resource; import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; +import org.simantics.district.imports.CSVImportModel; import org.simantics.district.imports.DistrictImportUtils; import org.simantics.district.network.ui.function.Functions; diff --git a/org.simantics.district.imports/META-INF/MANIFEST.MF b/org.simantics.district.imports/META-INF/MANIFEST.MF index b04e9223..747c33cb 100644 --- a/org.simantics.district.imports/META-INF/MANIFEST.MF +++ b/org.simantics.district.imports/META-INF/MANIFEST.MF @@ -4,7 +4,13 @@ Bundle-Name: Simantics District Imports Bundle-SymbolicName: org.simantics.district.imports Bundle-Version: 1.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: org.simantics.db +Require-Bundle: org.simantics.db, + org.simantics, + org.simantics.district.geotools, + org.simantics.district.network.ontology, + org.simantics.district.network, + org.simantics.diagram.ontology, + org.slf4j.api Export-Package: org.apache.commons.csv, org.simantics.district.imports Bundle-ClassPath: lib/commons-csv-1.4.jar, diff --git a/org.simantics.district.imports/build.properties b/org.simantics.district.imports/build.properties index 78db4425..4e38199d 100644 --- a/org.simantics.district.imports/build.properties +++ b/org.simantics.district.imports/build.properties @@ -1,5 +1,6 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - lib/commons-csv-1.4.jar +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + lib/commons-csv-1.4.jar,\ + scl/ diff --git a/org.simantics.district.imports/scl/Simantics/District/Import.scl b/org.simantics.district.imports/scl/Simantics/District/Import.scl new file mode 100644 index 00000000..9e423ca4 --- /dev/null +++ b/org.simantics.district.imports/scl/Simantics/District/Import.scl @@ -0,0 +1,45 @@ +import "Files" +import "Map" as Map +import "Simantics/DB" + +importJava "org.simantics.district.imports.CSVImportModel" where + data CSVImportModel + + @JavaName "" + csvImportModel :: () -> CSVImportModel + + setParentDiagram :: CSVImportModel -> Resource -> () + setSource :: CSVImportModel -> Path -> () + setDelimiter :: CSVImportModel -> Character -> () + + // Vertex + setXCoordIndex :: CSVImportModel -> Integer -> () + setYCoordIndex :: CSVImportModel -> Integer -> () + setZCoordIndex :: CSVImportModel -> Integer -> () + setHeatLoadDsIndex :: CSVImportModel -> Integer -> () + setHeatPowerIndex :: CSVImportModel -> Integer -> () + + // Edge + setStartXCoordIndex :: CSVImportModel -> Integer -> () + setStartYCoordIndex :: CSVImportModel -> Integer -> () + setStartZCoordIndex :: CSVImportModel -> Integer -> () + setEndXCoordIndex :: CSVImportModel -> Integer -> () + setEndYCoordIndex :: CSVImportModel -> Integer -> () + setEndZCoordIndex :: CSVImportModel -> Integer -> () + + setLengthIndex :: CSVImportModel -> Integer -> () + detailedGeometryIndex :: CSVImportModel -> Integer -> () + setDiameterIndex :: CSVImportModel -> Integer -> () + setOuterDiameterIndex :: CSVImportModel -> Integer -> () + setEdgePadding :: CSVImportModel -> Double -> () + + // Common + setSourceCRS :: CSVImportModel -> String -> () + setIdIndex :: CSVImportModel -> Integer -> () + setAddressIndex :: CSVImportModel -> Integer -> () + setComponentMappingIndex :: CSVImportModel -> Integer -> () + setComponentMappings :: CSVImportModel -> String -> Resource -> () + +importJava "org.simantics.district.imports.DistrictImportUtils" where + importVertices :: CSVImportModel -> () + importEdges :: CSVImportModel -> () diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java b/org.simantics.district.imports/src/org/simantics/district/imports/CSVImportModel.java similarity index 98% rename from org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java rename to org.simantics.district.imports/src/org/simantics/district/imports/CSVImportModel.java index 6861b5c4..5041f1bb 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java +++ b/org.simantics.district.imports/src/org/simantics/district/imports/CSVImportModel.java @@ -1,4 +1,4 @@ -package org.simantics.district.imports.ui; +package org.simantics.district.imports; import java.io.IOException; import java.nio.file.Path; @@ -10,7 +10,6 @@ import java.util.Map; import org.apache.commons.csv.CSVFormat; 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 { @@ -70,9 +69,9 @@ public class CSVImportModel { private int idIndex = -1; private double edgePadding = 0.0001; // default private int valvePositionIndx = -1; - private int addressIndex; - private int lengthIndex; - private int detailedGeometryIndex; + private int addressIndex = -1; + private int lengthIndex = -1; + private int detailedGeometryIndex = -1; // Third page @@ -462,7 +461,7 @@ public class CSVImportModel { this.idIndex = idIndex; } - public void setEdgePapping(double edgePadding) { + public void setEdgePadding(double edgePadding) { this.edgePadding = edgePadding; } 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 ef000d75..a1794b6a 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 @@ -10,6 +10,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -17,12 +18,43 @@ import java.util.function.Function; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; +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.NoSuchAuthorityCodeException; +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.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.DNEdgeBuilder; +import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.layer0.Layer0; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.simantics.district.network.DistrictNetworkUtil.ResourceVertex; + +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.index.quadtree.Quadtree; public class DistrictImportUtils { private DistrictImportUtils() { } + private static final Logger LOGGER = LoggerFactory.getLogger(DistrictImportUtils.class); + public static Resource importCSVAsLayer(Path csvFile) throws IOException { try (CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(Files.newBufferedReader(csvFile))) { @@ -195,4 +227,347 @@ public class DistrictImportUtils { return results; } + public static void importVertices(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException { + + Path csvFile = model.getSource(); + char delim = model.getDelimiter(); + + int xCoordColumnIndex = model.getXCoordIndex(); + int yCoordColumnIndex = model.getYCoordIndex(); + int zCoordColumnIndex = model.getZCoordIndex(); + int supplyTempColumnIndex = model.getSupplyTempIndex(); + int returnTempColumnIndex = model.getReturnTempIndex(); + int supplyPressureColumnIndex = model.getSupplyPressureIndex(); + int returnPressureColumnIndex = model.getReturnPressureIndex(); + int dpIndex = model.getDeltaPressureIndex(); + int dtIndex = model.getDeltaTemperatureIndex(); + int heatPowerIndex = model.getHeatPowerIndex(); + int valvePositionIndex = model.getValvePositionIndx(); + int nominalHeadMIndex = model.getNominalHeadMIndex(); + int nominalHeadBIndex = model.getNominalHeadBIndex(); + int nominalFlowIndex = model.getNominalFlowIndex(); + int maximumHeadMIndex = model.getMaximumHeadMIndex(); + int heatLoadDsIndex = model.getHeatLoadDsIndex(); + int massFlowIndex = model.getMassFlowIndex(); + int volFlowIndex = model.getVolFlowIndex(); + int velocityIndex = model.getVelocityIndex(); + int flowAreaIndex = model.getFlowAreaIndex(); + int nominalPressureLossIndex = model.getNominalPressureLossIndex(); + int addressIndex = model.getAddressIndex(); + + int mappingColumn = model.getComponentMappingIndex(); + int idColumn = model.getIdIndex(); + + String sourceEPSGCRS = model.getSourceCRS(); + + 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, true); + doTransform = true; + } + final boolean actualDoTransform = doTransform; + final MathTransform actualTransform = transform; + + Simantics.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + try { + Layer0Utils.setDependenciesIndexingDisabled(graph, true); + graph.markUndoPoint(); + + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + DistrictImportUtils.consumeCSV(csvFile, delim, true, (Function) row -> { + try { + String mappingValue = row.get(mappingColumn); + + String xCoords = row.get(xCoordColumnIndex); + String yCoords = row.get(yCoordColumnIndex); + double xCoord = Double.parseDouble(xCoords); + double yCoord = Double.parseDouble(yCoords); + + double z = 0; + if (zCoordColumnIndex != -1) { + String zs = row.get(zCoordColumnIndex); + + if (!zs.isEmpty()) { + try { + z = Double.parseDouble(zs); + } catch (NumberFormatException e1) { + throw new DatabaseException(e1); + } + } + } + + double[] coords; + if (actualDoTransform) { + DirectPosition2D targetPos = new DirectPosition2D(); + DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord); + DirectPosition res = actualTransform.transform(sourcePos, targetPos); + coords = res.getCoordinate(); + } else { + coords = new double[] { xCoord, yCoord }; + } + + // Switch to (longitude, latitude) + flipAxes(coords); + + Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, z, model.getComponentMappings().get(mappingValue)); + + writeStringValue(graph, row, idColumn, vertex, DN.HasId); + + writeValue(graph, row, supplyTempColumnIndex, vertex, DN.Vertex_HasSupplyTemperature); + writeValue(graph, row, returnTempColumnIndex, vertex, DN.Vertex_HasReturnTemperature); + writeValue(graph, row, supplyPressureColumnIndex, vertex, DN.Vertex_HasSupplyPressure); + writeValue(graph, row, returnPressureColumnIndex, vertex, DN.Vertex_HasReturnPressure); + writeValue(graph, row, dpIndex, vertex, DN.Vertex_HasDeltaPressure); + writeValue(graph, row, dtIndex, vertex, DN.Vertex_HasDeltaTemperature); + writeValue(graph, row, heatPowerIndex, vertex, DN.Vertex_HasHeatPower); + writeValue(graph, row, valvePositionIndex, vertex, DN.Vertex_HasValvePosition); + writeValue(graph, row, nominalHeadMIndex, vertex, DN.Vertex_HasNominalHeadM); + writeValue(graph, row, nominalHeadBIndex, vertex, DN.Vertex_HasNominalHeadB); + writeValue(graph, row, nominalFlowIndex, vertex, DN.Vertex_HasNominalFlow); + writeValue(graph, row, maximumHeadMIndex, vertex, DN.Vertex_HasMaximumHeadM); + writeValue(graph, row, heatLoadDsIndex, vertex, DN.Vertex_HasHeatLoadDs); + writeValue(graph, row, massFlowIndex, vertex, DN.Vertex_HasMassFlow); + writeValue(graph, row, volFlowIndex, vertex, DN.Vertex_HasVolFlow); + writeValue(graph, row, velocityIndex, vertex, DN.Vertex_HasVelocity); + writeValue(graph, row, flowAreaIndex, vertex, DN.Vertex_HasFlowArea); + writeValue(graph, row, nominalPressureLossIndex, vertex, DN.Vertex_HasNominalPressureLoss); + writeStringValue(graph, row, addressIndex, vertex, DN.Vertex_HasAddress); + } catch (DatabaseException | MismatchedDimensionException | TransformException e) { + throw new RuntimeException(e); + } + return true; + }); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + Layer0Utils.setDependenciesIndexingDisabled(graph, false); + } + } + }); + } + + public static void importEdges(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException { + + Path csvFile = model.getSource(); + char delim = model.getDelimiter(); + + + 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 diameterColumnIndex= model.getDiameterIndex(); + int outerDiameterColumnIndex = model.getOuterDiamterIndex(); + int nominalMassFlowIndex = model.getNominalMassFlowIndex(); + int tGroundIndex = model.gettGroundIndex(); + int edgeFlowAreaIndex = model.getEdgeFlowAreaIndex(); + int kReturnIndex = model.getkReturnIndex(); + int kSupplyIndex = model.getkSupplyIndex(); + int lengthIndex = model.getLengthIndex(); + int detailedGeometryIndex = model.getDetailedGeometryIndex(); + + int mappingColumn = model.getComponentMappingIndex(); + int idColumn = model.getIdIndex(); + + double padding = model.getEdgePadding(); + + String sourceEPSGCRS = model.getSourceCRS(); + + 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, true); + doTransform = true; + } + final boolean actualDoTransform = doTransform; + final MathTransform actualTransform = transform; + + double halfPadding = padding / 2; + + Quadtree vv = Simantics.getSession().syncRequest(new UniqueRead() { + + @Override + public Quadtree perform(ReadGraph graph) throws DatabaseException { + Collection vertices = graph.syncRequest(new ObjectsWithType(model.getParentDiagram(), Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex)); + Quadtree vv = new Quadtree(); + for (Resource vertex : vertices) { + double[] coords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY); + double x1 = coords[0] - halfPadding; + double y1= coords[1] - halfPadding; + double x2 = coords[0] + halfPadding; + double y2= coords[1] + halfPadding; + Envelope e = new Envelope(x1, x2, y1, y2); + vv.insert(e, new ResourceVertex(vertex, coords, true)); + } + return vv; + } + }); + + Simantics.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + try { + Layer0Utils.setDependenciesIndexingDisabled(graph, true); + graph.markUndoPoint(); + + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + DistrictImportUtils.consumeCSV(csvFile, delim, true, row -> { + try { + String mappingValue = row.get(mappingColumn); + + String startXCoords = row.get(startXCoordColumnIndex); + String startYCoords = row.get(startYCoordColumnIndex); + String startZCoords = row.get(startZValueColumnIndex); + String endXCoords = row.get(endXCoordColumnIndex); + String endYCoords = row.get(endYCoordColumnIndex); + String endZCoords = row.get(endZValueColumnIndex); + + double startXCoord = Double.parseDouble(startXCoords); // make negative + double startYCoord = Double.parseDouble(startYCoords); + double startZCoord = Double.parseDouble(startZCoords); + + double endXCoord = Double.parseDouble(endXCoords); // make negative + double endYCoord = Double.parseDouble(endYCoords); + double endZCoord = Double.parseDouble(endZCoords); + + double[] startCoords; + double[] endCoords; + if (actualDoTransform) { + DirectPosition2D startTargetPos = new DirectPosition2D(); + DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord); + DirectPosition startRes = actualTransform.transform(startSourcePos, startTargetPos); + startCoords = startRes.getCoordinate(); + + DirectPosition2D endTargetPos = new DirectPosition2D(); + DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord); + DirectPosition endRes = actualTransform.transform(endSourcePos, endTargetPos); + endCoords = endRes.getCoordinate(); + } else { + startCoords = new double[] { startXCoord , startYCoord }; + endCoords = new double[] { endXCoord , endYCoord }; + } + + // Switch to (longitude, latitude) + flipAxes(startCoords); + flipAxes(endCoords); + + Optional oedge = DNEdgeBuilder.create(graph, vv, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, startZCoord, endCoords, endZCoord, new double[0], padding, true); + if (oedge.isPresent()) { + Resource edge = oedge.get(); + writeStringValue(graph, row, idColumn, edge, DN.HasId); + + writeValue(graph, row, diameterColumnIndex, edge, DN.Edge_HasDiameter); + writeValue(graph, row, outerDiameterColumnIndex, edge, DN.Edge_HasOuterDiameter); + writeValue(graph, row, nominalMassFlowIndex, edge, DN.Edge_HasNominalMassFlow); + writeValue(graph, row, tGroundIndex, edge, DN.Edge_HasTGround); + writeValue(graph, row, kReturnIndex, edge, DN.Edge_HasKReturn); + writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply); + writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea); + writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength); + writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform); + } + + return true; + } catch (DatabaseException | MismatchedDimensionException | TransformException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + LOGGER.error("Could not import edges {}", model.getSource(), e); + } finally { + Layer0Utils.setDependenciesIndexingDisabled(graph, false); + } + } + }); + } + + private static void flipAxes(double[] coords) { + double tmp = coords[0]; + coords[0] = coords[1]; + coords[1] = tmp; + } + + private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException { + if (index != -1) { + String stringValue = row.get(index); + if (!stringValue.isEmpty()) { + try { + if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) { + stringValue = stringValue.substring(1, stringValue.length() - 1); + } + graph.claimLiteral(subject, relation, Double.parseDouble(stringValue), Bindings.DOUBLE); + } catch (NumberFormatException e) { + throw new DatabaseException(e); + } + } + } + } + + private static void writeStringValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException { + if (index != -1) { + String stringValue = row.get(index); + if (!stringValue.isEmpty()) { + try { + graph.claimLiteral(subject, relation, stringValue, Bindings.STRING); + } catch (NumberFormatException e) { + throw new DatabaseException(e); + } + } + } + } + + private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException { + if (index != -1) { + String stringValue = row.get(index); + if (!stringValue.isEmpty()) { + if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) { + stringValue = stringValue.substring(1, stringValue.length() - 1); + } + String[] coordPairs = stringValue.split(";"); + ArrayList dd = new ArrayList<>(coordPairs.length * 2); + for (int i = 0; i < coordPairs.length; i++) { + String coordPair = coordPairs[i]; + String[] p = coordPair.split(" "); + double x = Double.parseDouble(p[0]); + double y = Double.parseDouble(p[1]); + if (actualTransform != null) { + DirectPosition2D targetPos = new DirectPosition2D(); + DirectPosition2D sourcePos = new DirectPosition2D(y, x); + DirectPosition res = actualTransform.transform(sourcePos, targetPos); + double[] coords = res.getCoordinate(); + x = coords[1]; + y = coords[0]; + } + dd.add(x); + dd.add(y); + } + double[] detailedGeometryCoords = new double[dd.size()]; + for (int i = 0; i < dd.size(); i++) { + double d = dd.get(i); + detailedGeometryCoords[i] = d; + } + try { + graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY); + } catch (NumberFormatException e) { + throw new DatabaseException(e); + } + } + } + } } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java index d540a96c..edecb859 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeRoutePointToVertexHandler.java @@ -29,10 +29,10 @@ import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.db.request.Read; import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.DNEdgeBuilder; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.district.network.ui.DNEdgeBuilder; import org.simantics.district.network.ui.DistrictDiagramEditor; import org.simantics.district.network.ui.NetworkDrawingParticipant; import org.simantics.g2d.canvas.ICanvasContext; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeVertexToRoutePointHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeVertexToRoutePointHandler.java index a9ef98a2..cd713417 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeVertexToRoutePointHandler.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/ChangeVertexToRoutePointHandler.java @@ -30,10 +30,10 @@ import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.db.request.Read; import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.DNEdgeBuilder; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.district.network.ui.DNEdgeBuilder; import org.simantics.district.network.ui.DistrictDiagramEditor; import org.simantics.district.network.ui.NetworkDrawingParticipant; import org.simantics.g2d.canvas.ICanvasContext; 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 89878c5b..cc05a173 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 @@ -40,6 +40,7 @@ import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.request.WriteResultRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.exception.ServiceException; @@ -49,6 +50,7 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.db.layer0.variable.Variables.Role; import org.simantics.db.procedure.Procedure; +import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; @@ -244,8 +246,8 @@ public class Functions { private Resource leftClickVertexMapping; //private Resource defaultCRS; - private Combo compositeMappingCombo; - private Combo componentMappingCombo; + //private Combo compositeMappingCombo; + //private Combo componentMappingCombo; protected DefaultMappingsDialog(Shell parentShell, Resource configuration) { super(parentShell); @@ -299,7 +301,7 @@ public class Functions { //crsCombo.setItems(crss.keySet().toArray(new String[crss.size()])); - compositeMappingCombo.setItems(composites.keySet().toArray(new String[composites.size()])); + //compositeMappingCombo.setItems(composites.keySet().toArray(new String[composites.size()])); vertexMappingCombo.select(0); rightClickMappingCombo.select(0); leftClickMappingCombo.select(0); @@ -307,8 +309,8 @@ public class Functions { //crsCombo.select(0); - if (!composites.isEmpty()) - compositeMappingCombo.select(0); + //if (!composites.isEmpty()) + // compositeMappingCombo.select(0); }); } @@ -388,22 +390,22 @@ public class Functions { Label compositeMappingLabel = new Label(cmposite, SWT.NONE); compositeMappingLabel.setText("Select composite"); - compositeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); - GridDataFactory.fillDefaults().grab(true, false).applyTo(compositeMappingCombo); - compositeMappingCombo.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - recalculateMappapleComponents(); - } - }); - - Label compojnentMappingLabel = new Label(cmposite, SWT.NONE); - compojnentMappingLabel.setText("Select component"); +// compositeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); +// GridDataFactory.fillDefaults().grab(true, false).applyTo(compositeMappingCombo); +// compositeMappingCombo.addSelectionListener(new SelectionAdapter() { +// +// @Override +// public void widgetSelected(SelectionEvent e) { +// super.widgetSelected(e); +// recalculateMappapleComponents(); +// } +// }); - componentMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); - GridDataFactory.fillDefaults().grab(true, false).applyTo(componentMappingCombo); +// Label compojnentMappingLabel = new Label(cmposite, SWT.NONE); +// compojnentMappingLabel.setText("Select component"); +// +// componentMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); +// GridDataFactory.fillDefaults().grab(true, false).applyTo(componentMappingCombo); } protected void recalculateMappapleComponents() { @@ -463,38 +465,34 @@ public class Functions { procedure.execute(null); return; } - Simantics.getSession().asyncRequest( - NewCompositeActionFactory.createCompositeRequest(target, defaultName, compositeType), - new Procedure() { - @Override - public void execute(Resource composite) { - Simantics.getSession().asyncRequest(new WriteRequest() { - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram); - graph.claim(diagram, DN.EdgeDefaultMapping, dialog.getDefaultEdgeMapping()); - graph.claim(diagram, DN.VertexDefaultMapping, dialog.getDefaultVertexMapping()); - graph.claim(diagram, DN.RightClickDefaultMapping, dialog.getRightClickVertexMapping()); - graph.claim(diagram, DN.LeftClickDefaultMapping, dialog.getLeftClickVertexMapping()); - graph.claim(diagram, DN.HasSpatialRefSystem, dialog.getCRS()); - - // Generated name prefix from composite name - String compositeName = graph.getRelatedValue2(composite, Layer0.getInstance(graph).HasName, Bindings.STRING); - graph.claimLiteral(diagram, Layer0X.getInstance(graph).HasGeneratedNamePrefix, "N" + compositeName.substring(compositeName.length() - 1, compositeName.length())); - } - }); - DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true); - procedure.execute(composite); - } - - @Override - public void exception(Throwable t) { - LOGGER.error("Failed to create composite, see exception for details.", t); - procedure.exception(t); - } - }); + Simantics.getSession().asyncRequest(new WriteResultRequest() { + + @Override + public Resource perform(WriteGraph graph) throws DatabaseException { + return DistrictNetworkUtil.createNetworkDiagram(graph, target, compositeType, defaultName, + dialog.getDefaultEdgeMapping(), + dialog.getDefaultVertexMapping(), + dialog.getRightClickVertexMapping(), + dialog.getLeftClickVertexMapping(), + dialog.getCRS() + ); + } + + + }, new Procedure() { + + @Override + public void execute(Resource composite) { + DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true); + procedure.execute(composite); + } + + @Override + public void exception(Throwable t) { + LOGGER.error("Failed to create composite, see exception for details.", t); + procedure.exception(t); + } + }); } public static Collection getDistrictDiagrams(ReadGraph graph) throws DatabaseException { 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 6c13f90d..4d527c1a 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 @@ -21,10 +21,10 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Write; import org.simantics.diagram.elements.DiagramNodeUtil; import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.district.network.DNEdgeBuilder; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.district.network.ui.DNEdgeBuilder; import org.simantics.district.network.ui.NetworkDrawingParticipant; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; diff --git a/org.simantics.district.network/META-INF/MANIFEST.MF b/org.simantics.district.network/META-INF/MANIFEST.MF index dfb47169..761e37fb 100644 --- a/org.simantics.district.network/META-INF/MANIFEST.MF +++ b/org.simantics.district.network/META-INF/MANIFEST.MF @@ -16,7 +16,8 @@ Require-Bundle: org.simantics.db, org.simantics.scenegraph.profile;bundle-version="1.0.0", org.simantics;bundle-version="1.0.0", org.slf4j.api, - org.simantics.maps.elevation.server;bundle-version="1.0.0" + org.simantics.maps.elevation.server;bundle-version="1.0.0", + org.simantics.modeling Export-Package: org.simantics.district.network, org.simantics.district.network.changeset, org.simantics.district.network.profile diff --git a/org.simantics.district.network/scl/Simantics/District.scl b/org.simantics.district.network/scl/Simantics/District.scl index f96ed607..8e96b518 100644 --- a/org.simantics.district.network/scl/Simantics/District.scl +++ b/org.simantics.district.network/scl/Simantics/District.scl @@ -148,3 +148,7 @@ The result list can be smaller than the input resource list, even empty. """ dnElementsMappedToComponents :: [Resource] -> [Resource] dnElementsMappedToComponents mappedComponents = mapMaybe possibleDNElementMappedToComponent mappedComponents + + +importJava "org.simantics.district.network.DistrictNetworkUtil" where + createNetworkDiagram :: Resource -> Resource -> String -> Resource -> Resource -> Resource -> Resource -> Resource -> Resource diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java b/org.simantics.district.network/src/org/simantics/district/network/DNEdgeBuilder.java similarity index 92% rename from org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java rename to org.simantics.district.network/src/org/simantics/district/network/DNEdgeBuilder.java index b937ed2a..3f869649 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java +++ b/org.simantics.district.network/src/org/simantics/district/network/DNEdgeBuilder.java @@ -1,4 +1,4 @@ -package org.simantics.district.network.ui; +package org.simantics.district.network; import java.awt.geom.Rectangle2D; import java.util.Collection; @@ -19,7 +19,7 @@ import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; import org.simantics.diagram.synchronization.SynchronizationHints; import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; -import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.DistrictNetworkUtil.ResourceVertex; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.g2d.diagram.IDiagram; import org.simantics.layer0.Layer0; @@ -66,8 +66,8 @@ public class DNEdgeBuilder { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); // 2. Add vertices - Resource startVertex = getOrCreateVertex(graph, diagramResource, vertices, start, startElevation, padding); - Resource endVertex = getOrCreateVertex(graph, diagramResource, vertices, end, endElevation, padding); + Resource startVertex = getOrCreateVertex(graph, diagramResource, vertices, start, startElevation, padding, null); + Resource endVertex = getOrCreateVertex(graph, diagramResource, vertices, end, endElevation, padding, startVertex); if (startVertex.equals(endVertex)) { LOGGER.info("Circular edges are not supported, startVertex: {}, endVertex: {}", startVertex, endVertex); return Optional.empty(); @@ -122,7 +122,7 @@ public class DNEdgeBuilder { glm.putElementOnVisibleLayers(diagram, graph, res); } - private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Quadtree qtree, double[] coords, double elevation, double padding) throws DatabaseException { + private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Quadtree qtree, double[] coords, double elevation, double padding, Resource startVertex) throws DatabaseException { Resource vertex = null; double halfPadding = padding / 2; double maxDistance = Double.MAX_VALUE; @@ -140,7 +140,7 @@ public class DNEdgeBuilder { Rectangle2D tobecreated = new Rectangle2D.Double(x1, y1, padding, padding); if (existing.intersects(tobecreated)) { double dist = Math.sqrt((Math.pow(coords[0] - vertx.coords[0], 2) + (Math.pow(coords[1] - vertx.coords[1], 2)))); - if (dist <= maxDistance) { + if (dist <= maxDistance && vertx.vertex != startVertex) { vertex = vertx.vertex; maxDistance = dist; } @@ -157,16 +157,4 @@ public class DNEdgeBuilder { return DistrictNetworkUtil.createEdge(graph, diagramResource, mapping, detailedGeometryCoords); } - public static class ResourceVertex { - - final boolean isConsumer; - final Resource vertex; - final double[] coords; - - public ResourceVertex(Resource vertex, double[] coords, boolean isConsumer) { - this.vertex = vertex; - this.coords = coords; - this.isConsumer = isConsumer; - } - } } 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 bac4707d..519ad512 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 @@ -25,6 +25,7 @@ import org.simantics.diagram.synchronization.graph.layer.IGraphLayerUtil; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.adapters.NewCompositeActionFactory; import org.simantics.operation.Layer0X; public class DistrictNetworkUtil { @@ -251,6 +252,24 @@ public class DistrictNetworkUtil { DistrictNetworkResource.getInstance(graph).Diagram_backgroundColor, Bindings.getBindingUnchecked(RGB.Integer.class)); } + + public static Resource createNetworkDiagram(WriteGraph graph, Resource target, Resource compositeType, String defaultName, Resource defaultEdgeMapping, Resource defaultVertexMapping, Resource rightClickVertexMapping, Resource leftClickVertexMapping, Resource crs) throws DatabaseException { + Resource composite = NewCompositeActionFactory.createComposite(graph, target, defaultName, compositeType); + + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram); + graph.claim(diagram, DN.EdgeDefaultMapping, defaultEdgeMapping); + graph.claim(diagram, DN.VertexDefaultMapping, defaultVertexMapping); + graph.claim(diagram, DN.RightClickDefaultMapping, rightClickVertexMapping); + graph.claim(diagram, DN.LeftClickDefaultMapping, leftClickVertexMapping); + graph.claim(diagram, DN.HasSpatialRefSystem, crs); + + // Generated name prefix from composite name + String compositeName = graph.getRelatedValue2(composite, Layer0.getInstance(graph).HasName, Bindings.STRING); + graph.claimLiteral(diagram, Layer0X.getInstance(graph).HasGeneratedNamePrefix, "N" + compositeName.substring(compositeName.length() - 1, compositeName.length())); + + return composite; + } public static final class MappedComponentRequest extends ResourceRead { public MappedComponentRequest(Resource element) { @@ -263,4 +282,16 @@ public class DistrictNetworkUtil { } } + public static class ResourceVertex { + + public final boolean isConsumer; + public final Resource vertex; + public final double[] coords; + + public ResourceVertex(Resource vertex, double[] coords, boolean isConsumer) { + this.vertex = vertex; + this.coords = coords; + this.isConsumer = isConsumer; + } + } } -- 2.47.1