package net.refractions.linecleaner.ui;
import net.refractions.linecleaner.cleansing.CyclesProcessor;
import net.refractions.linecleaner.cleansing.DouglasPeuckerProcessor;
import net.refractions.linecleaner.cleansing.EndNodesProcessor;
import net.refractions.linecleaner.cleansing.MinimumLengthProcessor;
import net.refractions.linecleaner.cleansing.SimilarLinesProcessor;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class OptionsPage extends WizardPage {
private static final String NAME = "Options";
private static final String TITLE = "Configure options for the operations.";
private static final ImageDescriptor IMAGE = null;
private Text samplingDistance;
private Text verySimilarTolerance;
private Text similarTolerance;
private Text minimumLength;
private Text distanceTolerance;
private Text areaTolerance;
private Text dpTolerance;
private Text cyclesLength;
private String samplingDistanceDefault;
private String verySimilarToleranceDefault;
private String similarToleranceDefault;
private String minimumLengthDefault;
private String distanceToleranceDefault;
private String areaToleranceDefault;
private String dpToleranceDefault;
private String cyclesLengthDefault;
private IDialogSettings savedSettings;
protected OptionsPage(IDialogSettings savedSettings) {
super(NAME, TITLE, IMAGE);
this.savedSettings = savedSettings;
loadSettings();
}
public void saveSettings() {
savedSettings.put("areaTolerance", getAreaTolerance());
savedSettings.put("cyclesLength", getCyclesLength());
savedSettings.put("distanceTolerance", getDistanceTolerance());
savedSettings.put("dpTolerance", getDPTolerance());
savedSettings.put("minLength", getMinimumLength());
savedSettings.put("samplingDistance", getSamplingDistance());
savedSettings.put("similarTolerance", getSimilarTolerance());
savedSettings.put("verySimilarTolerance", getVerySimilarTolerance());
}
public void loadSettings() {
areaToleranceDefault = savedSettings.get("areaTolerance");
cyclesLengthDefault = savedSettings.get("cyclesLength");
distanceToleranceDefault = savedSettings.get("distanceTolerance");
dpToleranceDefault = savedSettings.get("dpTolerance");
minimumLengthDefault = savedSettings.get("minLength");
samplingDistanceDefault = savedSettings.get("samplingDistance");
similarToleranceDefault = savedSettings.get("similarTolerance");
verySimilarToleranceDefault = savedSettings.get("verySimilarTolerance");
if (areaToleranceDefault == null)
areaToleranceDefault = Double.toString(EndNodesProcessor.DEFAULT_AREA_TOLERANCE);
if (cyclesLengthDefault == null)
cyclesLengthDefault = Double.toString(CyclesProcessor.DEFAULT_LENGTH_TOLERANCE);
if (distanceToleranceDefault == null)
distanceToleranceDefault = Double.toString(EndNodesProcessor.DEFAULT_DISTANCE_TOLERANCE);
if (dpToleranceDefault == null)
dpToleranceDefault = Double.toString(DouglasPeuckerProcessor.DEFAULT_DISTANCE_TOLERANCE);
if (minimumLengthDefault == null)
minimumLengthDefault = Double.toString(MinimumLengthProcessor.DEFAULT_MINIMUM_LENGTH);
if (samplingDistanceDefault == null)
samplingDistanceDefault = Double.toString(SimilarLinesProcessor.DEFAULT_SAMPLING_DISTANCE);
if (similarToleranceDefault == null)
similarToleranceDefault = Double.toString(SimilarLinesProcessor.DEFAULT_SIMILAR_TOLERANCE);
if (verySimilarToleranceDefault == null)
verySimilarToleranceDefault = Double.toString(SimilarLinesProcessor.DEFAULT_VERY_SIMILAR_TOLERANCE);
}
public void createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NULL);
GridLayout mainGridLayout = new GridLayout();
mainGridLayout.numColumns = 2;
mainGridLayout.makeColumnsEqualWidth = true;
composite.setLayout(mainGridLayout);
GridLayout columnGridLayout = new GridLayout();
columnGridLayout.numColumns = 1;
Composite left = new Composite(composite, SWT.NULL);
left.setLayoutData(getDefaultGridData());
left.setLayout(columnGridLayout);
Composite right = new Composite(composite, SWT.NULL);
right.setLayoutData(getDefaultGridData());
right.setLayout(columnGridLayout);
Group minimumLength = createMinimumLengthGroup(left);
Group cycles = createCyclesGroup(left);
Group endNodes = createEndNodesGroup(left);
Group douglasP = createDouglasPeuckerGroup(right);
Group cleaning = createCleaningGroup(right);
cycles.setLayoutData(getDefaultGridData());
douglasP.setLayoutData(getDefaultGridData());
endNodes.setLayoutData(getDefaultGridData());
minimumLength.setLayoutData(getDefaultGridData());
cleaning.setLayoutData(getDefaultGridData());
setControl(composite);
}
private GridData getDefaultGridData() {
GridData gridData = new GridData();
gridData.horizontalAlignment = SWT.FILL;
gridData.verticalAlignment = SWT.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
return gridData;
}
private GridData getLabelGridData() {
GridData labelData = new GridData();
labelData.horizontalAlignment = SWT.FILL;
labelData.verticalAlignment = SWT.BEGINNING;
labelData.grabExcessHorizontalSpace = true;
labelData.grabExcessVerticalSpace = true;
return labelData;
}
private GridData getTextGridData() {
GridData textData = new GridData();
textData.horizontalAlignment = SWT.FILL;
textData.verticalAlignment = SWT.BEGINNING;
textData.grabExcessHorizontalSpace = true;
textData.grabExcessVerticalSpace = false;
return textData;
}
private Group createCleaningGroup(Composite parent) {
Group group = new Group(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(2, false);
GridData labelData = getLabelGridData();
GridData textData = getTextGridData();
group.setLayout(gridLayout);
group.setText("Light Conflation");
Label label = new Label(group, SWT.NONE);
label.setLayoutData(labelData);
label.setText("Sampling distance: ");
label.setToolTipText("The default is " + SimilarLinesProcessor.DEFAULT_SAMPLING_DISTANCE);
samplingDistance = new Text(group, SWT.BORDER);
samplingDistance.setLayoutData(textData);
samplingDistance.setText(samplingDistanceDefault);
samplingDistance.addKeyListener(updateButtonsKeyListener);
label = new Label(group, SWT.NONE);
label.setText("Very similar tolerance: ");
label.setLayoutData(labelData);
label.setToolTipText("The default is " + SimilarLinesProcessor.DEFAULT_VERY_SIMILAR_TOLERANCE);
verySimilarTolerance = new Text(group, SWT.BORDER);
verySimilarTolerance.setLayoutData(textData);
verySimilarTolerance.setText(verySimilarToleranceDefault);
verySimilarTolerance.addKeyListener(updateButtonsKeyListener);
label = new Label(group, SWT.NONE);
label.setText("Similar tolerance: ");
label.setLayoutData(labelData);
label.setToolTipText("The default is " + SimilarLinesProcessor.DEFAULT_SIMILAR_TOLERANCE);
similarTolerance = new Text(group, SWT.BORDER);
similarTolerance.setLayoutData(textData);
similarTolerance.setText(similarToleranceDefault);
similarTolerance.addKeyListener(updateButtonsKeyListener);
return group;
}
private Group createMinimumLengthGroup(Composite parent) {
Group group = new Group(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(2, false);
group.setLayout(gridLayout);
group.setText("Minimum Length");
Label label = new Label(group, SWT.NONE);
label.setLayoutData(getLabelGridData());
label.setText("Minimum length: ");
label.setToolTipText("For every line geometry in the dataset, its length is calculated. If it is equal to or less" +
" than the minimum length, it is deleted. The default value is " + MinimumLengthProcessor.DEFAULT_MINIMUM_LENGTH);
minimumLength = new Text(group, SWT.BORDER);
minimumLength.setLayoutData(getTextGridData());
minimumLength.setText(minimumLengthDefault);
minimumLength.addKeyListener(updateButtonsKeyListener);
return group;
}
private Group createEndNodesGroup(Composite parent) {
Group group = new Group(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(2, false);
group.setLayout(gridLayout);
group.setText("End Nodes");
Label label = new Label(group, SWT.NONE);
label.setText("Distance tolerance: ");
label.setLayoutData(getLabelGridData());
label.setToolTipText("If the distance between the any of the end-points of any two geometries " +
"is less than the distance tolerance, the two end-points will be snapped (moved) to the " +
"same point. The default value is " + EndNodesProcessor.DEFAULT_DISTANCE_TOLERANCE);
distanceTolerance = new Text(group, SWT.BORDER);
distanceTolerance.setLayoutData(getTextGridData());
distanceTolerance.setText(distanceToleranceDefault);
distanceTolerance.addKeyListener(updateButtonsKeyListener);
label = new Label(group, SWT.NONE);
label.setText("Area tolerance: ");
label.setLayoutData(getLabelGridData());
label.setToolTipText("Before a group of nodes are to be snapped together, their total area is taken" +
" into consideration. If this value is equal to or greater than area tolerance, the nodes are" +
" flagged, a warning is logged, and nothing further is done. The default value is " + EndNodesProcessor.DEFAULT_AREA_TOLERANCE);
areaTolerance = new Text(group, SWT.BORDER);
areaTolerance.setLayoutData(getTextGridData());
areaTolerance.setText(areaToleranceDefault);
areaTolerance.addKeyListener(updateButtonsKeyListener);
return group;
}
private Group createDouglasPeuckerGroup(Composite parent) {
Group group = new Group(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(2, false);
group.setLayout(gridLayout);
group.setText("Douglas-Peucker");
Label label = new Label(group, SWT.NONE);
label.setLayoutData(getLabelGridData());
label.setText("Distance tolerance: ");
label.setToolTipText("For Douglas-Peucker, a line is generated between the start and end-points" +
" of a line, and vertices that are farther away than the distance tolerance are removed. " +
"The default value is " + DouglasPeuckerProcessor.DEFAULT_DISTANCE_TOLERANCE);
dpTolerance = new Text(group, SWT.BORDER);
dpTolerance.setLayoutData(getTextGridData());
dpTolerance.setText(dpToleranceDefault);
dpTolerance.addKeyListener(updateButtonsKeyListener);
return group;
}
private Group createCyclesGroup(Composite parent) {
Group group = new Group(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(2, false);
group.setLayout(gridLayout);
group.setText("Cycles");
Label label = new Label(group, SWT.NONE);
label.setLayoutData(getLabelGridData());
label.setText("Total length tolerance: " );
label.setToolTipText("For the cycles processor, if a feature is a cycle, it will be deleted, unless" +
" it has a total length equal to or greater than the total length tolerance. " +
"If the total length tolerance is <= 0, then it is disabled. The default value is " +
CyclesProcessor.DEFAULT_LENGTH_TOLERANCE);
cyclesLength = new Text(group, SWT.BORDER);
cyclesLength.setLayoutData(getTextGridData());
cyclesLength.setText(cyclesLengthDefault);
cyclesLength.addKeyListener(updateButtonsKeyListener);
return group;
}
private void updateButtons() {
getWizard().getContainer().updateButtons();
}
@Override
public boolean isPageComplete() {
setErrorMessage(null);
return true;
}
private Double getValue(Text text) {
try {
Double result = Double.parseDouble(text.getText());
return result;
} catch (NumberFormatException e) {
text.setFocus();
text.selectAll();
setErrorMessage("Values must be numerical.");
updateButtons();
return null;
}
}
public double getAreaTolerance() {
Double value = getValue(areaTolerance);
return value;
}
public double getCyclesLength() {
return getValue(cyclesLength);
}
public double getDistanceTolerance() {
return getValue(distanceTolerance);
}
public double getDPTolerance() {
return getValue(dpTolerance);
}
public double getMinimumLength() {
return getValue(minimumLength);
}
public double getSamplingDistance() {
return getValue(samplingDistance);
}
public double getSimilarTolerance() {
return getValue(similarTolerance);
}
public double getVerySimilarTolerance() {
return getValue(verySimilarTolerance);
}
private UpdateKeyListener updateButtonsKeyListener = new UpdateKeyListener();
private class UpdateKeyListener implements KeyListener {
public void keyPressed(KeyEvent e) {
updateButtons();
}
public void keyReleased(KeyEvent e) {
updateButtons();
}
}
}