eu.esdihumboldt.hale.ui.io.instance.crs.SelectCRSDialog.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.io.instance.crs.SelectCRSDialog.java

Source

/*
 * Copyright (c) 2012 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     HUMBOLDT EU Integrated Project #030962
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */
package eu.esdihumboldt.hale.ui.io.instance.crs;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.geotools.referencing.CRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import eu.esdihumboldt.hale.common.instance.geometry.impl.CodeDefinition;
import eu.esdihumboldt.hale.common.instance.geometry.impl.WKTDefinition;
import eu.esdihumboldt.hale.common.schema.geometry.CRSDefinition;
import eu.esdihumboldt.hale.ui.internal.Messages;

/**
 * Dialog for selecting the CRS to use
 * 
 * @author Simon Templer
 * @partner 01 / Fraunhofer Institute for Computer Graphics Research
 */
public class SelectCRSDialog extends TitleAreaDialog implements IPropertyChangeListener {

    //   private static ALogger _log = ALoggerFactory.getLogger(SelectCRSDialog.class);

    /**
     * Text field for editing WKT
     */
    private class WKText {

        private CoordinateReferenceSystem crs;

        private String errorMessage;

        private final Text text;

        /**
         * Constructor
         * 
         * @param parent the parent composite
         */
        public WKText(Composite parent) {
            text = new Text(parent, SWT.MULTI | SWT.BORDER);

            text.addKeyListener(new KeyAdapter() {

                @Override
                public void keyReleased(KeyEvent e) {
                    valueChanged();
                }

            });
        }

        /**
         * Set the text
         * 
         * @param text the text
         */
        public void setText(String text) {
            this.text.setText(text);

            valueChanged();
        }

        /**
         * Get the text
         * 
         * @return the text
         */
        public String getText() {
            return text.getText();
        }

        private void valueChanged() {
            try {
                crs = CRS.parseWKT(getText());
                errorMessage = "Invalid WKT"; //$NON-NLS-1$
            } catch (Exception e) {
                errorMessage = e.getLocalizedMessage();
                crs = null;
            }

            updateMessage();
        }

        /**
         * Get the coordinate reference system
         * 
         * @return the coordinate reference system
         */
        public WKTDefinition getCRSDefinition() {
            return new WKTDefinition(getText(), crs);
        }

        /**
         * Returns if the field's value is valid
         * 
         * @return if the value is valid
         */
        public boolean isValid() {
            return crs != null;
        }

        /**
         * @return the errorMessage
         */
        public String getErrorMessage() {
            return errorMessage;
        }

        /**
         * @return the text field
         */
        public Text getTextField() {
            return text;
        }

    }

    /**
     * Field editor for a CRS code
     */
    private static class CRSFieldEditor extends StringFieldEditor {

        private CoordinateReferenceSystem crs;

        /**
         * @see StringFieldEditor#doCheckState()
         */
        @Override
        protected boolean doCheckState() {
            try {
                crs = CRS.decode(getStringValue());
                boolean valid = crs != null;
                setErrorMessage("Invalid CRS code"); //$NON-NLS-1$
                return valid;
            } catch (Exception e) {
                setErrorMessage(e.getMessage());
                return false;
            }
        }

        /**
         * Get the coordinate reference system
         * 
         * @return the coordinate reference system
         */
        public CodeDefinition getCRSDefinition() {
            return new CodeDefinition(getStringValue(), crs);
        }

    }

    private static final String DEFAULT_CODE = "EPSG:4326"; //$NON-NLS-1$

    private static final String DEFAULT_WKT = "PROJCS[\"MGI (Ferro)/AustriaGKWestZone\",\n" + //$NON-NLS-1$
            "\tGEOGCS[\"MGI (Ferro)\",\n" + //$NON-NLS-1$
            "\t\tDATUM[\"Militar-Geographische Institut (Ferro)\",\n" + //$NON-NLS-1$
            "\t\t\tSPHEROID[\"Bessel 1841\",6377397.155,299.1528128,\n" + //$NON-NLS-1$
            "\t\t\tAUTHORITY[\"EPSG\",\"7004\"]],AUTHORITY[\"EPSG\",\"6805\"]],\n" + //$NON-NLS-1$
            "\t\tPRIMEM[\"Ferro\",-17.666666666666668,AUTHORITY[\"EPSG\",\"8909\"]],\n" + //$NON-NLS-1$
            "\t\tUNIT[\"degree\",0.017453292519943295],\n" + //$NON-NLS-1$
            "\t\tAXIS[\"Geodetic latitude\",NORTH],\n" + //$NON-NLS-1$
            "\t\tAXIS[\"Geodetic longitude\",EAST],\n" + //$NON-NLS-1$
            "\t\tAUTHORITY[\"EPSG\",\"4805\"]],\n" + //$NON-NLS-1$
            "\tPROJECTION[\"Transverse Mercator\"],\n" + //$NON-NLS-1$
            "PARAMETER[\"central_meridian\",28.0],\n" + //$NON-NLS-1$
            "PARAMETER[\"latitude_of_origin\",0.0],\n" + //$NON-NLS-1$
            "PARAMETER[\"scale_factor\",1.0],\n" + //$NON-NLS-1$
            "PARAMETER[\"false_easting\",0.0],\n" + //$NON-NLS-1$
            "PARAMETER[\"false_northing\",-5000000.0],\n" + //$NON-NLS-1$
            "UNIT[\"m\",1.0],\n" + //$NON-NLS-1$
            "AXIS[\"Y\",EAST],\n" + //$NON-NLS-1$
            "AXIS[\"X\",NORTH],\n" + //$NON-NLS-1$
            "AUTHORITY[\"EPSG\",\"31251\"]]"; //$NON-NLS-1$

