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
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<String, Character> 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<String, Resource> componentMappings = new HashMap<>();
+ private boolean isVertexImport;
+
+ // Third page
public CSVImportModel() {
delimiters = DistrictImportUtils.getSupportedCSVDelimiterFormats();
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<String, Resource> 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;
+ }
+
}
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 {
@Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
model = new CSVImportModel();
+ addPage(new CSVImportWizardFirstPage(model));
addPage(new CSVImportWizardPage(model));
+ addPage(new ComponentMappingPage(model));
}
@Override
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();
}
--- /dev/null
+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<String, Resource> 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<Resource> 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);
+ }
+}
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;
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<Integer, String> 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<Integer, String> 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() {
TableItem item = headerTable.getItem(i);
item.dispose();
}
+
+ headerIndexAndValues.clear();
+
try {
List<CSVRecord> 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;
}
}
}
-
-// Map<CSVHeader, List<String>> headerAndValues = model.getHeaderAndRows(5);
-//
-// int coo = headerTable.getColumns().length;
-// int count = headerTable.getColumnCount();
-//
-// for (Map.Entry<CSVHeader, List<String>> 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);
+ }
+
}
--- /dev/null
+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<String, Resource> componentMappings;
+ private Collection<String> distinctMappingIvalues;
+ private Collection<String> 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<String, Resource> currentMappings = model.getComponentMappings();
+ if (currentMappings != null && distinctMappingIndexColumnValues != null && currentMappings.keySet().containsAll(distinctMappingIndexColumnValues))
+ setPageComplete(true);
+ else
+ setPageComplete(false);
+ }
+
+}
--- /dev/null
+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 <code>Combo</code> 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 <code>String[][]</code> is of "type"
+ * <code>String[][2]</code>.
+ *
+ * @return <code>true</code> if it is ok, and <code>false</code> 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;
+ }
+}
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;
public class DistrictImportUtils {
private DistrictImportUtils() { }
-
-
+
public static Resource importCSVAsLayer(Path csvFile) throws IOException {
try (CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(Files.newBufferedReader(csvFile))) {
}
}
+ public static Collection<String> readDistinctValuesOfColumn(Path source, char delim, int mappingIndex) throws IOException {
+ Set<String> results = new HashSet<>();
+ CSVFormat format = CSVFormat.newFormat(delim);
+ try (CSVParser parser = format.parse(Files.newBufferedReader(source))) {
+ Iterator<CSVRecord> 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;
+ }
+
}
--- /dev/null
+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();
+ }
+}
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) {
tileSize *= 0.5;
level++;
}
-
+ System.out.println("level " + level);
/*
* To convert y-coordinates to map coordinates in ruler, use:
* double val = (y-offsetY)/scaleY;
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
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,
<elements xsi:type="commands:Command" xmi:id="_6lrYUML_Eea1mdgpHNVHMA" elementId="org.simantics.district.network.ui.command.openDistrictEditor" commandName="Open District Editor"/>
<elements xsi:type="commands:Command" xmi:id="_A1HBQOFYEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.joinVertices" commandName="Join Vertices"/>
<elements xsi:type="commands:Command" xmi:id="_QzdUQOIcEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.setFocusable" commandName="Set Focusable"/>
+ <elements xsi:type="commands:Command" xmi:id="_4wJtADWxEeeVXaXEq4_qpA" elementId="org.simantics.district.network.ui.command.changemapping" commandName="Change Mapping"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_Js7rUMMAEea1mdgpHNVHMA" featurename="menuContributions" parentElementId="xpath:/">
<elements xsi:type="menu:MenuContribution" xmi:id="_MbrJgMMAEea1mdgpHNVHMA" elementId="org.simantics.district.network.ui.menucontribution.0" parentId="help">
<children xsi:type="menu:HandledMenuItem" xmi:id="_VCxYIN8NEeaigNyzMJBOrg" elementId="org.simantics.district.network.ui.handledmenuitem.importImage" label="Import PNG/SVG Image" iconURI="platform:/plugin/org.simantics.modeling.ui/icons/image_add.png" tooltip="Import PNG/SVG Image as a layout" command="_luNasN8NEeaigNyzMJBOrg"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_O_UgUOIgEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.handledmenuitem.joinvertices" label="Join Vertices" iconURI="platform:/plugin/org.simantics.ui/icons/etool16/arrow_join.png" tooltip="Join multiple vertices as one" command="_A1HBQOFYEeaJP6VyXP72Jw"/>
<children xsi:type="menu:DynamicMenuContribution" xmi:id="_dieAsOIgEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.dynamicmenucontribution.setFocusable" label="Set Focusable" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.SetFocusableDynamicMenuContribution"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_QbF4UDWyEeeVXaXEq4_qpA" elementId="org.simantics.district.network.ui.handledmenuitem.changemapping" label="Change Mapping" tooltip="Change mapping of multiple elements" command="_4wJtADWxEeeVXaXEq4_qpA"/>
</elements>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_dbiHcMMBEea1mdgpHNVHMA" featurename="handlers" parentElementId="xpath:/">
<elements xsi:type="commands:Handler" xmi:id="_DPcVsOFYEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.handler.joinVertices" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.JoinVerticesHandler" command="_A1HBQOFYEeaJP6VyXP72Jw"/>
<elements xsi:type="commands:Handler" xmi:id="_VPgBwOIcEeaJP6VyXP72Jw" elementId="org.simantics.district.network.ui.handler.setFocusable" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.SetFocusableHandler" command="_QzdUQOIcEeaJP6VyXP72Jw"/>
+ <elements xsi:type="commands:Handler" xmi:id="_LojWYDWyEeeVXaXEq4_qpA" elementId="org.simantics.district.network.ui.handler.0" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ChangeMappingTypeHandler" command="_4wJtADWxEeeVXaXEq4_qpA"/>
</fragments>
</fragment:ModelFragments>
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;
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<Resource> 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);
glm.putElementOnVisibleLayers(diagram, graph, res);
}
- private Resource getOrCreateVertex(WriteGraph graph, Collection<Resource> vertices, double[] coords, double padding) throws DatabaseException {
+ private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Collection<Resource> 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);
}
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);
}
-package org.simantics.district.network.ui;\r
-\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-public class DistrictNetworkEdge {\r
-\r
- private Path2D path;\r
- \r
- public DistrictNetworkEdge(Path2D path) {\r
- this.path = path;\r
- }\r
-\r
- public Path2D getPath() {\r
- return path;\r
- }\r
-\r
- public Rectangle2D getBounds(Rectangle2D rect) {\r
- rect.setFrame(path.getBounds2D());\r
- return rect;\r
- }\r
-}\r
+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;
+ }
+
+}
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;
return size;
}
-
}
static class DNEdgeConnectionHandler implements ConnectionHandler {
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;
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 {
Resource startVertex = graph.getSingleObject(edgeResource, DN.HasStartVertex);
Resource endVertex = graph.getSingleObject(edgeResource, DN.HasEndVertex);
-
+
// TODO: fix scale..
double scale = 100000;
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;
--- /dev/null
+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<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ if (elements.size() < 1)
+ return false;
+ try {
+ return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ 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<Resource> 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<Resource> elements;
+ private Map<String, Resource> vertexMappings = new HashMap<>();
+
+ private Resource defaultVertexMapping;
+
+ protected SelectMappingDialog(Shell parentShell, List<Resource> 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);
+
+ }
+ }
+}
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;
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;
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;
});
}
- public static void getDistrictDiagrams(ReadGraph graph) {
-
+ public static Collection<Resource> getDistrictDiagrams(ReadGraph graph) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ Collection<Resource> indexRoots = graph.sync(new ObjectsWithType(Simantics.getProjectResource(), L0.ConsistsOf, L0.IndexRoot));
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Set<Resource> results = new HashSet<>();
+ for (Resource indexRoot : indexRoots) {
+ Collection<Resource> diagrams = ModelingUtils.searchByType(graph, indexRoot, DN.Diagram);
+ results.addAll(diagrams);
+ }
+ return results;
}
}
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;
}
// render
g2d.draw(edge.getPath());
-
+
// Reset
g2d.setStroke(oldStroke);
g2d.setColor(oldColor);
if (ot != null)
g2d.setTransform(ot);
}
-
+
private boolean isSelected() {
return NodeUtil.isSelected(this, 1);
}
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;
protected double modifyHorizontalValue(double value) {
// TODO: fix scale!
double scale = 100000;
+// double scale = 1;
return ModelledCRS.xToLongitude(value / scale);
}
protected double modifyVerticalValue(double value) {
// TODO: fix scale!
double scale = 100000;
+// double scale = 1;
return ModelledCRS.yToLatitude(value / scale);
}
*/
// TODO: fix scale
double scale = 100000;
+// double scale = 1;
double startLat = ModelledCRS.yToLatitude(start.getY() / scale);
double startLon = ModelledCRS.xToLongitude(start.getX() / scale);
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);
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
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;
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);
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;
}
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);
double finald = Math.toDegrees(atan);
return finald;
}
-
+
public static double longitudeToX(double lon) {
return lon;
}
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;
new Thread(() -> {
try {
TileserverMapnikInstance.get().start();
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (Throwable t) {
+ LOGGER.error("Could not start integrated tile server", t);
}
}).start();
}
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;
}
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);
}
}