From 74f4811f07accc435297d7fb444a757f5d92cbce Mon Sep 17 00:00:00 2001 From: Bryan Kowal Date: Mon, 7 Jan 2013 18:14:07 -0600 Subject: [PATCH] Issue #1460 - Merge 4.7-GIS_Viewer into AWIPS2_baseline Former-commit-id: 76fe910606939dd7c23f3807bedc7592d4ff97d3 [formerly 76fe910606939dd7c23f3807bedc7592d4ff97d3 [formerly 9e0eae1725af06ce834c926a4d70195a075e8152]] Former-commit-id: 03f108f80bf37e127d60255cac506ee6bb350c0b Former-commit-id: bbeb6b510195e93aff84c67dd1e9973dc8e38249 --- cave/build/p2-build.xml | 58 +- .../.classpath | 7 + .../.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../META-INF/MANIFEST.MF | 21 + ...f.common.serialization.ISerializableObject | 1 + .../build.properties | 5 + .../plugin.xml | 12 + .../viz/gisdatastore/directory/Activator.java | 122 ++ .../directory/DirectoryDataStorePlugin.java | 181 +++ .../rsc/DirectoryDataStoreResourceData.java | 79 + .../.project | 17 + .../build.properties | 1 + .../feature.xml | 41 + .../.classpath | 7 + .../com.raytheon.uf.viz.gisdatastore/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../META-INF/MANIFEST.MF | 24 + .../build.properties | 5 + .../config.xml | 7 + .../plugin.xml | 74 + .../schema/gisDataStore.exsd | 109 ++ .../uf/viz/gisdatastore/Activator.java | 123 ++ .../viz/gisdatastore/IGisDataStorePlugin.java | 25 + .../viz/gisdatastore/actions/CropAction.java | 81 + .../actions/DisplayAttributes.java | 65 + .../gisdatastore/actions/ImportGisAction.java | 78 + .../gisdatastore/actions/RenameAction.java | 68 + .../actions/SetSampleAttributeAction.java | 78 + .../gisdatastore/rsc/DataStoreResource.java | 1413 +++++++++++++++++ .../rsc/DataStoreResourceData.java | 193 +++ .../uf/viz/gisdatastore/rsc/ReloadJob.java | 473 ++++++ .../gisdatastore/ui/AbstractFieldEditor.java | 157 ++ .../viz/gisdatastore/ui/AttributeViewer.java | 642 ++++++++ .../viz/gisdatastore/ui/ColorFieldEditor.java | 124 ++ .../gisdatastore/ui/ColumnSelectDialog.java | 94 ++ .../ui/GisDataStoreParametersDialog.java | 455 ++++++ .../ui/GisViewerPreferencePage.java | 90 ++ .../viz/gisdatastore/ui/LineStyleDialog.java | 130 ++ .../gisdatastore/ui/LineStyleFieldEditor.java | 133 ++ .../viz/gisdatastore/ui/LineWidthDialog.java | 130 ++ .../gisdatastore/ui/LineWidthFieldEditor.java | 141 ++ .../gisdatastore/ui/OpacityFieldEditor.java | 159 ++ .../gisdatastore/ui/PreferenceConverter.java | 201 +++ .../ui/SelectAttributeDialog.java | 112 ++ .../viz/gisdatastore/ui/SortOrderDialog.java | 234 +++ .../viz/gisdatastore/ui/StringConverter.java | 163 ++ 47 files changed, 6375 insertions(+), 30 deletions(-) create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/.classpath create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/.project create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/.settings/org.eclipse.jdt.core.prefs create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/MANIFEST.MF create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/build.properties create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/plugin.xml create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/Activator.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/DirectoryDataStorePlugin.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/rsc/DirectoryDataStoreResourceData.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.feature/.project create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.feature/build.properties create mode 100644 cave/com.raytheon.uf.viz.gisdatastore.feature/feature.xml create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/.classpath create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/.project create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/.settings/org.eclipse.jdt.core.prefs create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/META-INF/MANIFEST.MF create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/build.properties create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/config.xml create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/plugin.xml create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/schema/gisDataStore.exsd create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/Activator.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/IGisDataStorePlugin.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/CropAction.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/DisplayAttributes.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/ImportGisAction.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/RenameAction.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/SetSampleAttributeAction.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResourceData.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AbstractFieldEditor.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AttributeViewer.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColorFieldEditor.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColumnSelectDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisDataStoreParametersDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisViewerPreferencePage.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleFieldEditor.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthFieldEditor.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/OpacityFieldEditor.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/PreferenceConverter.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SelectAttributeDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SortOrderDialog.java create mode 100644 cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/StringConverter.java diff --git a/cave/build/p2-build.xml b/cave/build/p2-build.xml index 2fd38eadd4..a28b6ba957 100644 --- a/cave/build/p2-build.xml +++ b/cave/build/p2-build.xml @@ -272,40 +272,38 @@ - - - + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/.classpath b/cave/com.raytheon.uf.viz.gisdatastore.directory/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/.project b/cave/com.raytheon.uf.viz.gisdatastore.directory/.project new file mode 100644 index 0000000000..671b450250 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.gisdatastore.directory + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.gisdatastore.directory/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..c3745d3f80 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Nov 05 11:53:02 CST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..8779a54ea5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Shapefile support for DataStoreResource +Bundle-SymbolicName: com.raytheon.uf.viz.gisdatastore.directory;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.gisdatastore.directory.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.viz.core, com.raytheon.viz.ui +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.geotools, + com.raytheon.uf.common.status, + com.raytheon.uf.viz.gisdatastore, + com.raytheon.uf.viz.core, + com.raytheon.viz.core, + com.raytheon.viz.ui, + com.raytheon.uf.common.util, + com.raytheon.uf.viz.core.maps;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.gisdatastore.directory.rsc diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject new file mode 100644 index 0000000000..8eb2ecad04 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -0,0 +1 @@ +com.raytheon.uf.viz.gisdatastore.directory.rsc.DirectoryDataStoreResourceData diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/build.properties b/cave/com.raytheon.uf.viz.gisdatastore.directory/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/plugin.xml b/cave/com.raytheon.uf.viz.gisdatastore.directory/plugin.xml new file mode 100644 index 0000000000..42718c1f8e --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/Activator.java b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/Activator.java new file mode 100644 index 0000000000..5deb1993a0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/Activator.java @@ -0,0 +1,122 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.directory; + +import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore; + +/** + * The activator class controls the plug-in life cycle + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 12, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ +public class Activator extends AbstractUIPlugin { + public static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + // pref store + private HierarchicalPreferenceStore prefs; + + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.gisdatastore.directory"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore() + */ + @Override + public IPersistentPreferenceStore getPreferenceStore() { + try { + if (prefs == null) { + prefs = new HierarchicalPreferenceStore(this); + } + } catch (LocalizationException e) { + statusHandler.handle( + Priority.PROBLEM, + "Error reading preference store: " + + e.getLocalizedMessage(), e); + } + + return prefs; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/DirectoryDataStorePlugin.java b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/DirectoryDataStorePlugin.java new file mode 100644 index 0000000000..b96f4a1fe6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/DirectoryDataStorePlugin.java @@ -0,0 +1,181 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.directory; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Label; +import org.geotools.data.DataStore; +import org.geotools.data.directory.DirectoryDataStoreFactory; + +import com.raytheon.uf.viz.gisdatastore.IGisDataStorePlugin; +import com.raytheon.uf.viz.gisdatastore.directory.rsc.DirectoryDataStoreResourceData; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResourceData; + +/** + * Directory GisDataStorePlugin implementation + * + * Will load data from any recognized GIS feature file types in a directory + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 6, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class DirectoryDataStorePlugin implements IGisDataStorePlugin { + private static int DIR_LIST_SIZE = 10; + + private Map connectionParameters; + + private Combo dirCombo; + + private Button browseButton; + + private List dirList; + + @Override + public void createControls(final Composite comp) { + GridLayout layout = (GridLayout) comp.getLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + + Label label = new Label(comp, SWT.NONE); + label.setText("Directory:"); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + label.setLayoutData(layoutData); + + browseButton = new Button(comp, SWT.PUSH); + layoutData = new GridData(SWT.END, SWT.CENTER, false, false); + browseButton.setLayoutData(layoutData); + browseButton.setText("Browse..."); + browseButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + DirectoryDialog dlg = new DirectoryDialog(comp.getShell()); + dlg.setFilterPath(dirCombo.getText()); + String dir = dlg.open(); + if (dir != null) { + dirCombo.setText(dir); + } + } + }); + + dirCombo = new Combo(comp, SWT.DROP_DOWN); + layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + layoutData.widthHint = 300; + layoutData.horizontalSpan = 2; + dirCombo.setLayoutData(layoutData); + } + + @Override + public Map getConnectionParameters() { + return this.connectionParameters; + } + + @Override + public void loadFromPreferences() { + dirList = new ArrayList(DIR_LIST_SIZE); + IPreferenceStore prefs = Activator.getDefault().getPreferenceStore(); + for (int i = 0; i < DIR_LIST_SIZE; i++) { + String url = prefs.getString("DirectoryImportPath" + i); + dirList.add(url); + } + dirCombo.setItems(dirList.toArray(new String[dirList.size()])); + dirCombo.setText(dirList.get(0)); + } + + @Override + public void saveToPreferences() { + IPersistentPreferenceStore prefs = Activator.getDefault() + .getPreferenceStore(); + String dir = dirCombo.getText(); + if (dirList.contains(dir)) { + // dir already in list remove it + dirList.remove(dir); + } else if (dirList.size() == DIR_LIST_SIZE) { + // list at max size remove last entry + dirList.remove(DIR_LIST_SIZE - 1); + } + // put dir at front of list + dirList.add(0, dir); + + int i = 0; + for (String s : dirList) { + prefs.setValue("DirectoryImportPath" + i++, s); + } + + try { + prefs.save(); + } catch (IOException e) { + Activator.statusHandler.error( + "Unable to save recently used directories", e); + } + } + + @Override + public DataStore connectToDataStore() throws IOException { + String dir = dirCombo.getText(); + URL url = new File(dir).toURI().toURL(); + + Map params = new HashMap(); + params.put(DirectoryDataStoreFactory.URLP.key, url); + + DataStoreResourceData rd = constructResourceData(null, params); + DataStore dataStore = rd.getDataStore(); + + this.connectionParameters = params; + + return dataStore; + } + + @Override + public DataStoreResourceData constructResourceData(String typeName, + Map connectionParameters) { + DirectoryDataStoreResourceData rd = new DirectoryDataStoreResourceData( + typeName, connectionParameters); + return rd; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/rsc/DirectoryDataStoreResourceData.java b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/rsc/DirectoryDataStoreResourceData.java new file mode 100644 index 0000000000..8d70b2a3b4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.directory/src/com/raytheon/uf/viz/gisdatastore/directory/rsc/DirectoryDataStoreResourceData.java @@ -0,0 +1,79 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.directory.rsc; + +import java.io.IOException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import org.geotools.data.DataStore; +import org.geotools.data.directory.DirectoryDataStoreFactory; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResourceData; + +/** + * DataStore resource data class for GIS feature files + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 31, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +public class DirectoryDataStoreResourceData extends DataStoreResourceData { + public DirectoryDataStoreResourceData() { + } + + public DirectoryDataStoreResourceData(String typeName, + Map connectionParameters) { + super(typeName, connectionParameters); + } + + @Override + protected DataStore constructDataStore() throws IOException { + DirectoryDataStoreFactory factory = new DirectoryDataStoreFactory(); + Map params = new HashMap(); + for (Entry entry : getConnectionParameters().entrySet()) { + if (entry.getValue() instanceof Serializable) { + params.put(entry.getKey(), (Serializable) entry.getValue()); + } else { + throw new IllegalArgumentException(entry.getKey() + "(" + + entry.getValue().getClass().getName() + + ") not an instance of java.io.Serializable"); + } + } + DataStore dataStore = factory.createDataStore(params); + return dataStore; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore.feature/.project b/cave/com.raytheon.uf.viz.gisdatastore.feature/.project new file mode 100644 index 0000000000..7c06a73d13 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.feature/.project @@ -0,0 +1,17 @@ + + + com.raytheon.uf.viz.gisdatastore.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore.feature/build.properties b/cave/com.raytheon.uf.viz.gisdatastore.feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/cave/com.raytheon.uf.viz.gisdatastore.feature/feature.xml b/cave/com.raytheon.uf.viz.gisdatastore.feature/feature.xml new file mode 100644 index 0000000000..12b476b470 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore.feature/feature.xml @@ -0,0 +1,41 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/.classpath b/cave/com.raytheon.uf.viz.gisdatastore/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/.project b/cave/com.raytheon.uf.viz.gisdatastore/.project new file mode 100644 index 0000000000..b5a51b3538 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.gisdatastore + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.gisdatastore/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..8ba0d6aa4f --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Nov 05 10:48:54 CST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/cave/com.raytheon.uf.viz.gisdatastore/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.gisdatastore/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..d72119e4d7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/META-INF/MANIFEST.MF @@ -0,0 +1,24 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Gisdatastore +Bundle-SymbolicName: com.raytheon.uf.viz.gisdatastore;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.gisdatastore.Activator +Eclipse-RegisterBuddy: com.raytheon.viz.core, com.raytheon.viz.ui +Bundle-Vendor: RAYTHEON +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.geotools, + com.raytheon.uf.common.serialization, + com.raytheon.uf.common.status, + com.raytheon.uf.common.geospatial, + com.raytheon.uf.viz.core, + com.raytheon.uf.viz.core.maps;bundle-version="1.0.0", + com.raytheon.viz.core, + com.raytheon.viz.ui +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.gisdatastore, + com.raytheon.uf.viz.gisdatastore.rsc, + com.raytheon.uf.viz.gisdatastore.ui +Import-Package: com.raytheon.uf.common.dataplugin.gfe.type diff --git a/cave/com.raytheon.uf.viz.gisdatastore/build.properties b/cave/com.raytheon.uf.viz.gisdatastore/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.gisdatastore/config.xml b/cave/com.raytheon.uf.viz.gisdatastore/config.xml new file mode 100644 index 0000000000..12416abf0c --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/config.xml @@ -0,0 +1,7 @@ + + +hot pink +SOLID +2 +0.35 + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/plugin.xml b/cave/com.raytheon.uf.viz.gisdatastore/plugin.xml new file mode 100644 index 0000000000..09cc3561f6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/plugin.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/schema/gisDataStore.exsd b/cave/com.raytheon.uf.viz.gisdatastore/schema/gisDataStore.exsd new file mode 100644 index 0000000000..5196761c64 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/schema/gisDataStore.exsd @@ -0,0 +1,109 @@ + + + + + + + + + This extension point is used to identify classes that define new GIS DataStore implementations so that they can be found and registered at startup. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 13.2.1 + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/Activator.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/Activator.java new file mode 100644 index 0000000000..def8d10277 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/Activator.java @@ -0,0 +1,123 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore; + +import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore; + +/** + * The activator class controls the plug-in life cycle + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 12, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ +public class Activator extends AbstractUIPlugin { + public static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + // pref store + private HierarchicalPreferenceStore prefs; + + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.gisdatastore"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore() + */ + @Override + public IPersistentPreferenceStore getPreferenceStore() { + try { + if (prefs == null) { + prefs = new HierarchicalPreferenceStore(this); + } + } catch (LocalizationException e) { + statusHandler.handle( + Priority.PROBLEM, + "Error reading preference store: " + + e.getLocalizedMessage(), e); + } + + return prefs; + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/IGisDataStorePlugin.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/IGisDataStorePlugin.java new file mode 100644 index 0000000000..1b7025aced --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/IGisDataStorePlugin.java @@ -0,0 +1,25 @@ +package com.raytheon.uf.viz.gisdatastore; + +import java.io.IOException; +import java.util.Map; + +import org.eclipse.swt.widgets.Composite; +import org.geotools.data.DataStore; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResourceData; + +public interface IGisDataStorePlugin { + + public void createControls(final Composite comp); + + public Map getConnectionParameters(); + + public void loadFromPreferences(); + + public void saveToPreferences(); + + public DataStore connectToDataStore() throws IOException; + + public DataStoreResourceData constructResourceData(String typeName, + Map connectionParameters); +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/CropAction.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/CropAction.java new file mode 100644 index 0000000000..f4cd8b8e44 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/CropAction.java @@ -0,0 +1,81 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.actions; + +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.IRubberBandSelectionListener; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * Crop GIS resource action + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 29, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class CropAction extends AbstractRightClickAction { + public CropAction() { + super(AS_PUSH_BUTTON); + } + + @Override + public String getText() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + final DataStoreResource rsc = (DataStoreResource) this + .getSelectedRsc(); + if (rsc.isCropped()) { + return "Uncrop Shape"; + } + } + return "Crop Shape"; + } + + @Override + public void run() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + final DataStoreResource rsc = (DataStoreResource) this + .getSelectedRsc(); + if (rsc.isCropped()) { + rsc.uncrop(); + } else { + rsc.addRubberBandSelectionListener(new IRubberBandSelectionListener() { + @Override + public void rubberBandSelectionChanged(PixelExtent extent) { + rsc.removeRubberBandSelectionListener(this); + rsc.crop(extent); + } + }); + rsc.activateRubberBandBox(); + } + } + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/DisplayAttributes.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/DisplayAttributes.java new file mode 100644 index 0000000000..072dcef078 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/DisplayAttributes.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.actions; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.uf.viz.gisdatastore.ui.AttributeViewer; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * Show All Records action + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 29, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class DisplayAttributes extends AbstractRightClickAction { + + /** + * + */ + public DisplayAttributes() { + super("Display Attributes", AS_PUSH_BUTTON); + } + + @Override + public void run() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + DataStoreResource rsc = (DataStoreResource) this.getSelectedRsc(); + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + AttributeViewer.openDialog(shell, rsc); + + } + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/ImportGisAction.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/ImportGisAction.java new file mode 100644 index 0000000000..6ebef11c47 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/ImportGisAction.java @@ -0,0 +1,78 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.maps.actions.AbstractMapHandler; +import com.raytheon.uf.viz.gisdatastore.ui.GisDataStoreParametersDialog; +import com.raytheon.viz.ui.EditorUtil; + +/** + * Handler for Import GIS command + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 6, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class ImportGisAction extends AbstractMapHandler { + + private GisDataStoreParametersDialog dlg; + + private IDescriptor descriptor; + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. + * ExecutionEvent) + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + if (dlg == null || dlg.getShell() == null) { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + + descriptor = EditorUtil.getActiveVizContainer() + .getActiveDisplayPane().getRenderableDisplay() + .getDescriptor(); + + dlg = new GisDataStoreParametersDialog(shell, descriptor); + dlg.setBlockOnOpen(false); + } + dlg.open(); + return null; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/RenameAction.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/RenameAction.java new file mode 100644 index 0000000000..daa16108dc --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/RenameAction.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.actions; + +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * Rename Action + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 29, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class RenameAction extends AbstractRightClickAction { + + public RenameAction() { + super("Rename", AS_PUSH_BUTTON); + } + + @Override + public void run() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + DataStoreResource rsc = (DataStoreResource) this.getSelectedRsc(); + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + + InputDialog dlg = new InputDialog(shell, "Rename", + "Enter new name", rsc.getName(), null); + if (dlg.open() == Window.OK) { + rsc.setName(dlg.getValue()); + } + } + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/SetSampleAttributeAction.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/SetSampleAttributeAction.java new file mode 100644 index 0000000000..9430d94642 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/actions/SetSampleAttributeAction.java @@ -0,0 +1,78 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.actions; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.uf.viz.gisdatastore.ui.SelectAttributeDialog; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 13, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class SetSampleAttributeAction extends AbstractRightClickAction { + + /** + * + */ + public SetSampleAttributeAction() { + super("Select Sample Attribute...", AS_PUSH_BUTTON); + } + + @Override + public boolean isHidden() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + final DataStoreResource rsc = (DataStoreResource) this + .getSelectedRsc(); + return rsc.getProperties().isMapLayer(); + } + return true; + } + + @Override + public void run() { + if (this.getSelectedRsc() instanceof DataStoreResource) { + final DataStoreResource rsc = (DataStoreResource) this + .getSelectedRsc(); + + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + SelectAttributeDialog dlg = new SelectAttributeDialog(shell, rsc); + dlg.setBlockOnOpen(false); + dlg.open(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java new file mode 100644 index 0000000000..b07f3f11aa --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java @@ -0,0 +1,1413 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.rsc; + +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.geotools.coverage.grid.GeneralGridEnvelope; +import org.geotools.coverage.grid.GridGeometry2D; +import org.geotools.data.DataStore; +import org.geotools.data.DefaultQuery; +import org.geotools.data.FeatureSource; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; +import org.geotools.feature.FeatureCollection; +import org.geotools.geometry.GeneralEnvelope; +import org.geotools.geometry.jts.JTS; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.referencing.operation.DefaultMathTransformFactory; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterFactory2; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; + +import com.raytheon.uf.common.geospatial.MapUtil; +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.common.geospatial.util.WorldWrapCorrector; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IShadedShape; +import com.raytheon.uf.viz.core.drawables.IWireframeShape; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.MapDescriptor; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory; +import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.DensityCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.LabelableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.ShadeableCapability; +import com.raytheon.uf.viz.gisdatastore.Activator; +import com.raytheon.uf.viz.gisdatastore.ui.PreferenceConverter; +import com.raytheon.viz.ui.input.InputAdapter; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.Point; + +/** + * Resource to render data from a GeoTools DataStore + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 31, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class DataStoreResource extends + AbstractVizResource implements + IPropertyChangeListener, IResourceDataChanged { + private static final String ID_ATTRIBUTE_NAME = "Feature.ID"; + + private static final int CLICK_TOLERANCE = 3; + + private static final RGB RUBBER_BAND_COLOR = new RGB(0, 255, 0); + + /** + * The screen will be re-centered about the centroid of the selected feature + * only if the centroid lies outside the central portion of the screen as + * defined by this value. + */ + private static final double RECENTER_TOLERANCE = 0.8; + + public static final String HIGHLIGHT_COLOR_KEY = "HighlightColor"; + + public static final String HIGHLIGHT_COLOR_DEFAULT = "HotPink"; + + public static final String HIGHLIGHT_STYLE_KEY = "HighlightStyle"; + + public static final String HIGHLIGHT_STYLE_DEFAULT = "SOLID"; + + public static final String HIGHLIGHT_WIDTH_KEY = "HighlightWidth"; + + public static final String HIGHLIGHT_WIDTH_DEFAULT = "2"; + + public static final String PRODUCT_OPACITY_KEY = "ProductOpacity"; + + public static final String PRODUCT_OPACITY_DEFAULT = "0.35"; + + protected static final double EXPANSION_FACTOR = 0.25; + + /** + * at time of writing this is the density multiplier used to determine if a + * label should be drawn in ZoneSelectorResource + */ + private static final int BASE_DENSITY_MULT = 50; + + protected static class LabelNode { + private final Rectangle2D rect; + + private final String label; + + private final double[] location; + + public LabelNode(String label, double[] location, Rectangle2D rect) { + this.label = label; + this.location = location; + this.rect = rect; + } + + /** + * @return the rect + */ + public Rectangle2D getRect() { + return rect; + } + + /** + * @return the label + */ + public String getLabel() { + return label; + } + + /** + * @return the location + */ + public double[] getLocation() { + return location; + } + } + + static class DisplayAttributes { + private boolean visible; + + private boolean highlighted; + + private Point centroid; + + public DisplayAttributes() { + visible = true; + highlighted = false; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public boolean isHighlighted() { + return highlighted; + } + + public void setHighlighted(boolean highlighted) { + this.highlighted = highlighted; + } + + public Point getCentroid() { + return centroid; + } + + public void setCentroid(Point centroid) { + this.centroid = centroid; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (isVisible()) { + if (isHighlighted()) { + sb.append("Highlighted"); + } else { + sb.append("Visible"); + } + } else { + sb.append("Invisible"); + } + + return sb.toString(); + } + + } + + private class MouseHandler extends InputAdapter { + private Coordinate start; + + private Coordinate end; + + private boolean inDrag; + + @Override + public boolean handleMouseMove(int x, int y) { + if (rubberBandExtent != null) { + IDisplayPaneContainer container = getResourceContainer(); + Coordinate c = container.translateClick(x, y); + if (c != null) { + try { + dragPromptCoord = new ReferencedCoordinate(c) + .asPixel(getDescriptor().getGridGeometry()); + } catch (Exception e) { + dragPromptCoord = null; + } + } else { + dragPromptCoord = null; + } + issueRefresh(); + } + return false; + } + + @Override + public boolean handleMouseDown(int x, int y, int mouseButton) { + if (rubberBandExtent != null) { + if (mouseButton == 1) { + IDisplayPaneContainer container = getResourceContainer(); + Coordinate c = container.translateClick(x, y); + if (c != null) { + try { + start = new ReferencedCoordinate(c) + .asPixel(getDescriptor().getGridGeometry()); + end = start; + inDrag = true; + return true; + } catch (Exception e) { + start = null; + return false; + } + } + } + } + + return false; + } + + @Override + public boolean handleMouseDownMove(int x, int y, int mouseButton) { + if (rubberBandExtent != null) { + if (mouseButton == 1 && inDrag) { + IDisplayPaneContainer container = getResourceContainer(); + Coordinate c = container.translateClick(x, y); + if (c != null) { + try { + end = new ReferencedCoordinate(c) + .asPixel(getDescriptor().getGridGeometry()); + updateRubberBandBox(start, end); + return true; + } catch (Exception e) { + return false; + } + } + return true; + } + } + + return false; + } + + @Override + public boolean handleMouseUp(int x, int y, int mouseButton) { + if (rubberBandExtent != null) { + if (mouseButton == 1 && inDrag) { + IDisplayPaneContainer container = getResourceContainer(); + Coordinate c = container.translateClick(x, y); + if (c != null) { + try { + end = new ReferencedCoordinate(c) + .asPixel(getDescriptor().getGridGeometry()); + } catch (Exception e) { + // use previous end value + } + } + inDrag = false; + updateRubberBandBox(start, end); + deactivateRubberBandBox(); + return true; + } + } + + return super.handleMouseUp(x, y, mouseButton); + } + + @Override + public boolean handleDoubleClick(int x, int y, int button) { + if (!doubleClickListeners.isEmpty()) { + IDisplayPaneContainer container = getResourceContainer(); + Coordinate c = container.translateClick(x, y); + + try { + List features = findFeatures(new ReferencedCoordinate( + c)); + List featureIds = new ArrayList( + features.size()); + for (SimpleFeature feature : features) { + featureIds.add(feature.getID()); + } + for (Object obj : doubleClickListeners.getListeners()) { + IDoubleClickSelectionListener listener = (IDoubleClickSelectionListener) obj; + listener.selectedFeaturesChanged(featureIds); + } + + } catch (VizException e) { + // ignore click + } + } + + return super.handleDoubleClick(x, y, button); + } + } + + public static interface IRubberBandSelectionListener { + public void rubberBandSelectionChanged(PixelExtent extent); + } + + public static interface IDoubleClickSelectionListener { + public void selectedFeaturesChanged(List selectedIds); + } + + protected DataStore dataStore; + + private String typeName; + + private SimpleFeatureType schema; + + /** + * The valid time range for this resource. If null resource is time + * agnostic. + */ + private TimeRange timeRange; + + private String[] attributeNames; + + private Object[][] attributes; + + private Map displayAttributes; + + protected IWireframeShape outlineShape; + + protected IWireframeShape highlightShape; + + protected IFont font; + + protected PixelExtent lastExtent; + + protected PixelExtent projExtent; + + protected List labels; + + protected IShadedShape shadedShape; + + protected Map colorMap; + + protected String lastLabelField; + + protected String lastShadingField; + + private ReloadJob reloadJob; + + protected String geometryType; + + private String displayName; + + private RGB highlightColor; + + private LineStyle highlightStyle; + + private int highlightWidth; + + private boolean updateHighlights; + + private PixelExtent rubberBandExtent; + + private PixelExtent cropExtent; + + private MouseHandler mouseHandler; + + private ListenerList rubberBandListeners; + + private ListenerList doubleClickListeners; + + private Coordinate dragPromptCoord; + + private WorldWrapCorrector worldWrapCorrector; + + private String sampleAttribute; + + public DataStoreResource(DataStoreResourceData data, + LoadProperties loadProperties) throws IOException { + super(data, loadProperties); + reloadJob = new ReloadJob(); + + this.dataStore = data.getDataStore(); + this.typeName = data.getTypeName(); + this.displayName = data.getMapName(); + this.rubberBandListeners = new ListenerList(); + this.doubleClickListeners = new ListenerList(); + + GeneralEnvelope env = new GeneralEnvelope(MapUtil.LATLON_PROJECTION); + env.setEnvelope(-180.0, -90.0, 180.0, 90.0); + + GridGeometry2D latLonGridGeometry = new GridGeometry2D( + new GeneralGridEnvelope(new int[] { 0, 0 }, new int[] { 360, + 180 }, false), env); + this.worldWrapCorrector = new WorldWrapCorrector(latLonGridGeometry); + resourceData.addChangeListener(this); + mouseHandler = new MouseHandler(); + } + + @Override + protected void disposeInternal() { + + if (font != null) { + font.dispose(); + font = null; + } + + if (outlineShape != null) { + outlineShape.dispose(); + } + + if (shadedShape != null) { + shadedShape.dispose(); + } + + if (highlightShape != null) { + highlightShape.dispose(); + } + + // ensure mouseHandler is unregistered + if (mouseHandler != null) { + getResourceContainer().unregisterMouseHandler(mouseHandler); + } + + lastExtent = null; + + this.resourceData.disposeDataStore(); + this.reloadJob.cancel(); + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + + long t0 = System.currentTimeMillis(); + loadDataStore(); + System.out.println("loadDataStore took " + + (System.currentTimeMillis() - t0) + " ms"); + + getCapability(LabelableCapability.class).setAvailableLabelFields( + this.attributeNames); + + getCapability(ShadeableCapability.class).setAvailableShadingFields( + this.attributeNames); + + IPreferenceStore prefs = Activator.getDefault().getPreferenceStore(); + if (this.timeRange != null) { + float opacity = PreferenceConverter.getFloat(prefs, + PRODUCT_OPACITY_KEY, PRODUCT_OPACITY_DEFAULT); + getCapability(ShadeableCapability.class).setOpacity(opacity); + } + + highlightColor = PreferenceConverter.getRGB(prefs, HIGHLIGHT_COLOR_KEY, + HIGHLIGHT_COLOR_DEFAULT); + + highlightStyle = PreferenceConverter.getLineStyle(prefs, + HIGHLIGHT_STYLE_KEY, HIGHLIGHT_STYLE_DEFAULT); + + highlightWidth = PreferenceConverter.getInt(prefs, HIGHLIGHT_WIDTH_KEY, + HIGHLIGHT_WIDTH_DEFAULT); + + prefs.addPropertyChangeListener(this); + getResourceContainer().registerMouseHandler(mouseHandler); + } + + protected void loadDataStore() throws VizException { + try { + schema = dataStore.getSchema(typeName); + List attrDesc = schema + .getAttributeDescriptors(); + + // TODO: Should ID be in attributes and if so do we need a more + // unique attribute name + if (attrDesc == null) { + attributeNames = new String[] { ID_ATTRIBUTE_NAME }; + } else { + + List names = new ArrayList(attrDesc.size()); + names.add(ID_ATTRIBUTE_NAME); + for (AttributeDescriptor at : attrDesc) { + Class atType = at.getType().getBinding(); + if (!Geometry.class.isAssignableFrom(atType)) { + names.add(at.getLocalName()); + } + } + attributeNames = names.toArray(new String[names.size()]); + } + + displayAttributes = new HashMap( + (int) Math.ceil(attributeNames.length / 0.75f), 0.75f); + + } catch (Exception e) { + throw new VizException("Error loading shapefile: ", e); + } + } + + private void loadAttributes(Envelope envelope) { + DefaultQuery query = new DefaultQuery(); + query.setTypeName(typeName); + + FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools + .getDefaultHints()); + + String geomField = schema.getGeometryDescriptor().getLocalName(); + + ReferencedEnvelope bbox = new ReferencedEnvelope(envelope, + MapUtil.LATLON_PROJECTION); + Filter bboxFilter = ff.bbox(ff.property(geomField), bbox); + + query.setFilter(bboxFilter); + + FeatureCollection featureCollection = null; + Iterator featureIterator = null; + try { + FeatureSource featureSource = dataStore + .getFeatureSource(typeName); + + featureCollection = featureSource.getFeatures(query); + + int size = featureCollection.size(); + attributes = new Object[size][attributeNames.length]; + featureIterator = featureCollection.iterator(); + int i = 0; + while (featureIterator.hasNext()) { + int index = i++; + SimpleFeature f = featureIterator.next(); + + String id = f.getID(); + DisplayAttributes da = getDisplayAttributes(id); + Geometry g = (Geometry) f.getAttribute(geomField); + da.setCentroid(g.getCentroid()); + + attributes[index][0] = id; + for (int j = 1; j < attributeNames.length; j++) { + Object attr = f.getAttribute(attributeNames[j]); + attributes[index][j] = attr; + } + } + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } finally { + if (featureIterator != null) { + featureCollection.close(featureIterator); + } + } + } + + private Envelope buildEnvelope(PixelExtent extent) throws VizException { + Envelope env = null; + try { + Envelope e = descriptor.pixelToWorld(extent, descriptor.getCRS()); + + ReferencedEnvelope ref = new ReferencedEnvelope(e, + descriptor.getCRS()); + env = ref.transform(MapUtil.LATLON_PROJECTION, true); + } catch (Exception e) { + throw new VizException("Error transforming extent", e); + } + + return env; + } + + private Geometry buildBoundingGeometry(PixelExtent extent, + double worldToScreenRatio) { + + double[] northPole = getDescriptor().worldToPixel( + new double[] { 0, 90 }); + double[] southPole = getDescriptor().worldToPixel( + new double[] { 0, -90 }); + + double[] p = null; + if (northPole != null && extent.contains(northPole)) { + p = northPole; + } else if (southPole != null && extent.contains(southPole)) { + p = southPole; + } + + double delta = 1 / worldToScreenRatio; + + Geometry g; + if (p == null) { + g = geometryFromExtent(extent, worldToScreenRatio); + } else { + // if pole in the extent split the extent into four quadrants with + // corners at the pole + PixelExtent[] quadrant = new PixelExtent[4]; + quadrant[0] = new PixelExtent(extent.getMinX(), p[0] - delta, + extent.getMinY(), p[1] - delta); + quadrant[1] = new PixelExtent(p[0] + delta, extent.getMaxX(), + extent.getMinY(), p[1] - delta); + quadrant[2] = new PixelExtent(p[0] + delta, extent.getMaxX(), p[1] + + delta, extent.getMaxY()); + quadrant[3] = new PixelExtent(extent.getMinX(), p[0] - delta, p[1] + + delta, extent.getMaxY()); + + List geometries = new ArrayList(4); + for (PixelExtent ext : quadrant) { + if (ext.getWidth() > 0 && ext.getHeight() > 0) { + geometries.add(geometryFromExtent(ext, worldToScreenRatio)); + } + } + + GeometryFactory gf = new GeometryFactory(); + g = gf.createGeometryCollection(geometries + .toArray(new Geometry[geometries.size()])); + } + + MathTransform gridToCrs = getDescriptor().getGridGeometry() + .getGridToCRS(); + DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory(); + try { + MathTransform crsToLatLon = MapUtil + .getTransformToLatLon(getDescriptor().getCRS()); + MathTransform gridToLatLon = dmtf.createConcatenatedTransform( + gridToCrs, crsToLatLon); + g = JTS.transform(g, gridToLatLon); + + // correct for world wrap + g = this.worldWrapCorrector.correct(g); + + return g; + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error computing bounding geometry", e); + } + return null; + } + + private Geometry geometryFromExtent(PixelExtent extent, + double worldToScreenRatio) { + int nx = (int) Math.ceil(extent.getWidth() / worldToScreenRatio); + int ny = (int) Math.ceil(extent.getHeight() / worldToScreenRatio); + + double dx = extent.getWidth() / nx; + double dy = extent.getHeight() / ny; + + Coordinate[] coordinates = new Coordinate[2 * (nx + ny) + 1]; + int i = 0; + for (int x = 0; x < nx; x++) { + coordinates[i++] = new Coordinate(x * dx + extent.getMinX(), + extent.getMinY()); + } + for (int y = 0; y < ny; y++) { + coordinates[i++] = new Coordinate(extent.getMaxX(), y * dy + + extent.getMinY()); + } + for (int x = nx; x > 0; x--) { + coordinates[i++] = new Coordinate(x * dx + extent.getMinX(), + extent.getMaxY()); + } + for (int y = ny; y > 0; y--) { + coordinates[i++] = new Coordinate(extent.getMinX(), y * dy + + extent.getMinY()); + } + coordinates[i++] = coordinates[0]; + + GeometryFactory gf = new GeometryFactory(); + LinearRing shell = gf.createLinearRing(coordinates); + Geometry g = gf.createPolygon(shell, null); + return g; + } + + @Override + protected void paintInternal(IGraphicsTarget aTarget, + PaintProperties paintProps) throws VizException { + PixelExtent screenExtent = (PixelExtent) paintProps.getView() + .getExtent(); + + // determine if we should display in this frame + DataTime curTime = paintProps.getFramesInfo().getCurrentFrame(); + if (curTime != null && timeRange != null) { + if (timeRange.isValid()) { // non-zero duration + if (!timeRange.contains(curTime.getValidTime().getTime())) { + return; + } + } else { + if (!timeRange.getStart().equals( + curTime.getValidTime().getTime())) { + return; + } + } + } + + double worldToScreenRatio = paintProps.getView().getExtent().getWidth() + / paintProps.getCanvasBounds().width; + + String labelField = getCapability(LabelableCapability.class) + .getLabelField(); + boolean isLabeled = labelField != null; + + String shadingField = getCapability(ShadeableCapability.class) + .getShadingField(); + boolean isShaded = isPolygonal() && shadingField != null; + boolean isProduct = this.timeRange != null; + + boolean updateLabels = isLabeled && !labelField.equals(lastLabelField); + boolean updateShading = false; + if (isShaded || isProduct) { + if (shadingField == null) { + updateShading = lastShadingField != null; + } else { + updateShading = !shadingField.equals(lastShadingField); + } + } + boolean updateExtent = lastExtent == null + || !lastExtent.getEnvelope().contains( + clipToProjExtent(screenExtent).getEnvelope()); + + if (updateHighlights || updateLabels || updateShading || updateExtent) { + if (!paintProps.isZooming()) { + PixelExtent expandedExtent = getExpandedExtent(screenExtent); + // Envelope env = buildEnvelope(expandedExtent); + Geometry boundingGeom = buildBoundingGeometry(expandedExtent, + worldToScreenRatio); + + String geomField = schema.getGeometryDescriptor() + .getLocalName(); + + boolean highlightsOnly = updateHighlights && !updateLabels + && !updateShading && !updateExtent; + reloadJob.request(aTarget, this, boundingGeom, geomField, + labelField, shadingField, colorMap, isProduct, + highlightsOnly); + lastExtent = expandedExtent; + lastLabelField = labelField; + lastShadingField = shadingField; + updateHighlights = false; + } + } + + ReloadJob.Result result = reloadJob.getLatestResult(); + if (result != null) { + handleResult(result); + } + + float alpha = paintProps.getAlpha(); + + if ((isProduct || isShaded) && shadedShape != null + && shadedShape.isDrawable()) { + float opacity = getCapability(ShadeableCapability.class) + .getOpacity(); + aTarget.drawShadedShape(shadedShape, alpha * opacity); + } + + if (outlineShape != null && outlineShape.isDrawable() + && getCapability(OutlineCapability.class).isOutlineOn()) { + aTarget.drawWireframeShape(outlineShape, + getCapability(ColorableCapability.class).getColor(), + getCapability(OutlineCapability.class).getOutlineWidth(), + getCapability(OutlineCapability.class).getLineStyle(), + alpha); + } else if (outlineShape == null + && getCapability(OutlineCapability.class).isOutlineOn()) { + issueRefresh(); + } + + if (highlightShape != null && highlightShape.isDrawable() + && getCapability(OutlineCapability.class).isOutlineOn()) { + aTarget.drawWireframeShape(highlightShape, highlightColor, + highlightWidth, highlightStyle); + } + + double labelMagnification = getCapability(MagnificationCapability.class) + .getMagnification(); + + if (labels != null && isLabeled && labelMagnification != 0) { + drawLabels(aTarget, paintProps, labelMagnification, + worldToScreenRatio); + } + + if (rubberBandExtent != null) { + aTarget.drawShadedRect(rubberBandExtent, RUBBER_BAND_COLOR, 0.5, + null); + aTarget.drawRect(rubberBandExtent, RUBBER_BAND_COLOR, 2, 1.0); + } + + if (dragPromptCoord != null) { + DrawableString ds = new DrawableString("Drag to select", new RGB(0, + 0, 0)); + ds.setCoordinates(dragPromptCoord.x, dragPromptCoord.y); + ds.textStyle = TextStyle.BOXED; + ds.boxColor = new RGB(255, 255, 255); + ds.horizontalAlignment = HorizontalAlignment.LEFT; + ds.verticallAlignment = VerticalAlignment.BOTTOM; + aTarget.drawStrings(ds); + } + } + + private void handleResult(ReloadJob.Result result) throws VizException { + if (result.failed) { + lastExtent = null; // force to re-query when re-enabled + throw new VizException("Error processing map query request: ", + result.cause); + } + if (!result.highlightsOnly) { + if (outlineShape != null) { + outlineShape.dispose(); + } + + if (shadedShape != null) { + shadedShape.dispose(); + } + outlineShape = result.outlineShape; + labels = result.labels; + shadedShape = result.shadedShape; + colorMap = result.colorMap; + } + + if (highlightShape != null) { + highlightShape.dispose(); + } + highlightShape = result.highlightShape; + } + + private void drawLabels(IGraphicsTarget aTarget, + PaintProperties paintProps, double labelMagnification, + double worldToScreenRatio) throws VizException { + if (font == null) { + font = aTarget.initializeFont(aTarget.getDefaultFont() + .getFontName(), (float) (10 * labelMagnification), null); + font.setSmoothing(false); + } + + double offsetX = getCapability(LabelableCapability.class).getxOffset() + * worldToScreenRatio; + double offsetY = getCapability(LabelableCapability.class).getyOffset() + * worldToScreenRatio; + RGB color = getCapability(ColorableCapability.class).getColor(); + IExtent extent = paintProps.getView().getExtent(); + List strings = new ArrayList( + labels.size()); + List selectedNodes = new ArrayList(labels.size()); + List extents = new ArrayList(); + String lastLabel = null; + // get min distance + double density = this.getCapability(DensityCapability.class) + .getDensity(); + double minScreenDistance = Double.MAX_VALUE; + if (density > 0) { + minScreenDistance = worldToScreenRatio * BASE_DENSITY_MULT + / density; + } + + // find which nodes to draw + for (LabelNode node : labels) { + if (extent.contains(node.location)) { + if (shouldDraw(node, selectedNodes, minScreenDistance)) { + selectedNodes.add(node); + } + } + } + + // create drawable strings for selected nodes + for (LabelNode node : selectedNodes) { + DrawableString string = new DrawableString(node.label, color); + string.setCoordinates(node.location[0] + offsetX, node.location[1] + - offsetY); + string.font = font; + string.horizontalAlignment = HorizontalAlignment.CENTER; + string.verticallAlignment = VerticalAlignment.MIDDLE; + boolean add = true; + + IExtent strExtent = new PixelExtent( + node.location[0], + node.location[0] + + (node.rect.getWidth() * worldToScreenRatio), + node.location[1], + node.location[1] + + ((node.rect.getHeight() - node.rect.getY()) * worldToScreenRatio)); + + if (lastLabel != null && lastLabel.equals(node.label)) { + // check intersection of extents + for (IExtent ext : extents) { + if (ext.intersects(strExtent)) { + add = false; + break; + } + } + } else { + extents.clear(); + } + lastLabel = node.label; + extents.add(strExtent); + + if (add) { + strings.add(string); + } + } + + aTarget.drawStrings(strings); + } + + /** + * checks if the potentialNode has the same text AND is to close to an + * already selected node + * + * @param potentialNode + * @param selectedDrawList + * @param minScreenDistance + * @return + */ + protected boolean shouldDraw(LabelNode potentialNode, + List selectedDrawList, double minScreenDistance) { + boolean rval = false; + + // String label = potentialNode.getLabel(); + double x = potentialNode.getLocation()[0]; + double y = potentialNode.getLocation()[1]; + double minDistance = Double.MAX_VALUE; + + // check already selected labels + for (LabelNode node : selectedDrawList) { + // if (!node.getLabel().equals(label)) { + // continue; + // } + double distance = Math.abs(node.getLocation()[0] - x) + + Math.abs(node.getLocation()[1] - y); + minDistance = Math.min(distance, minDistance); + } + + if (minDistance >= minScreenDistance) { + rval = true; + } else { + rval = false; + } + + return rval; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#setDescriptor(com.raytheon + * .uf.viz.core.drawables.IDescriptor) + */ + @Override + public void setDescriptor(MapDescriptor descriptor) { + super.setDescriptor(descriptor); + + projExtent = new PixelExtent(descriptor.getGridGeometry() + .getGridRange()); + + lastExtent = null; + } + + @Override + public void project(CoordinateReferenceSystem crs) throws VizException { + super.project(crs); + + projExtent = new PixelExtent(descriptor.getGridGeometry() + .getGridRange()); + + lastExtent = null; + + if (this.outlineShape != null) { + outlineShape.dispose(); + this.outlineShape = null; + } + + if (this.shadedShape != null) { + shadedShape.dispose(); + this.shadedShape = null; + } + + if (this.highlightShape != null) { + this.highlightShape.dispose(); + this.highlightShape = null; + } + } + + @Override + public ResourceOrder getResourceOrder() { + String orderId = (this.getProperties().isMapLayer() ? "MAP_OUTLINE" + : "IMAGE_LOCAL"); + return RenderingOrderFactory.getRenderingOrder(orderId); + } + + /** + * @param screenExtent + * @return + */ + protected PixelExtent getExpandedExtent(PixelExtent screenExtent) { + PixelExtent expandedExtent = screenExtent.clone(); + expandedExtent.getEnvelope().expandBy( + expandedExtent.getWidth() * EXPANSION_FACTOR, + expandedExtent.getHeight() * EXPANSION_FACTOR); + + return clipToProjExtent(expandedExtent); + } + + protected PixelExtent clipToProjExtent(PixelExtent extent) { + Envelope e = extent.getEnvelope() + .intersection(projExtent.getEnvelope()); + + if (cropExtent != null) { + e = e.intersection(cropExtent.getEnvelope()); + } + + PixelExtent clipped = new PixelExtent(e.getMinX(), e.getMaxX(), + e.getMinY(), e.getMaxY()); + return clipped; + } + + protected String getGeometryType() { + if (geometryType == null) { + geometryType = schema.getGeometryDescriptor().getType() + .getBinding().getSimpleName(); + } + + return geometryType; + } + + protected boolean isPuntal() { + return getGeometryType().endsWith("Point"); + } + + protected boolean isLineal() { + return getGeometryType().endsWith("LineString"); + } + + protected boolean isPolygonal() { + return getGeometryType().endsWith("Polygon"); + } + + @Override + public String getName() { + if (this.displayName == null) { + return this.typeName; + } + return this.displayName; + } + + @Override + public Map interrogate(ReferencedCoordinate coord) + throws VizException { + Map data = null; + return data; + } + + @Override + public String inspect(ReferencedCoordinate coord) throws VizException { + String sampleString = null; + + // sampling is only supported when loaded as product + if (timeRange != null) { + if (sampleAttribute != null) { + List features = findFeatures(coord); + StringBuilder sb = new StringBuilder(); + for (SimpleFeature f : features) { + Object attr; + if (sampleAttribute.equals(ID_ATTRIBUTE_NAME)) { + attr = f.getID(); + } else { + attr = f.getAttribute(sampleAttribute); + } + if (sb.length() > 0) { + sb.append('\n'); + } + sb.append(String.valueOf(attr)); + } + sampleString = sb.toString(); + } else { + sampleString = "No Sample Attribute Selected"; + } + } + return sampleString; + } + + public void setName(String name) { + if (name != null && name.isEmpty()) { + name = null; + } + this.displayName = name; + this.resourceData.setMapName(name); + } + + public String[] getAttributeNames() { + return attributeNames; + } + + public Object[][] getAttributes() { + if (attributes == null) { + try { + // TODO need to fix this so it doesn't load features that are + // outside fully zoomed out window + Envelope env = buildEnvelope(projExtent); + long t0 = System.currentTimeMillis(); + loadAttributes(env); + System.out.println("loadAttributes took " + + (System.currentTimeMillis() - t0) + " ms"); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + return attributes; + } + + DataStore getDataStore() { + return dataStore; + } + + String getTypeName() { + return typeName; + } + + SimpleFeatureType getSchema() { + return schema; + } + + private List findFeatures(ReferencedCoordinate coord) + throws VizException { + + List features = new ArrayList(); + Coordinate pix; + try { + pix = coord.asPixel(getDescriptor().getGridGeometry()); + } catch (Exception e) { + throw new VizException( + "Error transforming sample point to lat/lon ", e); + } + + DefaultQuery query = new DefaultQuery(); + query.setTypeName(typeName); + + FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools + .getDefaultHints()); + + String geomField = schema.getGeometryDescriptor().getLocalName(); + + IExtent worldExtent = getDescriptor().getRenderableDisplay().getView() + .getExtent(); + Rectangle screenBounds = getResourceContainer().getActiveDisplayPane() + .getBounds(); + double worldToScreenRatio = worldExtent.getWidth() / screenBounds.width; + + double delta = CLICK_TOLERANCE * worldToScreenRatio; + PixelExtent bboxExtent = new PixelExtent(pix.x - delta, pix.x + delta, + pix.y - delta, pix.y + delta); + Geometry boundingGeom = buildBoundingGeometry(bboxExtent, + worldToScreenRatio); + + List filterList = new ArrayList( + boundingGeom.getNumGeometries()); + for (int i = 0; i < boundingGeom.getNumGeometries(); i++) { + Filter filter = ff.intersects(ff.property(geomField), + ff.literal(boundingGeom.getGeometryN(i))); + filterList.add(filter); + } + query.setFilter(ff.or(filterList)); + + FeatureCollection featureCollection = null; + Iterator featureIterator = null; + try { + FeatureSource featureSource = dataStore + .getFeatureSource(typeName); + + featureCollection = featureSource.getFeatures(query); + int size = featureCollection.size(); + + featureIterator = featureCollection.iterator(); + while (featureIterator.hasNext()) { + features.add(featureIterator.next()); + } + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } finally { + if (featureIterator != null) { + featureCollection.close(featureIterator); + } + } + return features; + } + + DisplayAttributes getDisplayAttributes(String id) { + DisplayAttributes da = this.displayAttributes.get(id); + if (da == null) { + da = new DisplayAttributes(); + this.displayAttributes.put(id, da); + } + return da; + } + + public void setVisible(String id, boolean visible) { + DisplayAttributes da = getDisplayAttributes(id); + da.setVisible(visible); + lastExtent = null; + issueRefresh(); + } + + public boolean getVisible(String id) { + DisplayAttributes da = getDisplayAttributes(id); + return da.isVisible(); + } + + public void setHighlighted(String id, boolean highlighted) { + DisplayAttributes da = getDisplayAttributes(id); + da.setHighlighted(highlighted); + updateHighlights = true; + ; + issueRefresh(); + } + + public boolean getHighlighted(String id) { + DisplayAttributes da = getDisplayAttributes(id); + return da.isHighlighted(); + } + + public void recenter(String id) { + DisplayAttributes da = getDisplayAttributes(id); + Point p = da.getCentroid(); + if (p != null) { + double[] center = new double[] { p.getCoordinate().x, + p.getCoordinate().y }; + + double[] pixel = this.getDescriptor().worldToPixel(center); + + IExtent extent = this.getDescriptor().getRenderableDisplay() + .getExtent().clone(); + extent.scale(RECENTER_TOLERANCE); + if (!extent.contains(pixel)) { + this.getDescriptor().getRenderableDisplay().recenter(center); + } + } + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + boolean update = false; + IPreferenceStore prefs = Activator.getDefault().getPreferenceStore(); + if (event.getProperty().equals(HIGHLIGHT_COLOR_KEY)) { + highlightColor = PreferenceConverter.getRGB(prefs, + HIGHLIGHT_COLOR_KEY, HIGHLIGHT_COLOR_DEFAULT); + update = true; + } else if (event.getProperty().equals(HIGHLIGHT_STYLE_KEY)) { + highlightStyle = PreferenceConverter.getLineStyle(prefs, + HIGHLIGHT_STYLE_KEY, HIGHLIGHT_STYLE_DEFAULT); + update = true; + } else if (event.getProperty().equals(HIGHLIGHT_WIDTH_KEY)) { + highlightWidth = PreferenceConverter.getInt(prefs, + HIGHLIGHT_WIDTH_KEY, HIGHLIGHT_WIDTH_DEFAULT); + update = true; + } else if (event.getProperty().equals(PRODUCT_OPACITY_KEY)) { + float opacity = PreferenceConverter.getFloat(prefs, + PRODUCT_OPACITY_KEY, PRODUCT_OPACITY_DEFAULT); + getCapability(ShadeableCapability.class).setOpacity(opacity); + } + + if (update) { + lastExtent = null; + issueRefresh(); + } + } + + public void activateRubberBandBox() { + rubberBandExtent = new PixelExtent(0, 0, 0, 0); + } + + public void updateRubberBandBox(Coordinate start, Coordinate end) { + dragPromptCoord = end; + double minX = Math.min(start.x, end.x); + double maxX = Math.max(start.x, end.x); + double minY = Math.min(start.y, end.y); + double maxY = Math.max(start.y, end.y); + rubberBandExtent = new PixelExtent(minX, maxX, minY, maxY); + issueRefresh(); + } + + public void deactivateRubberBandBox() { + if (rubberBandExtent.getWidth() > 0 && rubberBandExtent.getHeight() > 0) { + for (Object obj : rubberBandListeners.getListeners()) { + IRubberBandSelectionListener listener = (IRubberBandSelectionListener) obj; + listener.rubberBandSelectionChanged(rubberBandExtent); + } + } + + dragPromptCoord = null; + rubberBandExtent = null; + issueRefresh(); + } + + public void addRubberBandSelectionListener( + IRubberBandSelectionListener listener) { + rubberBandListeners.add(listener); + } + + public void removeRubberBandSelectionListener( + IRubberBandSelectionListener listener) { + rubberBandListeners.remove(listener); + } + + public void addDoubleClickSelectionListener( + IDoubleClickSelectionListener listener) { + doubleClickListeners.add(listener); + } + + public void removeDoubleClickSelectionListener( + IDoubleClickSelectionListener listener) { + doubleClickListeners.remove(listener); + } + + public void crop(PixelExtent extent) { + cropExtent = extent; + lastExtent = null; + issueRefresh(); + } + + public boolean isCropped() { + return cropExtent != null; + } + + public void uncrop() { + cropExtent = null; + lastExtent = null; + issueRefresh(); + + } + + public void setTimeRange(TimeRange timeRange) { + this.timeRange = timeRange; + } + + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type.equals(ChangeType.CAPABILITY)) { + if (object instanceof ColorableCapability) { + if (this.timeRange != null) { + // force rebuild of shaded shape to pick up color change + lastExtent = null; + } + } + } + issueRefresh(); + } + + public String getSampleAttribute() { + return sampleAttribute; + } + + public void setSampleAttribute(String sampleAttribute) { + this.sampleAttribute = sampleAttribute; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResourceData.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResourceData.java new file mode 100644 index 0000000000..a7d56f0f9b --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResourceData.java @@ -0,0 +1,193 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.rsc; + +import java.io.IOException; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.geotools.data.DataStore; + +import com.raytheon.uf.common.serialization.XmlGenericMapAdapter; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * Abstract base class for GeoTools DataStore base resource data classes + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 31, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +public abstract class DataStoreResourceData extends AbstractResourceData { + private DataStore dataStore; + + @XmlElement + @XmlJavaTypeAdapter(XmlGenericMapAdapter.class) + private Map connectionParameters; + + @XmlElement + private String typeName; + + @XmlElement + private String mapName; + + /** + * + */ + public DataStoreResourceData() { + } + + public DataStoreResourceData(String typeName, + Map connectionParameters) { + this.typeName = typeName; + this.mapName = typeName; + this.connectionParameters = connectionParameters; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public DataStoreResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + + DataStoreResource rsc; + try { + rsc = new DataStoreResource(this, loadProperties); + } catch (IOException e) { + throw new VizException("Error constructing GIS resource", e); + } + return rsc; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + // Default is to do nothing. + } + + public DataStore getDataStore() throws IOException { + if (dataStore == null) { + dataStore = constructDataStore(); + } + return dataStore; + } + + protected abstract DataStore constructDataStore() throws IOException; + + public void disposeDataStore() { + if (dataStore != null) { + dataStore.dispose(); + dataStore = null; + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof DataStoreResourceData)) { + return false; + } + DataStoreResourceData other = (DataStoreResourceData) obj; + if (connectionParameters == null) { + if (other.connectionParameters != null) { + return false; + } + } else if (!connectionParameters.equals(other.connectionParameters)) { + return false; + } + if (mapName == null) { + if (other.mapName != null) { + return false; + } + } else if (!mapName.equals(other.mapName)) { + return false; + } + if (typeName == null) { + if (other.typeName != null) { + return false; + } + } else if (!typeName.equals(other.typeName)) { + return false; + } + return true; + } + + public Map getConnectionParameters() { + return connectionParameters; + } + + public void setConnectionParameters(Map connectionParameters) { + this.connectionParameters = connectionParameters; + } + + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + if (this.mapName == null) { + this.mapName = typeName; + } + } + + String getMapName() { + return mapName; + } + + void setMapName(String mapName) { + this.mapName = mapName; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java new file mode 100644 index 0000000000..b2e471b147 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java @@ -0,0 +1,473 @@ +package com.raytheon.uf.viz.gisdatastore.rsc; + +import java.awt.geom.Rectangle2D; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ArrayBlockingQueue; + +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.swt.graphics.RGB; +import org.geotools.data.DefaultQuery; +import org.geotools.data.FeatureSource; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; +import org.geotools.feature.FeatureCollection; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterFactory2; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IShadedShape; +import com.raytheon.uf.viz.core.drawables.IWireframeShape; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.gisdatastore.Activator; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.DisplayAttributes; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.LabelNode; +import com.raytheon.viz.core.rsc.jts.JTSCompiler; +import com.raytheon.viz.core.rsc.jts.JTSCompiler.PointStyle; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.Point; + +class ReloadJob extends Job { + + private static final int QUEUE_LIMIT = 1; + + private static Random rand = new Random(System.currentTimeMillis()); + + private static int requestCounter = 0; + + public class Request { + int number; + + IGraphicsTarget target; + + DataStoreResource rsc; + + String geomField; + + String labelField; + + String shadingField; + + Geometry boundingGeom; + + Map colorMap; + + boolean isProduct; + + boolean highlightsOnly; + + Request(IGraphicsTarget target, DataStoreResource rsc, + Geometry boundingGeom, String geomField, String labelField, + String shadingField, Map colorMap, + boolean isProduct, boolean highlightsOnly) { + this.number = requestCounter++; + this.target = target; + this.rsc = rsc; + this.boundingGeom = boundingGeom; + this.geomField = geomField; + this.labelField = labelField; + this.shadingField = shadingField; + this.colorMap = colorMap; + this.isProduct = isProduct; + this.highlightsOnly = highlightsOnly; + } + + RGB getColor(Object key) { + if (colorMap == null) { + colorMap = new HashMap(); + } + RGB color = colorMap.get(key); + if (color == null) { + color = new RGB(rand.nextInt(206) + 50, rand.nextInt(206) + 50, + rand.nextInt(206) + 50); + colorMap.put(key, color); + } + + return color; + } + } + + public class Result { + public IWireframeShape outlineShape; + + public List labels; + + public IShadedShape shadedShape; + + public Map colorMap; + + public boolean failed; + + public Throwable cause; + + public IWireframeShape highlightShape; + + public boolean highlightsOnly; + + private Result() { + failed = true; + } + + public void dispose() { + if (outlineShape != null) { + outlineShape.dispose(); + outlineShape = null; + } + + if (shadedShape != null) { + shadedShape.dispose(); + shadedShape = null; + } + + if (highlightShape != null) { + highlightShape.dispose(); + highlightShape = null; + } + } + } + + private Request pendingRequest = null; + + private ArrayBlockingQueue resultQueue = new ArrayBlockingQueue( + QUEUE_LIMIT); + + public ReloadJob() { + super("Loading ..."); + } + + public void request(IGraphicsTarget target, DataStoreResource rsc, + Geometry boundingGeom, String geomField, String labelField, + String shadingField, Map colorMap, boolean isProduct, + boolean highlightsOnly) { + + synchronized (this) { + pendingRequest = new Request(target, rsc, boundingGeom, geomField, + labelField, shadingField, colorMap, isProduct, + highlightsOnly); + } + + this.schedule(); + } + + public Result getLatestResult() { + return resultQueue.poll(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. + * IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + Request req = null; + synchronized (this) { + req = pendingRequest; + pendingRequest = null; + } + while (req != null) { + System.out.println("Processing request: " + req.number); + + Result result = new Result(); + FeatureCollection featureCollection = null; + Iterator featureIterator = null; + try { + if (pendingRequest != null) { + System.out.println("Canceling request: " + req.number); + result.dispose(); + result = null; + return Status.CANCEL_STATUS; + } + + List fields = new ArrayList(); + fields.add(req.geomField); + if (req.labelField != null && !fields.contains(req.labelField)) { + fields.add(req.labelField); + } + if (req.shadingField != null + && !fields.contains(req.shadingField)) { + fields.add(req.shadingField); + } + + IWireframeShape newOutlineShape = req.target + .createWireframeShape(false, req.rsc.getDescriptor()); + + IWireframeShape newHighlightShape = req.target + .createWireframeShape(false, req.rsc.getDescriptor()); + + List newLabels = new ArrayList(); + + IShadedShape newShadedShape = null; + if (req.isProduct || req.shadingField != null) { + newShadedShape = req.target.createShadedShape(false, + req.rsc.getDescriptor().getGridGeometry(), true); + } + + // TODO: pass the crs on to JTSCompiler to indicate + // projection of shapefile data. + SimpleFeatureType schema = req.rsc.getSchema(); + CoordinateReferenceSystem crs = schema.getGeometryDescriptor() + .getCoordinateReferenceSystem(); + + JTSCompiler jtsCompiler = new JTSCompiler(newShadedShape, + newOutlineShape, req.rsc.getDescriptor(), + PointStyle.CROSS); + + JTSCompiler highlightCompiler = new JTSCompiler(null, + newHighlightShape, req.rsc.getDescriptor(), + PointStyle.CROSS); + + String shapeField = schema.getGeometryDescriptor() + .getLocalName(); + + DefaultQuery query = new DefaultQuery(); + + String typeName = req.rsc.getTypeName(); + query.setTypeName(typeName); + query.setPropertyNames(fields); + + if (req.boundingGeom != null) { + FilterFactory2 ff = CommonFactoryFinder + .getFilterFactory2(GeoTools.getDefaultHints()); + + List geomList = new ArrayList(); + flattenGeometry(req.boundingGeom, geomList); + + List filterList = new ArrayList( + geomList.size()); + for (Geometry g : geomList) { + Filter filter = ff.intersects(ff.property(shapeField), + ff.literal(g)); + filterList.add(filter); + } + query.setFilter(ff.or(filterList)); + } + + FeatureSource featureSource = req.rsc + .getDataStore().getFeatureSource(typeName); + + featureCollection = featureSource.getFeatures(query); + featureIterator = featureCollection.iterator(); + + // TODO: do we need to implement the GeometryCache/gidMap + // stuff like in DbMapResource? + + List resultingGeoms = new ArrayList(); + List highlightGeoms = new ArrayList(); + int numPoints = 0; + while (featureIterator.hasNext()) { + if (pendingRequest != null) { + System.out.println("Canceling request: " + req.number); + result.dispose(); + result = null; + return Status.CANCEL_STATUS; + } + + SimpleFeature f = featureIterator.next(); + String id = f.getID(); + DisplayAttributes da = req.rsc.getDisplayAttributes(id); + if (!da.isVisible()) { + continue; + } + + Geometry g = (Geometry) f.getAttribute(req.geomField); + if (da.isHighlighted()) { + highlightGeoms.add((Geometry) g.clone()); + } + + if (req.highlightsOnly) { + continue; + } + + Object labelAttr = null; + Object shadingAttr = null; + for (String name : fields) { + if (name.equals(req.labelField)) { + labelAttr = f.getAttribute(name); + } + if (name.equals(req.shadingField)) { + shadingAttr = f.getAttribute(name); + } + } + + if (labelAttr != null && g != null) { + String label; + if (labelAttr instanceof BigDecimal) { + label = Double.toString(((Number) labelAttr) + .doubleValue()); + } else { + label = labelAttr.toString(); + } + int numGeometries = g.getNumGeometries(); + List gList = new ArrayList( + numGeometries); + for (int polyNum = 0; polyNum < numGeometries; polyNum++) { + Geometry poly = g.getGeometryN(polyNum); + gList.add(poly); + } + // Sort polygons in g so biggest comes first. + Collections.sort(gList, new Comparator() { + @Override + public int compare(Geometry g1, Geometry g2) { + return (int) Math + .signum(g2.getEnvelope().getArea() + - g1.getEnvelope().getArea()); + } + }); + + for (Geometry poly : gList) { + Point point = poly.getInteriorPoint(); + if (point.getCoordinate() != null) { + double[] location = req.rsc + .getDescriptor() + .worldToPixel( + new double[] { + point.getCoordinate().x, + point.getCoordinate().y }); + + DrawableString ds = new DrawableString(label, + null); + ds.font = req.rsc.font; + Rectangle2D rect = req.target + .getStringsBounds(ds); + + LabelNode node = new LabelNode(label, location, + rect); + newLabels.add(node); + } + } + } + + if (g != null) { + numPoints += g.getNumPoints(); + resultingGeoms.add(g); + if (req.shadingField != null) { + g.setUserData(shadingAttr); + } + } + } + + newOutlineShape.allocate(numPoints); + RGB outlineColor = req.rsc.getCapability( + ColorableCapability.class).getColor(); + for (Geometry g : resultingGeoms) { + if (pendingRequest != null) { + System.out.println("Canceling request: " + req.number); + result.dispose(); + result = null; + return Status.CANCEL_STATUS; + } + + RGB color = null; + Object shadedField = g.getUserData(); + if (shadedField != null) { + color = req.getColor(shadedField); + } else { + color = outlineColor; + } + + try { + jtsCompiler.handle(g, color, true); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error reprojecting map outline", e); + } + } + + newOutlineShape.compile(); + + if (req.isProduct || req.shadingField != null) { + newShadedShape.compile(); + } + + for (Geometry g : highlightGeoms) { + if (pendingRequest != null) { + System.out.println("Canceling request: " + req.number); + result.dispose(); + result = null; + return Status.CANCEL_STATUS; + } + + try { + highlightCompiler.handle(g, true); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error reprojecting map outline", e); + } + } + + // uncomment to see boungingGeom as highlight for debug purposes + // highlightCompiler.handle(req.boundingGeom, true); + + newHighlightShape.compile(); + + result.outlineShape = newOutlineShape; + result.labels = newLabels; + result.shadedShape = newShadedShape; + result.colorMap = req.colorMap; + result.highlightShape = newHighlightShape; + result.highlightsOnly = req.highlightsOnly; + result.failed = false; + } catch (Throwable e) { + result.cause = e; + } finally { + if (featureIterator != null) { + featureCollection.close(featureIterator); + } + if (result != null) { + System.out.println("Completed request: " + req.number); + if (resultQueue.size() == QUEUE_LIMIT) { + resultQueue.poll(); + } + resultQueue.add(result); + req.rsc.issueRefresh(); + } + } + + synchronized (this) { + req = pendingRequest; + pendingRequest = null; + } + } + + return Status.OK_STATUS; + } + + /** + * Recursively traverse a Geometry and expand all geometry collections into + * a list of geometries + * + * @param geometry + * the geometry to flatten + * @param geomList + * the list of geometries + */ + private void flattenGeometry(Geometry geometry, List geomList) { + if (geometry instanceof GeometryCollection) { + GeometryCollection collection = (GeometryCollection) geometry; + for (int i = 0; i < collection.getNumGeometries(); i++) { + flattenGeometry(collection.getGeometryN(i), geomList); + } + } else { + geomList.add(geometry); + } + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AbstractFieldEditor.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AbstractFieldEditor.java new file mode 100644 index 0000000000..2d925a5d9a --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AbstractFieldEditor.java @@ -0,0 +1,157 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * Abstract base class for field editors with images. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 11, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ +public abstract class AbstractFieldEditor extends FieldEditor { + + protected Button fButton; + + protected Point fExtent; + + protected Image fImage; + + public AbstractFieldEditor() { + super(); + } + + public AbstractFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + @Override + protected void adjustForNumColumns(int numColumns) { + ((GridData) getLabelControl().getLayoutData()).horizontalSpan = numColumns - 1; + } + + protected Point computeImageSize(Control window) { + GC gc = new GC(window); + Font f = JFaceResources.getFontRegistry().get( + JFaceResources.DIALOG_FONT); + gc.setFont(f); + int height = gc.getFontMetrics().getHeight(); + gc.dispose(); + Point p = new Point(64, height); + return p; + } + + @Override + public int getNumberOfControls() { + return 2; + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + Control control = getLabelControl(parent); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, false, false); + gd.horizontalSpan = numColumns - 1; + control.setLayoutData(gd); + + fButton = new Button(parent, SWT.PUSH); + fButton.setLayoutData(new GridData()); + fExtent = computeImageSize(parent); + updateImage(); + fButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + open(); + } + }); + fButton.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent event) { + if (fImage != null) { + fImage.dispose(); + fImage = null; + } + } + }); + } + + /** + * Base method just removes old image. Subclasses should call super to + * dispose old image before updating the image. + */ + protected void updateImage() { + if (fImage != null) { + fImage.dispose(); + fImage = null; + } + } + + protected abstract void open(); + + protected abstract void setValueFromString(String value); + + protected abstract String getStringFromValue(); + + @Override + protected void doLoad() { + String value = getPreferenceStore().getString(getPreferenceName()); + setValueFromString(value); + updateImage(); + } + + @Override + protected void doLoadDefault() { + String value = getPreferenceStore().getDefaultString( + getPreferenceName()); + setValueFromString(value); + updateImage(); + } + + @Override + protected void doStore() { + getPreferenceStore() + .setValue(getPreferenceName(), getStringFromValue()); + } + +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AttributeViewer.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AttributeViewer.java new file mode 100644 index 0000000000..6deb0e885d --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/AttributeViewer.java @@ -0,0 +1,642 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +import com.raytheon.uf.common.dataplugin.gfe.type.Pair; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource.IDoubleClickSelectionListener; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.dialogs.ICloseCallback; + +/** + * GIS Attribute Viewer + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 30, 2012      #1326 randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class AttributeViewer extends CaveJFACEDialog implements RemoveListener { + private static final String HIGHLIGHT = "HighLight"; + + private static final String VISIBLE = "Visible"; + + private static Map map = new HashMap(); + + /** + * Open attribute viewer for the selected rsc (or bring to top if already + * open) + * + * @param shell + * @param rsc + * @return + */ + public static AttributeViewer openDialog(Shell shell, DataStoreResource rsc) { + AttributeViewer dlg = map.get(rsc); + if (dlg == null) { + + dlg = new AttributeViewer(shell, rsc); + dlg.open(); + } else { + dlg.bringToTop(); + } + return dlg; + } + + private static final int DEFAULT_WIDTH = 900; + + private static final int MAX_INITIAL_COLUMN_WIDTH = DEFAULT_WIDTH / 4; + + protected static final int MINIMUM_COLUMN_WIDTH = 10; + + /** + * Provides text for the columns in the attribute viewer from the attributes + * array + * + */ + private class TableLabelProvider extends LabelProvider implements + ITableLabelProvider { + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + return String.valueOf(((Object[]) element)[columnIndex]); + } + } + + /** + * Compares rows using values from the selected column and direction for + * sorting the table in the desired order. + * + */ + private class ColumnComparator extends ViewerComparator { + private List> sortOrder; + + @SuppressWarnings("unchecked") + @Override + public void sort(Viewer viewer, Object[] elements) { + Arrays.sort(elements, new Comparator() { + @Override + public int compare(Object a, Object b) { + List nameList = Arrays.asList(names); + int retval = 0; + for (Pair p : sortOrder) { + String field = p.getFirst(); + int column = nameList.indexOf(field); + int direction = p.getSecond(); + + Object aObj = ((Object[]) a)[column]; + Object bObj = ((Object[]) b)[column]; + + if ((aObj instanceof Comparable) + && (bObj instanceof Comparable)) { + retval = ((Comparable) aObj) + .compareTo(bObj); + } else { + retval = String.valueOf(aObj).compareTo( + String.valueOf(bObj)); + } + retval *= direction; + + if (retval != 0) { + return retval; + } + } + return retval; + } + }); + } + + /** + * Returns the sort order as a pair of column names and integers + * indicating sort direction (1 for ascending, -1 for descending) + * + * @return the sort order + */ + public List> getSortOrder() { + return sortOrder; + } + + /** + * Set the sort order as a pair of column names and integers indicating + * sort direction (1 for ascending, -1 for descending) + * + * @param sortOrder + */ + public void setSortOrder(List> sortOrder) { + this.sortOrder = sortOrder; + } + } + + private ColumnComparator comparator; + + private DataStoreResource rsc; + + private String title; + + private String[] names; + + private Object[][] attributes; + + private Shell parentShell; + + private TableViewer viewer; + + protected String[] selectedColumns; + + SortOrderDialog sortDlg; + + protected ColumnSelectDialog selectDlg; + + private int[] columnWidth; + + private IDoubleClickSelectionListener selectedListener; + + /** + * Create an attribute viewer for the specified DataStoreResource + * + * @param parentShell + * (only used for positioning the dialog) + * @param rsc + * the DataStoreResource + */ + public AttributeViewer(Shell parentShell, DataStoreResource rsc) { + // TODO: make open centered in parentShell + super(null); + this.setShellStyle(SWT.SHELL_TRIM | SWT.MENU); + this.rsc = rsc; + this.title = rsc.getName(); + this.names = rsc.getAttributeNames(); + this.selectedColumns = this.names; + this.parentShell = parentShell; + + // TODO: may need to deep copy this in case it changes out from under us + this.attributes = rsc.getAttributes(); + + map.put(rsc, this); + rsc.getDescriptor().getResourceList().addPreRemoveListener(this); + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Attributes: " + this.title); + + Menu menuBar = new Menu(newShell, SWT.BAR); + + MenuItem annotationMenuHeader = new MenuItem(menuBar, SWT.CASCADE); + annotationMenuHeader.setText("Annotation"); + + Menu annotationMenu = new Menu(newShell, SWT.DROP_DOWN); + annotationMenuHeader.setMenu(annotationMenu); + + MenuItem makeAllVisible = new MenuItem(annotationMenu, SWT.PUSH); + makeAllVisible.setText("Make All Visible"); + makeAllVisible.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + makeVisible(true, viewer.getTable().getItems()); + } + }); + + MenuItem clearHighlights = new MenuItem(annotationMenu, SWT.PUSH); + clearHighlights.setText("Clear Highlights"); + clearHighlights.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + highlight(false, viewer.getTable().getItems()); + } + }); + + MenuItem dataMenuHeader = new MenuItem(menuBar, SWT.CASCADE); + dataMenuHeader.setText("Data"); + Menu dataMenu = new Menu(newShell, SWT.DROP_DOWN); + dataMenuHeader.setMenu(dataMenu); + + MenuItem columnsItem = new MenuItem(dataMenu, SWT.PUSH); + columnsItem.setText("Select Columns..."); + columnsItem.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + selectColumns(); + } + }); + + MenuItem sortItem = new MenuItem(dataMenu, SWT.PUSH); + sortItem.setText("Sort..."); + sortItem.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + sortColumns(); + } + }); + + newShell.setMenuBar(menuBar); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + GridLayout layout = new GridLayout(); + composite.setLayout(layout); + + viewer = new TableViewer(composite, SWT.MULTI | SWT.BORDER + | SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION + | SWT.VIRTUAL); + Table table = viewer.getTable(); + + table.setHeaderVisible(true); + // table.setLinesVisible(true); + table.setSortDirection(SWT.UP); + comparator = new ColumnComparator(); + ArrayList> sortOrder = new ArrayList>( + 1); + comparator.setSortOrder(sortOrder); + viewer.setComparator(comparator); + + int i = 0; + GC gc = new GC(table); + columnWidth = new int[names.length]; + int totalWidth = 0; + for (String attrName : names) { + int index = i++; + int alignment = SWT.LEFT; + if (this.attributes[0][index] instanceof Integer) { + alignment = SWT.RIGHT; + } + TableViewerColumn tvc = new TableViewerColumn(viewer, alignment, + index); + final TableColumn column = tvc.getColumn(); + column.setText(attrName); + // column.addSelectionListener(new + // ColumnSelectionAdapter(tableViewer, + // index)); + column.pack(); + int extent = column.getWidth(); + for (Object[] atts : this.attributes) { + int width = gc.stringExtent(String.valueOf(atts[index])).x + 10; + + if (width > MAX_INITIAL_COLUMN_WIDTH) { + extent = MAX_INITIAL_COLUMN_WIDTH; + break; + } else if (width > extent) { + extent = width; + } + } + column.setWidth(extent); + columnWidth[index] = extent; + column.addControlListener(new ControlAdapter() { + + @Override + public void controlResized(ControlEvent e) { + TableColumn column = (TableColumn) e.widget; + int index = viewer.getTable().indexOf(column); + int width = column.getWidth(); + if (width > MINIMUM_COLUMN_WIDTH) { + columnWidth[index] = column.getWidth(); + } + + if (width == 0) { + List newSelected = new ArrayList(Arrays + .asList(selectedColumns)); + newSelected.remove(names[index]); + selectedColumns = newSelected + .toArray(new String[newSelected.size()]); + } + } + + }); + totalWidth += extent; + } + gc.dispose(); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + if (totalWidth > DEFAULT_WIDTH) { + layoutData.widthHint = DEFAULT_WIDTH; + } + layoutData.heightHint = table.getItemHeight() * 5; + table.setLayoutData(layoutData); + + IContentProvider contentProvider = new ArrayContentProvider(); + viewer.setLabelProvider(new TableLabelProvider()); + viewer.setContentProvider(contentProvider); + viewer.setInput(this.attributes); + + table.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + Table table = (Table) e.widget; + TableItem[] selected = table.getSelection(); + boolean highlight = (Boolean) selected[0].getData(HIGHLIGHT); + if (!highlight) { + recenter(selected[0]); + } + highlight(!highlight, selected); + } + }); + + table.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDown(MouseEvent e) { + Table table = (Table) e.widget; + if (e.button == 3) { + Point p = new Point(e.x, e.y); + TableItem clicked = table.getItem(p); + TableItem[] selected = table.getSelection(); + createPopupMenu(table, clicked, selected); + } + } + + }); + + Label label = new Label(composite, SWT.NONE); + label.setText(this.attributes.length + " rows"); + layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + label.setLayoutData(layoutData); + + initializeColors(); + + selectedListener = new IDoubleClickSelectionListener() { + + @Override + public void selectedFeaturesChanged(List selectedIds) { + Table table = viewer.getTable(); + int i = 0; + table.deselectAll(); + for (TableItem item : table.getItems()) { + if (selectedIds.contains(item.getText(0))) { + table.select(i); + } + i++; + } + if (table.getSelectionCount() > 0) { + table.showItem(table.getSelection()[0]); + } + } + }; + + table.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + rsc.removeDoubleClickSelectionListener(selectedListener); + } + }); + rsc.addDoubleClickSelectionListener(selectedListener); + + return composite; + } + + private void initializeColors() { + for (TableItem item : viewer.getTable().getItems()) { + String id = item.getText(0); + item.setData(VISIBLE, rsc.getVisible(id)); + item.setData(HIGHLIGHT, rsc.getHighlighted(id)); + setColors(item); + } + } + + private void createPopupMenu(Table table, final TableItem clicked, + final TableItem[] selected) { + Menu popupMenu = new Menu(table); + + MenuItem visible = new MenuItem(popupMenu, SWT.CHECK); + visible.setText("Visible"); + visible.setSelection((Boolean) clicked.getData(VISIBLE)); + visible.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + MenuItem item = (MenuItem) e.widget; + makeVisible(item.getSelection(), selected); + item.getParent().dispose(); + } + }); + + MenuItem highLight = new MenuItem(popupMenu, SWT.CHECK); + highLight.setText("Highlighted"); + highLight.setSelection((Boolean) clicked.getData(HIGHLIGHT)); + highLight.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + MenuItem item = (MenuItem) e.widget; + highlight(item.getSelection(), selected); + item.getParent().dispose(); + } + }); + popupMenu.setVisible(true); + } + + @Override + protected Control createButtonBar(Composite parent) { + return null; + } + + @Override + public boolean close() { + map.remove(this.rsc); + return super.close(); + } + + @Override + public void notifyRemove(ResourcePair rp) throws VizException { + AbstractVizResource rsc = rp.getResource(); + if (rsc instanceof DataStoreResource) { + AttributeViewer dlg = map.remove(rsc); + if (dlg != null) { + dlg.close(); + } + } + } + + private void makeVisible(boolean visible, TableItem[] items) { + for (TableItem item : items) { + item.setData(VISIBLE, visible); + setColors(item); + rsc.setVisible(item.getText(0), visible); + } + } + + private void highlight(boolean highlight, TableItem[] items) { + for (TableItem item : items) { + item.setData(HIGHLIGHT, highlight); + setColors(item); + rsc.setHighlighted(item.getText(0), highlight); + } + } + + private void recenter(TableItem item) { + rsc.recenter(item.getText(0)); + } + + private void setColors(TableItem item) { + boolean visible = (Boolean) item.getData(VISIBLE); + boolean highlight = (Boolean) item.getData(HIGHLIGHT); + + if (visible) { + if (highlight) { + item.setBackground(item.getDisplay().getSystemColor( + SWT.COLOR_YELLOW)); + } else { + item.setBackground(null); + } + } else { + item.setBackground(item.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + } + } + + private void selectColumns() { + if (selectDlg == null) { + selectDlg = new ColumnSelectDialog(getShell(), names, + selectedColumns); + selectDlg.setBlockOnOpen(false); + selectDlg.setCloseCallback(new ICloseCallback() { + @Override + public void dialogClosed(Object returnValue) { + int returnCode = (Integer) returnValue; + if (returnCode == Window.OK) { + String[] selectedColumns = selectDlg + .getSelectedColumns(); + setSelectedColumns(selectedColumns); + viewer.refresh(); + } + selectDlg = null; + } + }); + selectDlg.open(); + } else { + selectDlg.bringToTop(); + } + } + + /** + * Set the columns displayed in the desired order. + * + * @param selectedColumns + */ + private void setSelectedColumns(String[] selectedColumns) { + this.selectedColumns = selectedColumns; + List namesList = Arrays.asList(names); + List selectedList = Arrays.asList(selectedColumns); + List unselected = new ArrayList(namesList); + unselected.removeAll(selectedList); + List orderedList = new ArrayList(names.length); + orderedList.addAll(selectedList); + orderedList.addAll(unselected); + int[] order = new int[names.length]; + for (int i = 0; i < names.length; i++) { + order[i] = namesList.indexOf(orderedList.get(i)); + TableColumn column = viewer.getTable().getColumn(i); + if (!selectedList.contains(names[i])) { + column.setWidth(0); + } else { + column.setWidth(columnWidth[i]); + } + } + viewer.getTable().setColumnOrder(order); + } + + private void sortColumns() { + + if (sortDlg == null) { + sortDlg = new SortOrderDialog(getShell(), names, + comparator.getSortOrder()); + sortDlg.setBlockOnOpen(false); + sortDlg.setCloseCallback(new ICloseCallback() { + @Override + public void dialogClosed(Object returnValue) { + int returnCode = (Integer) returnValue; + if (returnCode == Window.OK) { + List> sortOrder = sortDlg + .getSortOrder(); + comparator.setSortOrder(sortOrder); + viewer.refresh(); + } + sortDlg = null; + } + }); + sortDlg.open(); + } else { + sortDlg.bringToTop(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColorFieldEditor.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColorFieldEditor.java new file mode 100644 index 0000000000..d8a5ba059d --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColorFieldEditor.java @@ -0,0 +1,124 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; + +import com.raytheon.uf.viz.core.RGBColors; + +/** + * Preference field editor for selecting a color for the DataStoreResource + * highlight + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ +public class ColorFieldEditor extends AbstractFieldEditor { + private static final RGB DEFAULT_COLOR = RGBColors.getRGBColor("HotPink"); + + private RGB fColor; + + /** + * + */ + public ColorFieldEditor() { + super(); + } + + /** + * @param name + * @param labelText + * @param parent + */ + public ColorFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + @Override + protected void init(String name, String text) { + super.init(name, text); + this.fColor = DEFAULT_COLOR; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#updateImage() + */ + @Override + protected void updateImage() { + super.updateImage(); + fImage = new Image(fButton.getDisplay(), fExtent.x, fExtent.y); + GC gc = new GC(fImage); + Color color = new Color(fButton.getDisplay(), this.fColor); + gc.setBackground(color); + gc.fillRectangle(0, 0, fExtent.x, fExtent.y); + color.dispose(); + gc.dispose(); + fButton.setImage(fImage); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#open() + */ + @Override + protected void open() { + ColorDialog colorDialog = new ColorDialog(fButton.getShell()); + colorDialog.setRGB(fColor); + RGB newColor = colorDialog.open(); + if (newColor != null) { + this.fColor = newColor; + updateImage(); + } + } + + @Override + protected void setValueFromString(String value) { + RGB newColor = StringConverter.asRGB(value); + if (newColor == null) { + newColor = DEFAULT_COLOR; + } + this.fColor = newColor; + updateImage(); + } + + @Override + protected String getStringFromValue() { + return StringConverter.asString(this.fColor); + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColumnSelectDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColumnSelectDialog.java new file mode 100644 index 0000000000..e79c694083 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/ColumnSelectDialog.java @@ -0,0 +1,94 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.widgets.duallist.DualList; +import com.raytheon.viz.ui.widgets.duallist.DualListConfig; + +/** + * Dialog to allow user to select the columns to be displayed and the order in + * which to display them + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 30, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class ColumnSelectDialog extends CaveJFACEDialog { + + private String[] available; + + private List selected; + + private DualList dualList; + + protected ColumnSelectDialog(Shell parentShell, String[] available, + String[] selected) { + super(parentShell); + this.available = available; + this.selected = new ArrayList(Arrays.asList(selected)); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Select Columns"); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = (Composite) super.createDialogArea(parent); + + DualListConfig config = new DualListConfig(); + config.setAvailableListLabel("Available"); + config.setFullList(Arrays.asList(available)); + config.setSelectedListLabel("Displayed"); + config.setSelectedList(selected); + config.setListHeight(100); + config.setListWidth(100); + config.setShowUpDownBtns(true); + dualList = new DualList(comp, SWT.NONE, config); + + return comp; + } + + public String[] getSelectedColumns() { + return dualList.getSelectedListItems(); + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisDataStoreParametersDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisDataStoreParametersDialog.java new file mode 100644 index 0000000000..e443a67151 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisDataStoreParametersDialog.java @@ -0,0 +1,455 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; +import org.geotools.data.DataStore; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.SimulatedTime; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.gisdatastore.Activator; +import com.raytheon.uf.viz.gisdatastore.IGisDataStorePlugin; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResourceData; +import com.raytheon.viz.core.ColorUtil; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.widgets.TimeRangeEntry; + +/** + * Generic GIS Connection Parameters Dialog + * + * Each GisDataStore implementation will need to provide an implementation of + * IParametersComp containing the necessary widgets to enter its specific + * connection parameters + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 5, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class GisDataStoreParametersDialog extends CaveJFACEDialog { + private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss'Z'"; + + private static final String GIS_DATA_STORE_PLUGIN_PREF = "GisDataStorePlugin"; + + private static final String EXTENSION_POINT_ID = "com.raytheon.uf.viz.gisdatastore.gisDataStore"; + + private IDescriptor descriptor; + + private DataTime currentFrame; + + private boolean loadAsProduct; + + private Map plugins; + + private String[] pluginNames; + + private String typeName; + + private IGisDataStorePlugin gdsPlugin; + + private Composite mainComp; + + private TimeRangeEntry timeRangeEntry; + + private Group connectionGroup; + + private Button connectButton; + + private Button disconnectButton; + + private List tablesList; + + private Button okButton; + + private DataStore dataStore; + + private String selectedPlugin; + + public GisDataStoreParametersDialog(Shell parentShell, + IDescriptor descriptor) { + super(parentShell); + this.descriptor = descriptor; + FramesInfo framesInfo = descriptor.getFramesInfo(); + + currentFrame = framesInfo.getCurrentFrame(); + if (currentFrame == null) { + currentFrame = new DataTime(SimulatedTime.getSystemTime().getTime()); + } + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets + * .Shell) + */ + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("GIS DataStore Parameters"); + } + + /* + * (non-Javadoc) Method declared on Dialog. + */ + @Override + protected Control createDialogArea(Composite parent) { + mainComp = (Composite) super.createDialogArea(parent); + Group dsTypeGroup = new Group(mainComp, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + dsTypeGroup.setLayoutData(layoutData); + GridLayout layout = new GridLayout(); + dsTypeGroup.setLayout(layout); + dsTypeGroup.setText("DataStore Type:"); + + Combo typeCombo = new Combo(dsTypeGroup, SWT.DROP_DOWN | SWT.READ_ONLY); + layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + typeCombo.setLayoutData(layoutData); + + for (String pluginName : getPluginNames()) { + typeCombo.add(pluginName); + } + + typeCombo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + String pluginName = ((Combo) e.widget).getText(); + selectPlugin(pluginName); + } + }); + + connectionGroup = new Group(mainComp, SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + connectionGroup.setLayoutData(layoutData); + layout = new GridLayout(); + connectionGroup.setLayout(layout); + connectionGroup.setText("Connection Parameters:"); + + Composite btnComp = new Composite(mainComp, SWT.NONE); + layoutData = new GridData(SWT.END, SWT.FILL, true, true); + btnComp.setLayoutData(layoutData); + layout = new GridLayout(2, false); + btnComp.setLayout(layout); + + connectButton = new Button(btnComp, SWT.PUSH); + layoutData = new GridData(SWT.END, SWT.CENTER, false, false); + connectButton.setLayoutData(layoutData); + connectButton.setText("Connect"); + connectButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + connect(); + } + }); + + disconnectButton = new Button(btnComp, SWT.PUSH); + layoutData = new GridData(SWT.END, SWT.CENTER, false, false); + disconnectButton.setLayoutData(layoutData); + disconnectButton.setText("Disconnect"); + disconnectButton.setEnabled(false); + disconnectButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + disconnect(); + } + }); + + Group productGroup = new Group(mainComp, SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + productGroup.setLayoutData(layoutData); + productGroup.setText("Load As:"); + layout = new GridLayout(2, true); + productGroup.setLayout(layout); + + Button mapButton = new Button(productGroup, SWT.RADIO); + layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + mapButton.setLayoutData(layoutData); + mapButton.setText("Map"); + mapButton.setSelection(!loadAsProduct); + + Button productButton = new Button(productGroup, SWT.RADIO); + layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + productButton.setLayoutData(layoutData); + productButton.setText("Product"); + productButton.setSelection(loadAsProduct); + + timeRangeEntry = new TimeRangeEntry(productGroup, SWT.HORIZONTAL); + layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + layoutData.horizontalSpan = 2; + timeRangeEntry.setLayoutData(layoutData); + timeRangeEntry.setDateFormat(DATE_TIME_FORMAT); + timeRangeEntry.setTimeZone(TimeZone.getTimeZone("GMT")); + timeRangeEntry.setTimeRange(currentFrame.getValidPeriod()); + timeRangeEntry.setEnabled(loadAsProduct); + + productButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Button button = (Button) e.widget; + loadAsProduct = button.getSelection(); + timeRangeEntry.setEnabled(loadAsProduct); + } + }); + + Group tableGroup = new Group(mainComp, SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + tableGroup.setLayoutData(layoutData); + layout = new GridLayout(1, false); + tableGroup.setLayout(layout); + layout.marginWidth = 0; + layout.marginHeight = 0; + tableGroup.setText("Table:"); + + tablesList = new List(tableGroup, SWT.SINGLE | SWT.BORDER + | SWT.V_SCROLL | SWT.H_SCROLL); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.heightHint = tablesList.getItemHeight() * 12; + tablesList.setLayoutData(layoutData); + tablesList.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + if (tablesList.getSelectionCount() > 0) { + typeName = tablesList.getSelection()[0]; + GisDataStoreParametersDialog.this.okButton.setEnabled(true); + buttonPressed(IDialogConstants.OK_ID); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + if (tablesList.getSelectionCount() > 0) { + typeName = tablesList.getSelection()[0]; + okButton.setEnabled(true); + } + } + }); + + applyDialogFont(mainComp); + + IPersistentPreferenceStore prefs = Activator.getDefault() + .getPreferenceStore(); + String pluginName = prefs.getString(GIS_DATA_STORE_PLUGIN_PREF); + if (!Arrays.asList(getPluginNames()).contains(pluginName)) { + pluginName = getPluginNames()[0]; + prefs.setToDefault(GIS_DATA_STORE_PLUGIN_PREF); + try { + prefs.save(); + } catch (IOException e1) { + Activator.statusHandler + .error("Unable to save most recently used GIS Plugin to prefrences", + e1); + } + } + + typeCombo.setText(pluginName); + selectedPlugin = null; + selectPlugin(pluginName); + return mainComp; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + okButton = getButton(IDialogConstants.OK_ID); + okButton.setEnabled(false); + } + + /* + * (non-Javadoc) Method declared on Dialog. + */ + @Override + protected void buttonPressed(int buttonId) { + if (dataStore != null) { + dataStore.dispose(); + } + super.buttonPressed(buttonId); + } + + @Override + protected void okPressed() { + try { + DataStoreResourceData rd = gdsPlugin.constructResourceData( + typeName, gdsPlugin.getConnectionParameters()); + DataStoreResource rsc = rd.construct(new LoadProperties(), + descriptor); + + if (loadAsProduct) { + rsc.setTimeRange(timeRangeEntry.getTimeRange()); + } + + RGB color = ColorUtil.getNewColor(descriptor); + rsc.getCapability(ColorableCapability.class).setColor(color); + + ResourceProperties props = new ResourceProperties(); + props.setVisible(true); + props.setMapLayer(!loadAsProduct); + descriptor.getResourceList().add(rsc, props); + + } catch (Exception e) { + Activator.statusHandler.error("Error importing GIS resource: ", e); + } + + super.okPressed(); + } + + private void selectPlugin(String pluginName) { + if (!pluginName.equals(selectedPlugin)) { + gdsPlugin = getPlugin(pluginName); + for (Control c : connectionGroup.getChildren()) { + c.dispose(); + } + disconnect(); + gdsPlugin.createControls(connectionGroup); + gdsPlugin.loadFromPreferences(); + connectionGroup.layout(); + getShell().pack(); + selectedPlugin = pluginName; + } + } + + private void connect() { + try { + dataStore = gdsPlugin.connectToDataStore(); + disconnectButton.setEnabled(true); + connectButton.setEnabled(false); + + IPersistentPreferenceStore prefs = Activator.getDefault() + .getPreferenceStore(); + prefs.setValue(GIS_DATA_STORE_PLUGIN_PREF, selectedPlugin); + try { + prefs.save(); + } catch (IOException e1) { + Activator.statusHandler + .error("Unable to save most recently used GIS Plugin to prefrences", + e1); + } + + gdsPlugin.saveToPreferences(); + + String[] typeNames = dataStore.getTypeNames(); + Arrays.sort(typeNames); + tablesList.setItems(typeNames); + if (typeName != null) { + int index = tablesList.indexOf(typeName); + if (index >= 0) { + tablesList.select(index); + } + } + } catch (Exception e) { + Activator.statusHandler.error(e.getLocalizedMessage(), e); + } + } + + private void disconnect() { + if (dataStore != null) { + dataStore.dispose(); + } + connectButton.setEnabled(true); + disconnectButton.setEnabled(false); + tablesList.removeAll(); + } + + public Map getConnectionParameters() { + return gdsPlugin.getConnectionParameters(); + } + + private IGisDataStorePlugin getPlugin(String pluginName) { + getPluginNames(); // ensure plugins are loaded + return plugins.get(pluginName); + } + + private String[] getPluginNames() { + if (pluginNames == null) { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint point = registry + .getExtensionPoint(EXTENSION_POINT_ID); + plugins = new HashMap(); + if (point != null) { + IExtension[] extensions = point.getExtensions(); + + for (IExtension ext : extensions) { + IConfigurationElement[] config = ext + .getConfigurationElements(); + + for (IConfigurationElement cfg : config) { + try { + IGisDataStorePlugin plugin = (IGisDataStorePlugin) cfg + .createExecutableExtension("class"); + String pluginName = cfg.getAttribute("name"); + plugins.put(pluginName, plugin); + } catch (CoreException e) { + Activator.statusHandler.error( + "Error loading unit registrations for " + + cfg.getAttribute("class"), e); + } + } + } + } + pluginNames = plugins.keySet().toArray(new String[plugins.size()]); + Arrays.sort(pluginNames); + } + return pluginNames; + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisViewerPreferencePage.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisViewerPreferencePage.java new file mode 100644 index 0000000000..2326223c9d --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/GisViewerPreferencePage.java @@ -0,0 +1,90 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +import com.raytheon.uf.viz.gisdatastore.Activator; +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; + +/** + * Preference page for GIS Viewer + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 26, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class GisViewerPreferencePage extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public GisViewerPreferencePage() { + super(FieldEditorPreferencePage.GRID); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + setPreferenceStore(store); + setDescription("GIS Viewer Preferences"); + } + + @Override + protected void createFieldEditors() { + AbstractFieldEditor colorEditor = new ColorFieldEditor( + DataStoreResource.HIGHLIGHT_COLOR_KEY, "Highlight Color", + getFieldEditorParent()); + + AbstractFieldEditor styleEditor = new LineStyleFieldEditor( + DataStoreResource.HIGHLIGHT_STYLE_KEY, "Highlight Style", + getFieldEditorParent()); + + AbstractFieldEditor widthEditor = new LineWidthFieldEditor( + DataStoreResource.HIGHLIGHT_WIDTH_KEY, "Highlight Width", + getFieldEditorParent()); + + AbstractFieldEditor opacityEditor = new OpacityFieldEditor( + DataStoreResource.PRODUCT_OPACITY_KEY, "Product Opacity", + getFieldEditorParent()); + + addField(colorEditor); + addField(styleEditor); + addField(widthEditor); + addField(opacityEditor); + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleDialog.java new file mode 100644 index 0000000000..a8a78c2af3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleDialog.java @@ -0,0 +1,130 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; + +/** + * Dialog for selecting line opacity + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class LineStyleDialog extends Dialog { + LineStyle style; + + protected LineStyleDialog(Shell parentShell, LineStyle origStyle) { + super(parentShell); + this.style = origStyle; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = (Composite) super.createDialogArea(parent); + Label label = new Label(comp, SWT.CENTER); + label.setText("Double-Click to select"); + GridData layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + label.setLayoutData(layoutData); + + Display d = comp.getDisplay(); + Table table = new Table(comp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.heightHint = table.getItemHeight() + * Math.min(10, LineStyle.values().length); + table.setLayoutData(layoutData); + + for (LineStyle ls : LineStyle.values()) { + if (ls.equals(LineStyle.DEFAULT)) { + continue; + } + TableItem item = new TableItem(table, SWT.NONE); + Image image = new Image(d, 128, 10); + Rectangle bounds = image.getBounds(); + int[] dashes = ls.getSWTLineStyle(); + GC gc = new GC(image); + gc.fillRectangle(bounds); + gc.setLineDash(dashes); + gc.drawLine(bounds.x, bounds.y + bounds.height / 2, + bounds.width - 1, bounds.y + bounds.height / 2); + + gc.dispose(); + item.setImage(image); + image.dispose(); + item.setData(ls); + + if (ls.equals(this.style)) { + table.setSelection(item); + } + } + table.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + Table table = (Table) e.widget; + TableItem item = table.getSelection()[0]; + style = (LineStyle) item.getData(); + okPressed(); + } + }); + + return comp; + } + + @Override + protected Control createButtonBar(Composite parent) { + return null; + } + + public LineStyle getStyle() { + return style; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleFieldEditor.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleFieldEditor.java new file mode 100644 index 0000000000..14c4a12454 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineStyleFieldEditor.java @@ -0,0 +1,133 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.window.Window; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; + +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; + +/** + * Preference field editor for selecting a color for the DataStoreResource + * highlight + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 26, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class LineStyleFieldEditor extends AbstractFieldEditor { + + protected LineStyle fStyle; + + protected LineStyleFieldEditor() { + super(); + } + + /** + * Creates a line opacity field editor. + * + * @param name + * the name of the preference this field editor works on + * @param labelText + * the label text of the field editor + * @param parent + * the parent of the field editor's control + */ + public LineStyleFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + @Override + protected void init(String name, String text) { + super.init(name, text); + this.fStyle = LineStyle.SOLID; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int) + */ + @Override + protected void adjustForNumColumns(int numColumns) { + ((GridData) fButton.getLayoutData()).horizontalSpan = numColumns - 1; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls() + */ + @Override + public int getNumberOfControls() { + return 2; + } + + @Override + protected void open() { + LineStyleDialog dlg = new LineStyleDialog(fButton.getShell(), fStyle); + if (dlg.open() == Window.OK) { + this.fStyle = dlg.getStyle(); + updateImage(); + } + } + + @Override + protected void updateImage() { + super.updateImage(); + fImage = new Image(fButton.getDisplay(), fExtent.x, fExtent.y); + GC gc = new GC(fImage); + // gc.setBackground(fButton.getBackground()); + gc.fillRectangle(0, 0, fExtent.x, fExtent.y); + int y = fExtent.y / 2; + gc.setLineDash(this.fStyle.getSWTLineStyle()); + gc.drawLine(0, y, fExtent.x, y); + gc.dispose(); + fButton.setImage(fImage); + } + + @Override + protected void setValueFromString(String value) { + LineStyle style = StringConverter.asLineStyle(value); + if (style == null) { + this.fStyle = LineStyle.SOLID; + } else { + this.fStyle = style; + } + } + + @Override + protected String getStringFromValue() { + return StringConverter.asString(fStyle); + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthDialog.java new file mode 100644 index 0000000000..4324a567ef --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthDialog.java @@ -0,0 +1,130 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +/** + * Dialog for selecting line width + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class LineWidthDialog extends Dialog { + int width; + + private int min; + + private int max; + + protected LineWidthDialog(Shell parentShell, int width, int min, int max) { + super(parentShell); + this.width = width; + this.min = min; + this.max = max; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = (Composite) super.createDialogArea(parent); + Label label = new Label(comp, SWT.CENTER); + label.setText("Double-Click to select"); + GridData layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + label.setLayoutData(layoutData); + + Display d = comp.getDisplay(); + Table table = new Table(comp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.heightHint = table.getItemHeight() + * Math.min(10, max - min + 1); + table.setLayoutData(layoutData); + + for (int w = min; w <= max; w++) { + TableItem item = new TableItem(table, SWT.NONE); + Image image = new Image(d, 128, 10); + Rectangle bounds = image.getBounds(); + GC gc = new GC(image); + gc.fillRectangle(bounds); + gc.setLineWidth(w); + gc.drawLine(bounds.x, bounds.y + bounds.height / 2, + bounds.width - 1, bounds.y + bounds.height / 2); + + gc.dispose(); + item.setImage(image); + image.dispose(); + item.setData(w); + + if (w == this.width) { + table.setSelection(item); + } + } + table.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + Table table = (Table) e.widget; + TableItem item = table.getSelection()[0]; + width = (Integer) item.getData(); + okPressed(); + } + }); + + return comp; + } + + @Override + protected Control createButtonBar(Composite parent) { + return null; + } + + public int getWidth() { + return this.width; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthFieldEditor.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthFieldEditor.java new file mode 100644 index 0000000000..665ca34877 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/LineWidthFieldEditor.java @@ -0,0 +1,141 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.window.Window; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; + +/** + * Preference field editor for selecting a line width for DataStoreResource + * highlight + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class LineWidthFieldEditor extends AbstractFieldEditor { + private static final int MAX_WIDTH = 5; + + private static final int MIN_WIDTH = 1; + + private static int DEFAULT_WIDTH = 2; + + private int fWidth; + + /** + * + */ + public LineWidthFieldEditor() { + super(); + } + + /** + * @param name + * @param labelText + * @param parent + */ + public LineWidthFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#updateImage() + */ + @Override + protected void updateImage() { + super.updateImage(); + fImage = new Image(fButton.getDisplay(), fExtent.x, fExtent.y); + GC gc = new GC(fImage); + // gc.setBackground(fButton.getBackground()); + gc.fillRectangle(0, 0, fExtent.x, fExtent.y); + int y = fExtent.y / 2; + gc.setLineWidth(this.fWidth); + gc.drawLine(0, y, fExtent.x, y); + gc.dispose(); + fButton.setImage(fImage); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#open() + */ + @Override + protected void open() { + LineWidthDialog dlg = new LineWidthDialog(fButton.getShell(), fWidth, + MIN_WIDTH, MAX_WIDTH); + if (dlg.open() == Window.OK) { + this.fWidth = dlg.getWidth(); + updateImage(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#setValueFromString + * (java.lang.String) + */ + @Override + protected void setValueFromString(String value) { + int width = MIN_WIDTH; + Integer i = StringConverter.asInteger(value); + if (i != null) { + width = i.intValue(); + } + + if (width < MIN_WIDTH) { + this.fWidth = MIN_WIDTH; + } else if (width > MAX_WIDTH) { + this.fWidth = MAX_WIDTH; + } else { + this.fWidth = width; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#getStringFromValue + * () + */ + @Override + protected String getStringFromValue() { + return StringConverter.asString(this.fWidth); + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/OpacityFieldEditor.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/OpacityFieldEditor.java new file mode 100644 index 0000000000..27f740c314 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/OpacityFieldEditor.java @@ -0,0 +1,159 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; + +import com.raytheon.viz.ui.dialogs.SetOpacityDialog; + +/** + * Preference field editor for selecting the opacity of a DataStoreResource when + * loaded as a product + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 13, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class OpacityFieldEditor extends AbstractFieldEditor { + private static final RGB COLOR = new RGB(0, 255, 255); + + protected float fOpacity; + + protected OpacityFieldEditor() { + super(); + } + + /** + * Creates a line opacity field editor. + * + * @param name + * the name of the preference this field editor works on + * @param labelText + * the label text of the field editor + * @param parent + * the parent of the field editor's control + */ + public OpacityFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + @Override + protected void init(String name, String text) { + super.init(name, text); + this.fOpacity = 0.35f; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int) + */ + @Override + protected void adjustForNumColumns(int numColumns) { + ((GridData) fButton.getLayoutData()).horizontalSpan = numColumns - 1; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls() + */ + @Override + public int getNumberOfControls() { + return 2; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.gisdatastore.ui.AbstractFieldEditor#open() + */ + @Override + protected void open() { + SetOpacityDialog dlg = new SetOpacityDialog(fButton.getShell(), + fOpacity, COLOR); + if (dlg.open() == Window.OK) { + this.fOpacity = dlg.getOpacity(); + updateImage(); + } + } + + @Override + protected void updateImage() { + super.updateImage(); + fImage = new Image(fButton.getDisplay(), fExtent.x, fExtent.y); + GC gc = new GC(fImage); + + Rectangle rect1 = fImage.getBounds(); + gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_BLACK)); + gc.fillRectangle(rect1); + + int dx = rect1.width / 5; + int dy = rect1.height / 5; + + Rectangle rect2 = new Rectangle(rect1.x + dx, rect1.y + dy, rect1.width + - 2 * dx, rect1.height - 2 * dy); + gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); + gc.drawRectangle(rect2); + + Color color = new Color(gc.getDevice(), COLOR); + gc.setBackground(color); + gc.setAlpha((int) (fOpacity * 255)); + gc.fillRectangle(rect1); + color.dispose(); + + gc.dispose(); + fButton.setImage(fImage); + } + + @Override + protected void setValueFromString(String value) { + Float opacity = StringConverter.asFloat(value); + if (opacity == null) { + this.fOpacity = 0.35f; + } else { + this.fOpacity = opacity; + } + } + + @Override + protected String getStringFromValue() { + return StringConverter.asString(fOpacity); + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/PreferenceConverter.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/PreferenceConverter.java new file mode 100644 index 0000000000..a22c53370a --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/PreferenceConverter.java @@ -0,0 +1,201 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.RGBColors; + +/** + * Utility for loading and saving GIS Viewer preferences + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class PreferenceConverter { + private PreferenceConverter() { + // unused, all methods are static + } + + /** + * Get an RGB color preference value. If no preference is stored, + * defaultValue will be returned + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param defaultValue + * the default value + * @return the RGB color + */ + public static RGB getRGB(IPreferenceStore prefs, String key, + String defaultValue) { + String value = prefs.getString(key); + RGB newColor = StringConverter.asRGB(value); + + if (newColor == null) { + newColor = StringConverter.asRGB(defaultValue); + } + return newColor; + } + + /** + * Store an RGB color preference value. + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param color + * the RGB color to be stored + */ + public static void setValue(IPreferenceStore prefs, String key, RGB color) { + String value = RGBColors.getColorName(color); + prefs.setValue(key, value); + } + + /** + * Get a LineStyle value. If no preference is stored, defaultValue will be + * returned + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param defaultValue + * the default value + * @return the LineStyle + */ + public static LineStyle getLineStyle(IPreferenceStore prefs, String key, + String defaultValue) { + String value = prefs.getString(key); + LineStyle style = StringConverter.asLineStyle(value); + + if (style == null) { + style = StringConverter.asLineStyle(defaultValue); + } + + return style; + } + + /** + * Store a LineStyle preference value. + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param opacity + * the LineStyle to be stored + */ + public static void setValue(IPreferenceStore prefs, String key, + LineStyle style) { + String value = style.name(); + prefs.setValue(key, value); + } + + /** + * Get an integer preference value. If no preference is stored, defaultValue + * will be returned + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param defaultValue + * the default value + * @return the integer value + */ + public static int getInt(IPreferenceStore prefs, String key, + String defaultValue) { + String stringValue = prefs.getString(key); + Integer value = StringConverter.asInteger(stringValue); + if (value == null) { + value = StringConverter.asInteger(defaultValue); + } + return value; + } + + /** + * Store an integer preference value. + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param value + * the integer value to be stored + */ + public static void setValue(IPreferenceStore prefs, String key, int value) { + String stringValue = StringConverter.asString(value); + prefs.setValue(key, stringValue); + } + + /** + * Get an float preference value. If no preference is stored, defaultValue + * will be returned + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param defaultValue + * the default value + * @return the float value + */ + public static float getFloat(IPreferenceStore prefs, String key, + String defaultValue) { + String stringValue = prefs.getString(key); + Float value = StringConverter.asFloat(stringValue); + if (value == null) { + value = StringConverter.asFloat(defaultValue); + } + return value; + } + + /** + * Store an float preference value. + * + * @param prefs + * the preference store + * @param key + * the preference key + * @param value + * the float value to be stored + */ + public static void setValue(IPreferenceStore prefs, String key, float value) { + String stringValue = StringConverter.asString(value); + prefs.setValue(key, stringValue); + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SelectAttributeDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SelectAttributeDialog.java new file mode 100644 index 0000000000..8ac0d18772 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SelectAttributeDialog.java @@ -0,0 +1,112 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.gisdatastore.rsc.DataStoreResource; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 13, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class SelectAttributeDialog extends CaveJFACEDialog { + + private DataStoreResource rsc; + + private String originalSampleAttribute; + + public SelectAttributeDialog(Shell parentShell, DataStoreResource rsc) { + super(parentShell); + this.rsc = rsc; + this.originalSampleAttribute = rsc.getSampleAttribute(); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Select Sample Attribute"); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite comp = (Composite) super.createDialogArea(parent); + + List attrList = new List(comp, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL + | SWT.H_SCROLL); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + attrList.setItems(rsc.getAttributeNames()); + if (attrList.getItemCount() > 20) { + layoutData.heightHint = attrList.getItemHeight() * 20; + } + attrList.setLayoutData(layoutData); + + if (originalSampleAttribute != null) { + attrList.setSelection(new String[] { originalSampleAttribute }); + } + attrList.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + List list = (List) e.widget; + String attr = list.getSelection()[0]; + rsc.setSampleAttribute(attr); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + List list = (List) e.widget; + String attr = list.getSelection()[0]; + rsc.setSampleAttribute(attr); + okPressed(); + } + }); + + return comp; + } + + @Override + protected void cancelPressed() { + rsc.setSampleAttribute(originalSampleAttribute); + super.cancelPressed(); + } + +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SortOrderDialog.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SortOrderDialog.java new file mode 100644 index 0000000000..182d113a0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/SortOrderDialog.java @@ -0,0 +1,234 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Shell; + +import com.raytheon.uf.common.dataplugin.gfe.type.Pair; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; + +/** + * Dialog to allow the user to define the sort order for the + * {@link AttributeViewer} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 29, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class SortOrderDialog extends CaveJFACEDialog { + private class SortField { + public static final int ASCENDING_VALUE = 1; + + public static final int DESCENDING_VALUE = -1; + + private static final String ASCENDING_TEXT = "Ascending"; + + private static final String DESCENDING_TEXT = "Descending"; + + private Group group; + + private Combo columnCombo; + + private Combo orderCombo; + + public SortField(Composite parent) { + group = new Group(parent, SWT.DEFAULT); + GridData layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, + false); + group.setLayoutData(layoutData); + GridLayout layout = new GridLayout(2, false); + group.setLayout(layout); + group.setText("Then by:"); + + columnCombo = new Combo(group, SWT.DROP_DOWN); + layoutData = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + columnCombo.setLayoutData(layoutData); + columnCombo.add("", 0); + columnCombo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + updateFields(); + } + }); + + orderCombo = new Combo(group, SWT.DROP_DOWN); + layoutData = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + orderCombo.setLayoutData(layoutData); + orderCombo.add(ASCENDING_TEXT); + orderCombo.add(DESCENDING_TEXT); + orderCombo.setText(orderCombo.getItem(0)); + } + + public void dispose() { + group.dispose(); + } + + public String getField() { + return columnCombo.getText(); + } + + public void setField(String field) { + this.columnCombo.setText(field); + } + + public int getOrder() { + return (orderCombo.getText().equals(ASCENDING_TEXT) ? ASCENDING_VALUE + : DESCENDING_VALUE); + } + + public void setOrder(int order) { + if (order > 0) { + orderCombo.setText(ASCENDING_TEXT); + } else if (order < 0) { + orderCombo.setText(DESCENDING_TEXT); + } + } + + public void setFields(List fields) { + String currentField = getField(); + columnCombo.removeAll(); + columnCombo.add(""); + for (String f : fields) { + columnCombo.add(f); + } + if (fields.contains(currentField)) { + columnCombo.setText(currentField); + } else { + columnCombo.setText(""); + } + } + + public void setLabel(String label) { + group.setText(label); + } + } + + private String[] columns; + + private List> initialOrder; + + private Composite mainComp; + + private List sortFields; + + protected SortOrderDialog(Shell parentShell, String[] columns, + List> order) { + super(parentShell); + this.columns = columns; + this.initialOrder = order; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Sort Order"); + } + + @Override + protected Control createDialogArea(Composite parent) { + mainComp = (Composite) super.createDialogArea(parent); + + this.sortFields = new ArrayList(); + for (Pair p : initialOrder) { + addField(p.getFirst(), p.getSecond()); + } + updateFields(); + + return mainComp; + } + + private SortField addField(String field, int order) { + SortField newField = new SortField(mainComp); + newField.setField(field); + newField.setOrder(order); + sortFields.add(newField); + return newField; + } + + private void removeField(SortField field) { + sortFields.remove(field); + field.dispose(); + } + + private void updateFields() { + List availableFields = new ArrayList( + Arrays.asList(columns)); + for (int i = 0; i < sortFields.size(); i++) { + SortField sf = sortFields.get(i); + sf.setFields(availableFields); + String s = sf.getField(); + if (s.isEmpty()) { + if (i < sortFields.size() - 1) { + removeField(sf); + i--; + } + } else { + availableFields.remove(s); + } + } + + if (sortFields.isEmpty() + || !sortFields.get(sortFields.size() - 1).getField().isEmpty()) { + SortField sf = addField("", SortField.ASCENDING_VALUE); + sf.setFields(availableFields); + } + + sortFields.get(0).setLabel("Sort by:"); + + mainComp.getShell().pack(); + } + + public List> getSortOrder() { + List> sortOrder = new ArrayList>(); + for (SortField sf : sortFields) { + if (sf.getField().isEmpty()) { + continue; + } + sortOrder.add(new Pair(sf.getField(), sf + .getOrder())); + } + + return sortOrder; + } +} diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/StringConverter.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/StringConverter.java new file mode 100644 index 0000000000..d9bf269a24 --- /dev/null +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/ui/StringConverter.java @@ -0,0 +1,163 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.gisdatastore.ui; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.RGBColors; + +/** + * Convert GIS Viewer preference types to/from strings + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 27, 2012            randerso     Initial creation
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ + +public class StringConverter { + private StringConverter() { + // unused, all methods are static + } + + /** + * Convert RGB color value to string + * + * @param color + * RGB color value + * @return string String value + */ + public static String asString(RGB color) { + return RGBColors.getColorName(color); + } + + /** + * Convert string to RGB color value + * + * @param string + * String value + * @return RGB color value or null if string is not a valid RGB color name + * or hex value of the form "#rrggbb" + */ + public static RGB asRGB(String string) { + RGB rgb = RGBColors.getRGBColor(string); + return rgb; + } + + /** + * Convert LineStyle value to string + * + * @param opacity + * LineStyle value + * @return string String value + */ + public static String asString(LineStyle style) { + return style.name(); + } + + /** + * Convert string to LineStyle value + * + * @param string + * String value + * @return LineStyle value or null if string is not a valid LineStyle name + */ + public static LineStyle asLineStyle(String string) { + LineStyle style = null; + + try { + style = LineStyle.valueOf(string); + } catch (Exception e) { + style = null; + } + + return style; + } + + /** + * Convert integer value to string + * + * @param value + * integer value + * @return string String value + */ + public static String asString(int value) { + return Integer.toString(value); + } + + /** + * Convert string to Integer value + * + * @param string + * String Value + * @return Integer value or null if string is not a valid integer + * representation + */ + public static Integer asInteger(String string) { + Integer value = null; + + try { + value = Integer.parseInt(string); + } catch (Exception e) { + value = null; + } + + return value; + } + + /** + * Convert float value to string + * + * @param value + * float value + * @return string String value + */ + public static String asString(float value) { + return Float.toString(value); + } + + /** + * Convert string to Float value + * + * @param string + * String Value + * @return Float value or null if string is not a valid float representation + */ + public static Float asFloat(String string) { + Float value = null; + + try { + value = Float.parseFloat(string); + } catch (Exception e) { + value = null; + } + + return value; + } +}