    private static String lastCode = DEFAULT_CODE;
    private static String lastWKT = DEFAULT_WKT;

    private CRSFieldEditor crsField;

    private WKText wktField;

    private static final String DEF_MESSAGE = ""; //$NON-NLS-1$

    private Button radioCRS;

    private Button radioWKT;

    private Group group;

    private CRSDefinition value;

    /**
     * Constructor
     * 
     * @param parentShell the parent shell
     * @param initalValue the initial value
     */
    public SelectCRSDialog(Shell parentShell, CRSDefinition initalValue) {
        super(parentShell);

        value = initalValue;
    }

    /**
     * @see TitleAreaDialog#createContents(Composite)
     */
    @Override
    protected Control createContents(Composite parent) {
        Control control = super.createContents(parent);

        setTitle(Messages.SelectCRSDialog_ContentTitle);
        setMessage(DEF_MESSAGE);

        updateState();
        updateMessage();

        return control;
    }

    /**
     * @see Window#configureShell(Shell)
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);

        newShell.setText(Messages.SelectCRSDialog_ShellTitle);
    }

    /**
     * @see TitleAreaDialog#createDialogArea(Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite page = new Composite(parent, SWT.NONE);
        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        page.setLayoutData(data);

        page.setLayout(new GridLayout(1, false));

        group = new Group(page, SWT.NONE);
        group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        group.setLayout(new GridLayout(3, false));
        group.setText(Messages.SelectCRSDialog_GroupText);

        SelectionListener radioListener = new SelectionListener() {

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                // ignore
            }

            @Override
            public void widgetSelected(SelectionEvent e) {
                updateSelection();
            }

        };

        boolean lastWasCode = value == null || value instanceof CodeDefinition;

        // CRS string
        radioCRS = new Button(group, SWT.RADIO);
        radioCRS.setSelection(lastWasCode);
        radioCRS.setText(Messages.SelectCRSDialog_RadioCRSText);
        radioCRS.addSelectionListener(radioListener);

        crsField = new CRSFieldEditor();
        crsField.fillIntoGrid(group, 2);
        crsField.setEmptyStringAllowed(false);
        String code;
        if (value instanceof CodeDefinition) {
            code = ((CodeDefinition) value).getCode();
        } else {
            code = lastCode;
        }
        crsField.setStringValue(code);
        crsField.setPropertyChangeListener(this);
        crsField.setEnabled(lastWasCode, group);

        // WKT string
        radioWKT = new Button(group, SWT.RADIO);
        radioWKT.setSelection(!lastWasCode);
        radioWKT.setText(Messages.SelectCRSDialog_RadioWKTText);
        radioWKT.addSelectionListener(radioListener);

        wktField = new WKText(group);
        wktField.getTextField().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        String wkt;
        if (value instanceof WKTDefinition) {
            wkt = ((WKTDefinition) value).getWkt();
        } else {
            wkt = lastWKT;
        }
        wktField.setText(wkt);
        wktField.getTextField().setEnabled(!lastWasCode);

        return page;
    }

    /**
     * Update the widgets to the radio selection
     */
    protected void updateSelection() {
        boolean enableCode = radioCRS.getSelection();

        crsField.setEnabled(enableCode, group);
        wktField.getTextField().setEnabled(!enableCode);

        updateMessage();
        updateState();
    }

    /**
     * @see Dialog#okPressed()
     */
    @Override
    protected void okPressed() {
        CRSDefinition crs;
        if (radioCRS.getSelection()) {
            crs = crsField.getCRSDefinition();
            lastCode = crsField.getCRSDefinition().getCode();
        } else {
            crs = wktField.getCRSDefinition();
            lastWKT = wktField.getCRSDefinition().getWkt();
        }

        value = crs;

        super.okPressed();
    }

    /**
     * @see Dialog#cancelPressed()
     */
    @Override
    protected void cancelPressed() {
        value = null;

        super.cancelPressed();
    }

    /**
     * Get the selected value
     * 
     * @return the selected CRS definition
     */
    public CRSDefinition getValue() {
        return value;
    }

    /**
     * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
     */
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        if (event.getProperty().equals(FieldEditor.VALUE)) {
            CRSFieldEditor editor = (CRSFieldEditor) event.getSource();
            updateMessage(editor);
        } else if (event.getProperty().equals(FieldEditor.IS_VALID)) {
            updateState();
        }
    }

    /**
     * Update the dialog message
     */
    private void updateMessage() {
        if (radioCRS.getSelection()) {
            updateMessage(crsField);
        } else {
            if (wktField.isValid()) {
                setErrorMessage(null);
                setMessage(wktField.getCRSDefinition().getCRS().getName().toString(), IMessageProvider.INFORMATION);
            } else {
                setErrorMessage(wktField.getErrorMessage());
                setMessage(DEF_MESSAGE);
            }
        }
    }

    /**
     * Update the dialog message
     * 
     * @param editor the active editor
     */
    private void updateMessage(CRSFieldEditor editor) {
        if (editor.isValid()) {
            setErrorMessage(null);
            setMessage(editor.getCRSDefinition().getCRS().getName().toString(), IMessageProvider.INFORMATION);
        } else {
            setErrorMessage(editor.getErrorMessage());
            setMessage(DEF_MESSAGE);
        }
    }

    /**
     * Update the button state
     */
    private void updateState() {
        getButton(OK).setEnabled(
                (radioCRS.getSelection() && crsField.isValid()) || (radioWKT.getSelection() && wktField.isValid()));
    }

}