From a0124cefb3c9853857a8083e51cc22093e01e7a5 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 18 Sep 2014 14:04:53 -0400 Subject: [PATCH 01/19] VLab Issue #4643 - Add NCP Configurable (Power) Legend capability Change-Id: If8e83f89ef655efc96173dd12c9bb6e0fd756b84 Former-commit-id: 47487d185a21965d3c5afaf49efd32cc061850ec [formerly 47487d185a21965d3c5afaf49efd32cc061850ec [formerly a7bdbb3edfc024c3812ff4531560ce4954d070ac]] Former-commit-id: 28fd9285ff247b9bc80a22c5b0e54ce1d3037285 Former-commit-id: a59af6845f4e01c22c3d4b85d0d8715276dce60a --- .../ncep/viz/common/display/IPowerLegend.java | 38 + .../ui/createRbd/CreateRbdControl.java | 830 +++++++++++++++++- .../ui/loadRbd/RbdViewComposite.java | 324 +++---- .../META-INF/MANIFEST.MF | 1 + .../plugin.xml | 10 + .../groupresource/GroupResource.java | 172 ++++ .../groupresource/GroupResourceData.java | 183 ++++ .../resources/groupresource/package-info.java | 37 + .../resources/manager/ResourceBndlLoader.java | 7 + .../resources/manager/ResourceCategory.java | 4 + .../manager/RscBundleDisplayMngr.java | 145 ++- .../viz/resources/misc/NCMoveDownAction.java | 82 ++ .../viz/resources/misc/NCMoveUpAction.java | 70 ++ .../viz/tools/hotKeys/NCHotKeyHandler.java | 72 +- .../viz/tools/wipe/WipeResultsAction.java | 5 +- .../ncep/viz/ui/display/NCLegendHandler.java | 236 ++++- .../ncep/viz/ui/display/NCLegendResource.java | 459 +++++++++- .../ncep/viz/ui/display/NCMapDescriptor.java | 11 +- .../ncep/viz/ui/display/NcDisplayMngr.java | 25 + 19 files changed, 2413 insertions(+), 298 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/IPowerLegend.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/GroupResource.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/GroupResourceData.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/package-info.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveDownAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveUpAction.java diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/IPowerLegend.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/IPowerLegend.java new file mode 100644 index 0000000000..40191595a1 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/IPowerLegend.java @@ -0,0 +1,38 @@ +/* + * IPowerLegend + * + * Date created: 03 AUGUST 2014 + * + * This code has been developed by the NCEP/SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.viz.common.display; + +import com.raytheon.uf.viz.core.rsc.IResourceGroup; + +/** + * Interface for group resource, which can be expanded in the legend. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 08/14        ?           B. Yin  Initial Creation.
+ * 
+ * 
+ * + * @author byin + * + */ + +public interface IPowerLegend extends IResourceGroup { + + public int getFuncKeyNum(); + + public boolean isNameExpanded(); + + public void setNameExpanded(boolean flag); + + public void setVisibleForAllResources(boolean visible); + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java index 5a8e9bc26f..a66c11e867 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java @@ -10,6 +10,8 @@ import gov.noaa.nws.ncep.viz.common.display.INcPaneID; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; +import gov.noaa.nws.ncep.viz.common.ui.color.GempakColor; import gov.noaa.nws.ncep.viz.resourceManager.timeline.GraphTimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl.IDominantResourceChangedListener; @@ -17,6 +19,7 @@ import gov.noaa.nws.ncep.viz.resourceManager.ui.createRbd.ResourceSelectionContr import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; import gov.noaa.nws.ncep.viz.resources.attributes.EditResourceAttrsAction; +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResourceData; import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; import gov.noaa.nws.ncep.viz.resources.manager.NcMapRBD; import gov.noaa.nws.ncep.viz.resources.manager.ResourceBndlLoader; @@ -34,6 +37,8 @@ import gov.noaa.nws.ncep.viz.ui.display.NcPaneLayout; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.EventObject; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -45,12 +50,24 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerEditor; +import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -58,6 +75,9 @@ import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Device; @@ -81,6 +101,7 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; @@ -89,6 +110,8 @@ import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.viz.ui.UiPlugin; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -142,6 +165,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 05/07/2014 TTR991 D. Sushon if a different NCP editor is selected, the CreateRDB tab should now adjust. * 05/29/2014 #1131 qzhou Added NcDisplayType * Modified creating new timelineControl in const and updateGUI + * 08/14/2014 ? B. Yin Added power legend (resource group) support. + * 09/092014 ? B. Yin Fixed NumPad enter issue and the "ResetToDefault" issue for groups. * * * @author ghull @@ -179,6 +204,22 @@ public class CreateRbdControl extends Composite implements IPartListener2 { private ListViewer seld_rscs_lviewer = null; + private TableViewer groupListViewer; + + private Text nameTxt; + + private Button delGrpBtn; + + private Composite grpColorComp; + + private ColorButtonSelector grpColorBtn; + + private Button grpMoveUpBtn; + + private Button grpMoveDownBtn; + + private int curGrp = -1; + private Button replace_rsc_btn = null; private Button edit_rsc_btn = null; @@ -217,6 +258,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { private Group pane_layout_grp = null; + private Group groupGrp = null; + private Button pane_sel_btns[][] = null; private Button import_pane_btn = null; @@ -263,12 +306,16 @@ public class CreateRbdControl extends Composite implements IPartListener2 { private Group timeline_grp; + private int grpColor = 1; + // private final String[] StandardZoomLevels = {"1", // "1.5","2","3","5","7.5","10","15","20","30"}; private static Map gempakProjMap = GempakProjectionValuesUtil .initializeProjectionNameMap(); + private static String ungrpStr = "Ungrouped"; + // the rbdMngr will be used to set the gui so it should either be // initialized/cleared or set with the initial RBD. public CreateRbdControl(Composite parent, RscBundleDisplayMngr mngr) @@ -505,10 +552,10 @@ public class CreateRbdControl extends Composite implements IPartListener2 { disp_type_lbl.setLayoutData(form_data); multi_pane_tog = new Button(rbd_grp, SWT.CHECK); - multi_pane_tog.setText("Multi-Pane Display"); + multi_pane_tog.setText("Multi-Pane"); form_data = new FormData(); form_data.top = new FormAttachment(rbd_name_txt, -10, SWT.TOP); - form_data.left = new FormAttachment(rbd_name_txt, 35, SWT.RIGHT); + form_data.left = new FormAttachment(rbd_name_txt, 15, SWT.RIGHT); multi_pane_tog.setLayoutData(form_data); auto_update_btn = new Button(rbd_grp, SWT.CHECK); @@ -532,6 +579,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { seld_rscs_grp = createSeldRscsGroup(); createPaneLayoutGroup(); + + createGroupGrp(); } private void createAreaGroup() { @@ -542,7 +591,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { form_data.top = new FormAttachment(disp_type_combo, 25, SWT.BOTTOM); // form_data.bottom = new FormAttachment( 100, -60 ); // if offset for // room for the Load and Save buttons - form_data.bottom = new FormAttachment(100, -10); + form_data.bottom = new FormAttachment(100, 0); form_data.left = new FormAttachment(0, 10); form_data.right = new FormAttachment(24, 0); @@ -698,8 +747,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { // form_data.top = new FormAttachment( rbd_name_txt, 25, SWT.BOTTOM ); form_data.top = new FormAttachment(auto_update_btn, 15, SWT.BOTTOM); form_data.left = new FormAttachment(geo_area_grp, 10, SWT.RIGHT); - form_data.right = new FormAttachment(100, -10); - form_data.bottom = new FormAttachment(geo_area_grp, 0, SWT.BOTTOM); + form_data.right = new FormAttachment(100, -300); + form_data.bottom = new FormAttachment(100, 0); seld_rscs_grp.setLayoutData(form_data); // This is multi-select to make Deleting resources easier. @@ -797,11 +846,492 @@ public class CreateRbdControl extends Composite implements IPartListener2 { edit_span_btn.setLayoutData(form_data); edit_span_btn.setEnabled(false); - seld_rscs_grp.pack(true); + // seld_rscs_grp.pack(true); return seld_rscs_grp; } + private void createGroupGrp() { + groupGrp = new Group(rbd_grp, SWT.SHADOW_NONE); + groupGrp.setText("Resource Group"); + + FormData fd = new FormData(); + fd.left = new FormAttachment(seld_rscs_grp, 10, SWT.RIGHT); + fd.top = new FormAttachment(0, 3); + fd.right = new FormAttachment(100, 0); + fd.bottom = new FormAttachment(100, 0); + groupGrp.setLayoutData(fd); + + groupGrp.setLayout(new FormLayout()); + + Label nameLbl = new Label(groupGrp, SWT.NONE); + nameLbl.setText("Name:"); + fd = new FormData(); + fd.left = new FormAttachment(0, 5); + fd.top = new FormAttachment(0, 5); + nameLbl.setLayoutData(fd); + + nameTxt = new Text(groupGrp, SWT.SINGLE | SWT.BORDER); + fd = new FormData(200, 20); + fd.left = new FormAttachment(nameLbl, 5, SWT.RIGHT); + fd.right = new FormAttachment(100, -40); + fd.top = new FormAttachment(nameLbl, -5, SWT.TOP); + nameTxt.setLayoutData(fd); + + nameTxt.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent ke) { + Text txt = (Text) ke.widget; + if ((ke.keyCode == SWT.CR || ke.keyCode == SWT.KEYPAD_CR) && !txt.getText().isEmpty()) { + + if (txt.getText().equalsIgnoreCase(ungrpStr)) { + curGrp = -1; + selectUngroupedGrp(); + seld_rscs_lviewer.setInput(rbdMngr + .getUngroupedResources()); + setGroupButtons(); + return; + } + + int ii = 0; + + for (ResourceSelection rsel : rbdMngr.getGroupResources()) { + if (rsel.getResourceData() instanceof GroupResourceData) { + if (((GroupResourceData) rsel.getResourceData()) + .getGroupName().equalsIgnoreCase( + txt.getText())) { + + groupListViewer.getTable().setSelection(ii); + curGrp = groupListViewer.getTable() + .getSelectionIndex(); + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer + .getTable().getSelection().length == 0 ? null + : groupListViewer.getTable() + .getSelection()[0] + .getText())); + setGroupButtons(); + + return; + + } + } + ii++; + } + + // groupListViewer.setSelection(selection) + + // Change group name + // ResourceSelection sel = getGroupResourceSelection(); + // if (sel != null) { + // ((GroupResourceData) sel.getResourceData()) + // .setGroupName(txt.getText()); + // groupListViewer.setInput(rbdMngr.getGroupResources()); + // groupListViewer.refresh(); + // groupListViewer.getTable().setSelection(curGrp); + // } else { + addResourceGroup(txt.getText()); + setGroupButtons(); + txt.setText(""); + // } + } + } + }); + + groupListViewer = new TableViewer(groupGrp, SWT.SINGLE | SWT.V_SCROLL + | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); + fd = new FormData(); + fd.top = new FormAttachment(nameLbl, 15, SWT.BOTTOM); + fd.bottom = new FormAttachment(100, -5); + fd.left = new FormAttachment(0, 5); + fd.right = new FormAttachment(100, -40); + + groupListViewer.getTable().setLayoutData(fd); + + groupListViewer.setContentProvider(new IStructuredContentProvider() { + + @Override + public Object[] getElements(Object inputElement) { + + // Add "Ungrouped" group + ResourcePair group = new ResourcePair(); + + GroupResourceData grd = new GroupResourceData(ungrpStr, 0, + grpColorBtn.getColorValue()); + group.setResourceData(grd); + + ResourceSelection ungrouped = null; + try { + ungrouped = ResourceFactory.createResource(group); + } catch (VizException e) { + } + + ResourceSelection[] groups = (ResourceSelection[]) inputElement; + + ResourceSelection[] groups1; + + if (ungrouped != null) { + if (groups != null) { + List list = new ArrayList( + Arrays.asList(groups)); + list.add(ungrouped); + groups1 = (ResourceSelection[]) list + .toArray(new ResourceSelection[list.size()]); + } else { + groups1 = new ResourceSelection[] { ungrouped }; + } + } else { + groups1 = groups; + } + + return groups1; + + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + }); + + groupListViewer.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + ResourceSelection rscSel = (ResourceSelection) element; + if (rscSel.getResourceData() instanceof GroupResourceData) { + return ((GroupResourceData) rscSel.getResourceData()) + .getGroupName(); + } else { + return "No Group Name"; + } + } + }); + + // enable/disable the Edit/Delete/Clear buttons... + groupListViewer + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + // System.out.println("table changed"); + + } + }); + + groupListViewer.getTable().addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + // System.out.println("Current grp XXXXXXXXXXXXXX: " + curGrp); + + curGrp = groupListViewer.getTable().getSelectionIndex(); + if (groupListViewer.getTable().getSelection()[0].getText() + .equalsIgnoreCase(ungrpStr)) { + curGrp = -1; + seld_rscs_lviewer.setInput(rbdMngr.getUngroupedResources()); + } else { + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer.getTable() + .getSelection().length == 0 ? null + : groupListViewer.getTable().getSelection()[0] + .getText())); + } + + setGroupButtons(); + + // System.out.println("Group: " + // + groupListViewer.getList().getSelection()[0]); + + } + }); + + /* + * TableViewerColumn columnViewer = new + * TableViewerColumn(groupListViewer, SWT.NONE); + * columnViewer.setLabelProvider(new CellLabelProvider() { + * + * @Override public void update(ViewerCell cell) { ResourceSelection + * rsel = (ResourceSelection) cell.getElement(); + * cell.setText(((GroupResourceData) rsel.getResourceData()) + * .getGroupName()); } }); + * + * columnViewer.getColumn().pack(); + * + * columnViewer.setEditingSupport(new EditingSupport(groupListViewer) { + * + * @Override protected void setValue(Object element, Object value) { // + * ((Element) element).setValue((String) value); ResourceSelection rsel + * = (ResourceSelection) element; + * + * ((GroupResourceData) rsel.getResourceData()) .setGroupName((String) + * value); groupListViewer.refresh(); } + * + * @Override protected Object getValue(Object element) { + * ResourceSelection rsel = (ResourceSelection) element; return + * ((GroupResourceData) rsel.getResourceData()) .getGroupName(); } + * + * @Override protected CellEditor getCellEditor(Object element) { return + * new TextCellEditor(groupListViewer.getTable()); } + * + * @Override protected boolean canEdit(Object element) { return true; } + * }); + * + * TableViewerFocusCellManager focusCellManager = new + * TableViewerFocusCellManager( groupListViewer, new + * FocusCellOwnerDrawHighlighter( groupListViewer)); + * + * ColumnViewerEditorActivationStrategy activationSupport = new + * ColumnViewerEditorActivationStrategy( groupListViewer) { protected + * boolean isEditorActivationEvent( ColumnViewerEditorActivationEvent + * event) { // Enable editor // only with // mouse double // click if + * (event.eventType == + * ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION) { + * EventObject source = event.sourceEvent; if (source instanceof + * MouseEvent && ((MouseEvent) source).button == 3) return false; + * + * return true; } + * + * return false; } }; + * + * TableViewerEditor.create(groupListViewer, focusCellManager, + * activationSupport, ColumnViewerEditor.TABBING_HORIZONTAL | + * ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | + * ColumnViewerEditor.TABBING_VERTICAL | + * ColumnViewerEditor.KEYBOARD_ACTIVATION); + */ + + groupListViewer.setColumnProperties(new String[] { "Group Name" }); + + groupListViewer.setCellModifier(new ICellModifier() { + + @Override + public boolean canModify(Object element, String property) { + // TODO Auto-generated method stub + return true; + } + + @Override + public Object getValue(Object element, String property) { + + ResourceSelection sel = (ResourceSelection) element; + return ((GroupResourceData) sel.getResourceData()) + .getGroupName(); + } + + @Override + public void modify(Object element, String property, Object value) { + + if (value != null && !((String) value).isEmpty()) { + ResourceSelection sel = (ResourceSelection) ((TableItem) element) + .getData(); + ((GroupResourceData) sel.getResourceData()) + .setGroupName((String) value); + groupListViewer.refresh(); + } + } + + }); + + groupListViewer.setCellEditors(new CellEditor[] { new TextCellEditor( + groupListViewer.getTable()) }); + + ColumnViewerEditorActivationStrategy activationSupport = new ColumnViewerEditorActivationStrategy( + groupListViewer) { + protected boolean isEditorActivationEvent( + ColumnViewerEditorActivationEvent event) { // Enable editor + // only with + // mouse double + // click + if (event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION) { + EventObject source = event.sourceEvent; + if (source instanceof MouseEvent + && ((MouseEvent) source).button == 3) + return false; + if (((GroupResourceData) ((ResourceSelection) ((org.eclipse.jface.viewers.ViewerCell) event + .getSource()).getElement()).getResourcePair() + .getResourceData()).getGroupName() + .equalsIgnoreCase(ungrpStr)) { + return false; + } + + return true; + } + + return false; + } + }; + + TableViewerEditor.create(groupListViewer, activationSupport, + ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR + | ColumnViewerEditor.TABBING_VERTICAL + | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + groupListViewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + + TableViewer tv = (TableViewer) event.getSource(); + + tv.setSelection(event.getSelection()); + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer.getTable() + .getSelection().length == 0 ? null + : groupListViewer.getTable().getSelection()[0] + .getText())); + + curGrp = groupListViewer.getTable().getSelectionIndex(); + + if (groupListViewer.getTable().getSelection()[0].getText() + .equalsIgnoreCase(ungrpStr)) { + selectUngroupedGrp(); + seld_rscs_lviewer.setInput(rbdMngr.getUngroupedResources()); + curGrp = -1; + } + + setGroupButtons(); + } + + }); + + groupListViewer.getTable().addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + org.eclipse.swt.widgets.Table grpList = (org.eclipse.swt.widgets.Table) event.widget; + + if (grpList.getItemCount() > 0) { + + if (event.y > grpList.getItemCount() + * grpList.getItemHeight()) { + grpList.deselectAll(); + curGrp = -1; + + selectUngroupedGrp(); + + seld_rscs_lviewer.setInput(rbdMngr + .getUngroupedResources()); + setGroupButtons(); + + nameTxt.setText(""); + } + } + } + }); + + grpMoveUpBtn = new Button(groupGrp, SWT.ARROW | SWT.UP); + grpMoveUpBtn.setToolTipText("Move Up"); + fd = new FormData(); + fd.width = 30; + fd.top = new FormAttachment(50, -70); + fd.left = new FormAttachment(groupListViewer.getTable(), 5, SWT.RIGHT); + grpMoveUpBtn.setLayoutData(fd); + grpMoveUpBtn.setEnabled(true); + grpMoveUpBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + StructuredSelection isel = ((StructuredSelection) groupListViewer + .getSelection()); + ResourceSelection sel = (ResourceSelection) isel + .getFirstElement(); + if (sel != null) { + rbdMngr.moveUpGrp(sel.getResourcePair()); + groupListViewer.setInput(rbdMngr.getGroupResources()); + groupListViewer.refresh(); + groupListViewer.setSelection(isel); + curGrp = groupListViewer.getTable().getSelectionIndex(); + setGroupButtons(); + } + } + }); + + grpMoveDownBtn = new Button(groupGrp, SWT.ARROW | SWT.DOWN); + grpMoveDownBtn.setToolTipText("Move Down"); + fd = new FormData(); + fd.width = 30; + fd.top = new FormAttachment(grpMoveUpBtn, 10, SWT.BOTTOM); + fd.left = new FormAttachment(groupListViewer.getTable(), 5, SWT.RIGHT); + grpMoveDownBtn.setLayoutData(fd); + grpMoveDownBtn.setEnabled(true); + grpMoveDownBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + StructuredSelection isel = ((StructuredSelection) groupListViewer + .getSelection()); + ResourceSelection sel = (ResourceSelection) isel + .getFirstElement(); + if (sel != null) { + rbdMngr.moveDownGrp(sel.getResourcePair()); + groupListViewer.setInput(rbdMngr.getGroupResources()); + groupListViewer.setSelection(isel); + + groupListViewer.refresh(); + curGrp = groupListViewer.getTable().getSelectionIndex(); + setGroupButtons(); + } + } + }); + delGrpBtn = new Button(groupGrp, SWT.PUSH); + delGrpBtn.setText("X"); + delGrpBtn.setToolTipText("Remove"); + fd = new FormData(); + fd.width = 30; + fd.top = new FormAttachment(grpMoveDownBtn, 10, SWT.BOTTOM); + fd.left = new FormAttachment(groupListViewer.getTable(), 5, SWT.RIGHT); + delGrpBtn.setLayoutData(fd); + delGrpBtn.setEnabled(true); + delGrpBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + ResourceSelection sel = (ResourceSelection) ((StructuredSelection) groupListViewer + .getSelection()).getFirstElement(); + if (sel != null) { + rbdMngr.removeSelectedResource(sel); + groupListViewer.setInput(rbdMngr.getGroupResources()); + groupListViewer.refresh(); + selectUngroupedGrp(); + seld_rscs_lviewer.setInput(rbdMngr.getUngroupedResources()); + setGroupButtons(); + curGrp = -1; + + } else { + } + } + }); + + grpColorComp = new Composite(groupGrp, SWT.NONE); + grpColorComp.setLayout(new FormLayout()); + grpColorComp.setToolTipText("Legend Color"); + grpColorBtn = new ColorButtonSelector(grpColorComp, 28, 22); + // grpColorBtn.setColorValue(new RGB(0, 255, 0)); + grpColorBtn.setColorValue(GempakColor.convertToRGB(1)); + + fd = new FormData(); + fd.width = 30; + fd.top = new FormAttachment(delGrpBtn, 10, SWT.BOTTOM); + fd.left = new FormAttachment(groupListViewer.getTable(), 6, SWT.RIGHT); + grpColorComp.setLayoutData(fd); + grpColorComp.pack(); + + grpColorBtn.addListener(new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + ResourceSelection sel = getGroupResourceSelection(); + if (sel != null) { + + ((GroupResourceData) sel.getResourceData()) + .setLegendColor(grpColorBtn.getColorValue()); + } + } + }); + + groupListViewer.setInput(rbdMngr.getGroupResources()); + + groupListViewer.refresh(true); + + selectUngroupedGrp(); + + setGroupButtons(); + + groupGrp.pack(); + groupGrp.setVisible(true); + } + private void createPaneLayoutGroup() { pane_layout_grp = new Group(rbd_grp, SWT.SHADOW_NONE); pane_layout_grp.setText("Pane Layout"); @@ -809,8 +1339,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { FormData fd = new FormData(); fd.left = new FormAttachment(seld_rscs_grp, 10, SWT.RIGHT); fd.top = new FormAttachment(0, 3); - fd.right = new FormAttachment(100, -10); - fd.bottom = new FormAttachment(100, -15); + fd.right = new FormAttachment(100, 0); + fd.bottom = new FormAttachment(100, 0); pane_layout_grp.setLayoutData(fd); Composite num_rows_cols_comp = new Composite(pane_layout_grp, SWT.NONE); @@ -821,7 +1351,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { num_rows_cols_comp.setLayout(gl); fd = new FormData(); - fd.left = new FormAttachment(0, 80); + fd.left = new FormAttachment(0, 100); fd.top = new FormAttachment(0, 3); fd.right = new FormAttachment(100, -10); num_rows_cols_comp.setLayoutData(fd); @@ -884,7 +1414,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { sel_pane_lbl.setText("Select Pane"); fd = new FormData(); fd.left = new FormAttachment(0, 5); - fd.top = new FormAttachment(num_rows_cols_comp, 8, SWT.BOTTOM); + fd.top = new FormAttachment(num_rows_cols_comp, 2, SWT.BOTTOM); sel_pane_lbl.setLayoutData(fd); Label sep = new Label(pane_layout_grp, SWT.SEPARATOR | SWT.HORIZONTAL); @@ -931,9 +1461,9 @@ public class CreateRbdControl extends Composite implements IPartListener2 { import_pane_btn = new Button(pane_layout_grp, SWT.PUSH); fd = new FormData(); fd.top = new FormAttachment(pane_sel_comp, 10, SWT.BOTTOM); - fd.left = new FormAttachment(0, 10); + fd.left = new FormAttachment(50, -120); import_pane_btn.setLayoutData(fd); - import_pane_btn.setText(" Import... "); + import_pane_btn.setText("Import..."); import_pane_btn.setEnabled(true); load_pane_btn = new Button(pane_layout_grp, SWT.PUSH); @@ -941,14 +1471,14 @@ public class CreateRbdControl extends Composite implements IPartListener2 { fd.top = new FormAttachment(import_pane_btn, 0, SWT.TOP); fd.left = new FormAttachment(50, -38); load_pane_btn.setLayoutData(fd); - load_pane_btn.setText(" Re-Load "); + load_pane_btn.setText(" Re-Load "); clr_pane_btn = new Button(pane_layout_grp, SWT.PUSH); - clr_pane_btn.setText(" Clear "); + clr_pane_btn.setText(" Clear "); fd = new FormData(); // fd.width = 75; fd.top = new FormAttachment(import_pane_btn, 0, SWT.TOP); - fd.right = new FormAttachment(100, -10); + fd.left = new FormAttachment(50, 50); clr_pane_btn.setLayoutData(fd); pane_layout_grp.setVisible(false); @@ -1126,8 +1656,37 @@ public class CreateRbdControl extends Composite implements IPartListener2 { ResourceSelection rscSel = (ResourceSelection) sel_elems .getFirstElement(); - if (!rbdMngr.replaceSelectedResource(rscSel, rbt)) { - // return; + StructuredSelection grp = (StructuredSelection) groupListViewer + .getSelection(); + + ResourceSelection sel = (ResourceSelection) grp + .getFirstElement(); + + if (sel != null + && ((GroupResourceData) sel.getResourcePair() + .getResourceData()).getGroupName() + .equalsIgnoreCase(ungrpStr)) { + sel = null; + } + + if (sel == null) { + if (!rbdMngr.replaceSelectedResource(rscSel, rbt)) { + // return; + } + } else { + ((GroupResourceData) sel.getResourceData()) + .replaceResourcePair( + rscSel.getResourcePair(), + rbt.getResourcePair()); + + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer + .getTable().getSelection().length == 0 ? null + : groupListViewer.getTable() + .getSelection()[0] + .getText())); + + seld_rscs_lviewer.refresh(true); } // remove this from the list of available dominant @@ -1158,11 +1717,40 @@ public class CreateRbdControl extends Composite implements IPartListener2 { } return; } - } else if (!rbdMngr.addSelectedResource(rbt)) { - if (done) { - rscSelDlg.close(); + } else { + + StructuredSelection grp = (StructuredSelection) groupListViewer + .getSelection(); + + ResourceSelection sel = (ResourceSelection) grp + .getFirstElement(); + + if (sel != null + && ((GroupResourceData) sel + .getResourcePair() + .getResourceData()).getGroupName() + .equalsIgnoreCase(ungrpStr)) { + sel = null; + } + + if (!rbdMngr.addSelectedResource(rbt, sel)) { + if (sel != null) { + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer + .getTable().getSelection().length == 0 ? null + : groupListViewer + .getTable() + .getSelection()[0] + .getText())); + + seld_rscs_lviewer.refresh(true); + } + + if (done) { + rscSelDlg.close(); + } + return; } - return; } } @@ -1930,16 +2518,44 @@ public class CreateRbdControl extends Composite implements IPartListener2 { // set the list of available resources for the timeline for (int paneIndx = 0; paneIndx < paneLayout.getNumberOfPanes(); paneIndx++) { + + // only add resources in current group + // yin if (curGrp >= 1000) { // may use later + // ResourceSelection sel = getGroupResourceSelection(); + + // if (sel != null) { + // for (ResourcePair pair : ((GroupResourceData) sel + // .getResourceData()).getResourceList()) { + // if (pair.getResourceData() instanceof + // AbstractNatlCntrsRequestableResourceData) { + // timelineControl + // .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) + // pair + // .getResourceData()); + // } + // } + // } + // } else { for (ResourceSelection rscSel : rbdMngr .getRscsForPane((NcPaneID) paneLayout .createPaneId(paneIndx))) { - if (rscSel.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { + if (rscSel.getResourceData() instanceof GroupResourceData) { + for (ResourcePair pair : ((GroupResourceData) rscSel + .getResourceData()).getResourceList()) { + if (pair.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { + timelineControl + .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) pair + .getResourceData()); + } + } + } else if (rscSel.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { timelineControl .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) rscSel .getResourceData()); } } + // } } NCTimeMatcher timeMatcher = rbdMngr.getInitialTimeMatcher(); @@ -2004,7 +2620,15 @@ public class CreateRbdControl extends Composite implements IPartListener2 { } public void removeSelectedResource(ResourceSelection rscSel) { - rbdMngr.removeSelectedResource(rscSel); + if (groupListViewer.getSelection() == null + || groupListViewer.getSelection().isEmpty() + || groupListViewer.getTable().getSelection()[0].getText() + .equalsIgnoreCase(ungrpStr)) { + rbdMngr.removeSelectedResource(rscSel); + } else { // remove from group + ((GroupResourceData) getGroupResourceSelection().getResourceData()) + .getResourceList().remove(rscSel.getResourcePair()); + } // remove this from the list of available dominant resources. if (rscSel.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { @@ -2101,6 +2725,13 @@ public class CreateRbdControl extends Composite implements IPartListener2 { } updateGUI(); + + curGrp = -1; + groupListViewer.setInput(rbdMngr.getGroupResources()); + seld_rscs_lviewer.setInput(rbdMngr.getUngroupedResources()); + seld_rscs_lviewer.refresh(); + setGroupButtons(); + } // reset the ListViewer's input and update all of the buttons @@ -2114,7 +2745,17 @@ public class CreateRbdControl extends Composite implements IPartListener2 { List origSeldRscsList = (List) orig_sel_elems .toList(); - seld_rscs_lviewer.setInput(rbdMngr.getSelectedRscs()); + if (groupListViewer.getSelection().isEmpty() + || groupListViewer.getTable().getSelection()[0].getText() + .equalsIgnoreCase(ungrpStr)) { + seld_rscs_lviewer.setInput(rbdMngr.getUngroupedResources()); + } else { + seld_rscs_lviewer.setInput(rbdMngr + .getResourcesInGroup(groupListViewer.getTable() + .getSelection().length == 0 ? null + : groupListViewer.getTable().getSelection()[0] + .getText())); + } seld_rscs_lviewer.refresh(true); List newSeldRscsList = new ArrayList(); @@ -2330,6 +2971,36 @@ public class CreateRbdControl extends Composite implements IPartListener2 { NcDisplayMngr.bringToTop(editor); + // Assign hot keys to group resources. + // Set visible for the selected group. + ResourceSelection rsel = getGroupResourceSelection(); + + for (AbstractRenderableDisplay rendDisp : rbdBndl.getDisplays()) { + int funKey = 1; + for (ResourcePair rp : rendDisp.getDescriptor() + .getResourceList()) { + if (rp.getResourceData() instanceof GroupResourceData) { + + GroupResourceData grd = (GroupResourceData) rp + .getResourceData(); + + grd.setFuncKeyNum(funKey); + funKey++; + + // If nothing selected, turn on all groups. + rp.getProperties().setVisible(true); + + if (rsel != null + && !((GroupResourceData) rsel.getResourcePair() + .getResourceData()).getGroupName() + .equals(grd.getGroupName())) { + rp.getProperties().setVisible(false); + } + + } + } + } + rbdLoader.addRBD(rbdBndl, editor); VizApp.runSync(rbdLoader); @@ -2521,6 +3192,19 @@ public class CreateRbdControl extends Composite implements IPartListener2 { try { rbdMngr.initFromRbdBundle(impRbd); + + groupListViewer.setInput(rbdMngr.getGroupResources()); + // the new group is always added at the top. + if (curGrp != -1) { + groupListViewer.getTable().setSelection(curGrp); + groupListViewer.refresh(); + + // seld_rscs_lviewer.setInput(null); + // seld_rscs_lviewer.refresh(); + } else { + this.selectUngroupedGrp(); + } + } catch (VizException e) { rbdMngr.init(curDispType); @@ -2603,7 +3287,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { updateSelectedResourcesView(true); } - public void updateGUIforMultipane(boolean isMultiPane) { + private void updateGUIforMultipane(boolean isMultiPane) { FormData fd = new FormData(); geo_sync_panes.setVisible(isMultiPane); @@ -2611,25 +3295,30 @@ public class CreateRbdControl extends Composite implements IPartListener2 { pane_layout_grp.setVisible(isMultiPane); if (isMultiPane) { + groupGrp.setVisible(false); + fd.left = new FormAttachment(geo_area_grp, 10, SWT.RIGHT); // fd.left = new FormAttachment( 30, 2 ); // fd.top = new FormAttachment( geo_area_grp, 0, SWT.TOP ); fd.top = new FormAttachment(geo_sync_panes, 10, SWT.BOTTOM); fd.bottom = new FormAttachment(geo_area_grp, 0, SWT.BOTTOM); fd.right = new FormAttachment(100, -300); + seld_rscs_grp.setLayoutData(fd); shell.setSize(new Point(multiPaneDlgWidth, shell.getSize().y)); } else { + groupGrp.setVisible(true); + fd.left = new FormAttachment(geo_area_grp, 10, SWT.RIGHT); // fd.left = new FormAttachment( 30, 2 ); // fd.top = new FormAttachment( geo_area_grp, 0, SWT.TOP ); fd.top = new FormAttachment(auto_update_btn, 5, SWT.BOTTOM); fd.right = new FormAttachment(100, -10); fd.bottom = new FormAttachment(geo_area_grp, 0, SWT.BOTTOM); - seld_rscs_grp.setLayoutData(fd); + // seld_rscs_grp.setLayoutData(fd); - shell.setSize(new Point(singlePaneDlgWidth, shell.getSize().y)); + shell.setSize(new Point(multiPaneDlgWidth - 10, shell.getSize().y)); } // the area name may be truncated based on a shorter toolbar widget @@ -2831,6 +3520,93 @@ public class CreateRbdControl extends Composite implements IPartListener2 { } + private void addResourceGroup(String name) { + ResourcePair group = new ResourcePair(); + + // Add group, the default hot key is F1 and will be re-assigned at + // the time all groups are loaded. + grpColorBtn.setColorValue(GempakColor.convertToRGB(grpColor++)); + + GroupResourceData grd = new GroupResourceData(name, 1, + grpColorBtn.getColorValue()); + group.setResourceData(grd); + try { + ResourceSelection sel = ResourceFactory.createResource(group); + rbdMngr.addSelectedResource(sel); + groupListViewer.setInput(rbdMngr.getGroupResources()); + + // the new group is always added at the top. + groupListViewer.getTable().setSelection(0); + curGrp = 0; + + groupListViewer.refresh(); + + seld_rscs_lviewer.setInput(null); + seld_rscs_lviewer.refresh(); + + } catch (VizException e) { + + } + + } + + private void setGroupButtons() { + + if (groupListViewer.getTable().getSelectionCount() <= 0 + || groupListViewer.getTable().getSelection()[0].getText() + .equalsIgnoreCase(ungrpStr)) { + grpMoveUpBtn.setEnabled(false); + grpMoveDownBtn.setEnabled(false); + grpColorComp.setEnabled(false); + delGrpBtn.setEnabled(false); + + } else if (groupListViewer.getTable().getItemCount() == 1) { + grpMoveUpBtn.setEnabled(false); + grpMoveDownBtn.setEnabled(false); + grpColorComp.setEnabled(true); + delGrpBtn.setEnabled(true); + } else { + int idx = groupListViewer.getTable().getSelectionIndex(); + if (idx == 0) { + grpMoveUpBtn.setEnabled(false); + grpMoveDownBtn.setEnabled(true); + grpColorComp.setEnabled(true); + delGrpBtn.setEnabled(true); + } + if (idx == groupListViewer.getTable().getItemCount() - 2) { + grpMoveUpBtn.setEnabled(true); + grpMoveDownBtn.setEnabled(false); + grpColorComp.setEnabled(true); + delGrpBtn.setEnabled(true); + } + if (idx != 0 + && idx != groupListViewer.getTable().getItemCount() - 2) { + grpMoveUpBtn.setEnabled(true); + grpMoveDownBtn.setEnabled(true); + grpColorComp.setEnabled(true); + delGrpBtn.setEnabled(true); + } + } + + // set the color button + ResourceSelection sel = getGroupResourceSelection(); + if (sel != null) { + grpColorBtn.setColorValue(sel.getResourceData().getLegendColor()); + } + + } + + private ResourceSelection getGroupResourceSelection() { + StructuredSelection isel = ((StructuredSelection) groupListViewer + .getSelection()); + return (ResourceSelection) isel.getFirstElement(); + } + + private void selectUngroupedGrp() { + groupListViewer.getTable().setSelection( + groupListViewer.getTable().getItemCount() - 1); + } + @Override public void partActivated(IWorkbenchPartReference partRef) { // Auto-generated method stub diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/RbdViewComposite.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/RbdViewComposite.java index 3eed043246..6d1add0d82 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/RbdViewComposite.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/RbdViewComposite.java @@ -5,6 +5,7 @@ import gov.noaa.nws.ncep.viz.common.area.PredefinedArea; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneID; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResourceData; import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; import java.util.ArrayList; @@ -28,7 +29,7 @@ import com.raytheon.uf.viz.core.drawables.AbstractDescriptor; import com.raytheon.uf.viz.core.drawables.ResourcePair; /** - * + * *
  * SOFTWARE HISTORY
  * Date       	Ticket#		Engineer	Description
@@ -36,179 +37,206 @@ import com.raytheon.uf.viz.core.drawables.ResourcePair;
  * 06/26/12      #568       G. Hull     Created to replace separate code in 
  * 										LoadControl, SelectRbd and ManageSpfControl
  * 12/01/13      #630       G. Hull     Show Area based on Source (Resource, Predefined...)
+ * 08/14/14       ?         B. Yin      Handle GroupResource for power legend.
  * 
  * 
* - * @author + * @author * @version 1 */ public class RbdViewComposite extends Composite { - private ListViewer rscLviewer = null; - private Label rbdNameLabel = null; - private Label rbdLocationLabel = null; - private Boolean viewSelectedPane = false; + private ListViewer rscLviewer = null; + + private Label rbdNameLabel = null; + + private Label rbdLocationLabel = null; + + private Boolean viewSelectedPane = false; + + public RbdViewComposite(Composite parent) { + super(parent, SWT.SHADOW_NONE); - public RbdViewComposite( Composite parent ) { - super( parent, SWT.SHADOW_NONE ); - Composite topComp = this; - - topComp.setLayout( new FormLayout() ); - rscLviewer = new ListViewer( topComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL ); - - FormData fd = new FormData(); - fd.top = new FormAttachment( 0, 20 ); - fd.left = new FormAttachment(0, 0); - fd.right = new FormAttachment( 100, 0 ); - fd.bottom = new FormAttachment( 100, -20 ); - rscLviewer.getList().setLayoutData( fd ); - + topComp.setLayout(new FormLayout()); + + rscLviewer = new ListViewer(topComp, SWT.SINGLE | SWT.BORDER + | SWT.V_SCROLL | SWT.H_SCROLL); + + FormData fd = new FormData(); + fd.top = new FormAttachment(0, 20); + fd.left = new FormAttachment(0, 0); + fd.right = new FormAttachment(100, 0); + fd.bottom = new FormAttachment(100, -20); + rscLviewer.getList().setLayoutData(fd); + // do this as an indication that the list is view-only - rscLviewer.getList().setBackground( parent.getBackground() ); + rscLviewer.getList().setBackground(parent.getBackground()); - rbdNameLabel = new Label( topComp, SWT.NONE); + rbdNameLabel = new Label(topComp, SWT.NONE); rbdNameLabel.setText("View RBD"); - fd = new FormData(); - fd.bottom = new FormAttachment( rscLviewer.getList(), -3, SWT.TOP ); - fd.left = new FormAttachment( rscLviewer.getList(), 0, SWT.LEFT ); - fd.right = new FormAttachment( rscLviewer.getList(), 0, SWT.RIGHT ); - rbdNameLabel.setLayoutData( fd ); + fd = new FormData(); + fd.bottom = new FormAttachment(rscLviewer.getList(), -3, SWT.TOP); + fd.left = new FormAttachment(rscLviewer.getList(), 0, SWT.LEFT); + fd.right = new FormAttachment(rscLviewer.getList(), 0, SWT.RIGHT); + rbdNameLabel.setLayoutData(fd); - rbdLocationLabel = new Label( topComp, SWT.NONE); + rbdLocationLabel = new Label(topComp, SWT.NONE); rbdLocationLabel.setText(""); - fd = new FormData(); - fd.top = new FormAttachment( rscLviewer.getList(), 3, SWT.BOTTOM ); - fd.left = new FormAttachment( rscLviewer.getList(), 0, SWT.LEFT ); - fd.right = new FormAttachment( rscLviewer.getList(), 0, SWT.RIGHT ); - rbdLocationLabel.setLayoutData( fd ); + fd = new FormData(); + fd.top = new FormAttachment(rscLviewer.getList(), 3, SWT.BOTTOM); + fd.left = new FormAttachment(rscLviewer.getList(), 0, SWT.LEFT); + fd.right = new FormAttachment(rscLviewer.getList(), 0, SWT.RIGHT); + rbdLocationLabel.setLayoutData(fd); - rscLviewer.setContentProvider( new IStructuredContentProvider() { - @Override - public Object[] getElements(Object inputElement) { - AbstractRBD selRbd = (AbstractRBD)inputElement; - if( selRbd == null ) { - return new String[0]; - } - - ArrayList rscNames = new ArrayList(); - boolean isMultiPane = (selRbd.getPaneLayout().getNumberOfPanes() > 1 ); - - // loop thru all of the resources in all of the panes and create the - // list of items for the viewer. These will depend on whether we are - // importing a single pane (in which case only the selected pane's - // resources are displayed) and whole RBDs (in which case all pane's - // resources are displayed) For multi-pane RBDs the format will include - // the name of the pane. - for( int paneIndx=0 ; paneIndx selRbd = (AbstractRBD) inputElement; + if (selRbd == null) { + return new String[0]; + } - boolean showPane = (!viewSelectedPane || - (viewSelectedPane && (paneId.compareTo( selRbd.getSelectedPaneId() ) == 0))); - - // show this pane only if its a single pane or if this is the - if( showPane ) { - - if( isMultiPane ) { - rscNames.add( "Pane ("+ paneId.toString() +")" ); - } - else { - rscNames.add( "Single Pane" ); - } - - // TODO: show the actual center/proj/zoomLevel??? - - PredefinedArea area = (PredefinedArea)disp.getInitialArea(); + ArrayList rscNames = new ArrayList(); + boolean isMultiPane = (selRbd.getPaneLayout() + .getNumberOfPanes() > 1); - if( area.getSource() == AreaSource.PREDEFINED_AREA ) { - rscNames.add("Predefined Area "+area.getAreaName() ); - } - else { - rscNames.add("Area From "+area.getAreaName() ); - } - - for( ResourcePair rp : mapDescr.getResourceList() ) { - if( rp.getResourceData() instanceof INatlCntrsResourceData ) { - INatlCntrsResourceData ncRsc = - (INatlCntrsResourceData)rp.getResourceData(); - String rscName = ncRsc.getResourceName().toString(); + // loop thru all of the resources in all of the panes and create + // the + // list of items for the viewer. These will depend on whether we + // are + // importing a single pane (in which case only the selected + // pane's + // resources are displayed) and whole RBDs (in which case all + // pane's + // resources are displayed) For multi-pane RBDs the format will + // include + // the name of the pane. + for (int paneIndx = 0; paneIndx < selRbd.getPaneLayout() + .getNumberOfPanes(); paneIndx++) { + INcPaneID paneId = selRbd.getPaneLayout().createPaneId( + paneIndx); - if( ncRsc.getIsEdited() ) { - rscName = rscName + "(E)"; - } - // if( ncRsc instanceof AbstractNatlCntrsRequestableResourceData && - // ((AbstractNatlCntrsRequestableResourceData)ncRsc).getIsDominant() ) { - // qualRscName = qualRscName + "(D)"; - // } + INatlCntrsRenderableDisplay disp = selRbd + .getDisplayPane(paneId); + AbstractDescriptor mapDescr = (AbstractDescriptor) disp + .getDescriptor(); - if( isMultiPane ) { - rscName = " " + rscName; - } + boolean showPane = (!viewSelectedPane || (viewSelectedPane && (paneId + .compareTo(selRbd.getSelectedPaneId()) == 0))); - rscNames.add( rscName ); - } - } - } - } - return rscNames.toArray(); - } - @Override - public void dispose() { } + // show this pane only if its a single pane or if this is + // the + if (showPane) { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - }); + if (isMultiPane) { + rscNames.add("Pane (" + paneId.toString() + ")"); + } else { + rscNames.add("Single Pane"); + } + + // TODO: show the actual center/proj/zoomLevel??? + + PredefinedArea area = (PredefinedArea) disp + .getInitialArea(); + + if (area.getSource() == AreaSource.PREDEFINED_AREA) { + rscNames.add("Predefined Area " + + area.getAreaName()); + } else { + rscNames.add("Area From " + area.getAreaName()); + } + + for (ResourcePair rp : mapDescr.getResourceList()) { + if (rp.getResourceData() instanceof INatlCntrsResourceData) { + INatlCntrsResourceData ncRsc = (INatlCntrsResourceData) rp + .getResourceData(); + + String rscName = ""; + if (ncRsc instanceof GroupResourceData) { + rscName = ((GroupResourceData) ncRsc) + .getGroupName(); + } else { + rscName = ncRsc.getResourceName() + .toString(); + } + + if (ncRsc.getIsEdited()) { + rscName = rscName + "(E)"; + } + // if( ncRsc instanceof + // AbstractNatlCntrsRequestableResourceData && + // ((AbstractNatlCntrsRequestableResourceData)ncRsc).getIsDominant() + // ) { + // qualRscName = qualRscName + "(D)"; + // } + + if (isMultiPane) { + rscName = " " + rscName; + } + + rscNames.add(rscName); + } + } + } + } + return rscNames.toArray(); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + }); // make this View-only rscLviewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - rscLviewer.getList().deselectAll(); - } - }); - - rscLviewer.addDoubleClickListener( new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - rscLviewer.getList().deselectAll(); - } - }); + public void selectionChanged(SelectionChangedEvent event) { + rscLviewer.getList().deselectAll(); + } + }); - } - - public void viewSelectedPane() { - viewSelectedPane = true; - } - - public void viewRbd( AbstractRBD rbd ) { - - if( rbd == null ) { - rbdNameLabel.setText( "" ); - rbdLocationLabel.setText(""); - } - else { - rbdNameLabel.setText( "RBD: " + rbd.getRbdName() ); + rscLviewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + rscLviewer.getList().deselectAll(); + } + }); - LocalizationFile lFile = rbd.getLocalizationFile(); - if( lFile == null ) { - rbdLocationLabel.setText(""); - } - else { - rbdLocationLabel.setText( "Localization="+ - lFile.getContext().getLocalizationLevel().toString()+":"+ - lFile.getContext().getContextName() ); - } - } - - rscLviewer.setInput( rbd ); - rscLviewer.refresh(); - } + } - public void refresh() { - rscLviewer.refresh( true ); - } + public void viewSelectedPane() { + viewSelectedPane = true; + } + + public void viewRbd(AbstractRBD rbd) { + + if (rbd == null) { + rbdNameLabel.setText(""); + rbdLocationLabel.setText(""); + } else { + rbdNameLabel.setText("RBD: " + rbd.getRbdName()); + + LocalizationFile lFile = rbd.getLocalizationFile(); + if (lFile == null) { + rbdLocationLabel.setText(""); + } else { + rbdLocationLabel.setText("Localization=" + + lFile.getContext().getLocalizationLevel().toString() + + ":" + lFile.getContext().getContextName()); + } + } + + rscLviewer.setInput(rbd); + rscLviewer.refresh(); + } + + public void refresh() { + rscLviewer.refresh(true); + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF index a40d04fd44..81b42827be 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF @@ -51,6 +51,7 @@ Export-Package: gov.noaa.nws.ncep.viz.resources; org.eclipse.swt.widgets, gov.noaa.nws.ncep.viz.common.ui.color, gov.noaa.nws.ncep.viz.ui.display", + gov.noaa.nws.ncep.viz.resources.groupresource, gov.noaa.nws.ncep.viz.resources.manager; uses:="javax.xml.bind.annotation.adapters, gov.noaa.nws.ncep.viz.resources, diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.resources/plugin.xml index 45083051c5..6a0199900e 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.resources/plugin.xml @@ -18,6 +18,16 @@ name="Change Area to Fit Image" sortID="13"> + + + * SOFTWARE HISTORY + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/14 ? B. Yin Initial creation. + * 09/14 ? B. Yin Added updateTimeLine for auto-update. + * + * + * @author byin + * @version 1.0 + */ +public class GroupResource extends + AbstractVizResource implements + IPowerLegend, INatlCntrsResource{ + + private GroupResourceData groupResourceData; + + private boolean nameExpended = false; + + public GroupResource(GroupResourceData resourceData, + LoadProperties loadProperties) throws VizException { + super(resourceData, loadProperties); + groupResourceData = (GroupResourceData) resourceData; + } + + @Override + public String getName() { + String name = groupResourceData.getGroupName() + "(F" + + groupResourceData.getFuncKeyNum() + ")"; + + return name; + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + int displayWidth = (int) (descriptor.getMapWidth() * paintProps + .getZoomLevel()); + + for (ResourcePair rp : this.resourceData.getResourceList()) { + AbstractVizResource resource = rp.getResource(); + if (resource == null) + continue; + ResourceProperties properties = rp.getProperties(); + + if (properties.isDisplayable(displayWidth)) { + PaintProperties newProps = new PaintProperties(paintProps); + newProps.setDataTime(descriptor.getTimeForResource(resource)); + + resource.paint(target, newProps); + } + } + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + // this.getCapability(GroupNamingCapability.class); + // this.getCapabilities(); + for (ResourcePair rp : this.resourceData.getResourceList()) { + AbstractVizResource rsc = rp.getResource(); + if (rsc != null) { + rsc.init(target); + } + } + } + + @Override + protected void disposeInternal() { + // lastTarget = null; + for (ResourcePair rp : this.resourceData.getResourceList()) { + rp.getResource().dispose(); + } + } + + @Override + public ResourceList getResourceList() { + if (resourceData != null) { + return resourceData.getResourceList(); + } else { + return null; + } + } + + @Override + public int getFuncKeyNum() { + return groupResourceData.getFuncKeyNum(); + } + + @Override + public boolean isNameExpanded() { + if (!this.getProperties().isVisible()) + setNameExpanded(false); + return nameExpended; + } + + @Override + public void setNameExpanded(boolean flag) { + nameExpended = flag; + } + + @Override + public void project(CoordinateReferenceSystem mapData) throws VizException { + super.project(mapData); + for (ResourcePair rp : this.resourceData.getResourceList()) { + AbstractVizResource rsc = rp.getResource(); + if (rsc != null) { + rsc.project(mapData); + } + } + } + + @Override + public void propertiesChanged(ResourceProperties updatedProps) { + + // if (updatedProps.isVisible()) { + // setVisibleForAllResources(true); + // } else { + // setVisibleForAllResources(false); + // } + } + + public void setVisibleForAllResources(boolean visible) { + + for (ResourcePair rp : this.resourceData.getResourceList()) { + AbstractVizResource resource = rp.getResource(); + if (resource == null) + continue; + resource.getProperties().setVisible(visible); + } + } + + public Boolean updateTimeline() { + for (ResourcePair rp : this.getResourceList()) { + if (rp.getResourceData() instanceof AbstractRequestableResourceData) { + ((AbstractNatlCntrsResource)rp.getResource()).updateTimeline(); + } + } + + return true; + } + + @Override + public void resourceAttrsModified() { + // TODO Auto-generated method stub + + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/GroupResourceData.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/GroupResourceData.java new file mode 100644 index 0000000000..c344929dfd --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/GroupResourceData.java @@ -0,0 +1,183 @@ +package gov.noaa.nws.ncep.viz.resources.groupresource; + +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResourceData; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceAttrSet; +import gov.noaa.nws.ncep.viz.resources.manager.ResourceName; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +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.IResourceGroup; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceList; + +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "GroupResourceData") +public class GroupResourceData extends AbstractNatlCntrsResourceData implements + IResourceGroup { + /** + * GroupResource - Display resources in group + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + *
+     * SOFTWARE HISTORY
+     * Date         Ticket#    Engineer    Description
+     * ------------ ---------- ----------- --------------------------
+     * 05/14        ?           B. Yin     Initial creation.
+     * 
+     * 
+ * + * @author byin + * @version 1.0 + */ + + @XmlElement + protected String groupName = "nc-group"; + + @XmlElement + private int funcKeyNum = 0; + + @XmlElement(name = "resource-in-group") + private ResourceList resourceList; + + public GroupResourceData() { + resourceList = new ResourceList(); + } + + public GroupResourceData(String name, int key, RGB color) { + this.setGroupName(name); + this.setFuncKeyNum(key); + this.setLegendColor(color); + resourceList = new ResourceList(); + } + + @Override + public AbstractVizResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new GroupResource(this, loadProperties); + } + + @Override + public void update(Object updateData) { + // TODO Auto-generated method stub + + } + + @Override + public boolean equals(Object obj) { + // TODO Auto-generated method stub + return false; + } + + public void addResource(ResourcePair rp) { + resourceList.add(rp); + } + + // @XmlElement(name = "resource-in-group") + public String[] getSerializableResources() { + if (resourceList != null) { + List rps = new ArrayList(resourceList.size()); + for (ResourcePair rp : resourceList) { + if (rp.getProperties().isSystemResource() == false) { + rps.add("test-yin"); + } + } + return rps.toArray(new String[rps.size()]); + } + return null; + } + + public void setSerializableResources(String[] resources) { + } + + public ResourceList getResourceList() { + return resourceList; + } + + public void setResourceList(ResourceList resourceList) { + this.resourceList = resourceList; + } + + public int getFuncKeyNum() { + return funcKeyNum; + } + + public void setFuncKeyNum(int funcHotKey) { + this.funcKeyNum = funcHotKey; + } + + @Override + public boolean setRscAttrSet(ResourceAttrSet attrSet) { + // TODO Auto-generated method stub + return false; + } + + @Override + public ResourceAttrSet getRscAttrSet() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setResourceName(ResourceName rscName) { + // TODO Auto-generated method stub + + } + + @Override + public boolean getIsEdited() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void setIsEdited(boolean e) { + // TODO Auto-generated method stub + + } + + @Override + public void setResourceVersion(String v) { + // TODO Auto-generated method stub + + } + + @Override + public String getResourceVersion() { + // TODO Auto-generated method stub + return null; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + @Override + public AbstractVizResource constructResource( + LoadProperties loadProperties, IDescriptor descriptor) + throws VizException { + return construct(loadProperties, descriptor); + } + + public void replaceResourcePair(ResourcePair oldPair, ResourcePair newPair) { + getResourceList().remove(oldPair); + getResourceList().add(newPair); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/package-info.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/package-info.java new file mode 100644 index 0000000000..143df4c956 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/groupresource/package-info.java @@ -0,0 +1,37 @@ +/** + * 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. + **/ +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 21, 2014            bingfan     Initial creation
+ *
+ * 
+ * + * @author bingfan + * @version 1.0 + */ + +package gov.noaa.nws.ncep.viz.resources.groupresource; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java index 6ac72be330..e1c80f7eda 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java @@ -30,6 +30,7 @@ import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener; import com.raytheon.viz.ui.UiPlugin; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -359,6 +360,12 @@ public class ResourceBndlLoader implements Runnable { // extends Job { .isEmpty()) { rscList.addAll(pane.getRenderableDisplay().getDescriptor() .getResourceList()); + //When adding PGEN back, add tne remove-listener + if (pane.getRenderableDisplay().getDescriptor().getResourceList().get(0).getResource().getClass().getName() + .endsWith("PgenResource")) { + rscList.addPreRemoveListener((RemoveListener) pane.getRenderableDisplay().getDescriptor().getResourceList().get(0).getResource()); + } + } rscList.instantiateResources(descr, true); diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java index eef52d1983..ea44005c11 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java @@ -19,6 +19,7 @@ import javax.xml.bind.annotation.adapters.XmlAdapter; * 02/13/13 #972 Greg Hull Created * 03/06/13 #958 Greg Hull Added SpaceRscCategory * 05/15/2014 #1131 Quan Zhou Added resource category GraphRscCategory. + * 09/10/2014 B. Hebbard Added NtransRscCategory * * * @author @@ -77,6 +78,9 @@ public class ResourceCategory implements Comparable { public static ResourceCategory GraphRscCategory = createCategory( "TIMESERIES", 860); + public static ResourceCategory NtransRscCategory = createCategory("NTRANS", + 870); + private static int nextCatOrder = OverlayRscCategory.order + 100; public static ResourceCategory NullCategory = new ResourceCategory("NULL", diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java index fe24e4e558..51d1b239ca 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java @@ -19,6 +19,7 @@ import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; import gov.noaa.nws.ncep.viz.common.ui.NmapCommon; import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResourceData; import gov.noaa.nws.ncep.viz.resources.manager.ResourceFactory.ResourceSelection; import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; @@ -78,6 +79,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 11/25/2013 #1078 Greg Hull check for FitToScreen and SizeOfImage in setPaneData() * 11/25/2013 #1079 Greg Hull checkAndUpdateAreaFromResource * 05/15/2014 #1131 Quan Zhou added rbdType GRAPH_DISPLAY + * 08/14/2014 ? B. Yin Handle GroupResource for power legend. * * * @author ghull @@ -171,17 +173,22 @@ public class RscBundleDisplayMngr { // replace the existing base overlay. public boolean addSelectedResource(ResourceSelection rbt) { // for( ResourceSelection r : seldResources ) { - for (int r = 0; r < seldResources.size(); r++) { - ResourceSelection rscSel = seldResources.elementAt(r); - if (rbt.getResourceName().equals(rscSel.getResourceName())) { - if (rscSel.isBaseLevelResource()) { - // baseOverlayResources - rbt.setIsBaseLevelResource(true); - seldResources.add(r, rbt); - seldResources.remove(r + 1); - return true; + if (!(rbt.getResourceData() instanceof GroupResourceData)) { //add group on top + for (int r = 0; r < seldResources.size(); r++) { + ResourceSelection rscSel = seldResources.elementAt(r); + if (rscSel.getResourceData() instanceof GroupResourceData) { //skip groups + continue; + } + if (rbt.getResourceName().equals(rscSel.getResourceName())) { + if (rscSel.isBaseLevelResource()) { + // baseOverlayResources + rbt.setIsBaseLevelResource(true); + seldResources.add(r, rbt); + seldResources.remove(r + 1); + return true; + } + return false; } - return false; } } @@ -951,6 +958,20 @@ public class RscBundleDisplayMngr { } + public boolean addSelectedResource(ResourceSelection rsel, + ResourceSelection grp) { + if (grp == null) { + return addSelectedResource(rsel); + } else { + if (grp.getResourceData() instanceof GroupResourceData) { + ((GroupResourceData) grp.getResourceData()).getResourceList() + .add(rsel.getResourcePair()); + return true; + } + } + return false; + } + public boolean addSelectedResourceToAllPanes(ResourceSelection rbt) { for (PaneSelectionData paneData : paneSelectionDataMap.values()) { paneData.addSelectedResource(rbt); @@ -1192,7 +1213,9 @@ public class RscBundleDisplayMngr { // loop thru the bundles for the selected rscs // - for (ResourceSelection rbt : paneData.getSelectedResources()) { + for (int ii = paneData.getSelectedResources().length - 1; ii >= 0; ii--) { + ResourceSelection rbt = paneData.getSelectedResources()[ii]; + ResourcePair rscPair = rbt.getResourcePair(); // if( dfltDomRscName == null && // rscPair.getResourceData() instanceof @@ -1219,4 +1242,104 @@ public class RscBundleDisplayMngr { return rbdBndl; } + + public ResourceSelection[] getGroupResources() { + ArrayList sels = new ArrayList(); + for (int ii = 0; ii < selectedPaneData.seldResources.size(); ii++) { + if (selectedPaneData.seldResources.get(ii).getResourceData() instanceof GroupResourceData) { + sels.add(selectedPaneData.seldResources.get(ii)); + } + } + return (ResourceSelection[]) sels.toArray(new ResourceSelection[sels + .size()]); + } + + public ResourceSelection[] getUngroupedResources() { + ArrayList sels = new ArrayList(); + for (int ii = 0; ii < selectedPaneData.seldResources.size(); ii++) { + if (!(selectedPaneData.seldResources.get(ii).getResourceData() instanceof GroupResourceData)) { + sels.add(selectedPaneData.seldResources.get(ii)); + } + } + return (ResourceSelection[]) sels.toArray(new ResourceSelection[sels + .size()]); + } + + public ResourceSelection[] getResourcesInGroup(String grpName) { + + if (grpName != null && !grpName.isEmpty()) { + ResourceSelection[] sels = getGroupResources(); + for (int ii = 0; ii < sels.length; ii++) { + if (sels[ii].getResourceData() instanceof GroupResourceData) { + GroupResourceData grd = (GroupResourceData) sels[ii] + .getResourceData(); + if (grd.getGroupName().equals(grpName)) { + + ResourceSelection[] resInGrp = new ResourceSelection[grd + .getResourceList().size()]; + for (int jj = 0; jj < resInGrp.length; jj++) { + try { + resInGrp[jj] = ResourceFactory + .createResource(grd.getResourceList() + .get(jj)); + } catch (VizException e) { + + } + } + + return resInGrp; + } + } + } + } + return null; + } + + public void moveUpGrp(ResourcePair pair) { + + int curIdx = -1; + int target = selectedPaneData.seldResources.size(); + for (int ii = 0; ii < selectedPaneData.seldResources.size(); ii++) { + + if (selectedPaneData.seldResources.get(ii).getResourcePair() == pair) { + curIdx = ii; + break; + } else if (selectedPaneData.seldResources.get(ii).getResourceData() instanceof GroupResourceData) { + target = ii; + } + } + + if (curIdx != -1 && target < curIdx) { + ResourceSelection sel = selectedPaneData.seldResources.get(curIdx); + selectedPaneData.seldResources.set(curIdx, + selectedPaneData.seldResources.get(target)); + selectedPaneData.seldResources.set(target, sel); + + } + + } + + public void moveDownGrp(ResourcePair pair) { + + int curIdx = -1; + int target = selectedPaneData.seldResources.size(); + for (int ii = selectedPaneData.seldResources.size() - 1; ii >= 0; ii--) { + + if (selectedPaneData.seldResources.get(ii).getResourcePair() == pair) { + curIdx = ii; + break; + } else if (selectedPaneData.seldResources.get(ii).getResourceData() instanceof GroupResourceData) { + target = ii; + } + } + + if (curIdx != -1 && target > curIdx) { + ResourceSelection sel = selectedPaneData.seldResources.get(curIdx); + selectedPaneData.seldResources.set(curIdx, + selectedPaneData.seldResources.get(target)); + selectedPaneData.seldResources.set(target, sel); + + } + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveDownAction.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveDownAction.java new file mode 100644 index 0000000000..60cd00514b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveDownAction.java @@ -0,0 +1,82 @@ +package gov.noaa.nws.ncep.viz.resources.misc; + +/** + * 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. + **/ + +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResource; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.ResourceList.MoveOperation; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * + * Move down a resource in the legend list. It works for resources in a group + * resource. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 08/14            ?        B. Yin    Initial Creation.
+ * 
+ * 
+ * + * @author byin + * @version 1 + */ +public class NCMoveDownAction extends AbstractRightClickAction { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + IDescriptor desc = getDescriptor(); + + for (ResourcePair pair : desc.getResourceList()) { + if (selectedRsc == pair) { + desc.getResourceList().moveResource( + getTopMostSelectedResource(), MoveOperation.Down); + break; + } else if (pair.getResource() instanceof GroupResource + && ((GroupResource) pair.getResource()).getResourceList() + .contains(selectedRsc)) { + ((GroupResource) pair.getResource()).getResourceList() + .moveResource(selectedRsc.getResource(), + MoveOperation.Down); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return "Move Down"; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveUpAction.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveUpAction.java new file mode 100644 index 0000000000..6954bb8dd1 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/misc/NCMoveUpAction.java @@ -0,0 +1,70 @@ +/* + * gov.noaa.nws.ncep.viz.resources.misc + * + * 13 August 2014 + * + * This code has been developed by the NCEP/SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.viz.resources.misc; + +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResource; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.ResourceList.MoveOperation; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * + * Move up a resource in the legend list. It works for resources in a group + * resource. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 08/14            ?        B. Yin    Initial Creation.
+ * 
+ * 
+ * + * @author byin + * @version 1 + */ +public class NCMoveUpAction extends AbstractRightClickAction { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + IDescriptor desc = getDescriptor(); + + for (ResourcePair pair : desc.getResourceList()) { + if (selectedRsc == pair) { + desc.getResourceList().moveResource( + getTopMostSelectedResource(), MoveOperation.Up); + break; + } else if (pair.getResource() instanceof GroupResource + && ((GroupResource) pair.getResource()).getResourceList() + .contains(selectedRsc)) { + ((GroupResource) pair.getResource()).getResourceList() + .moveResource(selectedRsc.getResource(), + MoveOperation.Up); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return "Move Up"; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/hotKeys/NCHotKeyHandler.java b/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/hotKeys/NCHotKeyHandler.java index b39d08c82c..06377825c5 100644 --- a/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/hotKeys/NCHotKeyHandler.java +++ b/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/hotKeys/NCHotKeyHandler.java @@ -7,24 +7,11 @@ */ package gov.noaa.nws.ncep.viz.tools.hotKeys; -import java.util.List; - -import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; -import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; - -import com.raytheon.viz.ui.UiUtil; -import com.raytheon.viz.ui.editor.AbstractEditor; - - /** * Hot Key handler to switch between tabs in the National Centers Perspective @@ -40,39 +27,42 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 03/20/2013 972 Greg H. use new NcDisplayName and NcDisplayMngr methods instead * of parsing the tab title. * - * + * 08/14/2014 ? B. Yin Change funtion keys to loop through resource group. + * + * * @author archana - * @version 1.0 - * + * @version 1.0 + * */ - public class NCHotKeyHandler extends AbstractHandler { +public class NCHotKeyHandler extends AbstractHandler { - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - if(event.getCommand() == null){ - return null; - } - - Object appCntxt = event.getApplicationContext(); - - if( appCntxt != null ) { - - } - - String tabKeyValue = event.getParameter("keyNum"); + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + if (event.getCommand() == null) { + return null; + } - if(tabKeyValue == null || tabKeyValue.isEmpty() ) { - return null; - } + Object appCntxt = event.getApplicationContext(); - AbstractEditor ncDisp = NcDisplayMngr.findDisplayByID( - new NcDisplayName( Integer.parseInt(tabKeyValue), "N/A" ) ); + if (appCntxt != null) { - if( ncDisp != null ) { - NcDisplayMngr.bringToTop( ncDisp ); - } + } - return null; - } + String tabKeyValue = event.getParameter("keyNum"); - } \ No newline at end of file + if (tabKeyValue == null || tabKeyValue.isEmpty()) { + return null; + } + + // AbstractEditor ncDisp = NcDisplayMngr.findDisplayByID( + // new NcDisplayName( Integer.parseInt(tabKeyValue), "N/A" ) ); + + // if( ncDisp != null ) { + // NcDisplayMngr.bringToTop( ncDisp ); + // } + + NcDisplayMngr.toggleOnResourceGroup(Integer.parseInt(tabKeyValue)); + return null; + } + +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/wipe/WipeResultsAction.java b/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/wipe/WipeResultsAction.java index bb10f29956..9b8d52afd3 100644 --- a/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/wipe/WipeResultsAction.java +++ b/ncep/gov.noaa.nws.ncep.viz.tools/src/gov/noaa/nws/ncep/viz/tools/wipe/WipeResultsAction.java @@ -20,6 +20,7 @@ import org.eclipse.ui.PlatformUI; //import gov.noaa.nws.ncep.viz.overlays.resources.*; import gov.noaa.nws.ncep.viz.resources.*; +import gov.noaa.nws.ncep.viz.resources.groupresource.GroupResourceData; import gov.noaa.nws.ncep.viz.ui.display.AbstractNcEditor; import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; @@ -43,6 +44,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 05/10 #265 G. Hull test for AbstractNatlCntrsRequestableResourceData to * remove PGEN dependency * 02/13 #972 G. Hull setDisplayModified flag + * 09/14 ? B. Yin Removed GroupResource * * * @@ -122,7 +124,8 @@ public class WipeResultsAction extends AbstractHandler { if(ard == null) return false; - if( ard instanceof AbstractNatlCntrsRequestableResourceData ) + if( ard instanceof AbstractNatlCntrsRequestableResourceData || + ard instanceof GroupResourceData ) return true; else return false; diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java index bcb32b28a7..6152ed9b33 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java @@ -19,13 +19,20 @@ **/ package gov.noaa.nws.ncep.viz.ui.display; +import gov.noaa.nws.ncep.viz.common.display.IPowerLegend; + import java.util.ArrayList; import java.util.List; +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.SWT; import org.eclipse.swt.widgets.Event; import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; @@ -57,6 +64,7 @@ import com.raytheon.viz.ui.input.EditableManager; * 10/19/2012 897 S. Gurung Updated handleKeyUp() to not toggle PgenResource and added code to * refresh the editor after handling events. * 12/19/2012 960 G. Hull use propertiesChanged() to toggle colorBar resources + * 08/18/2014 ? B. Yin Handle GroupResource. * * * @@ -83,6 +91,20 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { private static boolean isFirstTime = true; + private boolean doubleClick = false; + + private int doubleClickInterval = 300; + + // (Integer) + // Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval"); + + private Job singleClickJob; + + protected final Object singleClickJobLock = new Object(); + + private boolean isCtrlDown = false; + private boolean ctrlDown = false; + @Override public boolean handleMouseDown(int x, int y, int mouseButton) { @@ -94,58 +116,76 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { IDisplayPane activePane = editor.getActiveDisplayPane(); IRenderableDisplay display = editor.getActiveDisplayPane() .getRenderableDisplay(); - mouseDownRsc = resource.checkLabelSpace( - display.getDescriptor(), activePane.getTarget(), x, y); + List resourcesClicked = resource + .getResourceClicked(display.getDescriptor(), + activePane.getTarget(), x, y); + if (resourcesClicked != null && !resourcesClicked.isEmpty()) { + mouseDownRsc = resourcesClicked + .get(resourcesClicked.size() - 1); + } else { + mouseDownRsc = null; + } } } return false; } @Override - public boolean handleMouseUp(int x, int y, int mouseButton) { + public boolean handleMouseUp(final int x, final int y, final int mouseButton) { - AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); - if (mouseButton == 1) { - if (editor != null && editor instanceof AbstractNcEditor) { - IDisplayPane activePane = editor.getActiveDisplayPane(); - IRenderableDisplay display = editor.getActiveDisplayPane() - .getRenderableDisplay(); - ResourcePair rsc = resource.checkLabelSpace( - display.getDescriptor(), activePane.getTarget(), x, y); - - if (rsc != null && rsc == mouseDownRsc) { - - mouseDownRsc = null; - toggleVisibility(rsc); - editor.refresh(); - - return true; - } - } - } else if (mouseButton == 2) { - - if (mouseDownRsc != null - && mouseDownRsc.getResource().hasCapability( - EditableCapability.class)) { - // check / make editable - EditableManager.makeEditable( - mouseDownRsc.getResource(), - !mouseDownRsc.getResource() - .getCapability(EditableCapability.class) - .isEditable()); - mouseDownRsc = null; - - editor.refresh(); - return true; - } + //Because we wait certain milliseconds for double click, + //we have to save the status of the ctrl key. + if ( this.isCtrlDown ){ + ctrlDown = true; + } + else { + ctrlDown = false; + } + + + if (mouseDownRsc != null) { + + if (doubleClick) { + synchronized (singleClickJobLock) { + if (singleClickJob != null) { + singleClickJob.cancel(); + } + } + doubleClick = false; + return doubleClickMouseUp(x, y, mouseButton); + + } + + singleClickJob = new Job("SingleClickMouseUp") { + @Override + protected IStatus run(IProgressMonitor monitor) { + VizApp.runSync(new Runnable() { + @Override + public void run() { + singleClickMouseUp(x, y, mouseButton); + } + }); + synchronized (singleClickJobLock) { + singleClickJob = null; + } + return Status.OK_STATUS; + } + }; + singleClickJob.schedule(doubleClickInterval); + + return true; + } else { + return false; } - return false; } @Override public boolean handleDoubleClick(int x, int y, int mouseButton) { - return false; + if (mouseDownRsc != null && mouseButton == 1) { + doubleClick = true; + } + return true; } @Override @@ -176,6 +216,11 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { @Override public boolean handleKeyUp(int keyCode) { + if (keyCode == SWT.CONTROL) { + isCtrlDown = false; + return true; + } + if (keyCode != SWT.SHIFT && keyCode != SWT.ARROW_UP && keyCode != SWT.ARROW_DOWN) { return false; @@ -313,11 +358,13 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { if (keyCode == SWT.SHIFT) { isShiftDown = true; return false; + } else if (keyCode == SWT.CONTROL) { + isCtrlDown = true; } return false; } - private void toggleVisibility(ResourcePair rp) { + private void toggleVisibility(ResourcePair rp, ResourcePair grp) { AbstractVizResource rsc = rp.getResource(); if (rsc != null) { if (rsc.hasCapability(BlendedCapability.class)) { @@ -349,6 +396,115 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { return; } } + + // If the resource is turned on, turn on the resource group. + // Otherwise the resource is not visible. + if (grp != null && !rp.getProperties().isVisible()) { + grp.getProperties().setVisible(!rp.getProperties().isVisible()); + } + rp.getProperties().setVisible(!rp.getProperties().isVisible()); + + if (rp.getResource() instanceof IPowerLegend) { + IPowerLegend gr = (IPowerLegend) rp.getResource(); + // gr.setVisibleForAllResources(rp.getProperties().isVisible()); + + // if the group is turned + // if (!rp.getProperties().isVisible()) { + // gr.setNameExpanded(false); + // } + + // if CTRL is not down, disable all other groups + if (!ctrlDown) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + if (editor != null && editor instanceof AbstractNcEditor) { + IRenderableDisplay display = editor.getActiveDisplayPane() + .getRenderableDisplay(); + for (ResourcePair pair : display.getDescriptor() + .getResourceList()) { + if (pair.getResource() instanceof IPowerLegend + && pair != rp && rp.getProperties().isVisible()) { + pair.getProperties().setVisible(false); + // ((IPowerLegend) pair.getResource()) + // .setVisibleForAllResources(false); + } + } + } + } + } } + + private boolean singleClickMouseUp(int x, int y, int mouseButton) { + + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + if (mouseButton == 1) { + if (editor != null && editor instanceof AbstractNcEditor) { + IDisplayPane activePane = editor.getActiveDisplayPane(); + IRenderableDisplay display = editor.getActiveDisplayPane() + .getRenderableDisplay(); + + ResourcePair rsc; + ResourcePair grp = null; + List resourcesClicked = resource + .getResourceClicked(display.getDescriptor(), + activePane.getTarget(), x, y); + if (resourcesClicked != null && !resourcesClicked.isEmpty()) { + rsc = resourcesClicked.get(resourcesClicked.size() - 1); + // get the group that rsc belongs to. + if (resourcesClicked.size() > 1) { + grp = resourcesClicked.get(0); + } + } else { + rsc = null; + } + + if (rsc != null && rsc == mouseDownRsc) { + + mouseDownRsc = null; + toggleVisibility(rsc, grp); + editor.refresh(); + + return true; + } + } + } else if (mouseButton == 2) { + + if (mouseDownRsc != null + && mouseDownRsc.getResource().hasCapability( + EditableCapability.class)) { + // check / make editable + EditableManager.makeEditable( + mouseDownRsc.getResource(), + !mouseDownRsc.getResource() + .getCapability(EditableCapability.class) + .isEditable()); + mouseDownRsc = null; + + editor.refresh(); + return true; + } + } + return false; + } + + private boolean doubleClickMouseUp(int x, int y, int mouseButton) { + + if (mouseDownRsc.getResource() instanceof IPowerLegend) { + IPowerLegend gr = (IPowerLegend) mouseDownRsc.getResource(); + if (mouseDownRsc.getResource().getProperties().isVisible()) { + if (gr.isNameExpanded()) { + gr.setNameExpanded(false); + } else { + gr.setNameExpanded(true); + } + } + + resource.issueRefresh(); + return true; + } else { + return false; + } + } + } diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendResource.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendResource.java index a499fd9ed1..1496d1061a 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendResource.java @@ -19,26 +19,42 @@ ******************************************************************************************/ package gov.noaa.nws.ncep.viz.ui.display; +import gov.noaa.nws.ncep.viz.common.display.IPowerLegend; + +import java.awt.geom.Rectangle2D; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuManager; import org.eclipse.swt.graphics.RGB; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IDisplayPane; 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.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IFont.Style; +import com.raytheon.uf.viz.core.drawables.PaintProperties; import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.drawables.ext.ICanvasRenderingExtension; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.legend.ILegendDecorator; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.GenericResourceData; import com.raytheon.uf.viz.core.rsc.IInputHandler; import com.raytheon.uf.viz.core.rsc.IInputHandler.InputPriority; +import com.raytheon.uf.viz.core.rsc.IResourceGroup; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; import com.raytheon.uf.viz.core.rsc.legend.AbstractLegendResource; +import com.raytheon.viz.ui.cmenu.MoveDownAction; +import com.raytheon.viz.ui.cmenu.MoveUpAction; /** * Legend decorator for Natl Cntrs @@ -53,6 +69,7 @@ import com.raytheon.uf.viz.core.rsc.legend.AbstractLegendResource; * 02/06/2011 S. Gurung Separated/moved input handler code to class NCLegendHandler * 02/29/2011 651 Archana Added the overridden method fillContextMenu() * 07/27/2012 695 B. Yin Added editable capability for resource legends + * 08/18/2014 ? B. Yin Handle GroupResource. * * * @author ghull @@ -62,9 +79,17 @@ import com.raytheon.uf.viz.core.rsc.legend.AbstractLegendResource; public class NCLegendResource extends AbstractLegendResource implements ILegendDecorator { - private IInputHandler legendHandler = new NCLegendHandler(this); - - /** + private IInputHandler legendHandler = new NCLegendHandler(this); + + protected static final int BOTTOM_OFFSET_IN_PIXELS = 7; + + protected static final int RIGHT_OFFSET_IN_PIXELS = 18; + + private static IFont groupResourceFont; + + private double yStart; + + /** * @param resourceData * @param loadProperties */ @@ -73,6 +98,108 @@ public class NCLegendResource extends super(resourceData, loadProperties); } + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#paintInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + // Get the legend data to draw + LegendEntry[] legendData = getLegendData(descriptor); + + groupResourceFont = target.initializeFont(target.getDefaultFont() + .getFontName(), target.getDefaultFont().getFontSize(), + new Style[] { Style.ITALIC, Style.BOLD }); + yStart = paintProps.getCanvasBounds().height + - (BOTTOM_OFFSET_IN_PIXELS); + + List legendStrings = generateLegendStrings(target, + paintProps, legendData, RIGHT_OFFSET_IN_PIXELS); + + target.getExtension(ICanvasRenderingExtension.class).drawStrings( + paintProps, legendStrings.toArray(new DrawableString[0])); + } + + @SuppressWarnings("deprecation") + private List generateLegendStrings(IGraphicsTarget target, + PaintProperties paintProps, LegendEntry[] legendData, + int rightOffset) { + List legendStrings = new ArrayList(); + + for (LegendEntry le : legendData) { + + if (le.legendParts[0].resource.getResource() instanceof IPowerLegend) { + + IPowerLegend gr = (IPowerLegend) le.legendParts[0].resource + .getResource(); + if (gr.isNameExpanded()) { + LegendEntry[] legends = getLegendData(gr); + List legendStr = generateLegendStrings( + target, paintProps, legends, RIGHT_OFFSET_IN_PIXELS); + + if (legendStr != null && !legendStr.isEmpty()) { + + for (DrawableString dstring : legendStr) { + dstring.font = groupResourceFont; + + // Adjust xStart with the font. + String legendText = ""; + for (String str : dstring.getText()) { + legendText += str; + } + Rectangle2D stringBounds = target.getStringBounds( + dstring.font, legendText); + + double xStart = paintProps.getCanvasBounds().width + - ((rightOffset + stringBounds.getWidth())); + dstring.setCoordinates(xStart, dstring.basics.y); + + } + + legendStrings.addAll(legendStr); + } + } + } + + String allText = ""; + for (LegendData ld : le.legendParts) { + allText += ld.label; + } + + Rectangle2D allTextBounds = target + .getStringBounds(le.font, allText); + + double xStart = paintProps.getCanvasBounds().width + - ((rightOffset + allTextBounds.getWidth())); + + double maxHeight = 0.0; + for (LegendData ld : le.legendParts) { + String text = ld.label; + DrawableString string = new DrawableString(text, ld.color); + string.font = le.font; + string.setCoordinates(xStart, yStart); + + legendStrings.add(string); + + Rectangle2D textBounds = target.getStringsBounds(string); + xStart += textBounds.getWidth(); + if (textBounds.getHeight() > maxHeight) { + maxHeight = textBounds.getHeight(); + } + } + + yStart -= maxHeight; + + } + + return legendStrings; + } + /* * (non-Javadoc) * @@ -162,40 +289,314 @@ public class NCLegendResource extends } return entries; } - + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.legend.ILegendDecorator#getLegendData(com.raytheon + * .uf.viz.core.drawables.IDescriptor) + */ + private LegendEntry[] getLegendData(IResourceGroup groupResource) { + + List labels = new ArrayList(); + ResourceList resourceList = groupResource.getResourceList(); + if (resourceList != null) { + for (int i = 0; i < resourceList.size(); i++) { + ResourcePair resourcePair = resourceList.get(i); + // See if resource is a system resource (does not + // participate in legend) + boolean system = resourcePair.getProperties() + .isSystemResource(); + // See if resource is visible + boolean vis = resourcePair.getProperties().isVisible(); + AbstractVizResource rsc = resourcePair.getResource(); + if (system) { + continue; + } else { + LegendData legend = new LegendData(); + if (rsc == null) { + continue; + } else if (rsc.getStatus() != ResourceStatus.INITIALIZED) { + continue; + } else { + legend.label = rsc.getName(); + // if the resource is editable, add (Editable) to the + // legend string + if (rsc.hasCapability(EditableCapability.class) + && rsc.getCapability(EditableCapability.class) + .isEditable()) { + legend.label += " (Enabled) "; + } + legend.resource = resourcePair; + } + + if (!vis) { + legend.color = new RGB(50, 50, 50); + } else { + // get the color from the NatlCntrs Resource. + legend.color = new RGB(250, 250, 250); // default to + // white + + try { + // HACK ALERT : currently there is a cyclical + // dependency bug + // that prevents the display project from + // referencing the + // resources project. + // get the method from INatlCntrsResource to get the + // legend + // color + Method[] mthds = legend.resource.getResourceData() + .getClass().getMethods(); + + for (Method m : mthds) { + // System.out.println( m.getName() ); + if (m.getName().equals("getLegendColor")) { + if (m.getReturnType() == RGB.class) { + legend.color = (RGB) m + .invoke(legend.resource + .getResourceData()); + break; + } + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + labels.add(legend); + } + + } + } + + LegendEntry[] entries = new LegendEntry[labels.size()]; + for (int i = 0; i < entries.length; ++i) { + entries[i] = new LegendEntry(); + entries[i].legendParts = new LegendData[] { labels.get(i) }; + } + return entries; + } + protected void initInternal(IGraphicsTarget target) { try { - super.initInternal(target); - } catch (VizException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + super.initInternal(target); + } catch (VizException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + target.initializeFont(NCLegendResource.class.getName()); IDisplayPaneContainer rc = getResourceContainer(); - if (rc == null) - return; - + if (rc == null) + return; + rc.registerMouseHandler(legendHandler, InputPriority.SYSTEM_RESOURCE); } - + @Override - protected void disposeInternal() { - super.disposeInternal(); - - IDisplayPaneContainer rc = getResourceContainer(); - if (rc == null) - return; - + protected void disposeInternal() { + super.disposeInternal(); + + IDisplayPaneContainer rc = getResourceContainer(); + if (rc == null) + return; + rc.unregisterMouseHandler(legendHandler); - } - - @Override - protected ResourcePair checkLabelSpace(IDescriptor descriptor, - IGraphicsTarget target, double x, double y) { - // NOTE: Overridden so legend handlers can call - return super.checkLabelSpace(descriptor, target, x, y); - } + } + + @Override + public void provideContextMenuItems(IMenuManager menuManager, int x, int y) { + IGraphicsTarget target = null; + for (IDisplayPane pane : getResourceContainer().getDisplayPanes()) { + if (pane.getDescriptor() == descriptor) { + target = pane.getTarget(); + break; + } + } + ResourcePair rsc; + List resourcesClicked = getResourceClicked(descriptor, + target, x, y); + if (resourcesClicked != null && !resourcesClicked.isEmpty()) { + // Get the top level resource, otherwise some of the Raytheon code + // cannot find the resource. + rsc = resourcesClicked.get(resourcesClicked.size() - 1); + // rsc = resourcesClicked.get(0); + } else { + rsc = null; + } + + if (rsc != null && rsc.getResource() != null) { + + if (resourcesClicked.size() > 1) { + + // Some of Raytheon actions require the resource be in the + // descriptor. The code below is to add then remove the resource + // into/from the descriptor without firing listeners. + AbstractVizResource originalRes = rsc.getResource(); + + rsc.setResource(null); + originalRes.getDescriptor().getResourceList().add(rsc); + rsc.setResource(originalRes); + + fillContextMenu(menuManager, rsc); + + rsc.setResource(null); + originalRes.getDescriptor().getResourceList().remove(rsc); + rsc.setResource(originalRes); + } else { + fillContextMenu(menuManager, rsc); + } + + } + + for (IContributionItem item : menuManager.getItems()) { + if (item instanceof ActionContributionItem) { + ActionContributionItem act = (ActionContributionItem) item; + + // Remove Raytheon's move-up and move-down actions. + // They don't work with our ResourceGroup. + if (act.getAction() instanceof MoveDownAction + || act.getAction() instanceof MoveUpAction) { + act.setVisible(false); + } + else if ( rsc.getResource() instanceof IPowerLegend && act.getAction().getText().contains("Attributes") ){ + //for group resource, remove the "Edit Attributes" action + act.setVisible(false); + } + } + } + } + + protected List getResourceClicked(IDescriptor descriptor, + IGraphicsTarget target, double x, double y) { + LegendEntry[] legendData = getLegendData(descriptor); + if (legendData == null || legendData.length == 0) { + return null; + } + + // Get the ratio for pixel to gl pixel conversion + double ratio = descriptor.getRenderableDisplay().getView().getExtent() + .getWidth() + / descriptor.getRenderableDisplay().getBounds().width; + + IExtent extent = descriptor.getRenderableDisplay().getView() + .getExtent(); + + x = extent.getMinX() + (x * ratio); + y = extent.getMinY() + (y * ratio); + + double yStart = extent.getMaxY() - ((BOTTOM_OFFSET_IN_PIXELS) * ratio); + + if (y > yStart) { + return null; + } + + List resourcesClicked = new ArrayList(); + getResourceClickedInLegendGroup(descriptor, target, x, y, extent, + ratio, yStart, legendData, resourcesClicked); + + return resourcesClicked; + } + + @SuppressWarnings("deprecation") + private List getResourceClickedInLegendGroup( + IDescriptor descriptor, IGraphicsTarget target, double x, double y, + IExtent extent, double ratio, double yStart, + LegendEntry[] legendData, List resourcesClicked) { + for (LegendEntry le : legendData) { + + // Check if the entry is a group. For NC there is only one legend + // part. + boolean isExpandedGroup = false; + IPowerLegend gr = null; + ResourcePair grpPair = null; + for (LegendData ld : le.legendParts) { + if (ld.resource.getResource() instanceof IPowerLegend) { + grpPair = ld.resource; + gr = (IPowerLegend) ld.resource.getResource(); + isExpandedGroup = gr.isNameExpanded(); + break; + } + } + + // Calculate legend height + String allText = ""; + for (LegendData ld : le.legendParts) { + allText += ld.label; + } + + Rectangle2D allTextBounds = target + .getStringBounds(le.font, allText); + + double legendHeight = (allTextBounds.getHeight() * ratio); + double yEnd = yStart - legendHeight; + + // Calculate group resource legend height + double groupHeight = 0; + if (isExpandedGroup) { + Rectangle2D resourceGroupBounds = target.getStringBounds( + groupResourceFont, allText); + groupHeight = resourceGroupBounds.getHeight() * ratio + * gr.getResourceList().size(); + } + + if (isExpandedGroup && (y <= yStart && y > yStart - groupHeight)) { // in + // group + // resources + resourcesClicked.add(grpPair); + getResourceClickedInLegendGroup(descriptor, target, x, y, + extent, ratio, yStart, getLegendData(gr), + resourcesClicked); + // if not on any member of the group resource, remove the + // parent + if (resourcesClicked.get(resourcesClicked.size() - 1) == grpPair) { + resourcesClicked.remove(resourcesClicked.size() - 1); + } + break; + } else { // either not in group resource or click on the group name + + if (isExpandedGroup) { // click on the group name + yStart -= groupHeight; + yEnd = yStart - legendHeight; + } + + if (y <= yStart && y > yEnd) { + // Found the entry, look at data + + double xEnd = extent.getMaxX() + - (RIGHT_OFFSET_IN_PIXELS * ratio); + + if (x > xEnd) { + return resourcesClicked; + } + + double xStart = xEnd - (allTextBounds.getWidth() * ratio); + + if (x < xStart) { + return resourcesClicked; + } + + for (LegendData ld : le.legendParts) { + String text = ld.label; + Rectangle2D textBounds = target.getStringBounds( + le.font, text); + xEnd = xStart + (textBounds.getWidth() * ratio); + if (x <= xEnd) { + + resourcesClicked.add(ld.resource); + + return resourcesClicked; + } + xStart = xEnd; + } + } + yStart = yEnd; + } + } + return resourcesClicked; + } // @Override // protected void fillContextMenu(IMenuManager menuManager, diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCMapDescriptor.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCMapDescriptor.java index 2e5d623a47..7630e27155 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCMapDescriptor.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCMapDescriptor.java @@ -8,6 +8,7 @@ package gov.noaa.nws.ncep.viz.ui.display; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; +import gov.noaa.nws.ncep.viz.common.display.IPowerLegend; import java.lang.reflect.Method; import java.text.SimpleDateFormat; @@ -56,6 +57,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 07/15/11 C Chen fixed frame number not updated while looping problem * 11/11/11 Greg Hull rm frameChangeListener in place of Raytheon's, synchronize the listener * 01/21/12 #972 Greg Hull implement new INatlCntrsDescriptor + * 09/09/14 ? B. Yin Auto-update for resources in groups * * * @@ -149,10 +151,17 @@ public class NCMapDescriptor extends MapDescriptor implements INatlCntrsDescript try { // for (ResourcePair rp : resourceList) { - if (rp.getResourceData() instanceof AbstractRequestableResourceData) { + if (rp.getResourceData() instanceof AbstractRequestableResourceData || + ( rp.getResource()!= null && rp.getResource() instanceof IPowerLegend)) { if (rp.getResource() != null) { timeMatchingMap.put(rp.getResource(), dataTimes); + if ( rp.getResource() instanceof IPowerLegend ){ + for (ResourcePair pairInGroup : ((IPowerLegend)rp.getResource()).getResourceList() ) { + timeMatchingMap.put(pairInGroup.getResource(), dataTimes); + } + } + } // HACK ALERT : currently there is a cyclical dependency bug diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NcDisplayMngr.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NcDisplayMngr.java index f4a59e6c54..648a5f5e86 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NcDisplayMngr.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NcDisplayMngr.java @@ -5,6 +5,7 @@ import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneID; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; import gov.noaa.nws.ncep.viz.common.display.IPaneLayoutable; +import gov.noaa.nws.ncep.viz.common.display.IPowerLegend; import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; @@ -68,6 +69,7 @@ import com.raytheon.viz.ui.panes.VizDisplayPane; * 08/09/2012 837 Archana Updated getNcDisplayID() to fix a NumberFormatException * 02/10/2012 #971 Greg Hull Renamed from NmapUiUtils and add support for NcDisplayType and NcDisplayName * 05/15/2013 #862 Greg Hull call setPaneManager() ; add method findRenderableDisplayByPaneName() + * 08/18/2014 ? B. Yin Added a method for function key to toggle GroupResource. * * * @@ -530,4 +532,27 @@ public class NcDisplayMngr { } } + /* + * Function key to to activate GroupResource. + */ + public static final void toggleOnResourceGroup(int funcKeyNum) { + AbstractEditor currEditor = NcDisplayMngr.getActiveNatlCntrsEditor(); + for (ResourcePair pair : currEditor.getDisplayPanes()[0] + .getDescriptor().getResourceList()) { + if (pair.getResource() != null + && pair.getResource() instanceof IPowerLegend) { + IPowerLegend grpRes = (IPowerLegend) pair.getResource(); + if (grpRes.getFuncKeyNum() == funcKeyNum) { + ((AbstractVizResource) grpRes).getProperties() + .setVisible(true); + // grpRes.setVisibleForAllResources(true); + } else { + ((AbstractVizResource) grpRes).getProperties() + .setVisible(false); + // grpRes.setVisibleForAllResources(false); + } + } + } + currEditor.refresh(); + } } From 20106062b1c82885714d512115a98f6ed729bbd9 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 18 Sep 2014 14:12:12 -0400 Subject: [PATCH 02/19] VLab Issue #4637 - Fix NCP AWW display issues Change-Id: I7df6d95cd665805046a807d0900ee934da61c18e Former-commit-id: 2d3c8c041393a90246b992e39a0543a6d036b6b2 [formerly 2d3c8c041393a90246b992e39a0543a6d036b6b2 [formerly f31a665a587f7fa324afcfcc332eceb1518c96d6]] Former-commit-id: 79957a312ab49ef2e2ba47adff12c99445656d49 Former-commit-id: e4eb7de3e5904ed7e5db8b6cac3ca717f63160c4 --- .../edex/plugin/aww/decoder/AwwDecoder.java | 379 ++++++++------- .../ncep/edex/plugin/aww/util/AwwParser.java | 24 +- .../rsc/aww/query/WcnCountyQueryResult.java | 4 +- .../nws/ncep/viz/rsc/aww/wcn/WcnResource.java | 434 ++++++++++++++---- .../nws/ncep/viz/rsc/aww/wou/WouResource.java | 343 +++++++++++++- 5 files changed, 881 insertions(+), 303 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java index 505e5c8739..0a3fdf3cce 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java @@ -56,10 +56,11 @@ import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; * 1. if AwwParser.processWMO failed, simply * drop the record by throwing an exception * 2. comment out the end check "if(record == null") - * because it is a dead code. + * because it is a dead code. [DS- removed 8/14] * Aug 08, 2013 1028 G. Hull rm underscores from reportType and set mndTime in URI * Aug 30, 2013 2298 rjpeter Make getPluginName abstract * Mar 21, 2103 1112 S. Russell *.WCN files, get the watch number + * Aug 13, 2014 (none?) D. Sushon refactor to be sure all bulletins get decoded, removed some dead code, marked possibly dead code as such * * * This code has been developed by the SIB for use in the AWIPS2 system. @@ -79,7 +80,10 @@ public class AwwDecoder extends AbstractDecoder { public AwwDecoder() throws DecoderException { } - public PluginDataObject[] decode(byte[] data, Headers headers) throws DecoderException { + public PluginDataObject[] decode(byte[] data, Headers headers) + throws DecoderException { + + List outPdo = new ArrayList(); String traceId = ""; if (headers != null) { @@ -108,202 +112,235 @@ public class AwwDecoder extends AbstractDecoder { messageData = sep.next(); String theMessage = new String(messageData); - /* May have multiple duplicate bulletins, only get the first bulletin - * and eliminate the remaining bulletins after the first bulletin. */ Scanner cc = new Scanner(theMessage).useDelimiter(etx); if (cc.hasNext()) { theBulletin = cc.next(); } else { + // System.out.println("setting.... theBulletin = theMessage;"); theBulletin = theMessage; } - // Set MND (Mass News Disseminator) time string and convert it into - // Calendar object - MndTime mt = new MndTime(theBulletin.getBytes()); - mndTime = mt.getMndTime(); + do { - // Decode and set WMO line - AwwRecord record = AwwParser.processWMO(theBulletin, mndTime); - if (record == null) { - throw new AwwDecoderException("Error on decoding Aww Record"); - } + // Set MND (Mass News Disseminator) time string and convert it into + // Calendar object + MndTime mt = new MndTime(theBulletin.getBytes()); + mndTime = mt.getMndTime(); - boolean isWtchFlag = AwwDecoder.isWtch(record);// Ticket 456 - - // boolean isSevereWeatherStatusFlag = - // AwwDecoder.isSevereWeatherStatus(record); - - // Get report type - String reportType = AwwParser.getReportType(theBulletin); - - ArrayList segmentList = new ArrayList(); - segmentList.clear(); - - // Break the bulletin message into segments by a "$$" - Scanner sc = new Scanner(theBulletin).useDelimiter(segmentDelim); - - boolean isWCN = false; - String wcnLbl = AwwRecord.AwwReportType.WATCH_COUNTY_NOTIFICATION.name(); - wcnLbl = wcnLbl.replace("_", " "); - if (reportType.equals(wcnLbl)) { - isWCN = true; - } - - while (sc.hasNext()) { - String segment = sc.next(); - Matcher ugcMatcher = ugcPattern.matcher(segment); - // discard if the segment did not have an UGC line. - if (ugcMatcher.find() || isWtchFlag) { // ????? not sure if this - // logic is correct - segmentList.add(segment); + // Decode and set WMO line + AwwRecord record = AwwParser.processWMO(theBulletin, mndTime); + if (record == null) { + throw new AwwDecoderException("Error on decoding Aww Record"); } - } - if (record != null) { - try { - // process each segment in a order of UGC, VTEC, H-VTEC, FIPS, - // LATLON... - for (String segment : segmentList) { - Matcher ugcMatcher = ugcPattern.matcher(segment); - AwwUgc ugc = null; + boolean isWtchFlag = AwwDecoder.isWtch(record);// Ticket 456 - // TRAC 1112 - if (isWCN) { - String watchNumber = AwwParser.retrieveWatchNumberFromWCN(segment); - if (watchNumber != null) { - record.setWatchNumber(watchNumber); - if (ugcMatcher.find()) { - ugc = AwwParser.processUgc(ugcMatcher.group(), segment, mndTime, watchesList); + // boolean isSevereWeatherStatusFlag = + // AwwDecoder.isSevereWeatherStatus(record); //dead code? + + // Get report type + String reportType = AwwParser.getReportType(theBulletin); + + ArrayList segmentList = new ArrayList(); + segmentList.clear(); + + // Break the bulletin message into segments by a "$$" + Scanner sc = new Scanner(theBulletin).useDelimiter(segmentDelim); + + boolean isWCN = false; + String wcnLbl = AwwRecord.AwwReportType.WATCH_COUNTY_NOTIFICATION + .name(); + wcnLbl = wcnLbl.replace("_", " "); + if (reportType.equals(wcnLbl)) { + isWCN = true; + } + + while (sc.hasNext()) { + String segment = sc.next(); + Matcher ugcMatcher = ugcPattern.matcher(segment); + // discard if the segment did not have an UGC line. + if (ugcMatcher.find() || isWtchFlag) { // ????? not sure if this + // logic is correct + segmentList.add(segment); + } + } + + if (record != null) { + try { + // process each segment in a order of UGC, VTEC, H-VTEC, + // FIPS, LATLON... + for (String segment : segmentList) { + Matcher ugcMatcher = ugcPattern.matcher(segment); + AwwUgc ugc = null; + + // TRAC 1112 + if (isWCN) { + String watchNumber = AwwParser + .retrieveWatchNumberFromWCN(segment); + if (watchNumber != null) { + record.setWatchNumber(watchNumber); + if (ugcMatcher.find()) { + ugc = AwwParser.processUgc( + ugcMatcher.group(), segment, + mndTime, watchesList); + } } } - } - // local forecast - else if (isWtchFlag) { - ugc = AwwParser.processUgcForWtch(AwwParser.WTCH_BOX_UGC_LINE, segment, mndTime, record.getIssueOffice(), watchesList); - // else if(isSevereWeatherStatusFlag) - // ugc = - // AwwParser.processUgcForSereveWeatherStatus(ugcMatcher.group(), - // segment, mndTime, record.getIssueOffice(), - // watchesList); - String watchNumber = AwwParser.processUgcToRetrieveWatchNumberForThunderstormOrTornado(segment); - record.setWatchNumber(watchNumber); - // } else if(isSevereWeatherStatusFlag) { - // String watchNumber = - // AwwParser.processUgcToRetrieveWatchNumberForStatusReport(segment); - // record.setWatchNumber(watchNumber); - } else if (ugcMatcher.find()) { - ugc = AwwParser.processUgc(ugcMatcher.group(), segment, mndTime, watchesList); - } - - if (ugc != null) { - record.addAwwUGC(ugc); - - /* Collect watch numbers which are the event tracking - * numbers in VTEC lines as one of primary keys in AWW - * record to prevent not writing raw data to DB note: 1. - * each bulletin may have multiple segments 2. each - * segment has one UGC line but may have multiple VTEC - * lines and have more than one watch number */ - /* not quite sure the following logic is correct to - * retrieve and then store the watch number. thus - * comment it out now. M. Gao */ - // if (watchesList.size() > 0) { - // String collectWatches = null; - // for (int idxWatch = 0; idxWatch < watchesList.size(); - // idxWatch++) { - // - // if (idxWatch == 0) { - // collectWatches = watchesList.get(idxWatch); - // } else { - // collectWatches = collectWatches.concat("/") - // .concat(watchesList.get(idxWatch)); - // } - // } - // // System.out.println("==collection length=" + - // // collectWatches.length() ); - // record.setWatchNumber(collectWatches); - // } else { - // - // // The special reports may not have VTEC line; given - // // a default watch number "0000". - // record.setWatchNumber("0000"); - // } - - /* construct VTEC object and then add it to the current - * Ugc for SevereWeatherStatus aww reocrd */ - - if (AwwParser.isSegmentTextValid(segment)) { - /* parse and then set the Watch Number for Status - * Report */ - String watchNumber = AwwParser.processUgcToRetrieveWatchNumberForStatusReport(segment); + // local forecast + else if (isWtchFlag) { + ugc = AwwParser.processUgcForWtch( + AwwParser.WTCH_BOX_UGC_LINE, segment, + mndTime, record.getIssueOffice(), + watchesList); + // else if(isSevereWeatherStatusFlag) ---dead code? + // ugc = + // AwwParser.processUgcForSereveWeatherStatus(ugcMatcher.group(), + // segment, mndTime, record.getIssueOffice(), + // watchesList); + String watchNumber = AwwParser + .processUgcToRetrieveWatchNumberForThunderstormOrTornado(segment); record.setWatchNumber(watchNumber); - - AwwVtec awwVtec = AwwParser.processVtectForSevereWeatherStatus(theBulletin, record.getIssueTime(), record.getIssueOffice()); - Set awwVtecSet = new HashSet(); - awwVtecSet.add(awwVtec); - ugc.setAwwVtecLine(awwVtecSet); - /* now calculate status latlon info and then add to - * ugc */ - List pointAwwLatLonsList = AwwLatLonUtil.getAwwLatLonsListBySereveWeatherStatusPointLine(awwVtec.getVtecLine()); - for (AwwLatlons eachAwwLatlons : pointAwwLatLonsList) { - ugc.addAwwLatLon(eachAwwLatlons); - } + // } else if(isSevereWeatherStatusFlag) { dead code? + // String watchNumber = + // AwwParser.processUgcToRetrieveWatchNumberForStatusReport(segment); + // record.setWatchNumber(watchNumber); + } else if (ugcMatcher.find()) { + ugc = AwwParser.processUgc(ugcMatcher.group(), + segment, mndTime, watchesList); } + if (ugc != null) { + record.addAwwUGC(ugc); + + /* + * Collect watch numbers which are the event + * tracking numbers in VTEC lines as one of primary + * keys in AWW record to prevent not writing raw + * data to DB note: 1. each bulletin may have + * multiple segments 2. each segment has one UGC + * line but may have multiple VTEC lines and have + * more than one watch number + */ + /* + * not quite sure the following logic is correct to + * retrieve and then store the watch number. thus + * comment it out now. M. Gao + */ + // if (watchesList.size() > 0) { + // String collectWatches = null; + // for (int idxWatch = 0; idxWatch < + // watchesList.size(); + // idxWatch++) { + // + // if (idxWatch == 0) { + // collectWatches = watchesList.get(idxWatch); + // } else { + // collectWatches = collectWatches.concat("/") + // .concat(watchesList.get(idxWatch)); + // } + // } + // // System.out.println("==collection length=" + + // // collectWatches.length() ); + // record.setWatchNumber(collectWatches); + // } else { + // + // // The special reports may not have VTEC line; + // // given a default watch number "0000". + // record.setWatchNumber("0000"); + // } + + /* + * construct VTEC object and then add it to the + * current Ugc for SevereWeatherStatus aww reocrd + */ + + if (AwwParser.isSegmentTextValid(segment)) { + /* + * parse and then set the Watch Number for + * Status Report + */ + String watchNumber = AwwParser + .processUgcToRetrieveWatchNumberForStatusReport(segment); + record.setWatchNumber(watchNumber); + + AwwVtec awwVtec = AwwParser + .processVtectForSevereWeatherStatus( + theBulletin, + record.getIssueTime(), + record.getIssueOffice()); + Set awwVtecSet = new HashSet(); + awwVtecSet.add(awwVtec); + ugc.setAwwVtecLine(awwVtecSet); + /* + * now calculate status latlon info and then add + * to ugc + */ + List pointAwwLatLonsList = AwwLatLonUtil + .getAwwLatLonsListBySereveWeatherStatusPointLine(awwVtec + .getVtecLine()); + for (AwwLatlons eachAwwLatlons : pointAwwLatLonsList) { + ugc.addAwwLatLon(eachAwwLatlons); + } + } + + } } + + } catch (Exception e) { + logger.error("Error processing decoded segment", e); + record = null; + } + } + + if (record != null) { + // T976 - check if the record has a valid UGC. If not return an + // empty PluginDataObject array + if ((record.getAwwUGC() == null) + || (record.getAwwUGC().size() == 0)) { + return new PluginDataObject[0]; } - } catch (Exception e) { - logger.error("Error processing decoded segment", e); - record = null; - } - } - /* Check the AWW record object. If not, throws exception. */ - if (record != null) { - // T976 - check if the record has a valid UGC. If not return an - // empty PluginDataObject array - if ((record.getAwwUGC() == null) || (record.getAwwUGC().size() == 0)) { - return new PluginDataObject[0]; - } + record.setReportType(reportType.trim()); + record.setTraceId(traceId); + // Set MND remark before the URI is constructed + if ((mt.getMndTimeString() == null) + || mt.getMndTimeString().trim().isEmpty()) { + record.setMndTime("unknown"); + } else { + record.setMndTime(mt.getMndTimeString()); + } - record.setReportType(reportType.trim()); - record.setTraceId(traceId); - // Set MND remark before the URI is constructed - if ((mt.getMndTimeString() == null) || mt.getMndTimeString().trim().isEmpty()) { - record.setMndTime("unknown"); + try { + record.constructDataURI(); + } catch (PluginException e) { + throw new DecoderException(this.getClass() + .getCanonicalName() + + ":Error constructing dataURI:", e); + } } else { - record.setMndTime(mt.getMndTimeString()); + throw new DecoderException(this.getClass().getCanonicalName() + + ":Error Aww Record object is NULL"); } - try { - record.constructDataURI(); - } catch (PluginException e) { - throw new DecoderException("Error constructing dataURI", e); + // Decode and set attention line + record.setAttentionWFO(AwwParser.processATTN(theBulletin)); + + // Replace special characters to a blank so that it may be readable. + if (theBulletin.length() < 40000) { + record.setBullMessage(UtilN + .removeLeadingWhiteSpaces(theBulletin + .replace('\r', ' ').replace('\003', ' ') + .replace('\000', ' ').replace('\001', ' ') + .replace('\036', ' '))); } - } else { - throw new DecoderException("Error Aww Reocrd object is NULL"); - } - // Decode and set attention line - record.setAttentionWFO(AwwParser.processATTN(theBulletin)); - - // Replace special characters to a blank so that it may be readable. - if (theBulletin.length() < 40000) { - record.setBullMessage(UtilN - .removeLeadingWhiteSpaces(theBulletin.replace('\r', ' ').replace('\003', ' ').replace('\000', ' ').replace('\001', ' ').replace('\036', ' '))); - } - - // Return the AwwRecord record object. - // if (record == null) { - // return new PluginDataObject[0]; - // } else { - // return new PluginDataObject[] {record}; - // } - /* The reason the above is commented out is the check to see if record - * == null is a dead code. It will never get executed according the - * logic before the if statement. */ - return new PluginDataObject[] { record }; + outPdo.add(record); + if (cc.hasNext()) { + theBulletin = cc.next(); + } + } while (cc.hasNext()); + return outPdo.toArray(new PluginDataObject[] {}); } /** diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/util/AwwParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/util/AwwParser.java index 440c1ca359..43e6ae2f02 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/util/AwwParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/util/AwwParser.java @@ -19,6 +19,8 @@ * 01/26/2011 N/A M. Gao Refactor: * change the WMO regular expression more flexible. * 08/01/2013 1028 G. Hull sanity check on AwwReportType. + * 9/15/2014 4637 J. Huber Changed parser for WCN's to read VTEC lines to parse out the watch + * number instead of the WATCH NOTIFICATION string. * * * @@ -53,6 +55,7 @@ import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.database.DataAccessLayerException; public class AwwParser { + private final static String VTEC_EXP = "(/([A-Z]{1}).([A-Z]{3}).([A-Z]{4}).([A-Z]{2}).([A-Z]{1}).([0-9]{4}).([0-9]{6}T[0-9]{4})Z-([0-9]{6}T[0-9]{4})Z/\\x0d\\x0d\\x0a)+"; private static Logger logger = Logger.getLogger(AwwParser.class .getCanonicalName()); @@ -315,19 +318,18 @@ public class AwwParser { } /* TRAC 1112 Extract the watch number from a *.WCN file segment */ + /* + * RM 4697 Use VTEC Line to extract watch number instead of WATCH COUNTY + * NOTIFCATION text string + */ public static String retrieveWatchNumberFromWCN(String segment) { String watchNmbr = null; - int watchNmbrLength = 4; - int lengthDiff = 0; - String s = "WATCH COUNTY NOTIFICATION FOR WATCH\\s+(\\d+)\\s+"; - Pattern p = Pattern.compile(s); + Pattern p = Pattern.compile(VTEC_EXP); Matcher m = p.matcher(segment); - if (m.find()) { - watchNmbr = m.group(1); - watchNmbr = (watchNmbr != null) ? watchNmbr.trim() : watchNmbr; + watchNmbr = m.group(7); + watchNmbr = watchNmbr.replaceAll("^0+", ""); } - return watchNmbr; } @@ -392,9 +394,6 @@ public class AwwParser { String trackingNumber; int[] latlonIndex = new int[1]; - // Regular expression for VTEC line - final String VTEC_EXP = "(/([A-Z]{1}).([A-Z]{3}).([A-Z]{4}).([A-Z]{2}).([A-Z]{1}).([0-9]{4}).([0-9]{6}T[0-9]{4})Z-([0-9]{6}T[0-9]{4})Z/\\x0d\\x0d\\x0a)+"; - // Pattern used to extract VTEC line final Pattern vtecPattern = Pattern.compile(VTEC_EXP); @@ -629,9 +628,6 @@ public class AwwParser { String trackingNumber; int[] latlonIndex = new int[1]; - // Regular expression for VTEC line - final String VTEC_EXP = "(/([A-Z]{1}).([A-Z]{3}).([A-Z]{4}).([A-Z]{2}).([A-Z]{1}).([0-9]{4}).([0-9]{6}T[0-9]{4})Z-([0-9]{6}T[0-9]{4})Z/\\x0d\\x0d\\x0a)+"; - // final String WTCH_VTEC_EXP = // "WW\\s\\d{3}\\sTORNADO\\s([A-Z]{2}\\s)+CW\\s(\\d{6}Z)\\s\\-\\s(\\d{6}Z)"; final String WTCH_VTEC_EXP = "WW\\s(\\d{1,4})\\s(TORNADO|SEVERE TSTM)\\s((\\w+|\\s+)*)\\s(\\d{6}Z)\\s\\-\\s(\\d{6}Z)"; // Pattern used to extract VTEC line diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/query/WcnCountyQueryResult.java b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/query/WcnCountyQueryResult.java index 0ae5f04ae8..2ec5c61270 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/query/WcnCountyQueryResult.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/query/WcnCountyQueryResult.java @@ -197,8 +197,8 @@ public class WcnCountyQueryResult { ArrayList> list = fipsMultiResultMap.get(fips); - if (list == null) { - logger.log(Level.WARNING, "_______ No result for fips: " + fips); + if (list == null) {// mute? clouds output when CAVE is on during ingest + logger.log(Level.FINEST, "_______ No result for fips: " + fips); return new ArrayList>(); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java index 73c11c3ec2..fcbf9b0470 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java @@ -28,6 +28,9 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.swt.graphics.RGB; import org.geotools.geometry.jts.ReferencedEnvelope; @@ -83,7 +86,10 @@ import com.vividsolutions.jts.io.WKBReader; * Added label/time for union. Modified fill alpha to 0.5. * Remove constraint & metamap in initResource(). * 08/14/2013 1028 G. Hull Move to aww project. Use AwwReportType enum. - * + * 9/15/2014 4637 J. Huber Fixed a duplicate key issue in the display hash map as well as as logic error in + * parsing the ugc line where it started with a string that need to be re-parsed. Also + * incorporating changes made by Dimitry for actually handling the > in UGC as well as + * modifying times as appropriate. * * * @author ujosyula @@ -101,6 +107,8 @@ public class WcnResource extends private List modifyList; + int timesThrough = 2; + public class WcnRscDataObj implements IRscDataObject { String datauri; // used as a key string @@ -172,10 +180,28 @@ public class WcnResource extends WcnRscDataObj existingWcnData = wcnDataMap .get(wcnRscDataObj.datauri); + // RM 4697 make unique keys so that all ugc entries are mapped. + if (existingWcnData == null || wcnRscDataObj.issueTime - .greaterThan(existingWcnData.issueTime)) { - wcnDataMap.put(wcnRscDataObj.datauri, wcnRscDataObj); + .greaterThan(existingWcnData.issueTime) + || wcnDataMap.containsKey(wcnRscDataObj.datauri)) { + if (wcnDataMap.containsKey(wcnRscDataObj.datauri)) { + String s = ""; + String r = ""; + + // Put all counties in the WCN into the hash map key to + // avoid iterator clean up issues + + for (int i = 0; i < wcnRscDataObj.countyFips.size(); i++) { + s = wcnRscDataObj.countyFips.get(i); + r = r + " " + s; + } + wcnDataMap.put(wcnRscDataObj.datauri + " " + r, + wcnRscDataObj); + } else { + wcnDataMap.put(wcnRscDataObj.datauri, wcnRscDataObj); + } } return true; @@ -207,9 +233,84 @@ public class WcnResource extends } } + private void fipsRangeReparse(String inUgcPart, String countyname, + List outList) { + final String inclusiveDelim = ">"; + String county = countyname; + String countyFips; + + if (inUgcPart.length() == 10) { // "([A-Z]{3}[0-9]{3}[>][0-9]{3})" + String intervalToken = inUgcPart.substring(3, 10); + county = inUgcPart.substring(0, 3); + + // Format in NAMDDD1>DDD2 + StringTokenizer twoTokens = new StringTokenizer(intervalToken, + inclusiveDelim); + String firstToken = twoTokens.nextToken(); + String secondToken = twoTokens.nextToken(); + + Integer countyBegin = Integer.parseInt(firstToken); + Integer countyEnd = Integer.parseInt(secondToken); + + for (int counter = countyBegin; counter <= countyEnd; counter++) { + + String inclusiveToken = Integer.toString(counter); + + // set "1" to "001" ...etc + if (counter < 10) { + inclusiveToken = "00".concat(inclusiveToken); + } + + // set "10" to "010" ...etc + else if (counter < 100) { + inclusiveToken = "0".concat(inclusiveToken); + } + countyFips = county.concat(inclusiveToken); + + outList.add(countyFips); + // UGC.addAwwFIPS(currentFips); + } + } else if (inUgcPart.length() == 7) { // "([0-9]{3}[>][0-9]{3})" + // A continuation of previous county FIPS + // with format DDD1>DDD2 + StringTokenizer twoTokens = new StringTokenizer(inUgcPart, + inclusiveDelim); + String firstToken = twoTokens.nextToken(); + String secondToken = twoTokens.nextToken(); + + Integer countyBegin = Integer.parseInt(firstToken); + Integer countyEnd = Integer.parseInt(secondToken); + + for (int counter = countyBegin; counter <= countyEnd; counter++) { + + String inclusiveToken = Integer.toString(counter); + + // set "1" to "001" ...etc + if (counter < 10) { + inclusiveToken = "00".concat(inclusiveToken); + } + + // set "10" to "010" ...etc + else if (counter < 100) { + inclusiveToken = "0".concat(inclusiveToken); + } + countyFips = county.concat(inclusiveToken); + + outList.add(countyFips); + // UGC.addAwwFIPS(currentFips); + } + } else { + outList.add(inUgcPart);// risky? + } + } + private ArrayList getAwwtData(AwwRecord awwRecord) { WcnRscDataObj wcnStatusData = null; List wcnDataList = new ArrayList(); + + final String ENDTIME_REGEX = "([0-9]{6})"; + final Pattern endTimePattern = Pattern.compile(ENDTIME_REGEX); + try { Set awwUgc = awwRecord.getAwwUGC(); for (AwwUgc awwugcs : awwUgc) { @@ -228,18 +329,16 @@ public class WcnResource extends wcnStatusData.reportType = AwwReportType.TORNADO_WATCH;// "TORNADO"; } - if (!(wcnStatusData.isCounty = isCountyUgs(awwugcs))) {// verify - // = - // isn't - // typo - // System.err.println("****** " + - // awwugcs.getEventTrackingNumber() + "-" + if (!(wcnStatusData.isCounty = isCountyUgs(awwugcs))) { + // System.err.println("****** " + // + awwugcs.getEventTrackingNumber() + "-" // + awwugcs.getProdPurgeTime() + " **************");// TODO setMarineZonesFips(awwugcs.getAwwFIPS(), wcnStatusData);// T456 } String ugcline = awwugcs.getUgc();// get the ugc line to find // the counties if (ugcline != null && ugcline != "") { + wcnStatusData.watchNumber = awwugcs .getEventTrackingNumber(); wcnStatusData.countyUgc = new ArrayList(); @@ -251,61 +350,92 @@ public class WcnResource extends while (strugcs.hasMoreTokens()) { temp = strugcs.nextToken("-"); - if (temp != null) { - if (temp.contains("\r\r\n")) { + boolean dontSkip = true; + + Matcher endTimeMatcher = endTimePattern.matcher(temp); + if (endTimeMatcher.find()) { + dontSkip = false; + } + + if (temp != null && dontSkip) { + if (temp.startsWith("\r\r\n")) { // was + // .contains("\r\r\n") String temp1 = temp.substring(3); temp = temp1; } + if (temp.contains(countyname)) { - // System.out.println(temp + ":" - // + awwugcs.getEventTrackingNumber() - // + ":" + countyname + ":" - // + wcnStatusData.datauri); - (wcnStatusData.countyUgc).add(temp); - // awwugcs.setUgc(temp); - } else { - // WcnCountyQueryResult - // .trackError( - // System.getProperties() - // .getProperty( - // "user.home") - // + "//caveData//log.txt", - // "2:" - // + temp - // + ":" - // + awwugcs - // .getEventTrackingNumber() - // + ":" + countyname - // + ":" - // + wcnStatusData.datauri); - // System.err.println(temp + ":" - // + awwugcs.getEventTrackingNumber() - // + ":" + countyname + ":" - // + wcnStatusData.datauri); - try { - if (6 == temp.length() - && 0 < (Integer.parseInt(temp - .substring(0, 3)))) { - awwugcs.setUgc(temp.substring(0, 3)); - countyname = temp.substring(0, 3); + + if (temp.length() == 6) { + if ((0 == Character.getNumericValue(temp + .toCharArray()[3])) + && (0 == Character + .getNumericValue(temp + .toCharArray()[4])) + && (0 == Character + .getNumericValue(temp + .toCharArray()[5]))) { + } else { + (wcnStatusData.countyUgc).add(temp); + // awwugcs.setUgc(temp); } - } catch (NumberFormatException nfe) { - // do nothing? or?? - // awwugcs.setUgc(temp.substring(0, 3)); + } else { + fipsRangeReparse(temp, countyname, + (wcnStatusData.countyUgc)); + } + + } else if (temp.length() == 7) { + fipsRangeReparse(temp, countyname, + (wcnStatusData.countyUgc)); + } else { + if (!"".equalsIgnoreCase(temp) + && Character.isLetter(temp + .toCharArray()[0])) { countyname = temp.substring(0, 3); - } finally { // String temp1 = temp.substring(0, - // 3); temp = temp1; - // System.err.println(countyname); - (wcnStatusData.countyUgc).add(countyname - .concat(temp)); + String temp2 = countyname.substring(0, 3) + + temp.substring(3); + (wcnStatusData.countyUgc).add(temp2 + // countyname.concat(temp.substring(3)) + ); + // (wcnStatusData.countyUgc).add(temp); + } + + String temp2 = countyname.substring(0, 3) + + temp; + if (temp2.length() > 6) { + if (9 == temp2.length()) { + (wcnStatusData.countyUgc).add(temp2 + .substring(3, 9)); + } else { + // (wcnStatusData.countyUgc).add(temp2 + // .substring(0, 6)); + fipsRangeReparse(temp2.substring(0, 6), + countyname, + (wcnStatusData.countyUgc)); + } + } else { + if (!(6 > temp2.length()) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[3])) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[4])) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[5]))) { + System.err.println(temp2); + } else { + (wcnStatusData.countyUgc).add(temp2); + } } } i++; } } if (i > 1) { - wcnStatusData.countyUgc.remove(i - 1); - wcnStatusData.countyUgc.remove(i - 2); + wcnStatusData.countyUgc.remove(wcnStatusData.countyUgc + .size() - 1);// cleanup } wcnStatusData = getCountyNameLatLon(wcnStatusData); @@ -329,6 +459,14 @@ public class WcnResource extends if ((awwVtech.getAction().equalsIgnoreCase("COR")) || (awwVtech.getAction() .equalsIgnoreCase("CAN")) + || (awwVtech.getAction() + .equalsIgnoreCase("NEW")) + || (awwVtech.getAction() + .equalsIgnoreCase("EXA")) + || (awwVtech.getAction() + .equalsIgnoreCase("EXB")) + || (awwVtech.getAction() + .equalsIgnoreCase("EXT")) || (awwVtech.getAction() .equalsIgnoreCase("EXP"))) { modifyList.add(wcnStatusData); @@ -367,15 +505,15 @@ public class WcnResource extends } } catch (NumberFormatException nfe) { - // // may need to handle.. - // System.err - // .println("****** NumberFormatException fired off somewhere **********************************************" - // + "\n" + nfe.getLocalizedMessage()); + // may need to handle.. + System.err + .println("****** NumberFormatException **** ****** *** *** ****** *** *** ****** *** *** ******" + + "\n" + nfe.getLocalizedMessage()); } catch (Exception e) { - System.out.println("at line 212" + e);// TODO what is this? logger.warning("In getAwwtData(AwwRecord awwRecord)\n" + e.getClass().getCanonicalName() + ":" + e.getLocalizedMessage()); + e.printStackTrace(); } preProcessFrameUpdate(); @@ -383,6 +521,20 @@ public class WcnResource extends return (ArrayList) wcnDataList; } + // prior: + // "select AsBinary(the_geom), AsBinary(the_geom_0_001), wfo,name,id, lat, lon from mapdata.marinezones where "; + private static String queryPrefixMZ_LatLons = "select wfo,name,id, lat, lon from mapdata.marinezones"; + + // where ST_SetSrid('BOX3D(-180.0 -90.0, 180.0 90.0)'::box3d,4326)"; + + // private static final double ENV_MIN_X = -180.0; + // private static final double ENV_MAX_X = 180.0; + // private static final double ENV_MIN_Y = -90; + // private static final double ENV_MAX_Y = 90.0; + // private String geoConstraint = + // String.format("the_geom_0_001 && ST_SetSrid('BOX3D(%f %f, %f %f)'::box3d,4326)", + // ENV_MIN_X, ENV_MIN_Y, ENV_MAX_X, ENV_MAX_Y); + private WcnRscDataObj getCountyNameLatLon(WcnRscDataObj wdata) { wdata.countyPoints = new ArrayList(); wdata.countyNames = new ArrayList(); @@ -392,10 +544,13 @@ public class WcnResource extends try { int i = 0; + for (Iterator iterator = wdata.countyUgc.iterator(); iterator .hasNext();) { + String theKey = iterator.next(); + Station station = stationTable.getStation(StationField.STID, - iterator.next()); + theKey); if (station != null) { LatLonPoint point = new LatLonPoint(station.getLatitude(), station.getLongitude(), LatLonPoint.INDEGREES); @@ -404,16 +559,53 @@ public class WcnResource extends wdata.stateNames.add(station.getState()); wdata.countyLat[i] = station.getLatitude(); wdata.countyLon[i] = station.getLongitude(); - i++; - // if (wdata.isCounty) { // will do always work w/marine - // zones? //TODO cleanup if no - String s = station.getStnnum(); - wdata.countyFips.add(s.length() == 4 ? "0" + s : s); - // }// T456 AwwUgc.getAwwFIPS + + if (wdata.isCounty) { + String s = station.getStnnum(); + wdata.countyFips.add(s.length() == 4 ? "0" + s : s); + }// T456 AwwUgc.getAwwFIPS + + } else { + // ELSE: + // + // GUC110 == maps.id + // 69110 ??? + // Saipan == maps.name + // GU ... + // US ... + // 15.19 == maps.lat + // 145.76 == maps.lon + // 0 0.. + // 0 + // GUM == maps.wfo + // + + List results = DirectDbQuery.executeQuery( + queryPrefixMZ_LatLons.toString() + " where id = '" + + theKey + "'", "maps", QueryLanguage.SQL); + + LatLonPoint point = new LatLonPoint( + Float.parseFloat(results.get(0)[3].toString()), + Float.parseFloat(results.get(0)[4].toString()), + LatLonPoint.INDEGREES); + wdata.countyPoints.add(point); + wdata.countyNames.add(results.get(0)[1].toString()); + wdata.stateNames.add(""); + wdata.countyLat[i] = Float.parseFloat(results.get(0)[3] + .toString()); + wdata.countyLon[i] = Float.parseFloat(results.get(0)[4] + .toString()); + wdata.countyFips.add(results.get(0)[2].toString()); } + i++; } + } catch (IndexOutOfBoundsException idxOobEx) { + logger.log(Level.FINEST, + "In getCountyNameLatLon(WcnRscDataObj wdata)\n" // mute? + + idxOobEx.getClass().getCanonicalName() + + ":" + + idxOobEx.getLocalizedMessage()); } catch (Exception e) { - System.out.println("wcnResource.java at Line 245" + e); logger.warning("In getCountyNameLatLon(WcnRscDataObj wdata)\n" + e.getClass().getCanonicalName() + ":" + e.getLocalizedMessage()); @@ -434,11 +626,9 @@ public class WcnResource extends private void modifyQueue() { if (modifyList != null) { - // int idx = 0; for (WcnRscDataObj modify : modifyList) { for (IRscDataObject rscDataObj : newRscDataObjsQueue) { WcnRscDataObj candidate = (WcnRscDataObj) rscDataObj; - // System.out.print(idx + ":" + candidate.eventType); if (modify.evTrack.equalsIgnoreCase(candidate.evTrack) && modify.evOfficeId @@ -449,19 +639,23 @@ public class WcnResource extends .equalsIgnoreCase(candidate.evProductClass) && modify.evSignificance .equalsIgnoreCase(candidate.evSignificance)) { - // System.out.print(idx + ":" + candidate.eventType); if (candidate.eventType.equalsIgnoreCase("CAN")) { // System.err.print(modify.issueTime // .getDisplayString() // + "**" // + modify.evEndTime.getDisplayString()); - // candidate.evEndTime = modify.issueTime; - // candidate.eventTime = new DataTime( - // candidate.eventTime.getRefTimeAsCalendar(), - // new TimeRange(candidate.eventTime - // .getRefTimeAsCalendar(), - // candidate.evEndTime - // .getRefTimeAsCalendar()));// ? + candidate.evEndTime = modify.issueTime; + // (modify.issueTime.getValidTimeAsDate().getTime() + // <= modify.evEndTime + // .getValidTimeAsDate().getTime() ? + // modify.issueTime + // : modify.evEndTime); + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar()));// ? } else if (candidate.eventType.equalsIgnoreCase("COR")) { candidate.evEndTime = modify.evEndTime; candidate.eventTime = new DataTime( @@ -471,13 +665,46 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar()));// ? } else if (candidate.eventType.equalsIgnoreCase("EXP")) { - // candidate.evEndTime = modify.issueTime; - // candidate.eventTime = new DataTime( - // candidate.eventTime.getRefTimeAsCalendar(), - // new TimeRange(candidate.eventTime - // .getRefTimeAsCalendar(), - // candidate.evEndTime - // .getRefTimeAsCalendar())); + candidate.evEndTime = modify.issueTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("EXA")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("EXT")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("NEW")) { + candidate.eventTime = modify.eventTime; + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("EXB")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); } else if (candidate.eventType.equalsIgnoreCase("CON")) { candidate.evEndTime = modify.evEndTime; candidate.eventTime = new DataTime( @@ -487,7 +714,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar())); } else { - candidate.evEndTime = modify.issueTime; + candidate.evEndTime = modify.evEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -498,8 +725,6 @@ public class WcnResource extends } } - // System.out.println(); - // idx++; } }// end if !null } @@ -655,6 +880,24 @@ public class WcnResource extends draw = true; } + if (getCurrentFrameTime().getValidTimeAsDate().getTime() <= wcnData + .getDataTime().getValidPeriod().getEnd().getTime() + || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wcnData + .getDataTime().getValidPeriod().getStart() + .getTime()) { + draw = true;// verify this rule; + } + + if (getCurrentFrameTime().getValidTimeAsDate().getTime() > wcnData + .getDataTime().getValidPeriod().getEnd().getTime()) { + draw = false; + } + + if (getCurrentFrameTime().getValidTimeAsDate().getTime() < wcnData + .getDataTime().getValidPeriod().getStart().getTime()) { + draw = false; + } + if (getCurrentFrameTime().getValidTimeAsDate().getTime() == (wcnData .getDataTime().getValidPeriod().getEnd().getTime())) { // do not draw endtime frame, that's what nmap2 does @@ -687,7 +930,10 @@ public class WcnResource extends } } } catch (Exception e) { - System.out.println("error at line 392 " + e); + logger.warning("In paintFrame(AbstractFrameData frameData, IGraphicsTarget target,PaintProperties paintProps)\n" + + e.getClass().getCanonicalName() + + ":" + + e.getLocalizedMessage()); } } if (wcnRscData.getWatchBoxFillEnable()) { @@ -728,7 +974,8 @@ public class WcnResource extends enabledText.add(wcnData.watchNumber); } - if (wcnRscData.getWatchBoxTimeEnable()) { + if (wcnRscData.getWatchBoxTimeEnable()) { // change from + // box-time? DataTime startTime = new DataTime(wcnData.eventTime .getValidPeriod().getStart()); DataTime endTime = new DataTime(wcnData.eventTime @@ -778,7 +1025,6 @@ public class WcnResource extends /* * 0 for drawoutline 1 for shaded shape 2 for union */ - public void drawCountyOutline(WcnRscDataObj wcnData, IGraphicsTarget target, RGB color, int symbolWidth, LineStyle lineStyle, PaintProperties paintProps, @@ -930,7 +1176,7 @@ public class WcnResource extends } } } catch (Exception e) { - System.out.println("wcnResource.java at Line 427" + e); + System.out.println("wcnResource.java at Line 427" + e);// TODO fix } } @@ -1027,7 +1273,6 @@ public class WcnResource extends Collection gw = new ArrayList(), gu = new ArrayList(); for (int i = 0; i < wrdo.countyFips.size(); i++) { - // System.out.print("i" + i); // another loop handles multiple rows in maps // mapdata.county table for (ArrayList results : queryResult @@ -1041,7 +1286,7 @@ public class WcnResource extends for (Object[] result : results) { int k = 0; byte[] wkb1 = (byte[]) result[k]; - // System.out.print("k" + k); + MultiPolygon countyGeo = null; try { countyGeo = (MultiPolygon) wkbReader @@ -1148,6 +1393,13 @@ public class WcnResource extends return; } + if (getCurrentFrameTime().getValidTimeAsDate().getTime() <= wData + .getDataTime().getValidPeriod().getEnd().getTime() + || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wData + .getDataTime().getValidPeriod().getStart().getTime()) { + // draw = true;// verify this rule; // // // // // // // // //TODO + } + if (shadedShape != null && shadedShape.isDrawable() && drawOutlineOrShadedshapeorUnion == 1) { try { diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wou/WouResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wou/WouResource.java index 4fe2a976b6..c4a2001a24 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wou/WouResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wou/WouResource.java @@ -1,5 +1,6 @@ package gov.noaa.nws.ncep.viz.rsc.aww.wou; +import gov.noaa.nws.ncep.common.dataplugin.aww.AwwFips; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwRecord; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwRecord.AwwReportType; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwUgc; @@ -25,6 +26,9 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.swt.graphics.RGB; import org.geotools.geometry.jts.ReferencedEnvelope; @@ -80,6 +84,9 @@ import com.vividsolutions.jts.io.WKBReader; * Added label/time for union. Fixed a bug for querying county. Modified fill alpha to 0.5. * 09/13/12 857 Q. Zhou Remove constraint & metamap in initResource(). * 08/14/13 1028 G. Hull Move to aww project. Use AwwReportType enum. + * 9/15/14 4637 J. Huber Added fipsRangeReparse to handle "character" in UGC line. Also added logic on when to use it. + * Also fixed a clean up error for the county list array which prevented some counties from being + * displayed. * * * @@ -102,6 +109,9 @@ public class WouResource extends // Area change flag private boolean areaChangeFlag = false; + private static java.util.logging.Logger logger = java.util.logging.Logger + .getLogger(WouResource.class.getCanonicalName()); + private class WouRscDataObj implements IRscDataObject { String datauri; // used as a key string @@ -137,6 +147,10 @@ public class WouResource extends String evSignificance; + boolean isCounty; // TODO + + List countyFips = new ArrayList(); // probably TODO + @Override public DataTime getDataTime() { return eventTime; @@ -220,9 +234,8 @@ public class WouResource extends @Override public boolean updateFrameData(IRscDataObject rscDataObj) { if (!(rscDataObj instanceof WouRscDataObj)) { - System.out - .println("WouResource.updateFrameData: expecting objects " - + " of type WouRscDataObj???"); + logger.warning("WouResource.updateFrameData: expecting objects " + + " of type WouRscDataObj???"); return false; } @@ -269,10 +282,11 @@ public class WouResource extends wData.rebuild = true; } if (oldStatus != newStatus) { - if (newStatus) + if (newStatus) { wData.numOfActCnties++; - else + } else { wData.numOfActCnties--; + } } } } else { @@ -355,10 +369,11 @@ public class WouResource extends WouRscDataObj wouStatusData = null; List wouDataList = new ArrayList(); + final String ENDTIME_REGEX = "([0-9]{6})"; + final Pattern endTimePattern = Pattern.compile(ENDTIME_REGEX); + try { - Set awwUgc = awwRecord.getAwwUGC(); - for (AwwUgc awwugcs : awwUgc) { wouStatusData = new WouRscDataObj(); wouStatusData.issueTime = new DataTime(awwRecord.getIssueTime()); @@ -366,6 +381,10 @@ public class WouResource extends .getReportType(awwRecord.getReportType()); wouStatusData.datauri = awwRecord.getDataURI(); + if (!(wouStatusData.isCounty = isCountyUgs(awwugcs))) { + setMarineZonesFips(awwugcs.getAwwFIPS(), wouStatusData); + } + String ugcline = awwugcs.getUgc();// get the ugc line to find // the counties if (ugcline != null && ugcline != "") { @@ -378,27 +397,100 @@ public class WouResource extends StringTokenizer strugcs = new StringTokenizer(ugcline); while (strugcs.hasMoreTokens()) { temp = strugcs.nextToken("-"); - if (temp != null) { - if (temp.contains("\r\r\n")) { + + boolean dontSkip = true; + + Matcher endTimeMatcher = endTimePattern.matcher(temp); + if (endTimeMatcher.find()) { + dontSkip = false; + } + // Pull together a county list expanding the ">" + // character if necessary + if (temp != null && dontSkip) { + if (temp.startsWith("\r\r\n")) { String temp1 = temp.substring(3); temp = temp1; } if (temp.contains(countyname)) { - (wouStatusData.countyUgc).add(temp); + + if (temp.length() == 6) { + if ((0 == Character.getNumericValue(temp + .toCharArray()[3])) + && (0 == Character + .getNumericValue(temp + .toCharArray()[4])) + && (0 == Character + .getNumericValue(temp + .toCharArray()[5]))) { + // not in mapdata.marinezones yet, keep + // parsing + } else { + (wouStatusData.countyUgc).add(temp); + } + } else { + fipsRangeReparse(temp, countyname, + (wouStatusData.countyUgc)); + } + } else if (temp.length() == 7) { + fipsRangeReparse(temp, countyname, + (wouStatusData.countyUgc)); + } else { - (wouStatusData.countyUgc).add(countyname - .concat(temp)); + if (!"".equalsIgnoreCase(temp) + && Character.isLetter(temp + .toCharArray()[0])) { + countyname = temp.substring(0, 3); + String temp2 = countyname.substring(0, 3) + + temp.substring(3); + (wouStatusData.countyUgc).add(temp2); + } + + // (wouStatusData.countyUgc).add(countyname.concat(temp)); + + String temp2 = countyname.substring(0, 3) + + temp; + if (temp2.length() > 6) { + if (9 == temp2.length()) { + (wouStatusData.countyUgc).add(temp2 + .substring(3, 9)); + } else { + // (wcnStatusData.countyUgc).add(temp2 + // .substring(0, 6)); + fipsRangeReparse(temp2.substring(0, 6), + countyname, + (wouStatusData.countyUgc)); + } + } else { + if (!(6 > temp2.length()) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[3])) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[4])) + && (0 == Character + .getNumericValue(temp2 + .toCharArray()[5]))) { + // not in mapdata.marinezones yet, keep + // parsing + // System.err.println(temp2); + } else { + (wouStatusData.countyUgc).add(temp2); + } + } + } i++; } } if (i > 1) { - wouStatusData.countyUgc.remove(i - 1); - wouStatusData.countyUgc.remove(i - 2); + wouStatusData.countyUgc.remove(wouStatusData.countyUgc + .size() - 1);// cleanup } wouStatusData = getCountyNameLatLon(wouStatusData); } + int vtechNumber = awwugcs.getAwwVtecLine().size(); if (vtechNumber > 0) { for (AwwVtec awwVtech : awwugcs.getAwwVtecLine()) { @@ -417,6 +509,10 @@ public class WouResource extends if ((awwVtech.getAction().equalsIgnoreCase("COR")) || (awwVtech.getAction() .equalsIgnoreCase("CAN")) + || (awwVtech.getAction() + .equalsIgnoreCase("NEW")) + || (awwVtech.getAction() + .equalsIgnoreCase("EXT")) || (awwVtech.getAction() .equalsIgnoreCase("EXP"))) { modifyList.add(wouStatusData); @@ -449,12 +545,16 @@ public class WouResource extends wouDataList.add(wouStatusData); } } catch (Exception e) { - System.out.println("at line 212" + e); + logger.warning("In getCountyNameLatLon(WouRscDataObj wdata)\n" + + e.getClass().getCanonicalName() + ":" + + e.getLocalizedMessage()); } return (ArrayList) wouDataList; } + private static String queryPrefixMZ_LatLons = "select wfo,name,id, lat, lon from mapdata.marinezones"; + private WouRscDataObj getCountyNameLatLon(WouRscDataObj wdata) { wdata.countyPoints = new ArrayList(); wdata.countyNames = new ArrayList(); @@ -466,8 +566,11 @@ public class WouResource extends int i = 0; for (Iterator iterator = wdata.countyUgc.iterator(); iterator .hasNext();) { + + String theKey = iterator.next(); + Station station = stationTable.getStation(StationField.STID, - iterator.next()); + theKey); if (station != null) { LatLonPoint point = new LatLonPoint(station.getLatitude(), station.getLongitude(), LatLonPoint.INDEGREES); @@ -476,13 +579,56 @@ public class WouResource extends wdata.stateNames.add(station.getState()); wdata.countyLat[i] = station.getLatitude(); wdata.countyLon[i] = station.getLongitude(); - i++; + if (wdata.isCounty) { + String s = station.getStnnum(); + wdata.countyFips.add(s.length() == 4 ? "0" + s : s); + } + + } else { + // ELSE: + // + // GUC110 == maps.id + // 69110 ??? + // Saipan == maps.name + // GU ... + // US ... + // 15.19 == maps.lat + // 145.76 == maps.lon + // 0 0.. + // 0 + // GUM == maps.wfo + // + + List results = DirectDbQuery.executeQuery( + queryPrefixMZ_LatLons.toString() + " where id = '" + + theKey + "'", "maps", QueryLanguage.SQL); + + LatLonPoint point = new LatLonPoint( + Float.parseFloat(results.get(0)[3].toString()), + Float.parseFloat(results.get(0)[4].toString()), + LatLonPoint.INDEGREES); + wdata.countyPoints.add(point); + wdata.countyNames.add(results.get(0)[1].toString()); + wdata.stateNames.add(""); + wdata.countyLat[i] = Float.parseFloat(results.get(0)[3] + .toString()); + wdata.countyLon[i] = Float.parseFloat(results.get(0)[4] + .toString()); + wdata.countyFips.add(results.get(0)[2].toString()); } - + i++; } + } catch (IndexOutOfBoundsException idxOobEx) { + logger.log(Level.FINEST, + "In getCountyNameLatLon(WouRscDataObj wdata)\n" // mute? + + idxOobEx.getClass().getCanonicalName() + + ":" + + idxOobEx.getLocalizedMessage()); } catch (Exception e) { - System.out.println("wouResource.java at Line 245" + e); + logger.warning("In getCountyNameLatLon(WouRscDataObj wdata)\n" + + e.getClass().getCanonicalName() + ":" + + e.getLocalizedMessage()); } wdata.countyNumPoints = wdata.countyNames.size(); return wdata; @@ -492,7 +638,7 @@ public class WouResource extends @Override protected boolean preProcessFrameUpdate() { - // modifyQueue(); + modifyQueue(); return true; } @@ -512,9 +658,7 @@ public class WouResource extends && modify.evSignificance .equalsIgnoreCase(candidate.evSignificance)) { if (candidate.eventType.equalsIgnoreCase("CAN") - || candidate.eventType.equalsIgnoreCase("COR") || candidate.eventType.equalsIgnoreCase("EXP")) { - } else { candidate.evEndTime = modify.issueTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), @@ -522,6 +666,47 @@ public class WouResource extends .getRefTimeAsCalendar(), candidate.evEndTime .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("COR")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("EXT")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("NEW")) { + candidate.eventTime = modify.eventTime; + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else if (candidate.eventType.equalsIgnoreCase("CON")) { + candidate.evEndTime = modify.evEndTime; + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); + } else { + candidate.evEndTime = modify.evEndTime; // issueTime + candidate.eventTime = new DataTime( + candidate.eventTime.getRefTimeAsCalendar(), + new TimeRange(candidate.eventTime + .getRefTimeAsCalendar(), + candidate.evEndTime + .getRefTimeAsCalendar())); } } @@ -805,7 +990,9 @@ public class WouResource extends } } } catch (Exception e) { - System.out.println("error at line 392 " + e); + logger.warning("In getCountyNameLatLon(WouRscDataObj wdata)\n" + + e.getClass().getCanonicalName() + ":" + + e.getLocalizedMessage()); } } } @@ -1035,7 +1222,9 @@ public class WouResource extends } } } catch (Exception e) { - System.out.println("wouResource.java at Line 427" + e); + logger.warning("In getCountyNameLatLon(WouRscDataObj wdata)\n" + + e.getClass().getCanonicalName() + ":" + + e.getLocalizedMessage()); } } } @@ -1075,7 +1264,6 @@ public class WouResource extends } } - @SuppressWarnings("deprecation") private void drawSevereThunderstormWatchUnion(FrameData currFrameData, IGraphicsTarget target) throws VizException { LineStyle lineStyle = LineStyle.SOLID; @@ -1377,6 +1565,111 @@ public class WouResource extends return cntyName; } + private void fipsRangeReparse(String inUgcPart, String countyname, + List outList) { + final String inclusiveDelim = ">"; + String county = countyname; + String countyFips; + + if (inUgcPart.length() == 10) { // "([A-Z]{3}[0-9]{3}[>][0-9]{3})" + String intervalToken = inUgcPart.substring(3, 10); + county = inUgcPart.substring(0, 3); + + // Format in NAMDDD1>DDD2 + StringTokenizer twoTokens = new StringTokenizer(intervalToken, + inclusiveDelim); + String firstToken = twoTokens.nextToken(); + String secondToken = twoTokens.nextToken(); + + Integer countyBegin = Integer.parseInt(firstToken); + Integer countyEnd = Integer.parseInt(secondToken); + + for (int counter = countyBegin; counter <= countyEnd; counter++) { + + String inclusiveToken = Integer.toString(counter); + + // set "1" to "001" ...etc + if (counter < 10) { + inclusiveToken = "00".concat(inclusiveToken); + } + + // set "10" to "010" ...etc + else if (counter < 100) { + inclusiveToken = "0".concat(inclusiveToken); + } + countyFips = county.concat(inclusiveToken); + + outList.add(countyFips); + // UGC.addAwwFIPS(currentFips); + } + } else if (inUgcPart.length() == 7) { // "([0-9]{3}[>][0-9]{3})" + // A continuation of previous county FIPS + // with format DDD1>DDD2 + StringTokenizer twoTokens = new StringTokenizer(inUgcPart, + inclusiveDelim); + String firstToken = twoTokens.nextToken(); + String secondToken = twoTokens.nextToken(); + + Integer countyBegin = Integer.parseInt(firstToken); + Integer countyEnd = Integer.parseInt(secondToken); + + for (int counter = countyBegin; counter <= countyEnd; counter++) { + + String inclusiveToken = Integer.toString(counter); + + // set "1" to "001" ...etc + if (counter < 10) { + inclusiveToken = "00".concat(inclusiveToken); + } + + // set "10" to "010" ...etc + else if (counter < 100) { + inclusiveToken = "0".concat(inclusiveToken); + } + countyFips = county.concat(inclusiveToken); + + outList.add(countyFips); + // UGC.addAwwFIPS(currentFips); + } + } else { + outList.add(inUgcPart);// risky? + } + } + + void setMarineZonesFips(Set awwFipsSet, WouRscDataObj wrdo) { + + if (awwFipsSet != null && wrdo != null) { + for (AwwFips eachAwwFips : awwFipsSet) { + wrdo.countyFips.add(eachAwwFips.getFips()); + } + } + + } + + boolean isCountyUgs(AwwUgc au) { + Set awwFipsSet = au.getAwwFIPS(); + boolean out = false; + + if (awwFipsSet == null) { + return false; + } else { + + for (AwwFips eachAwwFips : awwFipsSet) { + + String eachFips = eachAwwFips.getFips(); + + if (eachFips == null || eachFips.isEmpty() + || eachFips.length() != 6) { + return false; + } + + out = ('C' == eachFips.charAt(2)); + } + } + + return out; + } + @Override public String getName() { String legendString = super.getName(); From f4e96b813491cc0f693b5de741db69e10f05c75b Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 18 Sep 2014 16:38:11 -0400 Subject: [PATCH 03/19] VLab Issue #4638 - Fix cycle times in Ntrans decoder Change-Id: I0bbf183c0cd0a22e8c8d6f49b1615c58e75d9bf9 Former-commit-id: ed1faf259312dd3bf1230d5488c3a0a3563b5aee [formerly ed1faf259312dd3bf1230d5488c3a0a3563b5aee [formerly ce241f8908f547326f0b813bf773f8d5debb33d3]] Former-commit-id: c7586b6739b8de9b3c3530c318c29a05c252127b Former-commit-id: 0a3b19e32355a1f1c118308124f995b3962e9872 --- .../plugin/ntrans/decoder/NtransDecoder.java | 584 ++++++++++++++---- 1 file changed, 458 insertions(+), 126 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ntrans/src/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ntrans/src/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoder.java index 6c7c8864c1..1d93904e32 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ntrans/src/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ntrans/src/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoder.java @@ -11,6 +11,9 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Calendar; import java.util.List; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.raytheon.edex.exception.DecoderException; import com.raytheon.edex.plugin.AbstractDecoder; @@ -33,22 +36,46 @@ import com.raytheon.uf.common.time.DataTime; * 10/2013 B. Hebbard Modify model name inference from metafile name * Aug 30, 2013 2298 rjpeter Make getPluginName abstract * 6/2014 T. Lee Added HYSPLIT and fixed "other" modelName + * 08/2014 B. Hebbard Revise createDataTime() to correct end-of-month boundary bug + * 08/2014 B. Hebbard Enhance to use (cycle) time info from metafile name, if available + * 09/2014 B. Hebbard Normalize (shorten) metafile name to remove directory artifacts added during dataflow, so user will see that they're used to and will fit selection dialog column * * * This code has been developed by the SIB for use in the AWIPS2 system. */ public class NtransDecoder extends AbstractDecoder { + private final static int NTRANS_FILE_TITLE_SIZE = 32; // bytes + + private final static int NTRANS_FRAME_LABEL_SIZE = 64; + + private final static int NTRANS_FRAME_LABEL_TIME_SUBSTRING_SIZE = 9; + + private final static int NTRANS_RESERVED_SPACE_SIZE = 38; + + Calendar decodeTime = null; + + private String normalizedMetafileName; + + Integer yearFromFileName = null; + + Integer monthFromFileName = null; + + Integer dateFromFileName = null; + + Integer hourFromFileName = null; + /** * Constructor * * @throws DecoderException */ public NtransDecoder() throws DecoderException { + decodeTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); } private class FrameHeader { - String validTimeString; + String frameHeaderTimeString; String productNameString; @@ -78,17 +105,26 @@ public class NtransDecoder extends AbstractDecoder { int fileMachineType = 0; int frameSizeX = 0; int frameSizeY = 0; - byte[] fileReservedSpace = new byte[38]; // TODO symbolic + byte[] fileReservedSpace = new byte[NTRANS_RESERVED_SPACE_SIZE]; // TODO + // symbolic List frameHeaders = new ArrayList(); List records = new ArrayList(); try { + decodeTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + fileName = inputFile.getName(); + + normalizedMetafileName = normalizeMetafileName(fileName); + + getTimeFromMetafileName(normalizedMetafileName); + inputStream = new FileInputStream(inputFile); // Read the entire file + // TODO: Wish we didn't have to do that, but decode method // wants to return all PDOs at once, so it's all got // to sit in memory anyway. Propose architecture change (?) @@ -118,7 +154,7 @@ public class NtransDecoder extends AbstractDecoder { // Read NTRANS metafile header - byte[] fileTitleBytes = new byte[32]; // TODO symbolic + byte[] fileTitleBytes = new byte[NTRANS_FILE_TITLE_SIZE]; byteBuffer.get(fileTitleBytes); fileTitle = new String(fileTitleBytes).trim(); // System.out.println("[File title: " + fileTitle + "]"); @@ -129,18 +165,18 @@ public class NtransDecoder extends AbstractDecoder { frameSizeX = toUnsigned(byteBuffer.getShort()); frameSizeY = toUnsigned(byteBuffer.getShort()); - byte[] fileReserved = new byte[38]; + byte[] fileReserved = new byte[NTRANS_RESERVED_SPACE_SIZE]; byteBuffer.get(fileReserved); // Read NTRANS frame headers (follow file header; precede frame // contents) for (int frame = 0; frame < fileMaxFrame; frame++) { - byte[] labelTitleBytes = new byte[64]; // TODO symbolic + byte[] labelTitleBytes = new byte[NTRANS_FRAME_LABEL_SIZE]; byteBuffer.get(labelTitleBytes); StringBuffer sb = new StringBuffer(); - for (int i = 0; (i < 64) && (labelTitleBytes[i] != 0x00); i++) { // TODO - // symbolic + for (int i = 0; (i < NTRANS_FRAME_LABEL_SIZE) + && (labelTitleBytes[i] != 0x00); i++) { sb.append((char) labelTitleBytes[i]); } String labelTitle = new String(sb); @@ -152,12 +188,14 @@ public class NtransDecoder extends AbstractDecoder { // System.out.println("[startPos " + startPos + " endPos " + // endPos + "]"); FrameHeader fh = new FrameHeader(); - if (labelTitle.length() < 8) { // TODO check! - fh.validTimeString = labelTitle; + if (labelTitle.length() < NTRANS_FRAME_LABEL_TIME_SUBSTRING_SIZE) { + fh.frameHeaderTimeString = labelTitle; fh.productNameString = ""; } else { - fh.validTimeString = labelTitle.substring(0, 9); - fh.productNameString = labelTitle.substring(9); + fh.frameHeaderTimeString = labelTitle.substring(0, + NTRANS_FRAME_LABEL_TIME_SUBSTRING_SIZE); + fh.productNameString = labelTitle + .substring(NTRANS_FRAME_LABEL_TIME_SUBSTRING_SIZE); } fh.startPos = startPos; fh.endPos = endPos; @@ -184,7 +222,8 @@ public class NtransDecoder extends AbstractDecoder { record.setReportType("NTRANS"); record.setModelName(inferModel(inputFile.getName()).replaceAll( "_", "-")); - record.setMetafileName(inputFile.getName().replaceAll("_", "-")); + record.setMetafileName(normalizedMetafileName.replaceAll("_", + "-")); record.setProductName(fh.productNameString .trim() .replaceAll("_", "-") @@ -195,8 +234,8 @@ public class NtransDecoder extends AbstractDecoder { // TODO acceptable?? .replaceAll(",", "-").replaceAll("--", "-") .replaceAll("--", "-")); // twice - record.setDataTime(createDataTime(fh.validTimeString)); - record.setValidTimeString(fh.validTimeString); + record.setDataTime(createDataTime(fh.frameHeaderTimeString)); + record.setValidTimeString(fh.frameHeaderTimeString); record.setImageData(frameImage); record.setImageSizeX(frameSizeX); record.setImageSizeY(frameSizeY); @@ -241,146 +280,439 @@ public class NtransDecoder extends AbstractDecoder { } - private DataTime createDataTime(String validTimeString) { - - // Create a standard DataTime object, with proper timing - // determined from valid time string (e.g., "27/06V042") - - // Get a Calendar object. Fields default to current time. - - Calendar calendar = Calendar.getInstance(); - Calendar now = Calendar.getInstance(); - - // Get components of validTimeString as 'int's - - // TODO -- generalize to take "F" as well as "V" strings? - // if so, may want to put in central utilities. - // TODO -- use more general/flexible pattern matching? - // TODO -- improve error handling/recovery - - // try { - String validDateString = validTimeString.substring(0, 2); - int validDate = Integer.parseInt(validDateString); - String validHourString = validTimeString.substring(3, 5); - int validHour = Integer.parseInt(validHourString); - String fcstHourString = validTimeString.substring(6, 9); - int fcstHour = Integer.parseInt(fcstHourString); - // } - // catch (Exception e) { - // TODO - // return new DataTime(calendar, 0); + public String normalizeMetafileName(String fileName) { + // Given..."gfs_gfs.20140901_gfs_20140901_12_ak" + // Want....................."gfs_20140901_12_ak" + // + // @formatter:off + // Darn... Following is thwarted by these cases: + // gfs_gfs.20140901_gfsver_20140901_18_na_mar + // ukmet.2014090_ukmet.2014090._ukmetver_20140901_00 + // wave_wave.20140901_nww3_20140901_12 + // wave_wave.20140902_nww3_20140902_00_akw + // + // final Pattern p = Pattern.compile("^(\\w+)_\\1\\.(\\d{6,8})_\\1_\\2"); + // Matcher m = p.matcher(fileName); + // if (m.find()) { + // fileName = fileName.replaceFirst("^(\\w+)_\\1\\.(\\d{6,8})_", ""); // } + // + // @formatter:on + // So, instead we... - // Alter specific fields to set to valid time. - // TODO -- use cycle time string if available to set year, month - // but must be very careful about applying rules + // If the string constains a ".", then remove everything from start of + // string through the FIRST "_" following the LAST "." - calendar.set(Calendar.DAY_OF_MONTH, validDate); - calendar.set(Calendar.HOUR_OF_DAY, validHour); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); + if (fileName.contains(".")) { + String[] splits = fileName.split("\\."); + String lastSplit = splits[splits.length - 1]; + // "reluctant" (?) match to assure first "_" + return lastSplit.replaceFirst("^.*?_", ""); + } else { + return fileName; + } + } - // Now subtract forecast hours to get initial (reference) or cycle time + private int normalizeYear(int shortYear) { - calendar.add(Calendar.HOUR_OF_DAY, -fcstHour); + // Year can be 2 digits. If so, select century to make it the one + // closest to the current year. - // Careful here: Calendar assumed valid time is in the current month - // (which, even with current data, could be off one month either way). + // (Yeah, I know it's overkill. But that's what we thought *last* + // century...) - // What we want for the month of the valid time is the latest month - // such that the (deduced) cycle time is not in the future (that is, - // not later than decode time "now"). + if (shortYear > 99) { + return shortYear; + } else { + if (decodeTime == null) { + decodeTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + } + int currYear = decodeTime.get(Calendar.YEAR); + int currCentury = currYear / 100; + int breakpoint = (currYear + 50) % 100; + int derivedYear = currCentury * 100 + shortYear; + if (shortYear > breakpoint) { + derivedYear++; + } + return derivedYear; + } + } - // The following two steps are designed to get us there. (Note that - // either or both can execute.) First, if the inferred cycle time is - // in the past, try adding a month... + private int CalendarMonth(int goodOldMonthNumber) { + // Just to be proper (since we don't control the values + // of these "magic constants", and so can't assume they + // won't change out from under us (say, in the unlikely + // but possible case that Calendar decides to go with + // 1-based months (like the rest of the world) instead + // of 0-based ones. (We're 0-based [array] here, too, but + // WE control the order, and shield it from the caller.) + // @formatter:off + final int[] CalendarMonthConstants = { + Calendar.JANUARY, + Calendar.FEBRUARY, + Calendar.MARCH, + Calendar.APRIL, + Calendar.MAY, + Calendar.JUNE, + Calendar.JULY, + Calendar.AUGUST, + Calendar.SEPTEMBER, + Calendar.OCTOBER, + Calendar.NOVEMBER, + Calendar.DECEMBER, + }; + return CalendarMonthConstants[goodOldMonthNumber - 1]; + // @formatter:on + } - if (calendar.before(now)) { - calendar.add(Calendar.MONTH, 1); + private void getTimeFromMetafileName(String fileName) { + + // NTRANS metafile names (almost?) always contain date and (sometimes) + // hour information. We assume that this refers to the cycle time of the + // model run which produced the images it contains. Since individual + // frame headers (contained within the body of the file) currently + // (2014-08) provide only valid times with date -- and no month or year + // -- taking these 'hints' from the file name, if available, allows us + // to handle legacy data properly, even if months or years old. + // + // This method operates on instance variables for both input and output. + // + // Input is fileName, which is assumed to have been set to the full name + // of the metafile currently being ingested, containing a substring of + // one of the following forms: + // @formatter:off + // YYYYMMDD + // YYYYMMDDHH + // YYYYMMDD_HH + // YYMMDD + // YYMMDD_HH + // @formatter:on + // + // Output takes the form of... + // yearFromFileName, monthFromFileName, + // dateFromFileName, hourFromFileName + // These are (boxed) Integer variables; a null value indicates no value + // is available for that field. + + final Pattern p = Pattern.compile("((\\d\\d){3,4})_?(\\d\\d)?"); + Matcher m = p.matcher(fileName); + + String matchString = ""; + String hourString = ""; + + String year = ""; + String month = ""; + String date = ""; + String hour = ""; + + while (m.find()) { + if (m.group(0).length() >= matchString.length()) { + matchString = m.group(0); + + String dateString = m.group(1).replaceFirst("_", ""); + + date = dateString.substring(dateString.length() - 2); + dateString = dateString.substring(0, dateString.length() - 2); + month = dateString.substring(dateString.length() - 2); + dateString = dateString.substring(0, dateString.length() - 2); + year = dateString.substring(dateString.length() - 2); + dateString = dateString.substring(0, dateString.length() - 2); + assert (dateString.isEmpty()); + + hourString = m.group(3); + } } - // Now -- regardless of whether the previous step executed (no "else" - // here) - // if the inferred cycle time is in the future, back up one month. + if (!matchString.isEmpty()) { + try { + yearFromFileName = normalizeYear(Integer.parseInt(year)); + monthFromFileName = Integer.parseInt(month); + dateFromFileName = Integer.parseInt(date); + if (!hourString.isEmpty()) { + hourFromFileName = Integer.parseInt(hourString); + } + } catch (Exception e) { + // TODO: ERROR + // Set *FromFileName back to null? Or not (leave partial partial + // parse results)? + } + } + } - if (calendar.after(now)) { - calendar.add(Calendar.MONTH, -1); + DataTime createDataTime(String frameHeaderTimeString, + String simulatedFileName, Calendar simulatedDecodeTime) { + decodeTime = simulatedDecodeTime; + return createDataTime(frameHeaderTimeString, simulatedFileName); + } + + DataTime createDataTime(String frameHeaderTimeString, + String simulatedFileName) { + fileName = simulatedFileName; + normalizedMetafileName = normalizeMetafileName(fileName); + getTimeFromMetafileName(normalizedMetafileName); + return createDataTime(frameHeaderTimeString); + } + + DataTime createDataTime(String frameHeaderTimeString) { + + // Create a standard DataTime object, with proper timing + // determined from given time string (e.g., "27/06V042") + // (from the frame header), AND fields parsed earlier from + // the metafile name (and stored in instance variables), + // if available. + + // -- + + // Get components of validframeHeaderTimeString as 'int's + + // Be able to decode... + // 8, 6, 4, or 2 digits, followed by... + // "/" followed by... + // 2 digits followed by... + // "F" or "V" followed by... + // any number of digits? 2-3? 1-6? + // NOT with intervening spaces? + + final Pattern p = Pattern + .compile("((\\d\\d){1,4})/(\\d\\d)(F|V)(\\d{1,4})"); + Matcher m = p.matcher(frameHeaderTimeString); + + boolean isV = false; + + Integer centuryFromFrameHeader = null; + Integer yearFromFrameHeader = null; + Integer monthFromFrameHeader = null; + Integer dateFromFrameHeader = null; + Integer hourFromFrameHeader = null; + Integer fcstHour = null; + + String dateString, hourString, fOrV, fcstHourString; + + if (m.find()) { + dateString = m.group(1); + hourString = m.group(3); + fOrV = m.group(4); + fcstHourString = m.group(5); + } else { + return new DataTime(decodeTime, 0); // should be error indication + } + + try { + switch (dateString.length()) { + case 8: + centuryFromFrameHeader = Integer.parseInt(dateString.substring( + 0, 2)); + dateString = dateString.substring(2); + // NO break; + case 6: + yearFromFrameHeader = Integer.parseInt(dateString.substring(0, + 2)); + dateString = dateString.substring(2); + if (centuryFromFrameHeader == null) { + yearFromFrameHeader = normalizeYear(yearFromFrameHeader); + } else { + yearFromFrameHeader += centuryFromFrameHeader * 100; + } + // NO break; + case 4: + monthFromFrameHeader = Integer.parseInt(dateString.substring(0, + 2)); + dateString = dateString.substring(2); + // NO break; + case 2: + dateFromFrameHeader = Integer.parseInt(dateString.substring(0, + 2)); + dateString = dateString.substring(2); + assert (dateString.isEmpty()); + break; + default: + // ERROR + break; + } + hourFromFrameHeader = Integer.parseInt(hourString); + isV = fOrV.equalsIgnoreCase("V"); + fcstHour = Integer.parseInt(fcstHourString); + } catch (Exception e) { + // TODO + return new DataTime(Calendar.getInstance(TimeZone + .getTimeZone("GMT")), 0); + } + + // Establish upper bound on what the specified time means. + // For F-type string, that would be the cycle time. + // For V-type string, that would be the valid time. + + // Start with the decode (system) time... + Calendar upperBoundTime = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + upperBoundTime.setTime(decodeTime.getTime()); + + // YEAR: If specified in the frame header, that takes priority... + if (yearFromFrameHeader != null) { + upperBoundTime.set(Calendar.YEAR, yearFromFrameHeader); + } + // ...otherwise use value from file name, if available... + else if (yearFromFileName != null) { + upperBoundTime.set(Calendar.YEAR, yearFromFileName); + } + // ...otherwise defaults to the current year. + + // MONTH: If specified in the frame header, that takes priority... + if (monthFromFrameHeader != null) { + upperBoundTime.set(Calendar.MONTH, + CalendarMonth(monthFromFrameHeader)); + } + // ...otherwise use value from file name, if available + else if (monthFromFileName != null) { + upperBoundTime + .set(Calendar.MONTH, CalendarMonth(monthFromFileName)); + } + // ...otherwise defaults to current month + + // DATE: If specified in the frame header, IGNORE FOR NOW... + // if (dateFromFrameHeader != null) { + // upperBoundTime.set(Calendar.DAY, + // CalendarMonth(monthFromFrameHeader)); + // } + // else + // ...BUT do use value from file name, if available + if (dateFromFileName != null) { + upperBoundTime.set(Calendar.DAY_OF_MONTH, dateFromFileName); + } + // ...otherwise defaults to current date + + // If we're dealing with a V-type string, we're determining the VALID + // time. Add forecast hours. + if (isV) { + upperBoundTime.add(Calendar.HOUR_OF_DAY, fcstHour); + } + + // Now calculate the actual valid time, starting with the latest + // possible... + + Calendar calculatedValidTime = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + calculatedValidTime.setTime(upperBoundTime.getTime()); + + // ...setting the date field to the specified date... + + calculatedValidTime.set(Calendar.DATE, dateFromFrameHeader); + + // ...but if greater than the latest possible valid date... + + int latestPossibleValidDate = upperBoundTime.get(Calendar.DAY_OF_MONTH); + if (dateFromFrameHeader > latestPossibleValidDate) { + // ...then it must be that date in the PRIOR month... + calculatedValidTime.add(Calendar.MONTH, -1); + } + + // Now set the hour field to the specified hour... + + calculatedValidTime.set(Calendar.HOUR_OF_DAY, hourFromFrameHeader); + + // ...and finally set sub-hour fields all to zero + + calculatedValidTime.set(Calendar.MINUTE, 0); + calculatedValidTime.set(Calendar.SECOND, 0); + calculatedValidTime.set(Calendar.MILLISECOND, 0); + + // Now calculate actual initial (reference) or cycle time + + Calendar calculatedCycleTime = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + calculatedCycleTime.setTime(calculatedValidTime.getTime()); + + // Subtract forecast hours to get initial (reference) or cycle time + if (isV) { + calculatedCycleTime.add(Calendar.HOUR_OF_DAY, -fcstHour); + } + + // Sanity check against file name date and hour (if known) + + int calculatedCycleDate = calculatedCycleTime + .get(Calendar.DAY_OF_MONTH); + int calculatedCycleHour = calculatedCycleTime.get(Calendar.HOUR_OF_DAY); + if (dateFromFileName != null && dateFromFileName != calculatedCycleDate) { + // WARNING!! + logger.warn("Cycle date " + dateFromFileName + + " from metafile name " + fileName + " differs from " + + calculatedCycleDate + " inferred from frame header " + + frameHeaderTimeString); + } else if (hourFromFileName != null + && hourFromFileName != calculatedCycleHour) { + // WARNING!! + logger.warn("Cycle hour " + hourFromFileName + + " from metafile name " + fileName + " differs from " + + calculatedCycleHour + " inferred from frame header " + + frameHeaderTimeString); } // Return DataTime, constructed from cycle time and forecast hour. - DataTime dataTime = new DataTime(calendar, fcstHour * 3600); + DataTime dataTime = new DataTime(calculatedCycleTime, fcstHour * 3600); return dataTime; } - private DataTime createDataTime(String initialTimeString, - String validTimeString) { - - // FUTURE -- use initialTimeString to influence deduction of - // full initial (reference) time from validTimeString - - // For now, initialTimeString not used... - - return createDataTime(validTimeString); - - /* - * - * // Create a standard DataTime object, with proper timing // - * determined from valid time string (e.g., "27/06V042") - * - * // Get components of validTimeString as 'int's // TODO -- generalize - * to take "F" as well as "V" strings? // if so, may want to put in - * central utilities. // TODO -- use more general/flexible pattern - * matching? - * - * String validDateString = validTimeString.substring(0, 1); int - * validDate = Integer.parseInt(validDateString); String validHourString - * = validTimeString.substring(3, 4); int validHour = - * Integer.parseInt(validHourString); String fcstHourString = - * validTimeString.substring(6, 8); int fcstHour = - * Integer.parseInt(fcstHourString); - * - * // Get a Calendar object. Fields default to current time. - * - * Calendar calendar = Calendar.getInstance(); - * - * // Alter specific fields to set to valid time. // TODO -- use cycle - * time string if available to set year, month // but must be very - * careful about applying rules - * - * calendar.set(Calendar.DAY_OF_MONTH, validDate); - * calendar.set(Calendar.HOUR_OF_DAY, validHour); - * calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); - * calendar.set(Calendar.MILLISECOND, 0); - * - * // Now subtract forecast hours to get initial (reference) time... - * - * calendar.add(Calendar.HOUR_OF_DAY, -fcstHour); - * - * // ...for DataTime constructor that wants it // (DataTime has many - * constructors, but none that // takes validTime and fcstHour) - * - * DataTime dataTime = new DataTime(calendar, fcstHour); - * - * return dataTime; - */ - } - private enum Model { // TODO - Remove this, to make decoder agnostic w.r.t. list of available // models. + // We do this temporarily because we don't yet know the possible formats // of filename strings we're going to be fed, so for now we just look - // for - // known model names appearing anywhere in the file name. + // for known model names appearing anywhere in the file name. // NOTE: Sequence is important only insofar as any model name must - // appear - // after all model names of which it is a proper substring. + // appear after all model names of which it is a proper substring. // Also, OPC_ENC comes first, since its metafiles may contain other // model substrings - OPC_ENS, CMCE_AVGSPR, CMCE, CMCVER, CMC, CPC, DGEX, ECENS_AVGSPR, ECENS, ECMWFVER, ECMWF_HR, ECMWF, ENSVER, FNMOCWAVE, GDAS, GEFS_AVGSPR, GEFS, GFSP, GFSVERP, GFSVER, GFS, GHM, HPCQPF, HPCVER, HWRF, ICEACCR, JMAP, JMA, MEDRT, NAEFS, NAM20, NAM44, NAMVER, NAM, NAVGEM, NOGAPS, NWW3P, NWW3, RAPP, RAP, SREFX, SST, UKMETVER, UKMET, VAFTAD + + // @formatter:off + OPC_ENS, + CMCE_AVGSPR, + CMCE, + CMCVER, + CMC, + CPC, + DGEX, + ECENS_AVGSPR, + ECENS, + ECMWFVER, + ECMWF_HR, + ECMWF, + ENSVER, + FNMOCWAVE, + GDAS, + GEFS_AVGSPR, + GEFS, + GFSP, + GFSVERP, + GFSVER, + GFS, + GHM, + HPCQPF, + HPCVER, + HWRF, + ICEACCR, + JMAP, + JMA, + MEDRT, + NAEFS, + NAM20, + NAM44, + NAMVER, + NAM, + NAVGEM, + NOGAPS, + NWW3P, + NWW3, + RAPP, + RAP, + SREFX, + SST, + UKMETVER, + UKMET, + VAFTAD + // @formatter:on }; private String inferModel(String fileName) { From 16ebd4fc25015947eb461ca364967f4a1e2d1578 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 18 Sep 2014 16:41:07 -0400 Subject: [PATCH 04/19] VLab Issue #4001 - Correct Natl Radar Mosaic CRS Change-Id: If72629e9c33f395d824ae450aadeaf28e8ffd9b5 Former-commit-id: 46e3af5569d962e9a3e66ca4535e4ebc407eb703 [formerly 46e3af5569d962e9a3e66ca4535e4ebc407eb703 [formerly 7a438074ef0aed8a2137adc3f0f32a08a21fd2b9]] Former-commit-id: 8f61a8e83271df3eba2ea9de6d5ec94a7331e632 Former-commit-id: 21dad5476d547bda605ba01898aa9a6796fd0689 --- .../plugin/mosaic/common/MosaicRecord.java | 69 ++++++++++++---- .../plugin/mosaic/uengine/MosaicTiler.java | 82 +++++++++---------- 2 files changed, 94 insertions(+), 57 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java index ad18487927..37a108994c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java @@ -27,13 +27,14 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.geotools.referencing.operation.DefaultMathTransformFactory; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Index; +import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.operation.MathTransform; -import com.raytheon.uf.common.dataplugin.IDecoderGettable; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.dataplugin.persist.IPersistable; @@ -70,6 +71,7 @@ import com.vividsolutions.jts.geom.Coordinate; * May 07, 2013 1869 bsteffen Remove dataURI column from * PluginDataObject. * Aug 06, 2013 2228 njensen Use deserialize(byte[]) + * Sep 08, 2014 sgilbert Correct CONUS image projection * * * @@ -212,6 +214,16 @@ public class MosaicRecord extends PersistablePluginDataObject implements @Transient private Map symbologyData = new HashMap(); + // public static final double GEMPAK_EARTH_RADIUS_KM = 6371.2213; + + public static final double MOSAIC_EARTH_RADIUS_KM = 6380.0; + + private static final int ALASKA_SOURCEID = 10051; + + private static final int HAWAII_SOURCEID = 10052; + + private static final DefaultMathTransformFactory dmtFactory = new DefaultMathTransformFactory(); + public MosaicRecord() { super(); this.nx = 0; @@ -518,17 +530,6 @@ public class MosaicRecord extends PersistablePluginDataObject implements this.elevation = elevation; } - /** - * Get the IDecoderGettable reference for this record. - * - * @return The IDecoderGettable reference for this record. Null for this - * class. - */ - @Override - public IDecoderGettable getDecoderGettable() { - return null; - } - /** * @return the symbologyBlock */ @@ -564,8 +565,17 @@ public class MosaicRecord extends PersistablePluginDataObject implements } public ProjectedCRS getCRS() { - return MapUtil.constructStereographic(MapUtil.AWIPS_EARTH_RADIUS, - MapUtil.AWIPS_EARTH_RADIUS, this.latitude, this.longitude); + if (this.getSourceId() != HAWAII_SOURCEID + && this.getSourceId() != ALASKA_SOURCEID) { + return generateLambertConformal_2StandardParallel( + MosaicRecord.MOSAIC_EARTH_RADIUS_KM * 1000, + MosaicRecord.MOSAIC_EARTH_RADIUS_KM * 1000, 33.0, 45.0, + this.longitude, this.latitude); + } else { + return MapUtil.constructStereographic(MapUtil.AWIPS_EARTH_RADIUS, + MapUtil.AWIPS_EARTH_RADIUS, this.latitude, this.longitude); + } + } /** @@ -774,4 +784,35 @@ public class MosaicRecord extends PersistablePluginDataObject implements public String getPluginName() { return "mosaic"; } + + /* + * This method is temporary and will not be needed when an appropriate + * MapUtil method is available that allows different standard parallels. + */ + private ProjectedCRS generateLambertConformal_2StandardParallel( + double majorAxis, double minorAxis, double stdParallel1, + double stdParallel2, double lonOfOrigin, double latOfOrigin) { + ParameterValueGroup parameters = null; + try { + parameters = dmtFactory + .getDefaultParameters("Lambert_Conformal_Conic_2SP"); + + parameters.parameter("semi_major").setValue(majorAxis); + parameters.parameter("semi_minor").setValue(minorAxis); + parameters.parameter("latitude_of_origin").setValue(latOfOrigin); + parameters.parameter("standard_parallel_1").setValue(stdParallel1); + parameters.parameter("standard_parallel_2").setValue(stdParallel2); + parameters.parameter("longitude_of_origin").setValue(lonOfOrigin); + parameters.parameter("false_easting").setValue(0.0); + parameters.parameter("false_northing").setValue(0.0); + + String name = "Lambert Conformal (SP: " + stdParallel1 + "/" + + stdParallel2 + ", Origin: " + lonOfOrigin + ")"; + + return MapUtil.constructProjection(name, parameters); + } catch (Exception e) { + // + return null; + } + } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/MosaicTiler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/MosaicTiler.java index 82c01b8102..9efeac539f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/MosaicTiler.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/MosaicTiler.java @@ -18,15 +18,18 @@ import org.opengis.referencing.crs.ProjectedCRS; * A tiler class that will allow the user to take a radial container and create * tiles at a particular zoom level. * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 09/2009 143 L. Lin Initial creation - * 12/2009 143 mgamazaychikov Made constructor and constructGridGeometry - * more suitable for raster images - * 01/2010 204 M. Li Set tileSize; correct geometry envelope + *
+ * Date         Ticket#         Engineer     Description 
+ * ------------ ----------      -----------  -------------------------- 
+ * 09/2009      143             L. Lin       Initial creation 
+ * 12/2009      143           mgamazaychikov Made constructor and constructGridGeometry more suitable for
+ * raster images 
+ * 01/2010      204             M. Li        Set tileSize; correct geometry envelope
+ * 09/2014                      sgilbert     Correct GridGeometry
  * 
* * This code has been developed by the SIB for use in the AWIPS2 system. + * * @author L. Lin * @version 1.0 */ @@ -36,11 +39,11 @@ public class MosaicTiler { private int levels; private int tileSize; - + private int tileSizeX, tileSizeY; private int fullResolution; - + private int fullResolutionX, fullResolutionY; private int actualArrayLength; @@ -51,10 +54,6 @@ public class MosaicTiler { private MosaicRecord mosaicData; - private double maxExtentW; - - private double maxExtentH; - private UnitConverter dataToImage; public MosaicTiler(MosaicRecord data) { @@ -89,8 +88,8 @@ public class MosaicTiler { this.levels = 1; this.tileSizeX = data.getNy(); this.tileSizeY = data.getNx(); - this.tileSize = data.getNy(); - + this.tileSize = data.getNy(); + this.fullResolutionX = (int) (this.tileSizeX * Math.pow(2, this.levels - 1)); this.fullResolutionY = (int) (this.tileSizeY * Math.pow(2, @@ -99,7 +98,6 @@ public class MosaicTiler { blankImage = new byte[actualArrayLength]; Arrays.fill(blankImage, (byte) 0); } - if (dataToImage == null) { this.dataToImage = UnitConverter.IDENTITY; @@ -110,7 +108,6 @@ public class MosaicTiler { this.dataToImage = dataToImage; } - } /** @@ -143,8 +140,8 @@ public class MosaicTiler { } /** - * Creates a full image of the mosaic data. The class needs to be constructed - * with the fullImage flag set to true for this to work. + * Creates a full image of the mosaic data. The class needs to be + * constructed with the fullImage flag set to true for this to work. * * @return A byte array of the full image */ @@ -155,42 +152,41 @@ public class MosaicTiler { public GridGeometry2D constructGridGeometry() { ProjectedCRS crs = mosaicData.getCRS(); + double minX, maxX, minY, maxY; GridGeometry2D gridGeometry2D = null; GeneralEnvelope generalEnvelope = new GeneralEnvelope(2); generalEnvelope.setCoordinateReferenceSystem(crs); - - maxExtentW = mosaicData.getResolution() * mosaicData.getNy(); - maxExtentH = mosaicData.getResolution() * mosaicData.getNx(); + + // Assumes 0,0 point ( lat/lon of origin in CRS ) is at center of image + // and points at corner of cell + maxX = mosaicData.getResolution() * mosaicData.getNy(); + maxY = mosaicData.getResolution() * mosaicData.getNx(); + double halfResolution = mosaicData.getResolution() / 2.0; + + maxX = (maxX / 2.0) - halfResolution; + maxY = (maxY / 2.0) - halfResolution; + minX = -maxX; + minY = -maxY; + maxX += mosaicData.getResolution(); + maxY += mosaicData.getResolution(); + + generalEnvelope.setRange(0, minX, maxX); + generalEnvelope.setRange(1, minY, maxY); if ("Raster".equals(mosaicData.getFormat())) { - maxExtentW /= 2; - maxExtentH /= 2; + gridGeometry2D = new GridGeometry2D(new GeneralGridEnvelope( + new int[] { 0, 0 }, new int[] { fullResolutionX, + fullResolutionY }, false), generalEnvelope); + } else if ("Radial".equals(mosaicData.getFormat())) { + gridGeometry2D = new GridGeometry2D(new GeneralGridEnvelope( + new int[] { 0, 0 }, new int[] { fullResolution, + fullResolution }, false), generalEnvelope); } - generalEnvelope.setRange(0, -maxExtentW, maxExtentW); - generalEnvelope.setRange(1, -maxExtentH, maxExtentH); - - if ("Raster".equals(mosaicData.getFormat())) { - gridGeometry2D = new GridGeometry2D(new GeneralGridEnvelope(new int[] { - 0, 0 }, new int[] { fullResolutionX, fullResolutionY }, false), - generalEnvelope); - } - else if ("Radial".equals(mosaicData.getFormat())) { - gridGeometry2D = new GridGeometry2D(new GeneralGridEnvelope(new int[] { - 0, 0 }, new int[] { fullResolution, fullResolution }, false), - generalEnvelope); - } - - return gridGeometry2D; } - public double getMaxExent() { - return maxExtentW; - - } - /** * Returns the actual width of the imagery. This is typically used for the * full image. From e85f1cdc5f48d3f0109df03326717e2c41f25532 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 18 Sep 2014 16:51:00 -0400 Subject: [PATCH 05/19] VLab Issue #4003 - Ntrans resource updates + PWAT Change-Id: Ibcdf8270afd10280f5b38e5595b850de021ffca2 Former-commit-id: 405ce899f3fac2e6c554492c57e97358c2a529c6 [formerly 405ce899f3fac2e6c554492c57e97358c2a529c6 [formerly 05f4987f726b132b98727fc5fe0c19b8ac1ae762]] Former-commit-id: 7b12478730692eba0d0641f00a1c14523f528bb8 Former-commit-id: 41593413090a87454b928f0ba11cb32c720426ae --- .../ncep/gempak/parameters/title/TITLE.java | 248 ++++++------- .../ModelFcstGridContours/SREF40-standard.xml | 2 +- .../ncep/PlotModels/ncuair/prec_wat.xml | 12 + .../ncep/PredefinedAreas/menus/AreaMenus.xml | 5 +- .../ncep/ResourceDefns/GRID/SREF40/SREF40.xml | 4 +- .../UPPER_AIR/UAIR/prec_wat.attr | 5 + .../ui/createRbd/NtransSelectionControl.java | 28 +- .../ncep/viz/rsc/mosaic/rsc/RadarTileSet.java | 13 +- .../viz/rsc/ncgrid/rsc/NcgridResource.java | 172 ++++----- .../nws/ncep/viz/rsc/ntrans/jcgm/README.txt | 4 +- .../ncep/viz/rsc/ntrans/ncgm/INcCommand.java | 8 +- .../nws/ncep/viz/rsc/ntrans/ncgm/NcCGM.java | 324 +---------------- .../rsc/ntrans/ncgm/NcCharacterHeight.java | 4 +- .../viz/rsc/ntrans/ncgm/NcCircleElement.java | 4 +- .../viz/rsc/ntrans/ncgm/NcFillColour.java | 4 +- .../viz/rsc/ntrans/ncgm/NcInteriorStyle.java | 4 +- .../viz/rsc/ntrans/ncgm/NcLineColour.java | 4 +- .../ncep/viz/rsc/ntrans/ncgm/NcLineWidth.java | 4 +- .../viz/rsc/ntrans/ncgm/NcPolygonElement.java | 8 +- .../ncep/viz/rsc/ntrans/ncgm/NcPolyline.java | 20 +- .../nws/ncep/viz/rsc/ntrans/ncgm/NcText.java | 4 +- .../viz/rsc/ntrans/ncgm/NcTextAlignment.java | 4 +- .../viz/rsc/ntrans/ncgm/NcTextColour.java | 4 +- .../viz/rsc/ntrans/ncgm/NcTextFontIndex.java | 4 +- .../ncep/viz/rsc/ntrans/rsc/ImageBuilder.java | 20 +- .../viz/rsc/ntrans/rsc/NtransResource.java | 327 ++++++------------ .../viz/rsc/ntrans/rsc/PaintableImage.java | 198 +++++++++++ .../NcPlotModelHdf5DataRequestor.java | 17 +- .../viz/rsc/plotdata/rsc/NcPlotResource2.java | 38 +- 29 files changed, 655 insertions(+), 838 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/ncuair/prec_wat.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/UPPER_AIR/UAIR/prec_wat.attr create mode 100644 ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/PaintableImage.java diff --git a/ncep/gov.noaa.nws.ncep.gempak.parameters/src/gov/noaa/nws/ncep/gempak/parameters/title/TITLE.java b/ncep/gov.noaa.nws.ncep.gempak.parameters/src/gov/noaa/nws/ncep/gempak/parameters/title/TITLE.java index ecd1e44fb5..474f988718 100644 --- a/ncep/gov.noaa.nws.ncep.gempak.parameters/src/gov/noaa/nws/ncep/gempak/parameters/title/TITLE.java +++ b/ncep/gov.noaa.nws.ncep.gempak.parameters/src/gov/noaa/nws/ncep/gempak/parameters/title/TITLE.java @@ -4,53 +4,45 @@ import gov.noaa.nws.ncep.viz.common.ui.color.GempakColor; import org.eclipse.swt.graphics.RGB; - /** - * TITLE is the title color, title line, and title string separated by slashes: - * - * title color / title line location / title string | short title - * - * If the title color is 0, a title is not plotted. - * - * The title line specifies the line on which the title will be written. - * The value of the title line has the following meanings: - * - * 0 bottom line - * -n n lines from bottom - * +n n lines from top - * - * If the line is not specified, the default is program dependent. - * - * The title string is the title to be written. If no title string is - * specified, a default title will be determined by the program. - * - * In the grid display programs, special characters will be replaced - * as follows: - * ^ Forecast date/time - * ~ Valid date/time - * @ Vertical level - * _ Grid function - * $ Nonzero scaling factor - * # Grid point location - * ? Day of the week flag - * - * If the information for which a character stands is not applicable to - * the program, nothing is output in its place. Zero values of the - * scaling factor are not displayed. - * - * If the "?" is included the abbreviated day of the week is added to the - * beginning of the date/time string. The day of the week flag must always - * be used in combination with either special character for specifying the - * date/time string. The result is the day of the week for the valid date/time. - * - * A short title may also be input by the user after a |. This is used - * to label the metafile frame in the NC device driver. If the short title - * is blank, a suitable label is generated for the frame. The day of the - * week is not included in the short title. - * - * + * TITLE is the title color, title line, and title string separated by slashes: + * + * title color / title line location / title string | short title + * + * If the title color is 0, a title is not plotted. + * + * The title line specifies the line on which the title will be written. The + * value of the title line has the following meanings: + * + * 0 bottom line -n n lines from bottom +n n lines from top + * + * If the line is not specified, the default is program dependent. + * + * The title string is the title to be written. If no title string is specified, + * a default title will be determined by the program. + * + * In the grid display programs, special characters will be replaced as follows: + * ^ Forecast date/time ~ Valid date/time @ Vertical level _ Grid function $ + * Nonzero scaling factor # Grid point location ? Day of the week flag + * + * If the information for which a character stands is not applicable to the + * program, nothing is output in its place. Zero values of the scaling factor + * are not displayed. + * + * If the "?" is included the abbreviated day of the week is added to the + * beginning of the date/time string. The day of the week flag must always be + * used in combination with either special character for specifying the + * date/time string. The result is the day of the week for the valid date/time. + * + * A short title may also be input by the user after a |. This is used to label + * the metafile frame in the NC device driver. If the short title is blank, a + * suitable label is generated for the frame. The day of the week is not + * included in the short title. + * + * *

- *

+ * 
+ * 
  * SOFTWARE HISTORY
  * Date          Ticket#     Engineer     Description
  * ------------ ---------- ----------- --------------------------
@@ -58,107 +50,85 @@ import org.eclipse.swt.graphics.RGB;
  * Nov 22,2010                X. Guo       Check title old syntax with ^ and ~
  * Mar 06,2013	 683		  Xiaochuan	   Handle 2 digit number for the colors
  * 										   set in title. Using default color when color
- * 										   number over 32. 		
- *                                         
+ * 										   number over 32.
+ * 
  * 
+ * * @author xguo * @version 1 - * @see $GEMPAK/help/hlx/title.hl2 + * @see $GEMPAK/help/hlx/title.hl2 */ public class TITLE { - //Title Color - private RGB titleColor = new RGB(255, 0, 0); - - //Title Line Location - private int titleLineLocation = 0; - - // Title String - private String titleString = null; - - public TITLE (String titleString) { - parseTitleString (titleString); - } - - private void parseTitleString (String title) { - int col = 0; - String expression_1 = "[-+]?[0-9]"; - String expression_2 = "[-+]?[0-9]{2}"; - String tmp; - int colors_size = GempakColor.values().length; - - if (title == null || title.trim().length() <= 0) return; - - /* - * check '/' character in the title string and handle the current format - */ - if ( title.indexOf('/') >= 0 ) { - String[] titleStr = title.trim().split("/"); - if ( titleStr.length >= 1 && titleStr[0] != null && - titleStr[0].trim().length() > 0) { - tmp = titleStr[0].trim(); - if ( tmp.matches(expression_1) || tmp.matches(expression_2)) { - col = Integer.valueOf(tmp); - } - } - if ( col > 0 && col <= colors_size) { - titleColor = GempakColor.convertToRGB(col); - } - else { // use white color when the number over size of GempakColor - titleColor = GempakColor.convertToRGB(1); - } - - if ( titleStr.length >= 2 && titleStr[1] != null && - titleStr[1].trim().length() > 0) { - tmp = titleStr[1].trim(); - if ( tmp.matches(expression_1)) { - titleLineLocation = Integer.valueOf(tmp); - } - } - if ( titleStr.length >= 3 && titleStr[2] != null && - titleStr[2].trim().length() > 0) { - titleString = checkOldTitleSyntax(titleStr[2].trim()); - } - else { - titleString = "~ @ _$"; - } - } - else {//use white color and whole string - titleColor = GempakColor.convertToRGB(1); - titleString = title.trim(); - } - } + // Title Color + private RGB titleColor = new RGB(255, 0, 0); - /** - * Check for old syntax with ^ and ~ - * @return String - */ - private String checkOldTitleSyntax ( String title ) { - String ttlstr = title; - int pos = ttlstr.indexOf('^'); - - if ( (ttlstr.charAt(0) == '~') && (pos > 0)) { - String tmpStr = ttlstr.substring(1,ttlstr.length()); - pos --; - while ( pos > 0 ) { - tmpStr = tmpStr.substring(0, pos-1) + "~" + tmpStr.substring(pos + 1, tmpStr.length()); - pos = tmpStr.indexOf('^'); - } - ttlstr = tmpStr; - } - - return ttlstr; - } - - public RGB getTitleColor() { - return titleColor; - } + // Title Line Location + private int titleLineLocation = 0; - public int getTitleLineLoaction() { - return titleLineLocation; - } + // Title String + private String titleString = null; - public String getTitleString () { - return titleString; - } + public TITLE(String titleString) { + parseTitleString(titleString); + } + + private void parseTitleString(String title) { + int col = 0; + String expression_1 = "[-+]?[0-9]"; + String expression_2 = "[-+]?[0-9]{2}"; + String tmp; + int colors_size = GempakColor.values().length; + + if (title == null || title.trim().length() <= 0) + return; + + /* + * check '/' character in the title string and handle the current format + */ + if (title.indexOf('/') >= 0) { + String[] titleStr = title.trim().split("/"); + if (titleStr.length >= 1 && titleStr[0] != null + && titleStr[0].trim().length() > 0) { + tmp = titleStr[0].trim(); + if (tmp.matches(expression_1) || tmp.matches(expression_2)) { + col = Integer.valueOf(tmp); + } + } + if (col > 0 && col <= colors_size) { + titleColor = GempakColor.convertToRGB(col); + } else { // use white color when the number over size of GempakColor + titleColor = GempakColor.convertToRGB(1); + } + + if (titleStr.length >= 2 && titleStr[1] != null + && titleStr[1].trim().length() > 0) { + tmp = titleStr[1].trim(); + if (tmp.matches(expression_1)) { + titleLineLocation = Integer.valueOf(tmp); + } + } + if (titleStr.length >= 3 && titleStr[2] != null + && titleStr[2].trim().length() > 0) { + titleString = titleStr[2].trim(); + } else { + titleString = "~ @ _$"; + } + } else {// use white color and whole string + titleColor = GempakColor.convertToRGB(1); + titleString = title.trim(); + } + } + + public RGB getTitleColor() { + return titleColor; + } + + public int getTitleLineLoaction() { + return titleLineLocation; + } + + public String getTitleString() { + return titleString; + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/ModelFcstGridContours/SREF40-standard.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/ModelFcstGridContours/SREF40-standard.xml index a40d57574d..ba65ed8e52 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/ModelFcstGridContours/SREF40-standard.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/ModelFcstGridContours/SREF40-standard.xml @@ -2,5 +2,5 @@ SREF40 standard - tp12c1 + 500mb_hght diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/ncuair/prec_wat.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/ncuair/prec_wat.xml new file mode 100644 index 0000000000..cf1b391da7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/ncuair/prec_wat.xml @@ -0,0 +1,12 @@ + + + + + + MC + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PredefinedAreas/menus/AreaMenus.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PredefinedAreas/menus/AreaMenus.xml index a43c437da2..33dcb265df 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PredefinedAreas/menus/AreaMenus.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PredefinedAreas/menus/AreaMenus.xml @@ -119,7 +119,10 @@ PREDEFINED_AREA N_Hemisphere - + + PREDEFINED_AREA + S_Hemisphere + GEMPAK_GEOG_AREA_CODE TROPSFC diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/GRID/SREF40/SREF40.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/GRID/SREF40/SREF40.xml index 5c09326976..7492aa4996 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/GRID/SREF40/SREF40.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/GRID/SREF40/SREF40.xml @@ -4,7 +4,7 @@ GRID ModelFcstGridContours - + ensembleMember CLOSEST_BEFORE_OR_AFTER 60 USE_CYCLE_TIME_FCST_HOURS @@ -14,7 +14,7 @@ pluginName=grid GDFILE=SREF212 - +ensembleMember=% true diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/UPPER_AIR/UAIR/prec_wat.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/UPPER_AIR/UAIR/prec_wat.attr new file mode 100644 index 0000000000..11bceb4d88 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/UPPER_AIR/UAIR/prec_wat.attr @@ -0,0 +1,5 @@ +! Parameters and Attributes for the default UAIR Resource +levelKey=500 +plotModel=@PlotModels/ncuair/prec_wat.xml +plotDensity=30 +conditionalFilter= \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/NtransSelectionControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/NtransSelectionControl.java index a081e21048..76e27c0bde 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/NtransSelectionControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/NtransSelectionControl.java @@ -56,6 +56,9 @@ import com.raytheon.uf.viz.core.exception.VizException; * ------------ ---------- ----------- -------------------------- * 07/23/2014 B. Hebbard Fork off NTRANS-specific code from ResourceSelectionControl * 08/26/2014 B. Hebbard Adjust metafile column comparator to put latest data at top + * 09/15/2014 B. Hebbard At CPC request, persist model selected across dialog close/open + * even if resource not preselected (from existing RBD contents). + * (This now differs from non-NTRANS behavior.) * *
* @@ -81,7 +84,7 @@ public class NtransSelectionControl extends ResourceSelectionControl { // protected static HashMap // prevCatSeldRscNames; - // a map to store the previous selections for each category. + // a map to store the previous selections for each type (model)y. protected static HashMap prevModelSelectedRscNames; // this list must stay in sync with the cycleTimeCombo. @@ -541,8 +544,7 @@ public class NtransSelectionControl extends ResourceSelectionControl { rscTypeLViewer.setComparator(new ViewerComparator() { // TODO : implement this if we want to group definitions according - // to - // some meaningful category.... + // to some meaningful category.... public int category(Object element) { ResourceDefinition rd = (ResourceDefinition) element; return (rd.isForecast() ? 1 : 0); @@ -639,11 +641,10 @@ public class NtransSelectionControl extends ResourceSelectionControl { String rscType = seldResourceName.getRscType(); if (!rscType.isEmpty()) { - // if this resource uses attrSetGroups then get get the list - // of - // groups. (PGEN uses groups but we will list the subTypes - // (products) - // and not the single PGEN attr set group) + // if this resource uses attrSetGroups then get get the + // list of groups. (PGEN uses groups but we will list + // the subTypes (products) and not the single PGEN attr + // set group) if (rscDefnsMngr.doesResourceUseAttrSetGroups(rscType) && !seldResourceName.isPgenResource()) { @@ -1115,8 +1116,14 @@ public class NtransSelectionControl extends ResourceSelectionControl { seldResourceName = new ResourceName(initRscName); seldResourceName.setRscCategory(resourceCategory); // NTRANS - if (seldResourceName != null) { - prevSelectedModel = seldResourceName.getRscType(); + if ((seldResourceName.getRscType() == null || seldResourceName + .getRscType().isEmpty()) + && (prevSelectedModel != null && !prevSelectedModel.isEmpty())) { + ResourceName previousRscNameForModel = prevModelSelectedRscNames + .get(prevSelectedModel); + if (previousRscNameForModel != null) { + seldResourceName = previousRscNameForModel; + } } filterCombo.setItems(new String[] { "All" }); @@ -1553,6 +1560,7 @@ public class NtransSelectionControl extends ResourceSelectionControl { prevModelSelectedRscNames.put(seldResourceName.getRscType(), seldResourceName); + prevSelectedModel = seldResourceName.getRscType(); } // TODO: add a way to let the user specifically choose the "LATEST" cycle diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.mosaic/src/gov/noaa/nws/ncep/viz/rsc/mosaic/rsc/RadarTileSet.java b/ncep/gov.noaa.nws.ncep.viz.rsc.mosaic/src/gov/noaa/nws/ncep/viz/rsc/mosaic/rsc/RadarTileSet.java index 9e1106c50c..7de196f301 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.mosaic/src/gov/noaa/nws/ncep/viz/rsc/mosaic/rsc/RadarTileSet.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.mosaic/src/gov/noaa/nws/ncep/viz/rsc/mosaic/rsc/RadarTileSet.java @@ -1,7 +1,9 @@ package gov.noaa.nws.ncep.viz.rsc.mosaic.rsc; import gov.noaa.nws.ncep.edex.plugin.mosaic.uengine.MosaicTiler; + import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.datum.PixelInCell; import com.raytheon.uf.common.datastorage.StorageException; import com.raytheon.uf.viz.core.IGraphicsTarget; @@ -21,6 +23,7 @@ import com.raytheon.viz.core.rsc.hdf5.AbstractTileSet; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 01/2001 204 M. Li Initial Creation. + * 09/2014 sgilbert Clean up unused method * * * @@ -47,7 +50,8 @@ public class RadarTileSet extends AbstractTileSet { String viewType) throws VizException { super(tiler.getLevels(), tiler.getTileSize(), tiler - .constructGridGeometry(), rsc, viewType); + .constructGridGeometry(), rsc, PixelInCell.CELL_CORNER, + viewType); this.tiler = tiler; } @@ -95,13 +99,6 @@ public class RadarTileSet extends AbstractTileSet { return true; } - /** - * @return - */ - public double getMaxExtent() { - return tiler.getMaxExent(); - } - public CoordinateReferenceSystem getCRS() { return this.originalGridGeometry.getCoordinateReferenceSystem(); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java index 934b3705f5..7c4da410dc 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java @@ -2924,7 +2924,7 @@ public class NcgridResource extends // modelname = modelname + ":" + gridRscData.getEventName(); // } // } - titleInfoStr = modelname + titleInfoStr = modelname + " " + replaceTitleSpecialCharacters(titleStr, cTime); if (shrttlStr != null) { titleInfoStr = titleInfoStr + " | " @@ -2941,139 +2941,117 @@ public class NcgridResource extends * location ? Day of the week flag */ private String replaceTitleSpecialCharacters(String title, DataTime cTime) { - String titleStr = title; - boolean daywk = false, daywkF = false, daywkV = false; - int pos, posV = -1, posF = -1; + StringBuilder titleBuilder = new StringBuilder(title); + int pos, posV, posF; DataTime currFrameTm = (DataTime) getCurrentFrameTime(); /* * check '!' and remove it for now ??? */ - if ((pos = titleStr.indexOf('!')) > 0) { - titleStr = titleStr.substring(0, pos); + if ((pos = titleBuilder.indexOf("!")) > 0) { + titleBuilder = titleBuilder.delete(pos, titleBuilder.length()); } /* - * check '?' flag for day of week + * get '~'/'^' position and decide which one to use. */ - if ((pos = titleStr.indexOf('?')) >= 0) { - if (pos == 0) { - titleStr = titleStr.substring(1, titleStr.length()); - } else { - titleStr = titleStr.substring(0, pos - 1) - + titleStr.substring(pos + 1, titleStr.length()); - } - daywk = true; - } - /* - * get '~'/'^' position and decide where to add day of week - */ - posF = titleStr.indexOf('^'); - posV = titleStr.indexOf('~'); - if (daywk) { - if (posF >= 0 || posV >= 0) { - if (posF <= posV && posF >= 0) { - daywkF = true; - } else if (posF < 0) { - daywkV = true; - } else if (posV >= 0) { - daywkV = true; - } else { - daywkF = true; + if (((posF = titleBuilder.indexOf("^")) >= 0) + | ((posV = titleBuilder.indexOf("~")) >= 0)) { + Calendar cal; + String timestampFormat; + /* + * The time will be placed where the furthest ~ or ^ is positioned + */ + pos = (posF > posV ? posF : posV); + /* + * The time to use will be which ever one comes latest in the title + * string. *EXCEPT* if the ~ is the first character in which case + * the valid time is used. + */ + if (posF > posV && posV != 0) { + cal = cTime.getRefTimeAsCalendar(); + timestampFormat = "%02d%02d%02d/%02d%02dF%03d"; + /* + * Legacy behavior will put the forcast time at the next + * position after the ^ when there is both ~ and ^ the ^ is + * after the ~ and the ~ is not the first character. We must add + * a space at the end if the ^ is the last character in the + * title. + */ + if (posF >= 0 && posV > 0) { + if (++pos == titleBuilder.length()) { + titleBuilder.append(" "); + } } - } - } - /* - * check '-' flag for valid date/time - */ - if (posV >= 0) { - String validTmStr; - Calendar cal = currFrameTm.getValidTime(); - int vTm = cTime.getFcstTime() / 3600; - String tmStr = String.format("%02d%02d%02d/%02d%02dV%03d", - (cal.get(Calendar.YEAR) % 100), - (cal.get(Calendar.MONTH) + 1), - cal.get(Calendar.DAY_OF_MONTH), - cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), - vTm); - if (daywkV) { - validTmStr = String.format( - "%s %s", - cal.getDisplayName(Calendar.DAY_OF_WEEK, - Calendar.SHORT, Locale.ENGLISH).toUpperCase(), - tmStr); } else { - validTmStr = tmStr; + cal = currFrameTm.getValidTime(); + timestampFormat = "%02d%02d%02d/%02d%02dV%03d"; } - titleStr = titleStr.substring(0, posV) + " " - + titleStr.substring(posV + 1, titleStr.length()) + " " - + validTmStr; - } - posF = titleStr.indexOf('^'); - /* - * check '^' flag for forecast date/time - */ - if (posF >= 0) { - Calendar cal = cTime.getRefTimeAsCalendar(); int vTm = cTime.getFcstTime() / 3600; - String fscTmStr = String.format("%02d%02d%02d/%02d%02dF%03d", + /* + * check '?' flag for day of week + */ + if (titleBuilder.indexOf("?") >= 0) { + deleteWildcard(titleBuilder, "?"); + String dayOfWeek = cal.getDisplayName(Calendar.DAY_OF_WEEK, + Calendar.SHORT, Locale.ENGLISH).toUpperCase() + + " "; + titleBuilder.insert(pos, dayOfWeek); + pos = pos + dayOfWeek.length(); + } + titleBuilder.insert(pos, String.format(timestampFormat, (cal.get(Calendar.YEAR) % 100), (cal.get(Calendar.MONTH) + 1), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), - vTm); - if (daywkF) { - // Calendar cal1 = Calendar.getInstance( - // TimeZone.getTimeZone("GMT") ); - cal.setTime(currFrameTm.getRefTime()); - fscTmStr = String.format( - "%s %s", - cal.getDisplayName(Calendar.DAY_OF_WEEK, - Calendar.SHORT, Locale.ENGLISH).toUpperCase(), - fscTmStr); - } - titleStr = titleStr.substring(0, posF) + " " - + titleStr.substring(posF + 1, titleStr.length()) + " " - + fscTmStr; + vTm)); + + deleteWildcard(titleBuilder, "^"); + deleteWildcard(titleBuilder, "~"); } /* * check '@' for Vertical level */ - if ((pos = titleStr.indexOf('@')) >= 0) { - titleStr = titleStr.substring(0, pos) + gridRscData.getGlevel() - + " " + getVerticalLevelUnits(gridRscData.getGvcord()) - + titleStr.substring(pos + 1, titleStr.length()); + if ((pos = titleBuilder.indexOf("@")) >= 0) { + deleteWildcard(titleBuilder, "@"); + titleBuilder.insert(pos, gridRscData.getGlevel() + " " + + getVerticalLevelUnits(gridRscData.getGvcord())); } /* * check '_' for Grid function */ - if ((pos = titleStr.indexOf('_')) >= 0) { - titleStr = titleStr.substring(0, pos) - + gridRscData.getGdpfun().toUpperCase() - + titleStr.substring(pos + 1, titleStr.length()); + if ((pos = titleBuilder.indexOf("_")) >= 0) { + deleteWildcard(titleBuilder, "_"); + titleBuilder.insert(pos, gridRscData.getGdpfun().toUpperCase()); } /* * check '$' for Nonzero scaling factor */ - if ((pos = titleStr.indexOf('$')) >= 0) { + if ((pos = titleBuilder.indexOf("$")) >= 0) { + deleteWildcard(titleBuilder, "$"); if (gridRscData.getScale().compareTo("0") != 0) { - titleStr = titleStr.substring(0, pos) + "(*10**" - + gridRscData.getScale() + ")" - + titleStr.substring(pos + 1, titleStr.length()); - } else { - titleStr = titleStr.substring(0, pos - 1) - + titleStr.substring(pos + 1, titleStr.length()); + titleBuilder.insert(pos, "(*10**" + gridRscData.getScale() + + ")"); } } /* * check '#' for Grid point location */ - if ((pos = titleStr.indexOf('#')) >= 0) { - titleStr = titleStr.substring(0, pos - 1) - + titleStr.substring(pos + 1, titleStr.length()); + if ((pos = titleBuilder.indexOf("#")) >= 0) { + deleteWildcard(titleBuilder, "#"); } - return titleStr; + return titleBuilder.toString(); + } + + /* + * Utility method to delete wildcard characters + */ + private void deleteWildcard(StringBuilder charSeq, String wildcard) { + int startIndex = charSeq.indexOf(wildcard); + if (startIndex >= 0) { + charSeq.delete(startIndex, startIndex + wildcard.length()); + } } /* diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/jcgm/README.txt b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/jcgm/README.txt index fbe62bf62e..60b5882b58 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/jcgm/README.txt +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/jcgm/README.txt @@ -1,5 +1,7 @@ jcgm -- Computer Graphics Metafile interpreter and renderer +See also the other README.TXT, in sibling "ncgm" package. + This package contains source code from the "jcgm" open source Java implementation to interpret and render Computer Graphics Metafile (CGM) graphics files. @@ -28,5 +30,5 @@ Classes in the "ncgm" package generally extend classes from "jcgm", in order to implement the INcCommand interface, and so perform this rendering. Note that all of the jcgm core classes are present, even though we do not -currently use most of them. This is for completeness, and to allow +currently use (extend) most of them. This is for completeness, and to allow possible future expansion. \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/INcCommand.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/INcCommand.java index ed0c5b8bc7..03430c280d 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/INcCommand.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/INcCommand.java @@ -19,13 +19,17 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties; import com.raytheon.uf.viz.core.exception.VizException; /** + * INcCommand: Interface implemented by selected CGM command classes that have + * been extended to allow themselves to contribute to an AWIPS II image. + * * @author bhebbard * */ public interface INcCommand { - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException; + public abstract void contributeToPaintableImage(ImageBuilder ib, + IGraphicsTarget target, PaintProperties paintProps, + IDescriptor descriptor) throws VizException; } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCGM.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCGM.java index bc960c66d7..c18c25a9dc 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCGM.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCGM.java @@ -24,12 +24,9 @@ */ package gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.BeginMetafile; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.BeginPicture; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.BeginPictureBody; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.CGM; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.CGMDisplay; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.CgmException; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ColourIndexPrecision; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ColourModel; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ColourPrecision; @@ -39,8 +36,6 @@ import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.Command; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.EdgeWidthSpecificationMode; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.EndMetafile; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.EndPicture; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.IBeginMetafileNameExtractor; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ICgmExtractor; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ICommandListener; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.IndexPrecision; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.IntegerPrecision; @@ -50,38 +45,25 @@ import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.Message; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.Messages; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.RealPrecision; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.RestrictedTextType; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ScalingMode; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.ScalingMode.Mode; -import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.VDCExtent; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.VDCIntegerPrecision; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.VDCRealPrecision; import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.VDCType; -import java.awt.Dimension; -import java.awt.geom.Point2D; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.DataInput; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.zip.GZIPInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** + * The central JCGM class, extended/modified/stripped for NTRANS needs. + * + * Represents one CGM image, as an ordered list of individual CGM commands. + * * @author bhebbard adapted from CGM.java by BBN * */ @@ -99,25 +81,7 @@ public class NcCGM extends CGM implements Cloneable { private final static int MAX_COMMANDS_PER_IMAGE = 999999; public NcCGM() { - // empty constructor //TODO: Remove? - } - - public NcCGM(File cgmFile) throws IOException { - // NO LONGER NEEDED - if (cgmFile == null) - throw new NullPointerException("unexpected null parameter"); - - InputStream inputStream; - String cgmFilename = cgmFile.getName(); - if (cgmFilename.endsWith(".cgm.gz") || cgmFilename.endsWith(".cgmz")) { - inputStream = new GZIPInputStream(new FileInputStream(cgmFile)); - } else { - inputStream = new FileInputStream(cgmFile); - } - DataInputStream in = new DataInputStream(new BufferedInputStream( - inputStream)); - read(in); - in.close(); + // default constructor } public void read(DataInput in) throws IOException { @@ -142,11 +106,14 @@ public class NcCGM extends CGM implements Cloneable { e.printStackTrace(); } - if (c == null) + if (c == null) { continue; // or should we add as null command? + } - if (c instanceof NcLineWidth || c instanceof NcTextAlignment) { - logger.info("[CGM command #" + com + " completed] " + if (c instanceof NcTextAlignment) { + // TODO: special investigation -- + // NTRANS doesn't use this command quite as expected + logger.debug("[CGM command #" + com + " completed] " + c.toString()); } @@ -179,183 +146,6 @@ public class NcCGM extends CGM implements Cloneable { } - /** - * Splits a CGM file containing several CGM files into pieces. Each single - * CGM file will be extracted to an own file. The name of that file is - * provided by the given {@code extractor}. - * - * @param cgmFile - * The CGM file to split - * @param outputDir - * The output directory to use. Must exist and be writable. - * @param extractor - * The extractor in charge of naming the split CGM files - * @throws IOException - * If the given CGM file could not be read or there was an error - * splitting the file - */ - public static void split(File cgmFile, File outputDir, - IBeginMetafileNameExtractor extractor) throws IOException { - if (cgmFile == null || outputDir == null || extractor == null) - throw new NullPointerException("unexpected null argument"); - - if (!outputDir.isDirectory()) - throw new IllegalArgumentException("outputDir must be a directory"); - - if (!outputDir.canWrite()) - throw new IllegalArgumentException("outputDir must be writable"); - - RandomAccessFile randomAccessFile = null; - try { - randomAccessFile = new RandomAccessFile(cgmFile, "r"); - FileChannel channel = randomAccessFile.getChannel(); - - Command c; - long startPosition = 0; - long currentPosition = 0; - String currentFileName = null; - - while ((c = Command.read(randomAccessFile)) != null) { - if (c instanceof BeginMetafile) { - // the CGM files will be cut at the begin meta file command - if (currentFileName != null) { - dumpToFile(outputDir, extractor, channel, - startPosition, currentPosition, currentFileName); - } - startPosition = currentPosition; - BeginMetafile beginMetafile = (BeginMetafile) c; - currentFileName = beginMetafile.getFileName(); - } - currentPosition = randomAccessFile.getFilePointer(); - } - - if (currentFileName != null) { - dumpToFile(outputDir, extractor, channel, startPosition, - currentPosition, currentFileName); - } - } finally { - if (randomAccessFile != null) { - randomAccessFile.close(); - } - } - } - - private static void dumpToFile(File outputDir, - IBeginMetafileNameExtractor extractor, FileChannel channel, - long startPosition, long currentPosition, String currentFileName) - throws IOException { - // dump the CGM file - MappedByteBuffer byteBuffer = channel.map( - FileChannel.MapMode.READ_ONLY, startPosition, currentPosition - - startPosition); - writeFile(byteBuffer, outputDir, - extractor.extractFileName(currentFileName)); - // don't forget to regularly clear the messages that - // we're not really using here - Messages.getInstance().reset(); - } - - /** - * Splits a CGM file containing several CGM files into pieces. The given - * extractor is in charge of dealing with the extracted CGM file. - * - * @param cgmFile - * The CGM file to split - * @param extractor - * An extractor that knows what to do with the extracted CGM file - * @throws IOException - * If an error happened reading the CGM file - * @throws CgmException - * If an error happened during the handling of the extracted CGM - * file - */ - public static void split(File cgmFile, ICgmExtractor extractor) - throws IOException, CgmException { - if (cgmFile == null || extractor == null) - throw new NullPointerException("unexpected null argument"); - - RandomAccessFile randomAccessFile = null; - try { - randomAccessFile = new RandomAccessFile(cgmFile, "r"); - FileChannel channel = randomAccessFile.getChannel(); - - Command c; - long startPosition = 0; - long currentPosition = 0; - String currentFileName = null; - - while ((c = Command.read(randomAccessFile)) != null) { - if (c instanceof BeginMetafile) { - // the CGM files will be cut at the begin meta file command - if (currentFileName != null) { - dumpToStream(extractor, channel, startPosition, - currentPosition, currentFileName); - } - startPosition = currentPosition; - BeginMetafile beginMetafile = (BeginMetafile) c; - currentFileName = beginMetafile.getFileName(); - } - currentPosition = randomAccessFile.getFilePointer(); - } - - // don't forget to also dump the last file - if (currentFileName != null) { - dumpToStream(extractor, channel, startPosition, - currentPosition, currentFileName); - } - } finally { - if (randomAccessFile != null) { - randomAccessFile.close(); - } - } - } - - private static void dumpToStream(ICgmExtractor extractor, - FileChannel channel, long startPosition, long currentPosition, - String currentFileName) throws IOException, CgmException { - // dump the CGM file - MappedByteBuffer byteBuffer = channel.map( - FileChannel.MapMode.READ_ONLY, startPosition, currentPosition - - startPosition); - - byte[] byteArray = new byte[(int) (currentPosition - startPosition)]; - byteBuffer.get(byteArray); - extractor.handleExtracted(extractor.extractFileName(currentFileName), - new ByteArrayInputStream(byteArray), byteArray.length); - // don't forget to regularly clear the messages that - // we're not really using here - Messages.getInstance().reset(); - } - - /** - * Writes the given bytes to a file - * - * @param byteBuffer - * The bytes to write to the file - * @param outputDir - * The output directory to use, assumed to be existing and - * writable - * @param fileName - * The file name to use - * @throws IOException - * On I/O error - */ - private static void writeFile(ByteBuffer byteBuffer, File outputDir, - String fileName) throws IOException { - File outputFile = new File(outputDir, fileName); - FileOutputStream out = null; - try { - out = new FileOutputStream(outputFile); - FileChannel channel = out.getChannel(); - channel.write(byteBuffer); - out.close(); - } finally { - if (out != null) { - out.close(); - } - } - } - /** * Adds the given listener to the list of command listeners * @@ -393,94 +183,6 @@ public class NcCGM extends CGM implements Cloneable { return Messages.getInstance(); } - public void paint(CGMDisplay d) { - for (Command c : this.commands) { - if (filter(c)) { - c.paint(d); - } - } - } - - private boolean filter(Command c) { - return true; - // List> classes = new ArrayList>(); - // //classes.add(PolygonElement.class); - // classes.add(Text.class); - // //classes.add(CircleElement.class); - // - // for (Class clazz: classes) { - // if (clazz.isInstance(c)) - // return false; - // } - // - // return true; - } - - /** - * Returns the size of the CGM graphic. - * - * @return The dimension or null if no {@link VDCExtent} command was found. - */ - public Dimension getSize() { - // default to 96 DPI which is the Microsoft Windows default DPI setting - return getSize(96); - } - - /** - * Returns the size of the CGM graphic taking into account a specific DPI - * setting - * - * @param dpi - * The DPI value to use - * @return The dimension or null if no {@link VDCExtent} command was found. - */ - public Dimension getSize(double dpi) { - Point2D.Double[] extent = extent(); - if (extent == null) - return null; - - double factor = 1; - - ScalingMode scalingMode = getScalingMode(); - if (scalingMode != null) { - Mode mode = scalingMode.getMode(); - if (ScalingMode.Mode.METRIC.equals(mode)) { - double metricScalingFactor = scalingMode - .getMetricScalingFactor(); - if (metricScalingFactor != 0) { - // 1 inch = 25,4 millimeter - factor = (dpi * metricScalingFactor) / 25.4; - } - } - } - - int width = (int) Math - .ceil((Math.abs(extent[1].x - extent[0].x) * factor)); - int height = (int) Math - .ceil((Math.abs(extent[1].y - extent[0].y) * factor)); - - return new Dimension(width, height); - } - - public Point2D.Double[] extent() { - for (Command c : this.commands) { - if (c instanceof VDCExtent) { - Point2D.Double[] extent = ((VDCExtent) c).extent(); - return extent; - } - } - return null; - } - - private ScalingMode getScalingMode() { - for (Command c : this.commands) { - if (c instanceof ScalingMode) { - return (ScalingMode) c; - } - } - return null; - } - public void showCGMCommands() { showCGMCommands(System.out); } @@ -496,7 +198,3 @@ public class NcCGM extends CGM implements Cloneable { } } - -/* - * vim:encoding=utf8 - */ diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCharacterHeight.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCharacterHeight.java index 82b6d8a161..f7760d3a19 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCharacterHeight.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCharacterHeight.java @@ -29,8 +29,8 @@ public class NcCharacterHeight extends CharacterHeight implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { // Only change if different from the current size if (ib.currentFont.getFontSize() != this.characterHeight) { // TODO String currentFontNames = ib.currentFont.getFontName(); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCircleElement.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCircleElement.java index 6a5409f626..e91e17cf25 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCircleElement.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcCircleElement.java @@ -29,8 +29,8 @@ public class NcCircleElement extends CircleElement implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { // Used only to draw (teeny) circles to mark lat/lon lines? // If not, will need to revisit assumptions below... TODO diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcFillColour.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcFillColour.java index f7ded21484..765ecb09a9 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcFillColour.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcFillColour.java @@ -26,8 +26,8 @@ public class NcFillColour extends FillColour implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { ib.currentFillColor = GempakColor.convertToRGB(this.colorIndex); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcInteriorStyle.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcInteriorStyle.java index eac84a05ae..04f175c9b6 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcInteriorStyle.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcInteriorStyle.java @@ -31,8 +31,8 @@ public class NcInteriorStyle extends InteriorStyle implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { switch (this.style) { case SOLID: // TODO: For now, SOLID is assumed for all filled polygons break; diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineColour.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineColour.java index 1221e755f4..46da4dd5d4 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineColour.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineColour.java @@ -27,8 +27,8 @@ public class NcLineColour extends LineColour implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { ib.currentLineColor = GempakColor.convertToRGB(this.colorIndex); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineWidth.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineWidth.java index 5bffc8b9b1..8446de2015 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineWidth.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcLineWidth.java @@ -25,8 +25,8 @@ public class NcLineWidth extends LineWidth implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { ib.currentLineWidth = this.width; // / 1.0; // TODO ?? } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolygonElement.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolygonElement.java index 224cb9a541..b3f515152f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolygonElement.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolygonElement.java @@ -40,11 +40,9 @@ public class NcPolygonElement extends PolygonElement implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { - - if (ib.shadedShapeReady) - return; // work already done + public void contributeToPaintableImage(ImageBuilder ib, + IGraphicsTarget target, PaintProperties paintProps, IDescriptor descriptor) + throws VizException { PathIterator pi = this.polygon.getPathIterator(null); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolyline.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolyline.java index 121c4ae1db..edab12b60f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolyline.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcPolyline.java @@ -27,22 +27,34 @@ public class NcPolyline extends Polyline implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, + IGraphicsTarget target, PaintProperties paintProps, + IDescriptor descriptor) throws VizException { + // Create a key for this wireframe, based on current settings of + // line color and line width (which must be held constant during + // a single wireframe paint operation) WireframeKey key = ib.new WireframeKey(ib.currentLineColor, ib.currentLineWidth); - IWireframeShape wireframeForThisKey = ib.wireframes.get(key); + // Put (or move) the key to last on the paint sequence + while (ib.wireframePaintOrder.remove(key)) + // Remove any existing occurrence(s) in the list... + ; + ib.wireframePaintOrder.add(key); // ...and add to the end + // Pull up the wireframe (for this key) under construction. + // If none exists yet, start one. + IWireframeShape wireframeForThisKey = ib.wireframes.get(key); if (wireframeForThisKey == null) { wireframeForThisKey = target .createWireframeShape(false, descriptor); ib.wireframes.put(key, wireframeForThisKey); } + // Process individual segments in the CGM polyline, adding them + // to the wireframe under construction. PathIterator pi = this.path.getPathIterator(null); - while (pi.isDone() == false) { processCurrentSegment(pi, wireframeForThisKey, ib); pi.next(); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcText.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcText.java index b9805130e3..c708c17628 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcText.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcText.java @@ -39,8 +39,8 @@ public class NcText extends Text implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { // TODO: Why currentLineColor and not currentTextColor? Legacy quirk? DrawableString ds = new DrawableString(this.string, ib.currentLineColor); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextAlignment.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextAlignment.java index 2775efb3bf..f4ff189a77 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextAlignment.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextAlignment.java @@ -28,8 +28,8 @@ public class NcTextAlignment extends TextAlignment implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { // Map/convert CGM-style text alignments to their IGraphicsTarget // equivalents. diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextColour.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextColour.java index 461aae7017..965fa9107c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextColour.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextColour.java @@ -27,8 +27,8 @@ public class NcTextColour extends TextColour implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { ib.currentTextColor = GempakColor.convertToRGB(this.colorIndex); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextFontIndex.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextFontIndex.java index 89d8ec9f35..187fe917ad 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextFontIndex.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/NcTextFontIndex.java @@ -33,8 +33,8 @@ public class NcTextFontIndex extends TextFontIndex implements INcCommand { } @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps, - IDescriptor descriptor, ImageBuilder ib) throws VizException { + public void contributeToPaintableImage(ImageBuilder ib, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor) throws VizException { if (notWarned) { logger.warn("Paint not implemented for CGM command: " + this); notWarned = false; diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/ImageBuilder.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/ImageBuilder.java index ba6f7c12cf..b6a87a20f0 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/ImageBuilder.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/ImageBuilder.java @@ -46,6 +46,10 @@ import com.raytheon.uf.viz.core.drawables.IWireframeShape; * commands (e.g., LineWidth); this structure also provides a place to hold * these states. * + * ImageBuilder is used to construct a PaintableImage, but is kept distinct so + * that the former can be discarded (along with any temporary "building + * materials" it contains) once the latter has been fully constructed. + * *
  * 
  * SOFTWARE HISTORY
@@ -121,12 +125,19 @@ public class ImageBuilder {
         private ImageBuilder getOuterType() {
             return ImageBuilder.this;
         }
+
+        public String toString() {
+            return (color.toString() + " Line Width " + width);
+        }
     }
 
     // Collection of all wireframes under construction, keyed by unique output
     // draw states
     public Map wireframes = new HashMap();
 
+    // Sequence in which to paint the wireframes
+    public List wireframePaintOrder = new ArrayList();
+
     // Line color set by the most recent CGM LineColour command. Default to
     // WHITE.
     public RGB currentLineColor = new RGB(255, 255, 255);
@@ -156,15 +167,6 @@ public class ImageBuilder {
 
     public RGB currentFillColor = new RGB(0, 255, 0);
 
-    public boolean shadedShapeReady = false; // if true, shaded shape
-                                             // constructed on
-                                             // first paint of this frame
-                                             // are already saved
-                                             // (in PictureInfo), and so we
-                                             // can skip
-                                             // regeneration on subsequent
-                                             // paints
-
     public double scale = 1.0;
 
     public double scaleNoZoom = 1.0;
diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/NtransResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/NtransResource.java
index 5c54b2df6f..cf07c98ad7 100644
--- a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/NtransResource.java
+++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/NtransResource.java
@@ -5,10 +5,8 @@ import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource;
 import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource;
 import gov.noaa.nws.ncep.viz.resources.manager.ResourceName;
 import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.Command;
-import gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm.INcCommand;
 import gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm.NcCGM;
 import gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm.NcText;
-import gov.noaa.nws.ncep.viz.rsc.ntrans.rsc.ImageBuilder.WireframeKey;
 import gov.noaa.nws.ncep.viz.ui.display.NCNonMapDescriptor;
 
 import java.io.ByteArrayInputStream;
@@ -29,18 +27,11 @@ import com.raytheon.uf.common.datastorage.Request;
 import com.raytheon.uf.common.datastorage.StorageException;
 import com.raytheon.uf.common.datastorage.records.IDataRecord;
 import com.raytheon.uf.common.time.DataTime;
-import com.raytheon.uf.viz.core.DrawableCircle;
 import com.raytheon.uf.viz.core.HDF5Util;
-import com.raytheon.uf.viz.core.IExtent;
 import com.raytheon.uf.viz.core.IGraphicsTarget;
-import com.raytheon.uf.viz.core.PixelExtent;
 import com.raytheon.uf.viz.core.catalog.LayerProperty;
 import com.raytheon.uf.viz.core.catalog.ScriptCreator;
 import com.raytheon.uf.viz.core.comm.Connector;
-import com.raytheon.uf.viz.core.drawables.IFont;
-import com.raytheon.uf.viz.core.drawables.IFont.Style;
-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.rsc.LoadProperties;
@@ -65,7 +56,7 @@ import com.raytheon.uf.viz.core.rsc.ResourceType;
  *                                      long CGM retrieval and parsing is done by the InitJob, and thus
  *                                      (1) user sees "Initializing..." and (2) GUI doesn't lock up
  * 29 Aug 2014              B. Hebbard  Remove time string and "/" separator from legend
- * 
+ * 12 Sep 2014              B. Hebbard  Refactor to avoid regenerating paintables from CGM on each paint.
  * 
  * 
* @@ -80,46 +71,20 @@ public class NtransResource extends private String legendStr = "NTRANS "; // init so not-null - private IFont font = null; - - private final Log logger = LogFactory.getLog(this.getClass()); // TODO - // static - // better?? - - private class NtransDisplayablePictureInfo { // CGM calls it a "picture". - // This is just a container holding the ready-to-paint information for - // a single NTRANS image. - NtransRecord ntransRecord; // the metadata record (PDO) - - NcCGM cgm; // constructed "jcgm" representation of the image - - public IShadedShape shadedShape; // shaded shapes (filled polygons) get - // special - // handling due to memory (heap - // runaway) issues; - // once generated (at first paint), - // cache here - // for future paints, instead of - // regenerating each time - - public NtransDisplayablePictureInfo(NtransRecord nr, NcCGM nc) { - ntransRecord = nr; - cgm = nc; - shadedShape = null; - } - - public void dispose() { - if (shadedShape != null) { - shadedShape.dispose(); - } - } - } + // TODO static better?? + private final Log logger = LogFactory.getLog(this.getClass()); private class FrameData extends AbstractFrameData { - // FrameData holds the displayable information for a single frame - // (time). - NtransDisplayablePictureInfo pictureInfo; + // FrameData holds information for a single frame (time). + + NtransRecord ntransRecord; // the metadata record (PDO) + + NcCGM cgmImage; // "jcgm" (connected Java objects) representation of the + // CGM image + + PaintableImage paintableImage; // AWIPS graphics elements of the image; + // compiled and ready to paint public FrameData(DataTime frameTime, int timeInt) { super(frameTime, timeInt); @@ -131,28 +96,26 @@ public class NtransResource extends + " instead of: " + rscDataObj.getClass().getName()); return false; } - // TODO : check that the cycle times match. - if (pictureInfo != null) { - + if (ntransRecord != null) { System.out .println("adding record to frame that has already been populated"); - // add code here to check if the new data is a better time - // match. if not then discard and - // if so dispose of the existing data and process the new record + // Add code here to check if the new data is a better time + // match. If not then discard, and if so dispose of the + // existing data and process the new record. [from GH] return false; } // Get PDO from the given RDO DfltRecordRscDataObj ntransRDO = (DfltRecordRscDataObj) rscDataObj; - NtransRecord nr = (NtransRecord) ntransRDO.getPDO(); + ntransRecord = (NtransRecord) ntransRDO.getPDO(); - // Get image data HDF5. + // Get binary CGM image data from data store long t0 = System.currentTimeMillis(); - byte[] imageBytes = getCgmFromNtrans(nr); + byte[] imageBytes = getBinaryCgmFromNtransRecord(ntransRecord); long t1 = System.currentTimeMillis(); if (imageBytes == null) { logger.error("NtransResource.updateFrameData imageBytes from NtransRecord is null "); @@ -167,46 +130,52 @@ public class NtransResource extends flipped = true; } - // Construct "jcgm" representation of the image + // Construct "jcgm" (Java objects) CGM representation of the image + // from the binary CGM - NcCGM cgm = new NcCGM(); + cgmImage = new NcCGM(); InputStream is = new ByteArrayInputStream(imageBytes); DataInput di = new DataInputStream(is); try { long t2 = System.currentTimeMillis(); - cgm.read(di); + cgmImage.read(di); // <-- Voom! long t3 = System.currentTimeMillis(); - logger.info("CGM image " + nr.getImageByteCount() + logger.info("CGM image " + ntransRecord.getImageByteCount() + " bytes retrieved from HDF5 in " + (t1 - t0) + " ms" + " and parsed in " + (t3 - t2) + " ms"); } catch (Exception e) { - logger.info("CGM image " + nr.getImageByteCount() + logger.info("CGM image " + ntransRecord.getImageByteCount() + " bytes retrieved from HDF5 in " + (t1 - t0) + " ms"); logger.error("EXCEPTION occurred interpreting CGM" - + " for metafile " + nr.getMetafileName() + " product " - + nr.getProductName()); + + " for metafile " + ntransRecord.getMetafileName() + + " product " + ntransRecord.getProductName()); e.printStackTrace(); } // Endianess revisited if (flipped) { // if we shuffled the bytes before parsing... - flipStrings(cgm); // ...then unshuffle the strings (now we know - // where they are) + flipStrings(cgmImage); // ...then unshuffle the strings + // (now that we know where they are) } // TODO Add optional (cool) debug dump of CGM representation - - // cgm.showCGMCommands(); - - // Save away just the info needed to draw this frame - - pictureInfo = new NtransDisplayablePictureInfo(nr, cgm); + // cgmImage.showCGMCommands(); return true; } + private byte[] shuffleByteArray(byte[] image) { + // Flip every even byte with its odd sibling (endianess reversal) + byte[] returnArray = new byte[image.length]; + for (int i = 0; i < image.length; i = i + 2) { + returnArray[i] = image[i + 1]; + returnArray[i + 1] = image[i]; + } + return returnArray; + } + private void flipStrings(NcCGM cgm) { for (Command c : cgm.getCommands()) { if (c instanceof NcText) { @@ -216,7 +185,7 @@ public class NtransResource extends } } - private byte[] getCgmFromNtrans(NtransRecord nr) { + private byte[] getBinaryCgmFromNtransRecord(NtransRecord nr) { // Given the NcscatRecord, locate the associated HDF5 data... @@ -239,12 +208,16 @@ public class NtransResource extends // String uri = nr.getDataURI(); String dataset = "NTRANS"; + // @formatter:off + /* // get filename and directory for IDataStore - // String dir = - // nr.getHDFPathProvider().getHDFPath(nr.getPluginName(), nr); - // String filename = - // nr.getHDFPathProvider().getHDFFileName(nr.getPluginName(), nr); - // File file = new File(dir, filename); + String dir = nr.getHDFPathProvider().getHDFPath(nr.getPluginName(), + nr); + String filename = nr.getHDFPathProvider().getHDFFileName( + nr.getPluginName(), nr); + File file = new File(dir, filename); + */ + // @formatter:on // ...and retrieve it @@ -273,8 +246,9 @@ public class NtransResource extends } public void dispose() { - if (pictureInfo != null) { - pictureInfo.dispose(); + if (paintableImage != null) { + paintableImage.dispose(); + paintableImage = null; } super.dispose(); } @@ -292,9 +266,9 @@ public class NtransResource extends super(resourceData, loadProperties); ntransResourceData = (NtransResourceData) resourceData; - // set the legend from the metafileName and productName - // NOTE : this assumes that the request type of EQUALS (ie only one kind - // of metafileName and productName) (??) + // Set the legend from the metafileName and productName. + // NOTE: This assumes that the request type of EQUALS + // (i.e. only one kind of metafileName and productName) (??) [from GH] // if (ntransResourceData.getMetadataMap().containsKey("metafileName") && ntransResourceData.getMetadataMap().containsKey( @@ -313,19 +287,18 @@ public class NtransResource extends return (AbstractFrameData) new FrameData(frameTime, timeInt); } - // query all the data in the db matching the request constraints (ie - // modelName, metaFile, and productName) - // and also match the selected cycle time. + // Query all the data in the DB matching the request constraints (modelName, + // metaFile, and productName) and also match the selected cycle time. // public void initResource(IGraphicsTarget grphTarget) throws VizException { - // set initial display values from resource attributes (as if after + // Set initial display values from resource attributes (as if after // modification) - // resourceAttrsModified(); - long t0 = System.currentTimeMillis(); + + // resourceAttrsModified(); // none now; possible future enhancement ResourceName rscName = getResourceData().getResourceName(); - // set the constraints for the query. + // Set the constraints for the query String[] dts = rscName.getCycleTime().toString().split(" "); String cycleTimeStr = dts[0] + " " + dts[1].substring(0, dts[1].length() - 2); @@ -339,15 +312,21 @@ public class NtransResource extends LayerProperty prop = new LayerProperty(); prop.setDesiredProduct(ResourceType.PLAN_VIEW); prop.setEntryQueryParameters(reqConstraintsMap, false); - prop.setNumberOfImages(15000); // TODO: max # records ?? should we cap - // this ? + prop.setNumberOfImages(15000); // TODO: max # records ?? + // Should we cap this ? String script = null; script = ScriptCreator.createScript(prop); - if (script == null) + if (script == null) { return; + } + long t0 = System.currentTimeMillis(); Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + long t1 = System.currentTimeMillis(); + + logger.info("Metadata records for " + this.newRscDataObjsQueue.size() + + " images retrieved from DB in " + (t1 - t0) + " ms"); for (Object pdo : pdoList) { for (IRscDataObject dataObject : processRecord(pdo)) { @@ -358,14 +337,10 @@ public class NtransResource extends // TODO -- why is this here? Still needed? setAllFramesAsPopulated(); - logger.info("Metadata records for " + this.newRscDataObjsQueue.size() - + " images retrieved from DB in " - + (System.currentTimeMillis() - t0) + " ms"); - - // following is done in ANCR.paintInternal too, but want to get it done + // Following is done in ANCR.paintInternal too, but want to get it done // on the init thread since it's time-consuming and (1) we want to show // the "Initializing..." pacifier message, and (2) not lock up the GUI - // thread during loading + // thread during loading. (Might want to consider doing this in ANCR.) if (!newRscDataObjsQueue.isEmpty() // || (!newFrameTimesList.isEmpty() && getDescriptor().isAutoUpdate()) ) { @@ -376,142 +351,58 @@ public class NtransResource extends public void paintFrame(AbstractFrameData frameData, IGraphicsTarget target, PaintProperties paintProps) throws VizException { + // Are we "go" to paint? + + if (frameData == null || target == null || paintProps == null) { + return; + } FrameData fd = (FrameData) frameData; + if (fd.ntransRecord == null) { + // throw new VizException(); + return; // TODO why? + } + if (fd.paintableImage == null && fd.cgmImage == null) { + // throw new VizException(); + return; // TODO why? + } - if (target != null && paintProps != null) { - NtransDisplayablePictureInfo pictureInfo = fd.pictureInfo; + // If a ready-to-paint image has not yet been built for this frame, then + // construct one from the (Java representation of the) CGM image - if (pictureInfo == null) + final boolean discardCGMAfterPaintableImageBuilt = true; + + if (fd.paintableImage == null) { + double scale = 1000.000 / (double) fd.ntransRecord.getImageSizeX(); + try { + fd.paintableImage = new PaintableImage(fd.cgmImage, target, + paintProps, descriptor, scale); + if (discardCGMAfterPaintableImageBuilt) { + fd.cgmImage = null; + } + } catch (Exception e) { + logger.error("[EXCEPTION occurred constructing paintable image" + + " for metafile " + fd.ntransRecord.getMetafileName() + + " product " + fd.ntransRecord.getProductName() + "]"); + fd.paintableImage = null; + fd.cgmImage = null; // don't keep trying on subsequent paints return; - - // Paint it - - if (this.font == null) { - this.font = target.initializeFont("Monospace", 12, - new IFont.Style[] { Style.BOLD }); } - ImageBuilder ib = new ImageBuilder(); - - ib.currentFont = this.font; - ib.scale = 1000.000 / (double) pictureInfo.ntransRecord - .getImageSizeX(); // TODO avoid hardcoding 1000 - if (pictureInfo.shadedShape != null) { - // if we've saved shaded shapes from a previous paint, - // NcPolygonElement - // can skip generating them all over again - ib.shadedShapeReady = true; - } else { - ib.shadedShape = target.createShadedShape(false, // mutable - descriptor.getGridGeometry(), false); // tesselate - } - - double screenToWorldRatio = paintProps.getCanvasBounds().width - / paintProps.getView().getExtent().getWidth(); - ib.scaleNoZoom = ib.scale / screenToWorldRatio; - ib.scaleNoZoom = ib.scale * paintProps.getZoomLevel(); - - IExtent screenExtent = paintProps.getView().getExtent(); - IExtent mapExtent = new PixelExtent(descriptor.getGridGeometry() - .getGridRange()); - - for (Command c : pictureInfo.cgm.getCommands()) { - if (c instanceof INcCommand) { - ((INcCommand) c).paint(target, paintProps, descriptor, ib); - } - } - - // Shaded Shape (filled polygons) was deferred. Paint it now. - - // if first paint of this image, save away shaded shape for future - // use - if (!ib.shadedShapeReady /* OR pictureInfo.shadedShape == null */) { - ib.shadedShape.compile(); - // pictureInfo.completedShadedShapes = - // ib.shadedShapes.toArray(new - // IShadedShape[ib.shadedShapes.size()]); - pictureInfo.shadedShape = ib.shadedShape; - ib.shadedShapeReady = true; - } - float alpha = 1.0f; // TODO verify - float brightness = 1.0f; - target.drawShadedShape(pictureInfo.shadedShape, alpha, brightness); - // TODO now that we don't dispose on each paint, need to do on - // resource termination? - // for (IShadedShape ss : ib.shadedShapes) { - // ss.dispose(); - // } - - // Wireframes were deferred. Paint them now. - - for (WireframeKey key : ib.wireframes.keySet()) { - IWireframeShape wireframeForThisKey = ib.wireframes.get(key); - if (wireframeForThisKey == null) { - // TODO assert - } else { - wireframeForThisKey.compile(); - target.drawWireframeShape(wireframeForThisKey, key.color, - (float) key.width); - wireframeForThisKey.dispose(); - } - } - - // Strings were deferred. Paint them now. - - target.drawStrings(ib.strings); - - // Circles were deferred. Paint them now. - - target.drawCircle(ib.circles.toArray(new DrawableCircle[ib.circles - .size()])); - - /* - * -- Greg's handy outline box... - * - * RGB color = new RGB( 250, 10, 10 ); - * - * if( font == null ) { font = target.initializeFont("Monospace", - * 14, new IFont.Style[] { IFont.Style.BOLD}); } PixelCoordinate - * textLoc = new PixelCoordinate( 500, 500, 0 ); - * target.drawString(font, "CGM IMAGE", textLoc.getX(), - * textLoc.getY(), 0.0, TextStyle.NORMAL, new RGB( 255, 255, 200 ), - * HorizontalAlignment.CENTER, VerticalAlignment.MIDDLE, 0.0); - * - * target.drawLine(0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, 0.0f, color, - * 1.0f ); target.drawLine(0.0f, 0.0f, 0.0f, 1000.0f, 0.0f, 0.0f, - * color, 1.0f ); target.drawLine(1000.0f, 0.0f, 0.0f, 1000.0f, - * 1000.0f, 0.0f, color, 1.0f ); target.drawLine(0.0f, 1000.0f, - * 0.0f, 1000.0f, 1000.0f, 0.0f, color, 1.0f ); color = new - * RGB(0,255,0); target.drawLine(10.0f, 10.0f, 10.0f, 10.0f, 990.0f, - * 10.0f, color, 1.0f ); target.drawLine(10.0f, 10.0f, 10.0f, - * 990.0f, 10.0f, 10.0f, color, 1.0f ); target.drawLine(990.0f, - * 10.0f, 10.0f, 990.0f, 990.0f, 10.0f, color, 1.0f ); - * target.drawLine(10.0f, 990.0f, 10.0f, 990.0f, 990.0f, 10.0f, - * color, 1.0f ); - */ - } - } + // Paint it - private byte[] shuffleByteArray(byte[] image) { - // Flip every even byte with its odd sibling (endianess reversal) - byte[] returnArray = new byte[image.length]; - for (int i = 0; i < image.length; i = i + 2) { - returnArray[i] = image[i + 1]; - returnArray[i + 1] = image[i]; - } - return returnArray; + fd.paintableImage.paint(); } public void resourceAttrsModified() { - // TODO?? + // So far, none exist (possible future enhancement) } @Override public String getName() { FrameData fd = (FrameData) getCurrentFrame(); - if (fd == null || fd.getFrameTime() == null || fd.pictureInfo == null - || fd.pictureInfo.cgm == null) { + if (fd == null || fd.getFrameTime() == null + || (fd.paintableImage == null && fd.cgmImage == null)) { return legendStr + "-No Data"; } return legendStr; // + " " diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/PaintableImage.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/PaintableImage.java new file mode 100644 index 0000000000..d71bc779e1 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/rsc/PaintableImage.java @@ -0,0 +1,198 @@ +package gov.noaa.nws.ncep.viz.rsc.ntrans.rsc; + +import gov.noaa.nws.ncep.viz.rsc.ntrans.jcgm.Command; +import gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm.INcCommand; +import gov.noaa.nws.ncep.viz.rsc.ntrans.ncgm.NcCGM; +import gov.noaa.nws.ncep.viz.rsc.ntrans.rsc.ImageBuilder.WireframeKey; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IFont.Style; +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; + +public class PaintableImage { + // This is just a container holding the ready-to-paint information for + // a single NTRANS image. + + // Once generated (at first paint), cache here for future paints, instead of + // regenerating each time + + // shaded shapes (filled polygons) especially necessary to avoid memory + // (heap runaway) issues; + public IShadedShape shadedShape; + + // Map of all now-compiled wireframes, keyed by unique output draw states + public Map wireframes = new HashMap(); + + // Sequence in which to paint the wireframes + public List wireframePaintOrder = new ArrayList(); + + // AWIPS II DrawableString text objects + public List strings = new ArrayList(); + + // AWIPS II DrawableCircle objects + public List circles = new ArrayList(); + + private IFont font = null; // TODO: Move this? + + private IGraphicsTarget target = null; + + private final Log logger = LogFactory.getLog(this.getClass()); + + public PaintableImage(NcCGM cgmImage, IGraphicsTarget target, + PaintProperties paintProps, IDescriptor descriptor, double scale) + throws VizException { + + // Construct a PaintableImage (containing ready-to-paint, + // compiled-where-necessary) AWIPS graphics elements, given + // the (Java) CGM image. + + this.target = target; + + ImageBuilder ib = new ImageBuilder(); + + if (this.font == null) { // TODO clean up font handling + this.font = target.initializeFont("Monospace", 12, + new IFont.Style[] { Style.BOLD }); + } + + ib.currentFont = this.font; + ib.scale = scale; + ib.shadedShape = target.createShadedShape(false, // mutable + descriptor.getGridGeometry(), false); // tesselate + + double screenToWorldRatio = paintProps.getCanvasBounds().width + / paintProps.getView().getExtent().getWidth(); + ib.scaleNoZoom = ib.scale / screenToWorldRatio; + ib.scaleNoZoom = ib.scale * paintProps.getZoomLevel(); + + // IExtent screenExtent = paintProps.getView().getExtent(); + // IExtent mapExtent = new PixelExtent(descriptor.getGridGeometry() + // .getGridRange()); + + // Loop through the CGM commands -- in order -- to build paintable + // AWIPS image elements... + + for (Command c : cgmImage.getCommands()) { + if (c instanceof INcCommand) { + try { + ((INcCommand) c).contributeToPaintableImage(ib, target, + paintProps, descriptor); + } catch (VizException e) { + logger.error("[EXCEPTION occurred processing CGM" + + " command " + c + "]"); + e.printStackTrace(); + throw (e); + } + } + } + + // Compilation: Now that we've processed all the CGM commands, "compile" + // those AWIPS graphics elements that need it once they're complete + // (here, shaded shapes and wireframe shapes... + + ib.shadedShape.compile(); + + for (WireframeKey key : ib.wireframes.keySet()) { + IWireframeShape wireframeForThisKey = ib.wireframes.get(key); + if (wireframeForThisKey == null || !wireframeForThisKey.isMutable()) { + // TODO assert: Wireframe missing, or not compiled yet + } else { + wireframeForThisKey.compile(); + } + } + + // Now retrieve from the ImageBuilder only the completed paintable + // objects that we want to save as this PaintableImage. + // (The temporary ImageBuilder object will then be discarded.) + + this.shadedShape = ib.shadedShape; + this.wireframes = ib.wireframes; + this.wireframePaintOrder = ib.wireframePaintOrder; + this.circles = ib.circles; + this.strings = ib.strings; + } + + public void paint() throws VizException { + + // Finally! Actually paint the AWIPS graphics elements... + + // Shaded Shape (filled polygons) + + if (shadedShape != null) { + float alpha = 1.0f; // TODO verify + float brightness = 1.0f; + target.drawShadedShape(shadedShape, alpha, brightness); + } + + // Wireframes + + // int count = 0; + for (WireframeKey key : wireframePaintOrder /* wireframes.keySet() */) { + IWireframeShape wireframeForThisKey = wireframes.get(key); + if (wireframeForThisKey == null /* + * || + * wireframeForThisKey.isMutable() + */) { + // TODO assert: Wireframe missing, or not compiled yet + throw new VizException(); + } else { + target.drawWireframeShape(wireframeForThisKey, key.color, + (float) key.width); + // System.out.println("[Drew wireframe " + ++count + " for " + // + key.toString()); + } + } + + // Strings + + target.drawStrings(strings); + + // Circles + + target.drawCircle(circles.toArray(new DrawableCircle[circles.size()])); + } + + public void dispose() { + if (shadedShape != null) { + shadedShape.dispose(); + shadedShape = null; + } + // any of the following really needed?? + if (wireframes != null) { + for (IWireframeShape wf : wireframes.values()) { + wf.dispose(); + } + wireframes.clear(); + wireframes = null; + } + if (strings != null) { + for (DrawableString ds : strings) { + // no such method ds.dispose(); + ds = null; + } + strings = null; + } + if (circles != null) { + for (DrawableCircle dc : circles) { + // no such method dc.dispose(); + dc = null; + } + circles = null; + } + } +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotModelHdf5DataRequestor.java b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotModelHdf5DataRequestor.java index f0aca4b331..dc693e5926 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotModelHdf5DataRequestor.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotModelHdf5DataRequestor.java @@ -51,6 +51,7 @@ import com.raytheon.uf.common.pointdata.PointDataContainer; import com.raytheon.uf.common.pointdata.PointDataDescription.Type; import com.raytheon.uf.common.pointdata.PointDataView; import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.DataTime.FLAG; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.viz.core.datastructure.DataCubeContainer; import com.raytheon.uf.viz.core.exception.VizException; @@ -69,9 +70,12 @@ import com.raytheon.viz.pointdata.PointDataRequest; * 05/20/2013?? 988 Archana.S Initial creation. * 02/26/2014 1061 B. Hebbard Don't block on JobPool cancel, so CAVE doesn't freeze if resource unloaded during long retrieval * 04/01/2014 1040 B. Hebbard In requestUpperAirData, (1) clear displayStationPlotBoolList for each new station, (2) call cond filter check with newInstance vs. metPrm - * 04/08/2014 1127 B. Hebbard In requestSurfaceData, exclude only those obs returned from HDF5 that don't match desired time; fix dataTime association; removed redunda + * 04/08/2014 1127 B. Hebbard In requestSurfaceData, exclude only those obs returned from HDF5 that don't match desired time; fix dataTime association; + * removed redundant datatimes from constraint. * 06/17/2014 932 S. Russell TTR 923, altered methods addToDerivedParamsList(), requestSurfaceData(), and newInstance() - * 07/08/2014 TTR1028 B. Hebbard In requestSurfaceData(-) and requestUpperAirData(-), prune out stations that already have all met params they need, to avoid unnecessary querying + * 07/08/2014 TTR1028 B. Hebbard In requestSurfaceData() and requestUpperAirData(), prune out stations that already have all met params they need, to avoid unnecessary querying + * 09/04/2014 1127 B. Hebbard Exempt forecast (e.g., MOS) datatimes from check in requestSurfaceData that sees if retrieved value matches desired time. This is because we retrieve only the refTime from HDF5 for comparison, which is sufficient for obs times, but not those with forecast component. + * * * */ @@ -1571,8 +1575,11 @@ public class NcPlotModelHdf5DataRequestor { DataTime dataTime = stationIdToDataTimeMap.get(stationId); + // Caution: Single-element constructor; assumes this is an + // observation time, and not a forecast time. See below. DataTime retrievedDataTime = new DataTime(new Date( pdv.getLong(refTimeDbName))); + // Since the constraints we use (if // plotProp.hasDistinctStationId) are "stationID" IN // list-of-all-stationIDs -AND- dataTime IN @@ -1584,7 +1591,11 @@ public class NcPlotModelHdf5DataRequestor { // we retrieved is the one we wanted for this station; // if not, ignore this obs. (An obs with the desired // time should appear elsewhere in the PDC). - if (!dataTime.equals(retrievedDataTime)) { + // Note that we exempt forecast (e.g., MOS) data times + // from this check, since we don't retrieve forecast + // hour from the DB for retrievedDataTime -- see above. + if (!dataTime.getUtilityFlags().contains(FLAG.FCST_USED) + && !dataTime.equals(retrievedDataTime)) { Tracer.print(Tracer.shortTimeString(time) + " Retrieved dataTime for station " + stationId + " is " + retrievedDataTime diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/NcPlotResource2.java b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/NcPlotResource2.java index 69a2bfdf96..a584003535 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/NcPlotResource2.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/NcPlotResource2.java @@ -58,6 +58,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Semaphore; @@ -137,6 +138,8 @@ import com.vividsolutions.jts.geom.Coordinate; * reduces 'trickling in' of stations after pan/zoom. Also changed resourceAttrsModified() * to remove all stations' met parameter data if requeryDataAndReCreateAllStnImages true, * to force re-query (now that we're bypassing stations that already have data). + * 09/03/2014 1009 kbugenhagen Reload Framedata.stationMap if all stations' dist values are null + * * * * @author brockwoo @@ -468,8 +471,11 @@ public class NcPlotResource2 extends } public class FrameData extends AbstractFrameData { + // map from the station Id to the station info (plotInfo and image) - private Map stationMap = new HashMap(); + // (using ConcurrentHashMap to take care of + // ConcurrentModificationException) + private Map stationMap = new ConcurrentHashMap(); private List plotInfoObjs = new ArrayList(); @@ -536,7 +542,10 @@ public class NcPlotResource2 extends String stnMapKey = getStationMapKey(plotInfo.latitude, plotInfo.longitude); - Station stn = stationMap.get(stnMapKey);// plotInfo.stationId ); + Station stn = new Station(); + if (stnMapKey != null) { + stn = stationMap.get(stnMapKey);// plotInfo.stationId ); + } // This can happen during an auto update or if there are multiple // reports for this frame. @@ -1045,9 +1054,6 @@ public class NcPlotResource2 extends } synchronized (frameData) { - // Tracer.print - // ("calling checkAndUpdateProgDisclosureProperties on frame - " + - // frameData.getShortFrameTime()); frameData.screenExtentsChangedForCurrentFrame = progressiveDisclosure .checkAndUpdateProgDisclosureProperties(); @@ -1072,6 +1078,22 @@ public class NcPlotResource2 extends Tracer.print("Calling from paintFrame() - about to schedule progressive disclosure the frame: " + frameData.getShortFrameTime()); + boolean mapPopulated = false; + for (Station station : frameData.stationMap.values()) { + if (station.distValue != null) { + mapPopulated = true; + break; + } + } + + // load frame data for new incoming (autoupdated) data + if (!mapPopulated) { + frameLoaderTask = new FrameLoaderTask( + frameData.getFrameTime()); + frameRetrievalPool.schedule(frameLoaderTask); + issueRefresh(); + } + frameData.progressiveDisclosureInProgress = true; progressiveDisclosure.queueListOfStationsToBeDisclosed( @@ -1603,6 +1625,12 @@ public class NcPlotResource2 extends + Tracer.shortTimeString(time)); dataRequestor.queueStationsForHdf5Query(time, disclosedStations); + } else { + Tracer.print("Prog disc returned " + "*NO*" + " stations" + + " for frame: " + Tracer.shortTimeString(time) + + " quitting with no HDF5 retrieval attempted"); + FrameData fd = ((FrameData) getFrame(time)); + fd.progressiveDisclosureInProgress = false; } sem.release(); Tracer.print("< Exit"); From e87440a87657b8d0667e9f5d057bd9612c326a65 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Tue, 23 Sep 2014 13:32:21 -0400 Subject: [PATCH 06/19] VLab Issue #4552 - Grid Resource to recognize sub-hourly forecasts This commit fixes #4552 Change-Id: Ic7f456b03ac4d00e551d3012f5b7a6034af33266 Former-commit-id: 1a8f79820d79d0765b0ad32cbc02726b6e575d26 [formerly 1a8f79820d79d0765b0ad32cbc02726b6e575d26 [formerly 960e36e6fe39425be6e17b492dbf7bebf059db39]] Former-commit-id: e024656cc7556a9737ff28427d1f8f1747e88687 Former-commit-id: 006bbfb87289ea78f8a015b297d59c2a84871d59 --- .../META-INF/MANIFEST.MF | 3 +- .../viz/common/util/CommonDateFormatUtil.java | 209 ++ .../META-INF/MANIFEST.MF | 5 +- .../nws/ncep/viz/gempak/util/GempakGrid.java | 909 +++---- .../ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java | 149 +- .../viz/rsc/ncgrid/dgdriv/TestDgdriv.java | 2251 +++++++++-------- .../viz/rsc/ncgrid/rsc/NcgridResource.java | 11 +- .../common/util/CommonDateFormatUtilTest.java | 341 +++ 8 files changed, 2162 insertions(+), 1716 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtil.java create mode 100644 tests/unit/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtilTest.java diff --git a/ncep/gov.noaa.nws.ncep.viz.common/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.common/META-INF/MANIFEST.MF index f992ee9f3e..a5ef14549a 100644 --- a/ncep/gov.noaa.nws.ncep.viz.common/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.common/META-INF/MANIFEST.MF @@ -26,7 +26,8 @@ Export-Package: gov.noaa.nws.ncep.viz.common, gov.noaa.nws.ncep.viz.common.soundingQuery, gov.noaa.nws.ncep.viz.common.staticPointDataSource, gov.noaa.nws.ncep.viz.common.ui, - gov.noaa.nws.ncep.viz.common.ui.color + gov.noaa.nws.ncep.viz.common.ui.color, + gov.noaa.nws.ncep.viz.common.util Import-Package: com.raytheon.uf.common.comm, com.raytheon.uf.viz.application, com.raytheon.viz.pointdata, diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtil.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtil.java new file mode 100644 index 0000000000..18e76a71ef --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtil.java @@ -0,0 +1,209 @@ +/** + * 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 gov.noaa.nws.ncep.viz.common.util; + +/** + * Static methods to convert between AWIPS2 Date strings to GEMPAK DATTIM + * string. Also contains helper methods to convert forecast time between time + * hours and minutes representation to time in seconds. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 29, 2014            jbernier     Initial creation
+ * 
+ * 
+ * + * @author jbernier + * @version 1.0 + */ + +public class CommonDateFormatUtil { + + public static final String AWIPS2_DATETIME_FORMAT = "YYYY-MM-dd HH:mm:ss.S", + GEMPAK_DATTIM_FORMAT = "yyMMdd/HHmm"; + + /** + * + * Converts AWIPS2 date time string into GEMPAK DATTIM string + * + * @param dbTime + * eg "2011-10-09 06:20:00.0 (1)" + * @return eq "111009/0620f00100" + */ + public static String dbtimeToDattim(String dbTime) { + StringBuilder aDattimBuilder = new StringBuilder(dbTime.substring(0, + AWIPS2_DATETIME_FORMAT.length())); + + aDattimBuilder.delete(0, 2); + deleteAllChar(aDattimBuilder, "-"); + deleteAllChar(aDattimBuilder, ":"); + deleteAllChar(aDattimBuilder, ".0"); + int indexOfDateTimeDelimiter = (dbTime.contains("_") ? aDattimBuilder + .indexOf("_") : aDattimBuilder.indexOf(" ")); + aDattimBuilder.replace(indexOfDateTimeDelimiter, + indexOfDateTimeDelimiter + 1, "/"); + + if (dbTime.contains("(") && dbTime.contains(")")) { + aDattimBuilder.append("f").append(getForecastTimeString(dbTime)); + } + return aDattimBuilder.toString(); + } + + private static void deleteAllChar(StringBuilder charSeq, String charToDelete) { + int startIndex = charSeq.indexOf(charToDelete); + while (startIndex >= 0 && startIndex < charSeq.length()) { + int endIndex = startIndex + charToDelete.length(); + charSeq.delete(startIndex, endIndex); + startIndex = charSeq.indexOf(charToDelete); + } + } + + /** + * + * Converts GEMPAK DATTIM string into AWIPS2 date time string + * + * @param aDattim + * eg "111009/0620f00100" + * @return eq "2011-10-09 06:20:00.0 (1)" + */ + public static String dattimToDbtime(String aDattim) { + StringBuilder dbTimeBuilder = new StringBuilder( + AWIPS2_DATETIME_FORMAT.length() + 10); + String[] dateTime = aDattim.substring(0, GEMPAK_DATTIM_FORMAT.length()) + .split("/"); + int date = Integer.parseInt(dateTime[0]), time = Integer + .parseInt(dateTime[1]); + + dbTimeBuilder.append(String.format("20%02d-%02d-%02d %02d:%02d:00.0", + date / 10000, (date % 10000) / 100, date % 100, time / 100, + time % 100)); + + if ((aDattim = aDattim.toUpperCase()).contains("F")) { + int spaceIndex = dbTimeBuilder.indexOf(" "); + dbTimeBuilder.replace(spaceIndex, spaceIndex + 1, "_"); + dbTimeBuilder.append("_(") + .append(getForecastColonTimeString(aDattim)).append(")"); + } + return dbTimeBuilder.toString(); + } + + /** + * + * Utility method to return forecast time in seconds given either GEMPAK or + * AWIPS2 date time strings + * + * @param anyTimeString + * eg "140808/0620f00115" or "2014-08-08 06:20:00.0 (1:15)" + * @return eg 4500 + */ + public static int getForecastTimeInSec(String anyTimeString) { + anyTimeString = anyTimeString.toUpperCase(); + int forecastHrs = 0, forecastMins = 0; + + if (anyTimeString.contains("F")) { + String forecastTime = anyTimeString.substring(anyTimeString + .indexOf("F") + 1); + forecastHrs = Integer.parseInt(forecastTime.substring(0, + "000".length())); + forecastMins = forecastTime.length() == 5 ? Integer + .parseInt(forecastTime.substring("000".length())) : 0; + } else if (anyTimeString.contains("(") && anyTimeString.contains(")")) { + String[] forecastTime = anyTimeString.substring( + anyTimeString.indexOf("(") + 1, anyTimeString.indexOf(")")) + .split(":"); + forecastHrs = Integer.parseInt(forecastTime[0]); + forecastMins = forecastTime.length == 2 ? Integer + .parseInt(forecastTime[1]) : 0; + } else { + forecastHrs = 0; + forecastMins = 0; + } + return forecastHrs * 3600 + forecastMins * 60; + } + + /** + * + * Utility method to return forecast time string formatted to HHHmm given + * either GEMPAK or AWIPS2 date time format string + * + * @param anyTimeFormat + * eg "140808/0620f00115" or "2014-08-08 06:20:00.0 (1:15)" + * @return eg "00115" + */ + public static String getForecastTimeString(String anyTimeFormat) { + int forecastTimeInSec = getForecastTimeInSec(anyTimeFormat); + + return getForecastTimeString(forecastTimeInSec); + } + + /** + * + * Utility method to return forecast time string formatted to HHHmm given a + * forecast time in seconds + * + * @param forecastTimeInSec + * eg 4500 + * @return eg "00115" + */ + public static String getForecastTimeString(int forecastTimeInSec) { + int forecastHrs = forecastTimeInSec / 3600; + int forecastMins = forecastTimeInSec % 3600 / 60; + + return String.format("%03d", forecastHrs) + + (forecastMins > 0 ? String.format("%02d", forecastMins) : ""); + } + + /** + * + * Utility method to return forecast time string formatted to HHH:mm given + * either GEMPAK or AWIPS2 date time format string + * + * @param anyTimeFormat + * eg "140808/0620f00115" or "2014-08-08 06:20:00.0 (1:15)" + * @return eg "1:15" + */ + public static String getForecastColonTimeString(String anyTimeFormat) { + int forecastTimeInSec = getForecastTimeInSec(anyTimeFormat); + + return getForecastColonTimeString(forecastTimeInSec); + } + + /** + * + * Utility method to return forecast time string formatted to HHH:mm given a + * forecast time in seconds + * + * @param forecastTimeInSec + * eg 4500 + * @return eg "1:15" + */ + public static String getForecastColonTimeString(int forecastTimeInSec) { + int forecastHrs = forecastTimeInSec / 3600; + int forecastMins = forecastTimeInSec % 3600 / 60; + + return String.valueOf(forecastHrs) + + (forecastMins > 0 ? ":" + String.format("%02d", forecastMins) + : ""); + } +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.gempak/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.gempak/META-INF/MANIFEST.MF index 37a5a29a3e..10e3f0ccc8 100644 --- a/ncep/gov.noaa.nws.ncep.viz.gempak/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.gempak/META-INF/MANIFEST.MF @@ -28,6 +28,7 @@ Export-Package: gov.noaa.nws.ncep.viz.gempak, gov.noaa.nws.ncep.viz.gempak.grid.units, gov.noaa.nws.ncep.viz.gempak.util Import-Package: com.raytheon.uf.common.derivparam.tree, - gov.noaa.nws.ncep.edex.common.ncinventory, + com.raytheon.uf.common.serialization, gov.noaa.nws.ncep.common.log.logger, - com.raytheon.uf.common.serialization + gov.noaa.nws.ncep.edex.common.ncinventory, + gov.noaa.nws.ncep.viz.common.util diff --git a/ncep/gov.noaa.nws.ncep.viz.gempak/src/gov/noaa/nws/ncep/viz/gempak/util/GempakGrid.java b/ncep/gov.noaa.nws.ncep.viz.gempak/src/gov/noaa/nws/ncep/viz/gempak/util/GempakGrid.java index c91e890381..e72e05cce1 100644 --- a/ncep/gov.noaa.nws.ncep.viz.gempak/src/gov/noaa/nws/ncep/viz/gempak/util/GempakGrid.java +++ b/ncep/gov.noaa.nws.ncep.viz.gempak/src/gov/noaa/nws/ncep/viz/gempak/util/GempakGrid.java @@ -1,10 +1,6 @@ package gov.noaa.nws.ncep.viz.gempak.util; -import java.util.ArrayList; - -import com.raytheon.uf.common.gridcoverage.LambertConformalGridCoverage; -import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage; -import com.raytheon.uf.common.gridcoverage.PolarStereoGridCoverage; +import gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil; import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag; import javax.measure.converter.UnitConverter; @@ -18,7 +14,9 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.raytheon.uf.common.geospatial.ISpatialObject; import com.raytheon.uf.common.geospatial.MapUtil; -import com.raytheon.uf.viz.core.comm.Connector; +import com.raytheon.uf.common.gridcoverage.LambertConformalGridCoverage; +import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage; +import com.raytheon.uf.common.gridcoverage.PolarStereoGridCoverage; import com.raytheon.uf.viz.core.exception.VizException; import com.sun.jna.Native; import com.sun.jna.ptr.IntByReference; @@ -26,527 +24,404 @@ import com.vividsolutions.jts.geom.Polygon; /** * @author gamaz - * - */ -/** - * @author gamaz - * + * */ public class GempakGrid { - - private static GridDiag gd = GridDiag.getInstance(); - - public final static String gempakPluginName = "gempak_gd"; // ghull added Dec 19, 2010 - - /** - * Gets the cycle times for a GEMPAK dataLocation from uEngine in YYMMDD_HHMM format. - * - * @param aDataLocation - * eg "$MODEL/gfs" - * @return - * @throws VizException - */ - public static String[] getGridCycleTimes( String aDataLocation,String gdFile ) throws VizException{ - byte[] cycles = new byte[1024]; - IntByReference iret = new IntByReference(0); - gd.gem.in_bdta_(iret); - gd.gem.gd_init_ (iret); - gd.gem.gdc_gcyc_(gdFile, cycles, iret); - if ( iret.getValue() == 0 ) { - String cycleTime = Native.toString(cycles); - String cycleTime1 = cycleTime.replaceAll("/", "_"); - String []cycleTimes = cycleTime1.trim().split(";"); - return cycleTimes; - } - else { - throw new VizException(); - } -// long st1 = System.currentTimeMillis(); -// StringBuilder query = new StringBuilder(); -// query.append("import NcModelCycleQuery\n"); -// query.append("req = NcModelCycleQuery.NcModelCycleQuery()\n"); -// query.append("req.setDataLocation('" + aDataLocation + "')\n"); -// query.append("req.setModelName('" + modelname + "')\n"); -// query.append("return req.execute()"); -// -// String script = query.toString(); -// try { -// String cycleListStr = (String) Connector.getInstance().connect( -// script, null, 600000)[0]; -// -// String[] cycleList = cycleListStr.split("\\|"); -// long st2 = System.currentTimeMillis(); -// System.out.println ("***get cycleTimes throught Connector took:" + (st2-st1)); -// return cycleList; -// } catch (VizException e) { -// throw new VizException(e); -// } - } - - /** - * Gets the available times for a GEMPAK dataLocation and a current cycle - * from uEngine in "YYYY-MM-DD HH:MM:SS.S (fHHH)" format. - * - * @param aDataLocation - * eg "$MODEL/gfs" - * @param aCurrentCycle - * eg "2010-11-28 18:00:00.0" - * @return - * @throws VizException - */ - public static String[] getAvailableGridTimes( String aDataLocation, String aCurrentCycle, String gdFile ) - throws VizException{ - byte[] availables = new byte[10000]; - IntByReference iret = new IntByReference(0); - gd.gem.in_bdta_(iret); - gd.gem.gd_init_ (iret); - String cycle=""; - if ( aCurrentCycle != null ){ - String []dtStr = aCurrentCycle.split(" "); - cycle =dtStr[0].split("-")[1] + dtStr[0].split("-")[2] +"/" +dtStr[1].split(":")[0]; - } - gd.gem.gdc_gtmf_(gdFile, cycle, availables, iret); - if ( iret.getValue() == 0 ) { - String availableTimes = Native.toString(availables); - String [] avaTimeStr = availableTimes.trim().split("\\|"); - String [] avaTimesList = new String [avaTimeStr.length]; - int i = 0; - for ( String ava:avaTimeStr) { - if ( ava.contains("F")) { - avaTimesList[i] = aCurrentCycle +" (" + Integer.parseInt(ava.split("F")[1]) + ")"; - } - else { - avaTimesList[i] = aCurrentCycle +" (0)"; - } - i ++; - } - return avaTimesList; - } - else { - throw new VizException(); - } -// long st1 = System.currentTimeMillis(); -// StringBuilder query = new StringBuilder(); -// query.append("import NcModelAvailableTimesQuery\n"); -// query.append("req = NcModelAvailableTimesQuery.NcModelAvailableTimesQuery()\n"); -// query.append("req.setDataLocation('" + aDataLocation + "')\n"); -// query.append("req.setModelName('" + modelName + "')\n"); -// query.append("req.setCurrentCycle('" + aCurrentCycle + "')\n"); -// query.append("return req.execute()"); -// -// String script = query.toString(); -// try { -// String avTimesListStr = (String) Connector.getInstance().connect( -// script, null, 600000)[0]; -// String[] avTimesList = avTimesListStr.split("\\|"); -// long st2 = System.currentTimeMillis(); -// System.out.println ("===get availableTimes throught connector took:" + (st2-st1)); -// return avTimesList; -// } catch (VizException e) { -// throw new VizException(e); -// } - } - - /** - * Gets the navigation information from a GEMPAK grid file and returns the coverage object. - * - * @param aDataLocation - * eg "$MODEL/gfs" - * @param aCurrentCycle - * eg "2010-11-28 18:00:00.0" - * @return - * @throws VizException - */ - public static ISpatialObject getGridNavigation (String anAlias, String aDataLocation, String aCurrentCycle) - throws VizException{ - int numberOfLayers = aDataLocation.split("/").length; - String model = aDataLocation.split("/")[numberOfLayers-1]; - String gdfile = constructGridFilename (anAlias, aDataLocation,aCurrentCycle); - float[] rnav = getGridNavigationBlock (gdfile); - String proj = getGridProjection (rnav); - DefaultGeographicCRS WGS84 = DefaultGeographicCRS.WGS84; - CoordinateReferenceSystem crs; - String crsWKT; - Polygon geometry; - - if (proj.equalsIgnoreCase("CED")) { - double minLat = MapUtil.correctLat(rnav[6]); - double maxLat = MapUtil.correctLat(rnav[8]); - double minLon = MapUtil.correctLon(rnav[7]); - double maxLon = MapUtil.correctLon(rnav[9]); - if (maxLon < minLon) { - maxLon += 360.0; - } - if (maxLon > 180) { - crs = new DefaultGeographicCRS(new DefaultGeodeticDatum("WGS84", - WGS84.getDatum().getEllipsoid(), new DefaultPrimeMeridian( - "DateLine", 180.0)), WGS84.getCoordinateSystem()); - } else { - crs = WGS84; - } - crsWKT = crs.toWKT(); - try { - geometry = MapUtil.createGeometry(minLat, minLon, maxLat, maxLon); - } catch (Exception e) { - throw new VizException("Error creating geometry", e); - } - CharSequence spacingUnit = "degree"; - - LatLonGridCoverage cov = new LatLonGridCoverage(); - cov.setSpacingUnit(spacingUnit.toString()); - cov.setDx(rnav[2]); - cov.setDy(rnav[3]); - int nx = (int) rnav[4]; - cov.setNx(Integer.valueOf(nx)); - int ny = (int) rnav[5]; - cov.setNy(Integer.valueOf(ny)); - cov.setCrs(crs); - cov.setCrsWKT(crsWKT); - cov.setGeometry(geometry); - cov.setLa1(minLat); - cov.setLa2(maxLat); - cov.setLo1(minLon); - cov.setLo2(maxLon); - cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3]+ " " + spacingUnit + " grid"); - cov.setGridGeometry(MapUtil.getGridGeometry(cov)); - cov.setDescription("GEMPAK CED grid"); - return cov; - } - else if (proj.equalsIgnoreCase("STR")) { - double majorAxis = 6371229.0; - double minorAxis = 6371229.0; - double lov = rnav[11]; - double la1 = rnav[6]; - double lo1 = rnav[7]; - int nx = (int) rnav[4]; - int ny = (int) rnav[5]; - /* TODO calculate dx, dx */ - double dx = 90.755; - double dy = 90.755; - crs = MapUtil.constructNorthPolarStereo(majorAxis, minorAxis, 60.0, lov); - crsWKT = crs.toWKT(); - CharSequence spacingUnit = "km"; - try { - Unit spacingUnitObj = Unit.valueOf(spacingUnit); - if (spacingUnitObj.isCompatible(SI.METRE)) { - UnitConverter converter = spacingUnitObj - .getConverterTo(SI.METRE); - geometry = MapUtil.createGeometry(crs, la1, lo1, converter - .convert(dx), converter.convert(dy), nx, ny); - } else { - throw new VizException("Unable to convert " + spacingUnit - + " to meters while creating geometry!"); - } - } catch (Exception e) { - throw new VizException("Error creating geometry", e); - } - PolarStereoGridCoverage cov = new PolarStereoGridCoverage(); - cov.setCrs(crs); - cov.setCrsWKT(crsWKT); - cov.setGeometry(geometry); - cov.setLa1(la1); - cov.setLo1(lo1); - cov.setLov(lov); - cov.setNx(Integer.valueOf(nx)); - cov.setNy(Integer.valueOf(ny)); - cov.setGridGeometry(MapUtil.getGridGeometry(cov)); - cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3]+ " " + spacingUnit + " grid"); - cov.setDescription("GEMPAK STR grid"); - return cov; - } - else if (proj.equalsIgnoreCase("LCC")) { - /* TODO add code for LCC proj */ - double majorAxis = 6371229.0; - double minorAxis = 6371229.0; - double lov = rnav[11]; - double latin1 = rnav[10]; - double latin2 = rnav[12]; - double la1 = rnav[6]; - double lo1 = rnav[7]; - int nx = (int) rnav[4]; - int ny = (int) rnav[5]; - CharSequence spacingUnit = "km"; - double dx = 12.191; - double dy = 12.191; - crs = MapUtil.constructLambertConformal(majorAxis, minorAxis, latin1, - latin2, lov); - crsWKT = crs.toWKT(); - try { - Unit spacingUnitObj = Unit.valueOf(spacingUnit); - if (spacingUnitObj.isCompatible(SI.METRE)) { - UnitConverter converter = spacingUnitObj - .getConverterTo(SI.METRE); - geometry = MapUtil.createGeometry(crs, la1, lo1, converter - .convert(dx), converter.convert(dy), nx, ny); - } else { - throw new VizException("Unable to convert " + spacingUnit - + " to meters while creating geometry!"); - } + private static GridDiag gd = GridDiag.getInstance(); - } catch (Exception e) { - throw new VizException("Error creating geometry", e); - } - LambertConformalGridCoverage cov = new LambertConformalGridCoverage(); - cov.setCrs(crs); - cov.setCrsWKT(crsWKT); - cov.setGeometry(geometry); - cov.setLa1(la1); - cov.setLo1(lo1); - cov.setLov(lov); - cov.setNx(Integer.valueOf(nx)); - cov.setNy(Integer.valueOf(ny)); - cov.setGridGeometry(MapUtil.getGridGeometry(cov)); - cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3]+ " " + spacingUnit + " grid"); - cov.setDescription("GEMPAK LCC grid"); - return cov; - } - else if (proj.equalsIgnoreCase("MER")) { - /* TODO add code for MER proj */ - return null; - } - else { - return null; - } - } - - /** - * Constructs a GEMPAK grid filename eg "gfs_2010112818f003" - * - * @param anAlias - * eg "GFS" - * @param aLocation - * eg "$MODEL/gfs" - * @param aTime - * eg "2010-11-28 18:00:00.0 (3)" - * @return - */ - private static String constructGridFilename(String anAlias, String aLocation, String aTime) { - try { - String fileNameTemplate = getGempakGridTemplate(anAlias); - IntByReference iret = new IntByReference(0); - byte[] theFileName = new byte[50]; - String gTime = dbtimeToDattim(aTime); - String fullPath = aLocation+ "/" + fileNameTemplate; - gd.gem.cfl_mnam_ ( gTime, fullPath, theFileName, iret); - if ( iret.getValue () != 0 ) { - return null; - } - return Native.toString(theFileName); - } catch (VizException e) { - // TODO Auto-generated catch block - return null; - } - } - - /** - * Extracts navigation block from GEMPAK grid - * - * @param aGridFile - * @return - */ - private static float [] getGridNavigationBlock(String aGridFile) { - float[] rnav = new float[20]; - float[] anl = new float[20]; - IntByReference wrtflg = new IntByReference(-1); - IntByReference mxanl = new IntByReference(1); - IntByReference mxnav = new IntByReference(20); - IntByReference iacss = new IntByReference(0); - IntByReference msxgrd = new IntByReference(0); - IntByReference iret = new IntByReference(0); - IntByReference mode = new IntByReference(0); + public final static String gempakPluginName = "gempak_gd"; // ghull added + // Dec 19, 2010 - gd.gem.in_bdta_(iret); - gd.gem.gd_init_ (iret); - gd.gem.gg_init_ (mode,iret); - gd.gem.dg_intl_ (iret); + /** + * Gets the cycle times for a GEMPAK dataLocation from uEngine in + * YYMMDD_HHMM format. + * + * @param aDataLocation + * eg "$MODEL/gfs" + * @return + * @throws VizException + */ + public static String[] getGridCycleTimes(String aDataLocation, String gdFile) + throws VizException { + byte[] cycles = new byte[1024]; + IntByReference iret = new IntByReference(0); + gd.gem.in_bdta_(iret); + gd.gem.gd_init_(iret); + gd.gem.gdc_gcyc_(gdFile, cycles, iret); + if (iret.getValue() == 0) { + String cycleTime = Native.toString(cycles); + String cycleTime1 = cycleTime.replaceAll("/", "_"); + String[] cycleTimes = cycleTime1.trim().split(";"); + return cycleTimes; + } else { + throw new VizException(); + } + // long st1 = System.currentTimeMillis(); + // StringBuilder query = new StringBuilder(); + // query.append("import NcModelCycleQuery\n"); + // query.append("req = NcModelCycleQuery.NcModelCycleQuery()\n"); + // query.append("req.setDataLocation('" + aDataLocation + "')\n"); + // query.append("req.setModelName('" + modelname + "')\n"); + // query.append("return req.execute()"); + // + // String script = query.toString(); + // try { + // String cycleListStr = (String) Connector.getInstance().connect( + // script, null, 600000)[0]; + // + // String[] cycleList = cycleListStr.split("\\|"); + // long st2 = System.currentTimeMillis(); + // System.out.println ("***get cycleTimes throught Connector took:" + + // (st2-st1)); + // return cycleList; + // } catch (VizException e) { + // throw new VizException(e); + // } + } - gd.gem.gdc_open_ (aGridFile, wrtflg, mxanl, mxnav, iacss, - anl, rnav, msxgrd, iret); - - return rnav; - - } - - /** - * Extracts grid projections from GEMPAK grid navigation block - * - * @param rnav - * @return - */ - private static String getGridProjection (float[] rnav) { - IntByReference iret = new IntByReference(0); - byte[] cproj = new byte[5]; - IntByReference kx = new IntByReference(0); - IntByReference ky = new IntByReference(0); - gd.gem.grc_rnav_ (rnav, cproj, kx, ky, iret); - return Native.toString(cproj); - } - - /** - * Serves as a wrapper for the legacy ctb_dtpath function - * - * @param anAlias - * eg "GFS" - * @return - */ - public static String getGempakGridPath ( String anAlias) throws VizException { - IntByReference iret = new IntByReference(0); - byte[] thePath = new byte[30]; - gd.gem.ctb_dtpath_ (anAlias, thePath, iret); - if ( iret.getValue () != 0 ) { - throw new VizException("Alias " + anAlias + " not found in legacy datatype.tbl"); - } - return Native.toString(thePath); - } - - /** - * Serves as a wrapper for the legacy ctb_dttmpl function - * - * @param anAlias - * eg "GFS" - * @return - */ - public static String getGempakGridTemplate ( String anAlias) throws VizException { - IntByReference iret = new IntByReference(0); - byte[] theTemplate = new byte[50]; - gd.gem.ctb_dttmpl_ (anAlias, theTemplate, iret); - if ( iret.getValue () != 0 ) { - throw new VizException("Alias " + anAlias + " not found in legacy datatype.tbl"); - } - return Native.toString(theTemplate); - } - - /** - * - * Converts AWIPS2 date time string into GEMPAK DATTIM string - * - * @param aTime - * eg "2011-10-09 06:20:00.0 (1)" - * @return - * eq "111009/0620f001" - */ - private static String dbtimeToDattim(String aTime) { - String aDattim = null; - String[] inputStringArray = new String[2]; - - CharSequence char0 = "("; - /* - * Process time contains forecast hour info - */ - if ( aTime.contains(char0) ) { - String zeroes = null; - int ind1 = aTime.indexOf("("); - int ind2 = aTime.indexOf(")"); - if ( ind2-ind1 == 2 ) { - zeroes = "00"; - } - else if ( ind2-ind1 == 3 ) { - zeroes = "0"; - } - String str1 = aTime.substring(0, ind1-1); - String str2 = ""; - if ( zeroes != null) { - str2 = "f"+zeroes+aTime.substring(ind1+1, ind2); - } - else { - str2 = "f"+aTime.substring(ind1+1, ind2); - } - - if ( aTime.contains("_") ) { - inputStringArray = str1.split("_"); - } - else if ( ! aTime.contains("_") ) { - inputStringArray = str1.split(" "); - } + /** + * Gets the available times for a GEMPAK dataLocation and a current cycle + * from uEngine in "YYYY-MM-DD HH:MM:SS.S (fHHH)" format. + * + * @param aDataLocation + * eg "$MODEL/gfs" + * @param aCurrentCycle + * eg "2010-11-28 18:00:00.0" + * @return + * @throws VizException + */ + public static String[] getAvailableGridTimes(String aDataLocation, + String aCurrentCycle, String gdFile) throws VizException { + byte[] availables = new byte[10000]; + IntByReference iret = new IntByReference(0); + gd.gem.in_bdta_(iret); + gd.gem.gd_init_(iret); + String cycle = ""; + if (aCurrentCycle != null) { + String[] dtStr = aCurrentCycle.split(" "); + cycle = dtStr[0].split("-")[1] + dtStr[0].split("-")[2] + "/" + + dtStr[1].split(":")[0]; + } + gd.gem.gdc_gtmf_(gdFile, cycle, availables, iret); + if (iret.getValue() == 0) { + String availableTimes = Native.toString(availables); + String[] avaTimeStr = availableTimes.trim().split("\\|"); + String[] avaTimesList = new String[avaTimeStr.length]; + int i = 0; + for (String ava : avaTimeStr) { + if (ava.contains("F")) { + avaTimesList[i] = aCurrentCycle + " (" + + Integer.parseInt(ava.split("F")[1]) + ")"; + } else { + avaTimesList[i] = aCurrentCycle + " (0)"; + } + i++; + } + return avaTimesList; + } else { + throw new VizException(); + } + // long st1 = System.currentTimeMillis(); + // StringBuilder query = new StringBuilder(); + // query.append("import NcModelAvailableTimesQuery\n"); + // query.append("req = NcModelAvailableTimesQuery.NcModelAvailableTimesQuery()\n"); + // query.append("req.setDataLocation('" + aDataLocation + "')\n"); + // query.append("req.setModelName('" + modelName + "')\n"); + // query.append("req.setCurrentCycle('" + aCurrentCycle + "')\n"); + // query.append("return req.execute()"); + // + // String script = query.toString(); + // try { + // String avTimesListStr = (String) Connector.getInstance().connect( + // script, null, 600000)[0]; + // String[] avTimesList = avTimesListStr.split("\\|"); + // long st2 = System.currentTimeMillis(); + // System.out.println ("===get availableTimes throught connector took:" + // + (st2-st1)); + // return avTimesList; + // } catch (VizException e) { + // throw new VizException(e); + // } + } - /* - * YYYY-MM-DD HH:MM:SS.S (HHH)-> YYMMDD/HHMMfHHH - * 2009-10-22 16:00:00.0 (5)-> 091022/1600f005 - * 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5) + str2; - } - /* - * Process time that does NOT contain forecast hour info - */ - else { - inputStringArray = aTime.split(" "); + /** + * Gets the navigation information from a GEMPAK grid file and returns the + * coverage object. + * + * @param aDataLocation + * eg "$MODEL/gfs" + * @param aCurrentCycle + * eg "2010-11-28 18:00:00.0" + * @return + * @throws VizException + */ + public static ISpatialObject getGridNavigation(String anAlias, + String aDataLocation, String aCurrentCycle) throws VizException { + int numberOfLayers = aDataLocation.split("/").length; + String model = aDataLocation.split("/")[numberOfLayers - 1]; + String gdfile = constructGridFilename(anAlias, aDataLocation, + aCurrentCycle); + float[] rnav = getGridNavigationBlock(gdfile); + String proj = getGridProjection(rnav); - /* - * YYYY-MM-DD HH:MM:SS.S -> YYMMDD/HHMM - * 2009-01-20 02:25:00.0 -> 090120/0225 - * 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5); - } - return aDattim; - } - - /* - * Converts GEMPAK DATTIM string into AWIPS2 date time string - */ - public static String dattimToDbtime(String aDattim) { - aDattim = aDattim.toUpperCase(); - String retDateTime = null; - String[] inputStringArray = new String[2]; - CharSequence char0 = "F"; - if ( aDattim.contains(char0) ) { - - int ind1 = aDattim.indexOf("F00"); - int addChars = 3; - if ( ind1 == -1 ) { - ind1 = aDattim.indexOf("F0"); - addChars = 2; - } - if ( ind1 == -1 ) { - ind1 = aDattim.indexOf("F"); - addChars = 1; - } - int ind2 = aDattim.length(); - - String str1 = aDattim.substring(0, ind1); - String str2 = aDattim.substring(ind1+addChars,ind2 ); - inputStringArray = str1.split("/"); + DefaultGeographicCRS WGS84 = DefaultGeographicCRS.WGS84; + CoordinateReferenceSystem crs; + String crsWKT; + Polygon geometry; - /* - * YYMMDD/HHMMfHHH -> YYYY-MM-DD HH:MM:SS.S - * 090120/0225f005 -> 2009-01-20 02:25:00.0 - * 012345 0123 - */ - retDateTime = "20" + inputStringArray[0].substring(0, 2) + "-" - + inputStringArray[0].substring(2, 4) + "-" - + inputStringArray[0].substring(4, 6) + "_" - + inputStringArray[1].substring(0, 2) + ":" - + inputStringArray[1].substring(2, 4) + ":00.0_("+ str2 + ")"; - } - /* - * Process time that does NOT contain forecast hour info - */ - else { - inputStringArray = aDattim.split("/"); + if (proj.equalsIgnoreCase("CED")) { + double minLat = MapUtil.correctLat(rnav[6]); + double maxLat = MapUtil.correctLat(rnav[8]); + double minLon = MapUtil.correctLon(rnav[7]); + double maxLon = MapUtil.correctLon(rnav[9]); + if (maxLon < minLon) { + maxLon += 360.0; + } + if (maxLon > 180) { + crs = new DefaultGeographicCRS(new DefaultGeodeticDatum( + "WGS84", WGS84.getDatum().getEllipsoid(), + new DefaultPrimeMeridian("DateLine", 180.0)), + WGS84.getCoordinateSystem()); + } else { + crs = WGS84; + } + crsWKT = crs.toWKT(); + try { + geometry = MapUtil.createGeometry(minLat, minLon, maxLat, + maxLon); + } catch (Exception e) { + throw new VizException("Error creating geometry", e); + } + CharSequence spacingUnit = "degree"; - /* - * YYMMDD/HHMM -> YYYY-MM-DD HH:MM:SS.S - * 090120/0225 -> 2009-01-2002:25:00.0 - * s012345 0123 - */ - retDateTime = "20" + inputStringArray[0].substring(0, 2) + "-" - + inputStringArray[0].substring(2, 4) + "-" - + inputStringArray[0].substring(4, 6) + " " - + inputStringArray[1].substring(0, 2) + ":" - + inputStringArray[1].substring(2, 4) + ":00.0"; - } + LatLonGridCoverage cov = new LatLonGridCoverage(); + cov.setSpacingUnit(spacingUnit.toString()); + cov.setDx(rnav[2]); + cov.setDy(rnav[3]); + int nx = (int) rnav[4]; + cov.setNx(Integer.valueOf(nx)); + int ny = (int) rnav[5]; + cov.setNy(Integer.valueOf(ny)); + cov.setCrs(crs); + cov.setCrsWKT(crsWKT); + cov.setGeometry(geometry); + cov.setLa1(minLat); + cov.setLa2(maxLat); + cov.setLo1(minLon); + cov.setLo2(maxLon); + cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3] + " " + + spacingUnit + " grid"); + cov.setGridGeometry(MapUtil.getGridGeometry(cov)); + cov.setDescription("GEMPAK CED grid"); + return cov; + } else if (proj.equalsIgnoreCase("STR")) { + double majorAxis = 6371229.0; + double minorAxis = 6371229.0; + double lov = rnav[11]; + double la1 = rnav[6]; + double lo1 = rnav[7]; + int nx = (int) rnav[4]; + int ny = (int) rnav[5]; + /* TODO calculate dx, dx */ + double dx = 90.755; + double dy = 90.755; + crs = MapUtil.constructNorthPolarStereo(majorAxis, minorAxis, 60.0, + lov); + crsWKT = crs.toWKT(); + CharSequence spacingUnit = "km"; + try { + Unit spacingUnitObj = Unit.valueOf(spacingUnit); + if (spacingUnitObj.isCompatible(SI.METRE)) { + UnitConverter converter = spacingUnitObj + .getConverterTo(SI.METRE); + geometry = MapUtil.createGeometry(crs, la1, lo1, + converter.convert(dx), converter.convert(dy), nx, + ny); + } else { + throw new VizException("Unable to convert " + spacingUnit + + " to meters while creating geometry!"); + } + } catch (Exception e) { + throw new VizException("Error creating geometry", e); + } + PolarStereoGridCoverage cov = new PolarStereoGridCoverage(); + cov.setCrs(crs); + cov.setCrsWKT(crsWKT); + cov.setGeometry(geometry); + cov.setLa1(la1); + cov.setLo1(lo1); + cov.setLov(lov); + cov.setNx(Integer.valueOf(nx)); + cov.setNy(Integer.valueOf(ny)); + cov.setGridGeometry(MapUtil.getGridGeometry(cov)); + cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3] + " " + + spacingUnit + " grid"); + cov.setDescription("GEMPAK STR grid"); + return cov; + } else if (proj.equalsIgnoreCase("LCC")) { + /* TODO add code for LCC proj */ + double majorAxis = 6371229.0; + double minorAxis = 6371229.0; + double lov = rnav[11]; + double latin1 = rnav[10]; + double latin2 = rnav[12]; + double la1 = rnav[6]; + double lo1 = rnav[7]; + int nx = (int) rnav[4]; + int ny = (int) rnav[5]; + CharSequence spacingUnit = "km"; + double dx = 12.191; + double dy = 12.191; + crs = MapUtil.constructLambertConformal(majorAxis, minorAxis, + latin1, latin2, lov); + crsWKT = crs.toWKT(); + try { + Unit spacingUnitObj = Unit.valueOf(spacingUnit); + if (spacingUnitObj.isCompatible(SI.METRE)) { + UnitConverter converter = spacingUnitObj + .getConverterTo(SI.METRE); + geometry = MapUtil.createGeometry(crs, la1, lo1, + converter.convert(dx), converter.convert(dy), nx, + ny); + } else { + throw new VizException("Unable to convert " + spacingUnit + + " to meters while creating geometry!"); + } - return retDateTime; - } + } catch (Exception e) { + throw new VizException("Error creating geometry", e); + } + LambertConformalGridCoverage cov = new LambertConformalGridCoverage(); + cov.setCrs(crs); + cov.setCrsWKT(crsWKT); + cov.setGeometry(geometry); + cov.setLa1(la1); + cov.setLo1(lo1); + cov.setLov(lov); + cov.setNx(Integer.valueOf(nx)); + cov.setNy(Integer.valueOf(ny)); + cov.setGridGeometry(MapUtil.getGridGeometry(cov)); + cov.setName("GEMPAK " + model + rnav[2] + "x" + rnav[3] + " " + + spacingUnit + " grid"); + cov.setDescription("GEMPAK LCC grid"); + return cov; + } else if (proj.equalsIgnoreCase("MER")) { + /* TODO add code for MER proj */ + return null; + } else { + return null; + } + } + /** + * Constructs a GEMPAK grid filename eg "gfs_2010112818f003" + * + * @param anAlias + * eg "GFS" + * @param aLocation + * eg "$MODEL/gfs" + * @param aTime + * eg "2010-11-28 18:00:00.0 (3)" + * @return + */ + private static String constructGridFilename(String anAlias, + String aLocation, String aTime) { + try { + String fileNameTemplate = getGempakGridTemplate(anAlias); + IntByReference iret = new IntByReference(0); + byte[] theFileName = new byte[50]; + String gTime = CommonDateFormatUtil.dbtimeToDattim(aTime); + String fullPath = aLocation + "/" + fileNameTemplate; + gd.gem.cfl_mnam_(gTime, fullPath, theFileName, iret); + if (iret.getValue() != 0) { + return null; + } + return Native.toString(theFileName); + } catch (VizException e) { + // TODO Auto-generated catch block + return null; + } + } + + /** + * Extracts navigation block from GEMPAK grid + * + * @param aGridFile + * @return + */ + private static float[] getGridNavigationBlock(String aGridFile) { + float[] rnav = new float[20]; + float[] anl = new float[20]; + IntByReference wrtflg = new IntByReference(-1); + IntByReference mxanl = new IntByReference(1); + IntByReference mxnav = new IntByReference(20); + IntByReference iacss = new IntByReference(0); + IntByReference msxgrd = new IntByReference(0); + IntByReference iret = new IntByReference(0); + IntByReference mode = new IntByReference(0); + + gd.gem.in_bdta_(iret); + gd.gem.gd_init_(iret); + gd.gem.gg_init_(mode, iret); + gd.gem.dg_intl_(iret); + + gd.gem.gdc_open_(aGridFile, wrtflg, mxanl, mxnav, iacss, anl, rnav, + msxgrd, iret); + + return rnav; + + } + + /** + * Extracts grid projections from GEMPAK grid navigation block + * + * @param rnav + * @return + */ + private static String getGridProjection(float[] rnav) { + IntByReference iret = new IntByReference(0); + byte[] cproj = new byte[5]; + IntByReference kx = new IntByReference(0); + IntByReference ky = new IntByReference(0); + gd.gem.grc_rnav_(rnav, cproj, kx, ky, iret); + return Native.toString(cproj); + } + + /** + * Serves as a wrapper for the legacy ctb_dtpath function + * + * @param anAlias + * eg "GFS" + * @return + */ + public static String getGempakGridPath(String anAlias) throws VizException { + IntByReference iret = new IntByReference(0); + byte[] thePath = new byte[30]; + gd.gem.ctb_dtpath_(anAlias, thePath, iret); + if (iret.getValue() != 0) { + throw new VizException("Alias " + anAlias + + " not found in legacy datatype.tbl"); + } + return Native.toString(thePath); + } + + /** + * Serves as a wrapper for the legacy ctb_dttmpl function + * + * @param anAlias + * eg "GFS" + * @return + */ + public static String getGempakGridTemplate(String anAlias) + throws VizException { + IntByReference iret = new IntByReference(0); + byte[] theTemplate = new byte[50]; + gd.gem.ctb_dttmpl_(anAlias, theTemplate, iret); + if (iret.getValue() != 0) { + throw new VizException("Alias " + anAlias + + " not found in legacy datatype.tbl"); + } + return Native.toString(theTemplate); + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java index a2b7ba99bf..f86ef05359 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java @@ -7,11 +7,11 @@ package gov.noaa.nws.ncep.viz.rsc.ncgrid.dgdriv; import gov.noaa.nws.ncep.common.log.logger.NcepLogger; import gov.noaa.nws.ncep.common.log.logger.NcepLoggerManager; import gov.noaa.nws.ncep.edex.common.dataRecords.NcFloatDataRecord; +import gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil; import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag; import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag.gempak; import gov.noaa.nws.ncep.viz.gempak.grid.units.GempakGridParmInfoLookup; import gov.noaa.nws.ncep.viz.gempak.grid.units.GempakGridVcrdInfoLookup; -import gov.noaa.nws.ncep.viz.gempak.util.GempakGrid; import gov.noaa.nws.ncep.viz.rsc.ncgrid.NcgribLogger; import gov.noaa.nws.ncep.viz.rsc.ncgrid.customCoverage.CustomLambertConformalCoverage; import gov.noaa.nws.ncep.viz.rsc.ncgrid.customCoverage.CustomLatLonCoverage; @@ -22,7 +22,6 @@ import gov.noaa.nws.ncep.viz.rsc.ncgrid.rsc.NcEnsembleResourceData; import gov.noaa.nws.ncep.viz.rsc.ncgrid.rsc.NcgridResourceData; import java.io.File; -import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -136,6 +135,8 @@ public class Dgdriv { private String gdfile, gdpfun, gdattim, glevel, gvcord, scale, garea, dataSource; + private String gempakTime; + private boolean scalar, arrowVector, flop, flip; private String gdfileOriginal; @@ -148,6 +149,8 @@ public class Dgdriv { private ArrayList dataForecastTimes; + private int forecastTimeInSec; + private NcgridDataCache cacheData; private static NcgribLogger ncgribLogger = NcgribLogger.getInstance();; @@ -158,9 +161,6 @@ public class Dgdriv { * TODO Work around solution - need to find a way to set logging level * programmatically */ - private static final DecimalFormat forecastHourFormat = new DecimalFormat( - "000"); - private static String[] nativeLogTypes = { "|critical", "|error", "|info", "|debug" }; @@ -238,6 +238,9 @@ public class Dgdriv { public void setGdattim(String gdattim) { this.gdattim = gdattim; + this.gempakTime = CommonDateFormatUtil.dbtimeToDattim(gdattim); + this.forecastTimeInSec = CommonDateFormatUtil + .getForecastTimeInSec(gempakTime); } public void setGlevel(String glevel) { @@ -674,7 +677,7 @@ public class Dgdriv { "From db_init: error initializing DB common area"); } - String currentTime = dbtimeToDattim(gdattim); + String currentTime = gempakTime; gd.gem.db_wsetnavtime_(currentTime, iret); if (iret.getValue() != 0) { throw new DgdrivException( @@ -730,7 +733,7 @@ public class Dgdriv { // else { // gd.gem.dgc_ndtm_ (dbtimeToDattim(gdattim), iret); // } - gd.gem.dgc_ndtm_(dbtimeToDattim(gdattim), iret); + gd.gem.dgc_ndtm_(gempakTime, iret); if (iret.getValue() != 0) { gd.gem.erc_wmsg("DG", iret, "", ier); proces = false; @@ -1306,72 +1309,13 @@ public class Dgdriv { // TODO Auto-generated method stub StringBuilder resultsBuf = new StringBuilder(); for (DataTime dt : dataForecastTimes) { - resultsBuf.append(dbtimeToDattim(dt.toString())); + resultsBuf + .append(CommonDateFormatUtil.dbtimeToDattim(dt.toString())); resultsBuf.append("|"); } return resultsBuf.substring(0, resultsBuf.length() - 1); } - private String dbtimeToDattim(String aTime) { - String aDattim = null; - String[] inputStringArray = new String[2]; - - CharSequence char0 = "("; - /* - * Process time contains forecast hour info - */ - if (aTime.contains(char0)) { - String zeroes = null; - int ind1 = aTime.indexOf("("); - int ind2 = aTime.indexOf(")"); - if (ind2 - ind1 == 2) { - zeroes = "00"; - } else if (ind2 - ind1 == 3) { - zeroes = "0"; - } - String str1 = aTime.substring(0, ind1 - 1); - String str2 = ""; - if (zeroes != null) { - str2 = "f" + zeroes + aTime.substring(ind1 + 1, ind2); - } else { - str2 = "f" + aTime.substring(ind1 + 1, ind2); - } - - if (aTime.contains("_")) { - inputStringArray = str1.split("_"); - } else if (!aTime.contains("_")) { - inputStringArray = str1.split(" "); - } - - /* - * YYYY-MM-DD HH:MM:SS.S (HHH)-> YYMMDD/HHMMfHHH 2009-10-22 - * 16:00:00.0 (5)-> 091022/1600f005 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5) + str2; - } - /* - * Process time that does NOT contain forecast hour info - */ - else { - inputStringArray = aTime.split(" "); - - /* - * YYYY-MM-DD HH:MM:SS.S -> YYMMDD/HHMM 2009-01-20 02:25:00.0 -> - * 090120/0225 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5); - } - return aDattim; - } - /* * Flips the data from CAVE order and changes the missing data value from * CAVE -999999.0f to GEMPAK -9999.0f @@ -1533,24 +1477,15 @@ public class Dgdriv { StringBuilder sb = new StringBuilder(); String[] tmStr = uriStr[2].split("_"); String dataDateStr = tmStr[0]; - String fhrs = tmStr[2].substring(tmStr[2].indexOf("(") + 1, - tmStr[2].indexOf(")")); - String fhStr; - if (fhrs == null) { - fhStr = "000"; - } else { - int number = 0; - try { - number = Integer.parseInt(fhrs); - } catch (NumberFormatException e) { - // - } - fhStr = forecastHourFormat.format(number); - } + int fcstTimeInSec = CommonDateFormatUtil + .getForecastTimeInSec(uriStr[2]); + String fcstTimeStr = CommonDateFormatUtil + .getForecastTimeString(fcstTimeInSec); + sb.append(path); sb.append("-"); sb.append(dataDateStr); - String dataTimeStr = tmStr[1].split(":")[0] + "-FH-" + fhStr; + String dataTimeStr = tmStr[1].split(":")[0] + "-FH-" + fcstTimeStr; sb.append("-"); sb.append(dataTimeStr); sb.append(".h5"); @@ -1855,13 +1790,13 @@ public class Dgdriv { String prefix = modelName + "_" + dbTag + "_" + eventName + "_"; for (int i = 0; i < responseList.size(); i++) { - Object fhrValue = responseList.get(i).get( + Object fSecValue = responseList.get(i).get( GridDBConstants.FORECAST_TIME_QUERY); Object refValue = responseList.get(i).get( GridDBConstants.REF_TIME_QUERY); - if (fhrValue != null && fhrValue instanceof Integer + if (fSecValue != null && fSecValue instanceof Integer && refValue != null && refValue instanceof Date) { - int fhr = ((Integer) fhrValue).intValue() / 3600; + int fcstTimeInSec = ((Integer) fSecValue).intValue(); DataTime refTime = new DataTime((Date) refValue); String[] dts = refTime.toString().split(" "); @@ -1872,8 +1807,13 @@ public class Dgdriv { retFileNames = retFileNames + "|"; } - retFileNames = retFileNames + prefix + dt + hh + "f" - + forecastHourFormat.format(fhr); + retFileNames = retFileNames + + prefix + + dt + + hh + + "f" + + CommonDateFormatUtil + .getForecastTimeString(fcstTimeInSec); } } } catch (VizException e) { @@ -1895,8 +1835,9 @@ public class Dgdriv { try { Date date = sdf.parse(times[0]); - int fhr = Integer.parseInt(times[1]) * 3600; - dt = new DataTime(date, fhr); + int fcstTimeInSec = CommonDateFormatUtil + .getForecastTimeInSec(gempakTimeStr); + dt = new DataTime(date, fcstTimeInSec); } catch (Exception e) { dt = null; } @@ -1974,19 +1915,20 @@ public class Dgdriv { long t1 = System.currentTimeMillis(); if (ncgribLogger.enableDiagnosticLogs()) { - String[] parmList = parameters.split("\\|"); - String refTimeg = parmList[5].toUpperCase().split("F")[0]; - String refTime = GempakGrid.dattimToDbtime(refTimeg); - refTime = refTime.substring(0, refTime.length() - 2); - String fcstTimeg = parmList[5].toUpperCase().split("F")[1]; + String refTime = rcMap.get(GridDBConstants.REF_TIME_QUERY) + .getConstraintValue(); + int fcstTime = Integer.parseInt(rcMap.get( + GridDBConstants.FORECAST_TIME_QUERY).getConstraintValue()); + String fcstTimeg = CommonDateFormatUtil + .getForecastColonTimeString(fcstTime); if (datauri != null) { logger.info("### getDataURIFromAssembler(" + datauri + ") for(" - + parameters + ") reftime:" + refTime + "(" - + Integer.parseInt(fcstTimeg) + ") took: " + (t1 - t0)); + + parameters + ") reftime:" + refTime + "(" + fcstTimeg + + ") took: " + (t1 - t0)); } else { logger.info("??? getDataURIFromAssembler(null) for(" - + parameters + ") reftime:" + refTime + "(" - + Integer.parseInt(fcstTimeg) + ") took: " + (t1 - t0)); + + parameters + ") reftime:" + refTime + "(" + fcstTimeg + + ") took: " + (t1 - t0)); } } @@ -2251,16 +2193,13 @@ public class Dgdriv { return null; } String refTimeg = parmList[5].toUpperCase().split("F")[0]; - String refTime = GempakGrid.dattimToDbtime(refTimeg); - refTime = refTime.substring(0, refTime.length() - 2); - String fcstTimeg = parmList[5].toUpperCase().split("F")[1]; - String fcstTime = Integer - .toString(((Integer.parseInt(fcstTimeg)) * 3600)); + String refTime = CommonDateFormatUtil.dattimToDbtime(refTimeg); + String fcstTimeInSec = Integer.toString(forecastTimeInSec); rcMap.put(GridDBConstants.REF_TIME_QUERY, new RequestConstraint(refTime)); rcMap.put(GridDBConstants.FORECAST_TIME_QUERY, new RequestConstraint( - fcstTime)); + fcstTimeInSec)); if (ncgribLogger.enableDiagnosticLogs()) { logger.info("exit getRequestConstraint - rcMap:" + rcMap.toString()); } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/TestDgdriv.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/TestDgdriv.java index e196712ffc..f5cdbc57fc 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/TestDgdriv.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/dgdriv/TestDgdriv.java @@ -1,54 +1,51 @@ package gov.noaa.nws.ncep.viz.rsc.ncgrid.dgdriv; + /** * */ +import gov.noaa.nws.ncep.edex.common.dataRecords.NcFloatDataRecord; +import gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil; +import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag; +import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag.gempak; + import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import com.sun.jna.Native; -import com.sun.jna.ptr.FloatByReference; -import com.sun.jna.ptr.IntByReference; - -//import com.raytheon.uf.common.dataplugin.level.Level; +import com.raytheon.uf.common.dataplugin.grid.GridRecord; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; -//import com.raytheon.uf.common.derivparam.tree.DataTree; -//import com.raytheon.uf.common.derivparam.tree.LevelNode; import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.Request; import com.raytheon.uf.common.datastorage.records.IDataRecord; import com.raytheon.uf.common.geospatial.ISpatialObject; -import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.viz.core.VizApp; -import com.raytheon.uf.viz.core.catalog.LayerProperty; -import com.raytheon.uf.viz.core.catalog.ScriptCreator; -import com.raytheon.uf.viz.core.comm.Connector; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.rsc.ResourceType; - -import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag; -import gov.noaa.nws.ncep.viz.gempak.grid.jna.GridDiag.gempak; -import gov.noaa.nws.ncep.viz.gempak.util.GempakGrid; -import gov.noaa.nws.ncep.viz.rsc.ncgrid.dgdriv.DgdrivException; -import com.raytheon.uf.common.dataplugin.grid.GridRecord; -//import gov.noaa.nws.ncep.viz.gempak.grid.inv.NcInventory; -import gov.noaa.nws.ncep.edex.common.dataRecords.NcFloatDataRecord; - import com.raytheon.uf.common.gridcoverage.GridCoverage; import com.raytheon.uf.common.gridcoverage.LambertConformalGridCoverage; import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage; import com.raytheon.uf.common.gridcoverage.MercatorGridCoverage; import com.raytheon.uf.common.gridcoverage.PolarStereoGridCoverage; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.catalog.LayerProperty; +import com.raytheon.uf.viz.core.catalog.ScriptCreator; +import com.raytheon.uf.viz.core.comm.Connector; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.ResourceType; +import com.sun.jna.Native; +import com.sun.jna.ptr.FloatByReference; +import com.sun.jna.ptr.IntByReference; +//import com.raytheon.uf.common.dataplugin.level.Level; +//import com.raytheon.uf.common.derivparam.tree.DataTree; +//import com.raytheon.uf.common.derivparam.tree.LevelNode; +//import gov.noaa.nws.ncep.viz.gempak.grid.inv.NcInventory; //import gov.noaa.nws.ncep.common.log.logger.NcepLogger; //import gov.noaa.nws.ncep.common.log.logger.NcepLoggerManager; /** - * The Dgdriv class provides setters GEMPAK for grid diagnostic parameters - * and then executes the grid retrieval methods. - * + * The Dgdriv class provides setters GEMPAK for grid diagnostic parameters and + * then executes the grid retrieval methods. + * *
  * SOFTWARE HISTORY
  * Date			Ticket#		Engineer    	Description
@@ -83,1187 +80,1267 @@ import com.raytheon.uf.common.gridcoverage.PolarStereoGridCoverage;
  * 10/2011		168			mgamazaychikov	added methods to removed dependency on datatype.tbl
  * 10/2011                  X. Guo          Added grib inventory
  * 
- * + * * @author tlee * @version 1.0 */ public class TestDgdriv { - //private static NcepLogger logger = NcepLoggerManager.getNcepLogger(TestDgdriv.class); - private static GridDiag gd; - private String gdfile, gdpfun, gdattim, glevel, gvcord, scale, garea, proj, dataSource; - private boolean scalar; - private String gdfileOriginal; - - private float resultMin=9999999.0f, resultMax=0.0f; - private ISpatialObject spatialObj; - private ArrayList dataForecastTimes; - private static Connector conn; -// private NcInventory inventory; - - /* - * TODO Work around solution - need to find away to set logging level programmatically - */ - private static boolean nativeLogging = true; -// private static boolean nativeLogging = false; - + // private static NcepLogger logger = + // NcepLoggerManager.getNcepLogger(TestDgdriv.class); + private static GridDiag gd; - public TestDgdriv() { - /* - * Initialize GEMPLT, DG and grid libraries. - */ -// gd.initialize(); - gd = GridDiag.getInstance(); - gdfile = ""; - gdfileOriginal=""; - gdpfun = ""; - gdattim = ""; - glevel = ""; - gvcord = ""; - scale = ""; - garea = ""; - proj = ""; - scalar = false; - dataForecastTimes = new ArrayList(); -// dataTree = NcInventory.getInstance().getNcDataTree(); -// inventory = NcInventory.getInstance(); - try { - conn = Connector.getInstance(); - } catch (VizException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public String getGdpfun() { - return gdpfun; - } + private String gdfile, gdpfun, gdattim, glevel, gvcord, scale, garea, proj, + dataSource; - public void setGdpfun(String gdpfun) { - this.gdpfun = gdpfun; - } + private boolean scalar; - public boolean isScalar() { - return scalar; - } + private String gdfileOriginal; - public void setScalar(boolean scalar) { - this.scalar = scalar; - } + private float resultMin = 9999999.0f, resultMax = 0.0f; + private ISpatialObject spatialObj; + + private ArrayList dataForecastTimes; + + private static Connector conn; + + // private NcInventory inventory; + + /* + * TODO Work around solution - need to find away to set logging level + * programmatically + */ + private static boolean nativeLogging = true; + + // private static boolean nativeLogging = false; + + public TestDgdriv() { + /* + * Initialize GEMPLT, DG and grid libraries. + */ + // gd.initialize(); + gd = GridDiag.getInstance(); + gdfile = ""; + gdfileOriginal = ""; + gdpfun = ""; + gdattim = ""; + glevel = ""; + gvcord = ""; + scale = ""; + garea = ""; + proj = ""; + scalar = false; + dataForecastTimes = new ArrayList(); + // dataTree = NcInventory.getInstance().getNcDataTree(); + // inventory = NcInventory.getInstance(); + try { + conn = Connector.getInstance(); + } catch (VizException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public String getGdpfun() { + return gdpfun; + } + + public void setGdpfun(String gdpfun) { + this.gdpfun = gdpfun; + } + + public boolean isScalar() { + return scalar; + } + + public void setScalar(boolean scalar) { + this.scalar = scalar; + } + + public void setGdfile(String gdfile) { + this.gdfile = gdfile; + this.gdfileOriginal = gdfile; + } + + public void setGdattim(String gdattim) { + this.gdattim = gdattim; + } + + public void setGlevel(String glevel) { + this.glevel = glevel; + } + + public void setGvcord(String gvcord) { + this.gvcord = gvcord; + } + + public void setScale(String scale) { + this.scale = scale; + } + + public void setGarea(String garea) { + this.garea = garea.toUpperCase(); + } + + public void setProj(String proj) { + this.proj = proj; + } + + public void setDataSource(String dataSource) { + this.dataSource = dataSource.trim().toUpperCase(); + } + + public void setSpatialObject(ISpatialObject spatialObject) { + this.spatialObj = spatialObject; + + } + + final int BUFRLENGTH = 128; + + final int PRMLENGTH = 40; + + final int IMISSD = -9999; + + IntByReference iret = new IntByReference(0); + + IntByReference ier = new IntByReference(0); + + IntByReference iscale = new IntByReference(0); - public void setGdfile (String gdfile) { - this.gdfile = gdfile; - this.gdfileOriginal = gdfile; - } - - - public void setGdattim (String gdattim) { - this.gdattim = gdattim; - } - - public void setGlevel (String glevel) { - this.glevel = glevel; - } - - public void setGvcord (String gvcord) { - this.gvcord = gvcord; - } - - public void setScale (String scale) { - this.scale = scale; - } - - public void setGarea (String garea) { - this.garea = garea.toUpperCase(); - } - - public void setProj (String proj) { - this.proj = proj; - } - - public void setDataSource(String dataSource) { - this.dataSource = dataSource.trim().toUpperCase(); - } - - public void setSpatialObject(ISpatialObject spatialObject) { - this.spatialObj = spatialObject; - - } - - final int BUFRLENGTH = 128; - final int PRMLENGTH = 40; - final int IMISSD = -9999; - - IntByReference iret = new IntByReference(0); - IntByReference ier = new IntByReference(0); - IntByReference iscale = new IntByReference(0); IntByReference iscalv = new IntByReference(0); + IntByReference chngnv = new IntByReference(1); + IntByReference coladd = new IntByReference(0); + IntByReference gottm = new IntByReference(0); + IntByReference drpflg = new IntByReference(0); + IntByReference level1 = new IntByReference(0); + IntByReference level2 = new IntByReference(0); + IntByReference ivcord = new IntByReference(0); + IntByReference fileflg = new IntByReference(0); + IntByReference termflg = new IntByReference(1); - + IntByReference maxgrd = new IntByReference(IMISSD); + IntByReference ix1 = new IntByReference(0); + IntByReference iy1 = new IntByReference(0); + IntByReference ix2 = new IntByReference(0); + IntByReference iy2 = new IntByReference(0); + IntByReference kx = new IntByReference(IMISSD); + IntByReference ky = new IntByReference(IMISSD); + IntByReference igx = new IntByReference(0); + IntByReference igy = new IntByReference(0); - IntByReference numerr = new IntByReference(0); - + + IntByReference numerr = new IntByReference(0); + FloatByReference rmax = new FloatByReference(0.F); + FloatByReference rmin = new FloatByReference(0.F); String garout = ""; + String prjout = ""; + String satfil = ""; + String outfil = ""; + String skip = "N"; - String errorURI =""; + + String errorURI = ""; + byte[] pfunc = new byte[BUFRLENGTH]; - byte[] parmu = new byte[PRMLENGTH]; - byte[] parmv = new byte[PRMLENGTH]; - byte[] time = new byte [PRMLENGTH]; - byte [] time1 = new byte [BUFRLENGTH]; - byte [] time2 = new byte [BUFRLENGTH]; - byte [] gareabuf = new byte [BUFRLENGTH]; - byte [] prjbuf = new byte [BUFRLENGTH]; - boolean proces = true; - Map hm = new HashMap(); - private String eventName; - - DiagnosticsCallback diagCallback=null; - ReturnFileNameCallback flnmCallback = null; - ReturnCycleForecastHoursCallback fhrsCallback = null; - ReturnNavigationCallback navCallback = null; - ReturnDataCallback dataCallback = null; - ReturnDataURICallback duriCallback = null; - - private class DiagnosticsCallback implements gempak.DbCallbackWithMessage { - @Override - public boolean callback(String msg) { - String sep = "::"; - if ( msg.contains("|debug") ) { - String logMessage = msg.split("\\|")[0] + ":" + msg.split(sep)[1]; - System.out.println("\t\tC DEBUG MESSAGE " + logMessage); - //logger.debug("C DEBUG MESSAGE " +logMessage); - } - else if ( msg.contains("|info") ) { - String logMessage = msg.split("\\|")[0] + ":" + msg.split(sep)[1]; - System.out.println("\tC INFO MESSAGE " + logMessage); - //logger.info("C INFO MESSAGE " +logMessage); - } - else if ( msg.contains("|error") ) { - String logMessage = msg.split("\\|")[0] + ":" + msg.split(sep)[1]; - System.out.println("\nC ERROR MESSAGE " + logMessage); - //logger.error("C ERROR MESSAGE " +logMessage); - } - - return true; - } - } - - private class ReturnDataCallback implements gempak.DbCallbackWithMessage { + byte[] parmu = new byte[PRMLENGTH]; - @Override - public boolean callback(String msg) { - if (msg.contains("/")) { - try { - String[] msgArr = msg.split(";"); - if (msgArr.length == 3) { - String dataURI = msgArr[0]; - int nx = Integer.parseInt(msgArr[1].trim()); - int ny = Integer.parseInt(msgArr[2].trim()); - long t0 = System.currentTimeMillis(); - //float[] rData = retrieveData(dataURI); - float[] rData = new float[nx*ny]; - for ( int j=0; j<(nx*ny); j++ ) rData[j]= (float)j; - - - long t1 = System.currentTimeMillis(); - int rDataSize = rData.length; - IntByReference datSize = new IntByReference(rDataSize); - gd.gem.db_returndata(flipData(rData, nx, ny),datSize); - long t2 = System.currentTimeMillis(); - System.out.println("\tretrieve data took " + (t1-t0)); - //logger.info("retrieve data took " + (t1-t0)); - System.out.println("\treturn data took " + (t2-t1)); - //logger.info("return data took " + (t2-t1)); - return true; - } else { - errorURI = msg; - proces = false; - return true; - } - } catch (Exception e) { - errorURI = msg; - proces = false; - return true; - } - } else { - return true; - } - } - } - - private class ReturnNavigationCallback implements gempak.DbCallbackWithMessage { + byte[] parmv = new byte[PRMLENGTH]; - @Override - public boolean callback(String msg) { - long t0 = System.currentTimeMillis(); - //String navigationString = getGridNavigationContent(spatialObj); - String navigationString = "STR;147;110;2680;-1394750;-9999;-9999;-1050000;907550;907550"; - //logger.debug("Retrieved this navigation string " + navigationString); - gd.gem.db_returnnav(navigationString); - long t1 = System.currentTimeMillis(); - System.out.println("\treturn navigation " + navigationString + " took " + (t1-t0)); - //logger.info("return navigation " + navigationString + " took " + (t1-t0)); - return true; - } - } - - private class ReturnDataURICallback implements gempak.DbCallbackWithMessage { + byte[] time = new byte[PRMLENGTH]; - @Override -// public boolean callback(String msg) { -// if (msg.contains("import")) { -// try { -// long t0 = System.currentTimeMillis(); -// String dataURI = executeScript(msg); -// gd.gem.db_returnduri(dataURI); -// long t1 = System.currentTimeMillis(); -// System.out.println("\treturn dataURI " + dataURI + " took " + (t1-t0)); -// logger.info("return dataURI " + dataURI + " took " + (t1-t0)); -// return true; -// } catch (VizException e) { -// errorURI = msg; -// proces = false; -// return true; -// } -// } else { -// return true; -// } -// } - public boolean callback(String msg) { - try { - long t0 = System.currentTimeMillis(); - System.out.println("Looking for DURI: "+msg); - //String dataURI = getDataURI(msg); - String dataURI = "/ncgrib/2011-10-03_12:00:00.0_(6)/NAM104/GH/MB/200.0/-999999.0/null/null/NAM104/2/nam.t12z.grbgrd06.tm00.grib2/HGHT/PRES/45"; - System.out.println("GotBack DURI: "+dataURI); - gd.gem.db_returnduri(dataURI); - long t1 = System.currentTimeMillis(); - System.out.println("\treturn dataURI " + dataURI + " took " + (t1-t0)); - //logger.info("return dataURI " + dataURI + " took " + (t1-t0)); - return true; - } catch (Exception e) { - errorURI = msg; - proces = false; - return true; - } - } - } - - private class ReturnCycleForecastHoursCallback implements gempak.DbCallbackWithoutMessage { + byte[] time1 = new byte[BUFRLENGTH]; - @Override - public boolean callback() { - long t0 = System.currentTimeMillis(); - //String cycleFcstHrsString = getCycleFcstHrsString(dataForecastTimes); - String cycleFcstHrsString = "111003/1200f003|111003/1200f006|111003/1200f009|111003/1200f012"; - gd.gem.db_returnfhrs(cycleFcstHrsString); - long t1 = System.currentTimeMillis(); - System.out.println("\treturn cycle forecast hours string " + cycleFcstHrsString + " took " + (t1-t0)); - //logger.info("return cycle forecast hours string " + cycleFcstHrsString + " took " + (t1-t0)); - return true; - } - } - - private class ReturnFileNameCallback implements gempak.DbCallbackWithMessage { + byte[] time2 = new byte[BUFRLENGTH]; - @Override - public boolean callback(String msg) { - if (msg.contains("import")) { - try { - long t0 = System.currentTimeMillis(); - String fileNames = executeScript(msg); - System.out.println("Retrieved members:" + fileNames); - gd.gem.db_returnflnm(fileNames); - long t1 = System.currentTimeMillis(); - System.out.println("\treturn file names string " + fileNames + " took " + (t1-t0)); - //logger.info("return file names string " + fileNames + " took " + (t1-t0)); - return true; - } catch (VizException e) { - errorURI = msg; - proces = false; - return true; - } - } else { - return true; - } - } - } + byte[] gareabuf = new byte[BUFRLENGTH]; - public NcFloatDataRecord execute() throws DgdrivException { - - /* - * Tag the gdfile string for ncgrib dataSource - */ - this.gdfile = getTaggedGdfile(); - proces = true; -// System.out.println(); + byte[] prjbuf = new byte[BUFRLENGTH]; - /* - * TODO Work around solution - need to find away to set logging level programmatically - */ - - if ( nativeLogging ) { - diagCallback = new DiagnosticsCallback(); - gd.gem.db_diagCallback (diagCallback); - } - - flnmCallback = new ReturnFileNameCallback(); - gd.gem.db_flnmCallback(flnmCallback); - fhrsCallback = new ReturnCycleForecastHoursCallback(); - gd.gem.db_fhrsCallback (fhrsCallback); + boolean proces = true; + + Map hm = new HashMap(); + + private String eventName; + + DiagnosticsCallback diagCallback = null; + + ReturnFileNameCallback flnmCallback = null; + + ReturnCycleForecastHoursCallback fhrsCallback = null; + + ReturnNavigationCallback navCallback = null; + + ReturnDataCallback dataCallback = null; + + ReturnDataURICallback duriCallback = null; + + private class DiagnosticsCallback implements gempak.DbCallbackWithMessage { + + @Override + public boolean callback(String msg) { + String sep = "::"; + if (msg.contains("|debug")) { + String logMessage = msg.split("\\|")[0] + ":" + + msg.split(sep)[1]; + System.out.println("\t\tC DEBUG MESSAGE " + logMessage); + // logger.debug("C DEBUG MESSAGE " +logMessage); + } else if (msg.contains("|info")) { + String logMessage = msg.split("\\|")[0] + ":" + + msg.split(sep)[1]; + System.out.println("\tC INFO MESSAGE " + logMessage); + // logger.info("C INFO MESSAGE " +logMessage); + } else if (msg.contains("|error")) { + String logMessage = msg.split("\\|")[0] + ":" + + msg.split(sep)[1]; + System.out.println("\nC ERROR MESSAGE " + logMessage); + // logger.error("C ERROR MESSAGE " +logMessage); + } + + return true; + } + } + + private class ReturnDataCallback implements gempak.DbCallbackWithMessage { + + @Override + public boolean callback(String msg) { + if (msg.contains("/")) { + try { + String[] msgArr = msg.split(";"); + if (msgArr.length == 3) { + String dataURI = msgArr[0]; + int nx = Integer.parseInt(msgArr[1].trim()); + int ny = Integer.parseInt(msgArr[2].trim()); + long t0 = System.currentTimeMillis(); + // float[] rData = retrieveData(dataURI); + float[] rData = new float[nx * ny]; + for (int j = 0; j < (nx * ny); j++) + rData[j] = (float) j; + + long t1 = System.currentTimeMillis(); + int rDataSize = rData.length; + IntByReference datSize = new IntByReference(rDataSize); + gd.gem.db_returndata(flipData(rData, nx, ny), datSize); + long t2 = System.currentTimeMillis(); + System.out.println("\tretrieve data took " + (t1 - t0)); + // logger.info("retrieve data took " + (t1-t0)); + System.out.println("\treturn data took " + (t2 - t1)); + // logger.info("return data took " + (t2-t1)); + return true; + } else { + errorURI = msg; + proces = false; + return true; + } + } catch (Exception e) { + errorURI = msg; + proces = false; + return true; + } + } else { + return true; + } + } + } + + private class ReturnNavigationCallback implements + gempak.DbCallbackWithMessage { + + @Override + public boolean callback(String msg) { + long t0 = System.currentTimeMillis(); + // String navigationString = getGridNavigationContent(spatialObj); + String navigationString = "STR;147;110;2680;-1394750;-9999;-9999;-1050000;907550;907550"; + // logger.debug("Retrieved this navigation string " + + // navigationString); + gd.gem.db_returnnav(navigationString); + long t1 = System.currentTimeMillis(); + System.out.println("\treturn navigation " + navigationString + + " took " + (t1 - t0)); + // logger.info("return navigation " + navigationString + " took " + + // (t1-t0)); + return true; + } + } + + private class ReturnDataURICallback implements gempak.DbCallbackWithMessage { + + @Override + // public boolean callback(String msg) { + // if (msg.contains("import")) { + // try { + // long t0 = System.currentTimeMillis(); + // String dataURI = executeScript(msg); + // gd.gem.db_returnduri(dataURI); + // long t1 = System.currentTimeMillis(); + // System.out.println("\treturn dataURI " + dataURI + " took " + + // (t1-t0)); + // logger.info("return dataURI " + dataURI + " took " + (t1-t0)); + // return true; + // } catch (VizException e) { + // errorURI = msg; + // proces = false; + // return true; + // } + // } else { + // return true; + // } + // } + public boolean callback(String msg) { + try { + long t0 = System.currentTimeMillis(); + System.out.println("Looking for DURI: " + msg); + // String dataURI = getDataURI(msg); + String dataURI = "/ncgrib/2011-10-03_12:00:00.0_(6)/NAM104/GH/MB/200.0/-999999.0/null/null/NAM104/2/nam.t12z.grbgrd06.tm00.grib2/HGHT/PRES/45"; + System.out.println("GotBack DURI: " + dataURI); + gd.gem.db_returnduri(dataURI); + long t1 = System.currentTimeMillis(); + System.out.println("\treturn dataURI " + dataURI + " took " + + (t1 - t0)); + // logger.info("return dataURI " + dataURI + " took " + + // (t1-t0)); + return true; + } catch (Exception e) { + errorURI = msg; + proces = false; + return true; + } + } + } + + private class ReturnCycleForecastHoursCallback implements + gempak.DbCallbackWithoutMessage { + + @Override + public boolean callback() { + long t0 = System.currentTimeMillis(); + // String cycleFcstHrsString = + // getCycleFcstHrsString(dataForecastTimes); + String cycleFcstHrsString = "111003/1200f003|111003/1200f006|111003/1200f009|111003/1200f012"; + gd.gem.db_returnfhrs(cycleFcstHrsString); + long t1 = System.currentTimeMillis(); + System.out.println("\treturn cycle forecast hours string " + + cycleFcstHrsString + " took " + (t1 - t0)); + // logger.info("return cycle forecast hours string " + + // cycleFcstHrsString + " took " + (t1-t0)); + return true; + } + } + + private class ReturnFileNameCallback implements + gempak.DbCallbackWithMessage { + + @Override + public boolean callback(String msg) { + if (msg.contains("import")) { + try { + long t0 = System.currentTimeMillis(); + String fileNames = executeScript(msg); + System.out.println("Retrieved members:" + fileNames); + gd.gem.db_returnflnm(fileNames); + long t1 = System.currentTimeMillis(); + System.out.println("\treturn file names string " + + fileNames + " took " + (t1 - t0)); + // logger.info("return file names string " + fileNames + + // " took " + (t1-t0)); + return true; + } catch (VizException e) { + errorURI = msg; + proces = false; + return true; + } + } else { + return true; + } + } + } + + public NcFloatDataRecord execute() throws DgdrivException { + + /* + * Tag the gdfile string for ncgrib dataSource + */ + this.gdfile = getTaggedGdfile(); + proces = true; + // System.out.println(); + + /* + * TODO Work around solution - need to find away to set logging level + * programmatically + */ + + if (nativeLogging) { + diagCallback = new DiagnosticsCallback(); + gd.gem.db_diagCallback(diagCallback); + } + + flnmCallback = new ReturnFileNameCallback(); + gd.gem.db_flnmCallback(flnmCallback); + fhrsCallback = new ReturnCycleForecastHoursCallback(); + gd.gem.db_fhrsCallback(fhrsCallback); navCallback = new ReturnNavigationCallback(); - gd.gem.db_navCallback (navCallback); - dataCallback = new ReturnDataCallback(); - gd.gem.db_dataCallback (dataCallback); - duriCallback = new ReturnDataURICallback(); - gd.gem.db_duriCallback (duriCallback); - - long t0 = System.currentTimeMillis(); - - - gd.gem.in_bdta_(iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException("From in_bdta: error initializing GEMPAK"); - } - - gd.gem.gd_init_ (iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException("From gd_init: error initializing Grid library common area"); - } + gd.gem.db_navCallback(navCallback); + dataCallback = new ReturnDataCallback(); + gd.gem.db_dataCallback(dataCallback); + duriCallback = new ReturnDataURICallback(); + gd.gem.db_duriCallback(duriCallback); + long t0 = System.currentTimeMillis(); - IntByReference mode = new IntByReference(0); - gd.gem.gg_init_ (mode,iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException("From gg_init: error starting GPLT"); - } - - gd.gem.dg_intl_ (iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException("From dg_intl: error initializing Grid diagnostics common block"); - } - - gd.gem.db_init_ (iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException("From db_init: error initializing DB common area"); - } - - -// gd.gem.init_driver(iret); -// if ( iret.getValue() != 0 ) { -// throw new DgdrivException("From init_driver: error initializing..."); -// } - - String currentTime = dbtimeToDattim(gdattim); - gd.gem.db_wsetnavtime_ (currentTime, iret); - if ( iret.getValue () != 0 ) { - throw new DgdrivException ("From db_wsetnavtime: error setting the navigation time " + currentTime); - } - - /* - * Process the gdfile string for ensemble request - */ - if (this.gdfile.startsWith("{") && this.gdfile.endsWith("}") ) { - prepareEnsembleDTInfo(); - } - else { - prepareGridDTInfo(); - } + gd.gem.in_bdta_(iret); + if (iret.getValue() != 0) { + throw new DgdrivException("From in_bdta: error initializing GEMPAK"); + } - long t05 = System.currentTimeMillis(); - //logger.info("init and settime took: " + (t05-t0)); - /* + gd.gem.gd_init_(iret); + if (iret.getValue() != 0) { + throw new DgdrivException( + "From gd_init: error initializing Grid library common area"); + } + + IntByReference mode = new IntByReference(0); + gd.gem.gg_init_(mode, iret); + if (iret.getValue() != 0) { + throw new DgdrivException("From gg_init: error starting GPLT"); + } + + gd.gem.dg_intl_(iret); + if (iret.getValue() != 0) { + throw new DgdrivException( + "From dg_intl: error initializing Grid diagnostics common block"); + } + + gd.gem.db_init_(iret); + if (iret.getValue() != 0) { + throw new DgdrivException( + "From db_init: error initializing DB common area"); + } + + // gd.gem.init_driver(iret); + // if ( iret.getValue() != 0 ) { + // throw new + // DgdrivException("From init_driver: error initializing..."); + // } + + String currentTime = dbtimeToDattim(gdattim); + gd.gem.db_wsetnavtime_(currentTime, iret); + if (iret.getValue() != 0) { + throw new DgdrivException( + "From db_wsetnavtime: error setting the navigation time " + + currentTime); + } + + /* + * Process the gdfile string for ensemble request + */ + if (this.gdfile.startsWith("{") && this.gdfile.endsWith("}")) { + prepareEnsembleDTInfo(); + } else { + prepareGridDTInfo(); + } + + long t05 = System.currentTimeMillis(); + // logger.info("init and settime took: " + (t05-t0)); + /* * Process the GDFILE input. */ if (proces) { - if ( gdfile.contains(":") ) { - gd.gem.db_wsetevtname_ (gdfile.split(":")[1], iret); - } - gd.gem.dgc_nfil_ (gdfile, "", iret); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } - + if (gdfile.contains(":")) { + gd.gem.db_wsetevtname_(gdfile.split(":")[1], iret); + } + gd.gem.dgc_nfil_(gdfile, "", iret); + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } + } long t06 = System.currentTimeMillis(); - System.out.println("dgc_nfil took " + (t06-t05)); - //logger.info("dgc_nfil took: " + (t06-t05)); - + System.out.println("dgc_nfil took " + (t06 - t05)); + // logger.info("dgc_nfil took: " + (t06-t05)); + /* * Process the GDATTIM input; setup the time server. - */ + */ if (proces) { -// if (this.gdfile.startsWith("{") && this.gdfile.endsWith("}")) { -// String fTime = "f06"; -// gd.gem.dgc_ndtm_ (fTime, iret); -// } -// else { -// gd.gem.dgc_ndtm_ (dbtimeToDattim(gdattim), iret); -// } - gd.gem.dgc_ndtm_ (dbtimeToDattim(gdattim), iret); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } + // if (this.gdfile.startsWith("{") && this.gdfile.endsWith("}")) { + // String fTime = "f06"; + // gd.gem.dgc_ndtm_ (fTime, iret); + // } + // else { + // gd.gem.dgc_ndtm_ (dbtimeToDattim(gdattim), iret); + // } + gd.gem.dgc_ndtm_(dbtimeToDattim(gdattim), iret); + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } } - + long t07 = System.currentTimeMillis(); - //logger.info("dgc_ndtm took: " + (t07-t06)); - + // logger.info("dgc_ndtm took: " + (t07-t06)); + if (proces) { - /* - * Check if GAREA == "grid", if so, then set coladd= false to NOT add - * a column to globe wrapping grids. - */ - if ( garea.compareToIgnoreCase("GRID")== 0 ) { - coladd = new IntByReference(0); - } - /* + /* + * Check if GAREA == "grid", if so, then set coladd= false to NOT + * add a column to globe wrapping grids. + */ + if (garea.compareToIgnoreCase("GRID") == 0) { + coladd = new IntByReference(0); + } + /* * Set the attributes that do not vary within the time loop. */ - gd.gem.inc_scal (scale, iscale, iscalv, iret); + gd.gem.inc_scal(scale, iscale, iscalv, iret); long t07b = System.currentTimeMillis(); - //logger.info("inc_scal took: " + (t07b-t07)); - + // logger.info("inc_scal took: " + (t07b-t07)); + /* * Get the next time to process from time server. */ - gd.gem.dgc_ntim_(chngnv, coladd, time1, time2, gottm, iret ); + gd.gem.dgc_ntim_(chngnv, coladd, time1, time2, gottm, iret); long t08 = System.currentTimeMillis(); - //logger.info("dgc_ntim took: " + (t08-t07b)); + // logger.info("dgc_ntim took: " + (t08-t07b)); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } else { - gd.gem.tgc_dual (time1, time2, time, iret); - long t08b = System.currentTimeMillis(); - //logger.info("tgc_dual took: " + (t08b-t08)); - } + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } else { + gd.gem.tgc_dual(time1, time2, time, iret); + long t08b = System.currentTimeMillis(); + // logger.info("tgc_dual took: " + (t08b-t08)); + } } - - /* - * Set the map projection and graphics area. - */ + /* + * Set the map projection and graphics area. + */ long t09a = System.currentTimeMillis(); if (proces) { - gd.gem.dgc_fixa_ ( garea, proj, gareabuf, prjbuf, iret); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } + gd.gem.dgc_fixa_(garea, proj, gareabuf, prjbuf, iret); + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } } long t09 = System.currentTimeMillis(); - //logger.info("dgc_fixa took: " + (t09-t09a)); + // logger.info("dgc_fixa took: " + (t09-t09a)); /* * Fortran wrapper used and use byte array instead of String as input!! */ if (proces) { - gd.gem.ggc_maps (prjbuf, gareabuf, satfil, drpflg, iret); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } + gd.gem.ggc_maps(prjbuf, gareabuf, satfil, drpflg, iret); + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } } long t10 = System.currentTimeMillis(); - //logger.info("ggc_maps took: " + (t10-t09)); + // logger.info("ggc_maps took: " + (t10-t09)); - /* - * Setup the grid subset that covers the graphics area. - */ -// if (proces) { -// gd.gem.dgc_subg_ (skip, maxgrd, ix1, iy1, ix2, iy2, iret); -// if ( iret.getValue () != 0 ) { -// gd.gem.erc_wmsg ("DG", iret, "", ier); -// proces = false; -// } -// } + /* + * Setup the grid subset that covers the graphics area. + */ + // if (proces) { + // gd.gem.dgc_subg_ (skip, maxgrd, ix1, iy1, ix2, iy2, iret); + // if ( iret.getValue () != 0 ) { + // gd.gem.erc_wmsg ("DG", iret, "", ier); + // proces = false; + // } + // } long t11 = System.currentTimeMillis(); - //logger.info("dgc_subg took: " + (t11-t10)); + // logger.info("dgc_subg took: " + (t11-t10)); - /* - * Return grid dimension for grid diagnostic calculation. - */ + /* + * Return grid dimension for grid diagnostic calculation. + */ if (proces) { - gd.gem.dg_kxky_( kx, ky, iret); - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, "", ier); - proces = false; - } + gd.gem.dg_kxky_(kx, ky, iret); + if (iret.getValue() != 0) { + gd.gem.erc_wmsg("DG", iret, "", ier); + proces = false; + } } - + float[] ugrid = null; - float[] vgrid = null; - int grid_size = kx.getValue()*ky.getValue(); - if ( kx.getValue() > 0 && ky.getValue() > 0 ) { - ugrid = new float[grid_size]; - vgrid = new float[grid_size]; - } - else { - proces = false; - } - - long t012 = System.currentTimeMillis(); - System.out.println("From gdc_nfil to dgc_grid took:" + (t012-t06)); - //logger.info("From gdc_nfil to dgc_grid took: " + (t012-t06)); - /* - * Compute the requested grid. - */ - if (proces) { - - - if (scalar) { - gd.gem.dgc_grid_( time, glevel, gvcord, gdpfun, pfunc, ugrid, igx, igy, - time1, time2, level1, level2, ivcord, parmu, iret); - System.out.println("RETURN FROM DGC_GRID: "+iret.getValue()); - if (iret.getValue() != 0 ) System.out.println("NONZERORETURNFROMDGC_GRID!! "+iret.getValue()); - } else { - gd.gem.dgc_vecr_ ( time, glevel, gvcord, gdpfun, pfunc, - ugrid, vgrid, igx, igy, time1, time2, level1, level2, - ivcord, parmu, parmv, iret); - if (iret.getValue() != 0 ) System.out.println("NONZERORETURNFROMDGC_VECR!! "+iret.getValue()); - } - if (!proces) { - throw new DgdrivException("Error retrieving data record " - + errorURI); - } - if ( iret.getValue () != 0 ) { - gd.gem.erc_wmsg ("DG", iret, Native.toString(pfunc), ier); - proces = false; - } - } - long t013 = System.currentTimeMillis(); - System.out.println("dgc_grid took " + (t013-t012)); - //logger.info("dgc_grid took: " + (t013-t012)); - - /* - * Compute the scaling factor and scale the grid data. - */ - if (proces) { - NcFloatDataRecord fds = new NcFloatDataRecord(); - IntByReference ix12 = new IntByReference(1); - IntByReference iy12 = new IntByReference(1); - gd.gem.grc_sscl( iscale, igx, igy, ix12, iy12, igx, igy, ugrid, rmin, rmax, iret); - fds.setXdata(flopData(ugrid, igx.getValue(), igy.getValue())); - fds.setDimension(2); - fds.setSizes(new long[] { igx.getValue(), igy.getValue()}); - fds.setVector(false); - - resultMin = rmin.getValue(); - resultMax = rmax.getValue(); - - if (!scalar){ // vector - resultMin = 100.0f; - resultMax = 0.0f; - gd.gem.grc_sscl( iscale, igx, igy, ix1, iy1, ix2, iy2, vgrid, rmin, rmax, iret); - fds.setYdata(flopData(vgrid, igx.getValue(), igy.getValue())); - fds.setDimension(2); - fds.setSizes(new long[] { igx.getValue(), igy.getValue()}); - fds.setVector(true); - - for (int i = 0; i < grid_size; i++) { - if (ugrid[i] == -9999.0 || vgrid[i] == -9999.0) continue; - float speed = (float) Math.hypot(ugrid[i], vgrid[i]); - if (speed > resultMax) resultMax = speed; - if (speed < resultMin) resultMin = speed; - } - - } - /* - * Free memory for all internal grids - */ - gd.gem.dg_fall_( iret); - long t1 = System.currentTimeMillis(); - //logger.info("Scaling took: " + (t1-t013)); - System.out.println("Scaling took:" + (t1-t013)); - printInfoMessage(t1 - t0); - // if (flnmCallback==null || fhrsCallback==null || - // diagCallback==null || navCallback==null || - // dataCallback==null || duriCallback ==null ) System.out.println("NULL CALLBACK"); - return fds; - } - else { - /* - * Write error message only in case of failure - */ - gd.gem.er_gnumerr_(numerr, iret); - int num = numerr.getValue(); - int index = 0; - byte[] errmsg = new byte[BUFRLENGTH]; - StringBuffer strBuf = new StringBuffer(); - while (index < num) { - numerr.setValue(index); - gd.gem.er_gerrmsg_(numerr, errmsg, iret); - strBuf.append(Native.toString(errmsg)); - strBuf.append("\n"); - index++; - } - throw new DgdrivException(strBuf.toString()); + float[] vgrid = null; + int grid_size = kx.getValue() * ky.getValue(); + if (kx.getValue() > 0 && ky.getValue() > 0) { + ugrid = new float[grid_size]; + vgrid = new float[grid_size]; + } else { + proces = false; } - } - - private void prepareGridDTInfo() { - String alias = this.gdfile; - String path = "A2DB_GRID"; - String template = this.gdfileOriginal + "_db"; - if ( this.gdfileOriginal.contains(":")) { - template = this.gdfileOriginal.substring(0, this.gdfileOriginal.indexOf(":")) + "_db"; - } - IntByReference iret = new IntByReference(0); - System.out.println(); - gd.gem.db_seta2dtinfo_ (alias, path, template, iret); - - } + long t012 = System.currentTimeMillis(); + System.out.println("From gdc_nfil to dgc_grid took:" + (t012 - t06)); + // logger.info("From gdc_nfil to dgc_grid took: " + (t012-t06)); + /* + * Compute the requested grid. + */ + if (proces) { - private void prepareEnsembleDTInfo() { - String thePath = "A2DB_GRID"; - StringBuffer sba = new StringBuffer(); - StringBuffer sbp = new StringBuffer(); - StringBuffer sbt = new StringBuffer(); - String [] gdfileArray = this.gdfileOriginal.substring(this.gdfileOriginal.indexOf("{")+1, this.gdfileOriginal.indexOf("}")).split(","); - for (int igd=0;igd resultMax) + resultMax = speed; + if (speed < resultMin) + resultMin = speed; + } - private String getTaggedGdfile() { - if ( this.dataSource.equalsIgnoreCase("ncgrib")) { -// String tag = this.dataSource + "_"; - String tag = "A2DB_"; - /* - * For gdfile containing event name do not have to do - * anything as long as the tag is prefixed - * eg GHM:greg07e becomes A2DB_GHM:greg07e - */ - - /* - * For gdfile containing ensemble have to preprocess - * eg {GFS|11/12, NAM|11/06} becomes {A2DB_GFS|11/12, A2DB_NAM|11/06} - */ - if (this.gdfileOriginal.startsWith("{") && this.gdfileOriginal.endsWith("}") ) { - String [] gdfileArray = this.gdfileOriginal.substring(this.gdfileOriginal.indexOf("{")+1, this.gdfileOriginal.indexOf("}")).split(","); - StringBuffer strb = new StringBuffer(); -// System.out.println(); - for (int igd=0;igd dataForecastTimes) { - // TODO Auto-generated method stub - StringBuffer resultsBuf = new StringBuffer(); - for (DataTime dt: dataForecastTimes) { - resultsBuf.append(dbtimeToDattim(dt.toString())); - resultsBuf.append("|"); - } - return resultsBuf.substring(0, resultsBuf.length() - 1); - } + } - private String dbtimeToDattim(String aTime) { - String aDattim = null; - String[] inputStringArray = new String[2]; - - CharSequence char0 = "("; - /* - * Process time contains forecast hour info - */ - if ( aTime.contains(char0) ) { - String zeroes = null; - int ind1 = aTime.indexOf("("); - int ind2 = aTime.indexOf(")"); - if ( ind2-ind1 == 2 ) { - zeroes = "00"; - } - else if ( ind2-ind1 == 3 ) { - zeroes = "0"; - } - String str1 = aTime.substring(0, ind1-1); - String str2 = ""; - if ( zeroes != null) { - str2 = "f"+zeroes+aTime.substring(ind1+1, ind2); - } - else { - str2 = "f"+aTime.substring(ind1+1, ind2); - } - - if ( aTime.contains("_") ) { - inputStringArray = str1.split("_"); - } - else if ( ! aTime.contains("_") ) { - inputStringArray = str1.split(" "); - } + private void prepareGridDTInfo() { + String alias = this.gdfile; + String path = "A2DB_GRID"; + String template = this.gdfileOriginal + "_db"; + if (this.gdfileOriginal.contains(":")) { + template = this.gdfileOriginal.substring(0, + this.gdfileOriginal.indexOf(":")) + + "_db"; + } + IntByReference iret = new IntByReference(0); + System.out.println(); + gd.gem.db_seta2dtinfo_(alias, path, template, iret); - /* - * YYYY-MM-DD HH:MM:SS.S (HHH)-> YYMMDD/HHMMfHHH - * 2009-10-22 16:00:00.0 (5)-> 091022/1600f005 - * 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5) + str2; - } - /* - * Process time that does NOT contain forecast hour info - */ - else { - inputStringArray = aTime.split(" "); + } - /* - * YYYY-MM-DD HH:MM:SS.S -> YYMMDD/HHMM - * 2009-01-20 02:25:00.0 -> 090120/0225 - * 0123456789 0123456789 - */ - aDattim = inputStringArray[0].substring(2, 4) - + inputStringArray[0].substring(5, 7) - + inputStringArray[0].substring(8, 10) + "/" - + inputStringArray[1].substring(0, 2) - + inputStringArray[1].substring(3, 5); - } - return aDattim; - } - - /* - * Flips the data from CAVE order and changes the missing data value from - * CAVE -999999.0f to GEMPAK -9999.0f - */ - private float[] flipData(float[] inGrid, int nx, int ny) { + private void prepareEnsembleDTInfo() { + String thePath = "A2DB_GRID"; + StringBuffer sba = new StringBuffer(); + StringBuffer sbp = new StringBuffer(); + StringBuffer sbt = new StringBuffer(); + String[] gdfileArray = this.gdfileOriginal.substring( + this.gdfileOriginal.indexOf("{") + 1, + this.gdfileOriginal.indexOf("}")).split(","); + for (int igd = 0; igd < gdfileArray.length; igd++) { + sbp.append(thePath); + sbp.append("|"); + if (gdfileArray[igd].contains("|")) { + String[] tempArr = gdfileArray[igd].split("\\|"); + String ensName = tempArr[0]; + sba.append("A2DB_" + ensName); + System.out.println(); + sba.append("|"); + sbt.append(getEnsembleTemplate(ensName)); + sbt.append("|"); + } else { + String ensName = gdfileArray[igd]; + sba.append("A2DB_" + ensName); + sba.append("|"); + sbt.append(getEnsembleTemplate(ensName)); + sbt.append("|"); + } + } + String alias = sba.toString().substring(0, sba.toString().length() - 1); + String path = sbp.toString().substring(0, sbp.toString().length() - 1); + String template = sbt.toString().substring(0, + sbt.toString().length() - 1); + IntByReference iret = new IntByReference(0); + System.out.println(); + gd.gem.db_seta2dtinfo_(alias, path, template, iret); + } - float[] outGridFlipped = new float[inGrid.length]; + private String getEnsembleTemplate(String ensName) { + StringBuilder query = new StringBuilder(); + query.append("import GempakEnsembleTemplateGenerator\n"); + query.append("query = GempakEnsembleTemplateGenerator.GempakEnsembleTemplateGenerator('ncgrib')\n"); + query.append("query.setEnsembleName('" + ensName + "')\n"); + query.append("return query.execute()\n"); - int kk = 0; + String scriptToRun = query.toString(); + long t0 = System.currentTimeMillis(); - for (int jj = 0; jj < ny; jj++) { - int m1 = nx * ny - nx * (jj + 1); - int m2 = nx * ny - nx * jj; - for (int ii = m1; ii < m2; ii++) { - if (inGrid[ii] < -900000.0) { - outGridFlipped[kk] = -9999.0f; - kk++; - } else { - outGridFlipped[kk] = inGrid[ii]; - kk++; - } - } - } + Object[] pdoList; + try { + pdoList = conn.connect(scriptToRun, null, 60000); + String ensTemplate = (String) pdoList[0]; + long t1 = System.currentTimeMillis(); + System.out.println("\tgetEnsembleTemplate took: " + (t1 - t0)); + // logger.info("getEnsembleTemplate took: " + (t1-t0)); + return ensTemplate; + } catch (VizException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } - return outGridFlipped; - } - - /* - * Flops the data from GEMPAK order and changes the missing data value from - * GEMPAK -9999.0f to CAVE -999999.0f - */ - private float[] flopData(float[] inGrid, int nx, int ny) { + private String getEnsTime(String string) { + // TODO Auto-generated method stub + return string; + } - float[] outGridFlopped = new float[inGrid.length]; - int kk = 0; - for (int jj = ny - 1; jj >= 0; jj--) { - int m1 = nx * jj; - int m2 = m1 + (nx - 1); - for (int ii = m1; ii <= m2; ii++) { - if (inGrid[ii] == -9999.0f) { - outGridFlopped[kk] = -999999.0f; - kk++; - } else { - outGridFlopped[kk] = inGrid[ii]; - kk++; - } - } + private String getTaggedGdfile() { + if (this.dataSource.equalsIgnoreCase("ncgrib")) { + // String tag = this.dataSource + "_"; + String tag = "A2DB_"; + /* + * For gdfile containing event name do not have to do anything as + * long as the tag is prefixed eg GHM:greg07e becomes + * A2DB_GHM:greg07e + */ - } - return outGridFlopped; - } - - - private String getEnsTimes () { - String tmp1 = this.gdfile.substring(this.gdfile.indexOf("{")+1, this.gdfile.indexOf("}")); - String[] tmp = tmp1.split(","); - String tmp2 = ""; - for ( String st: tmp) { - String tmp3[] = st.split("\\|"); - tmp2 = tmp2 + tmp3[1]; - tmp2 = tmp2 + "|"; - - } - String returnStr = tmp2.substring(0, tmp2.length()-1); - return returnStr; - } - - private void printInfoMessage (long t) { - String gdFile; - if ( this.gdfile.startsWith("{") && this.gdfile.endsWith("}") ) { - gdFile = this.gdfile.substring(this.gdfile.indexOf("{") + 1, this.gdfile.indexOf("}")); - } - else { - gdFile = this.gdfile; - } - StringBuilder toprint = new StringBuilder(); -// System.out.print ( "\nCalculating " + gdFile.toUpperCase() + " "); - toprint.append("Requesting " + gdFile.toUpperCase() + " "); - - /* - if (this.vector) { -// System.out.print(this.gvect.toUpperCase()); - toprint.append(this.gvect.toUpperCase()); - } - else { -// System.out.print(this.gfunc.toUpperCase()); - toprint.append(this.gfunc.trim().toUpperCase()); - } - */ - toprint.append(this.gdpfun.trim().toUpperCase()); - -// System.out.print ( " ^" + this.gdattim + " @" + this.glevel + " %" + this.gvcord.toUpperCase()); -// System.out.print (" has taken --> " + t + " ms\n"); -// //System.out.println("\nMin: " + resultMin + " Max: " + resultMax + "\n"); - toprint.append(" ^" + this.gdattim + " @" + this.glevel + " %" + this.gvcord.toUpperCase()); - toprint.append(" from " + this.dataSource + " took: " + t + " ms\n"); -// toprint.append("\nMin: " + resultMin + " Max: " + resultMax + "\n"); - System.out.println(toprint.toString()); - //logger.info(toprint.toString()); - - } - - private static float[] retrieveData(String dataURI) throws VizException { + /* + * For gdfile containing ensemble have to preprocess eg {GFS|11/12, + * NAM|11/06} becomes {A2DB_GFS|11/12, A2DB_NAM|11/06} + */ + if (this.gdfileOriginal.startsWith("{") + && this.gdfileOriginal.endsWith("}")) { + String[] gdfileArray = this.gdfileOriginal.substring( + this.gdfileOriginal.indexOf("{") + 1, + this.gdfileOriginal.indexOf("}")).split(","); + StringBuffer strb = new StringBuffer(); + // System.out.println(); + for (int igd = 0; igd < gdfileArray.length; igd++) { + strb.append(tag); + strb.append(gdfileArray[igd]); + strb.append(","); - long t001 = System.currentTimeMillis(); - IDataRecord dr = null; - try { - String fileName = getFilename(dataURI); - String dataset = "Data"; - Request request = Request.ALL; + } + String retStr = strb.toString().substring(0, + strb.toString().length() - 1); + return "{" + retStr + "}"; + } + return tag + this.gdfile; + } else { + return this.gdfile; + } + } - IDataStore ds = DataStoreFactory.getDataStore(new File(fileName)); - dr = ds.retrieve("", dataURI + "/" + dataset, request); - float[] data = (float[]) dr.getDataObject(); - long t002 = System.currentTimeMillis(); - //ogger.info("Reading " + dataURI + " from hdf5 took: " + (t002-t001)); - //System.out.println("Reading from hdf5 took: " + (t002-t001)); - return data; - } catch (Exception e) { - throw new VizException("Error retrieving data for record:" - + dataURI, e); - } - } + private String getCycleFcstHrsString(ArrayList dataForecastTimes) { + // TODO Auto-generated method stub + StringBuffer resultsBuf = new StringBuffer(); + for (DataTime dt : dataForecastTimes) { + resultsBuf.append(dbtimeToDattim(dt.toString())); + resultsBuf.append("|"); + } + return resultsBuf.substring(0, resultsBuf.length() - 1); + } - public static String getFilename(String dataURI) { - String filename = null; - File file = null; - String path = dataURI.split("/")[3]; - StringBuffer sb = new StringBuffer(64); - String dataDateStr = dataURI.split("/")[2].split("_")[0]; - String dataTimeStr = dataURI.split("/")[2].split("_")[1].split(":")[0] - + dataURI.split("/")[2].split("_")[1].split(":")[1]; - sb.append(dataDateStr); - sb.append("-"); - sb.append(dataTimeStr); - sb.append(".h5"); + private String dbtimeToDattim(String aTime) { + String aDattim = null; + String[] inputStringArray = new String[2]; - //if (DataMode.getSystemMode() == DataMode.THRIFT) { - // file = new File(File.separator + dataURI.split("/")[1] - // + File.separator + path + File.separator + sb.toString()); - //} else if (DataMode.getSystemMode() == DataMode.PYPIES) { - file = new File(dataURI.split("/")[1] + File.separator + path - + File.separator + sb.toString()); - //} else { - // file = new File(VizApp.getDataDir() + File.separator - // + dataURI.split("/")[1] + File.separator + path - // + File.separator + sb.toString()); - //} + CharSequence char0 = "("; + /* + * Process time contains forecast hour info + */ + if (aTime.contains(char0)) { + String zeroes = null; + int ind1 = aTime.indexOf("("); + int ind2 = aTime.indexOf(")"); + if (ind2 - ind1 == 2) { + zeroes = "00"; + } else if (ind2 - ind1 == 3) { + zeroes = "0"; + } + String str1 = aTime.substring(0, ind1 - 1); + String str2 = ""; + if (zeroes != null) { + str2 = "f" + zeroes + aTime.substring(ind1 + 1, ind2); + } else { + str2 = "f" + aTime.substring(ind1 + 1, ind2); + } - if (file != null) - filename = file.getPath(); - return filename; - } - - private static String getGridNavigationContent(ISpatialObject obj) { + if (aTime.contains("_")) { + inputStringArray = str1.split("_"); + } else if (!aTime.contains("_")) { + inputStringArray = str1.split(" "); + } - GridCoverage gc = (GridCoverage) obj; - StringBuffer resultsBuf = new StringBuffer(); + /* + * YYYY-MM-DD HH:MM:SS.S (HHH)-> YYMMDD/HHMMfHHH 2009-10-22 + * 16:00:00.0 (5)-> 091022/1600f005 0123456789 0123456789 + */ + aDattim = inputStringArray[0].substring(2, 4) + + inputStringArray[0].substring(5, 7) + + inputStringArray[0].substring(8, 10) + "/" + + inputStringArray[1].substring(0, 2) + + inputStringArray[1].substring(3, 5) + str2; + } + /* + * Process time that does NOT contain forecast hour info + */ + else { + inputStringArray = aTime.split(" "); - if (gc instanceof LatLonGridCoverage) { - /* - * LatLonGridCoverage - */ - LatLonGridCoverage llgc = (LatLonGridCoverage) gc; - resultsBuf.append("CED"); - resultsBuf.append(";"); - resultsBuf.append(llgc.getNx()); - resultsBuf.append(";"); - resultsBuf.append(llgc.getNy()); - resultsBuf.append(";"); - Double dummy = llgc.getLa1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = llgc.getLo1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = llgc.getLa2() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = llgc.getLo2() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = -9999.0; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = llgc.getDx() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = llgc.getDy() * 10000; - resultsBuf.append(dummy.intValue()); - } else if (gc instanceof LambertConformalGridCoverage) { - resultsBuf.append("LCC"); - resultsBuf.append(";"); - LambertConformalGridCoverage lcgc = (LambertConformalGridCoverage) gc; - resultsBuf.append(lcgc.getNx()); - resultsBuf.append(";"); - resultsBuf.append(lcgc.getNy()); - resultsBuf.append(";"); - Double dummy = lcgc.getLa1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getLo1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getLatin1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getLatin2() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getLov() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getDx() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = lcgc.getDy() * 10000; - resultsBuf.append(dummy.intValue()); - } else if (gc instanceof MercatorGridCoverage) { - MercatorGridCoverage mgc = (MercatorGridCoverage) gc; - resultsBuf.append("MER"); - resultsBuf.append(";"); - resultsBuf.append(mgc.getNx()); - resultsBuf.append(";"); - resultsBuf.append(mgc.getNy()); - resultsBuf.append(";"); - Double dummy = mgc.getLa1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getLo1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getLatin() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getLa2() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getLo2() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getDx() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = mgc.getDy() * 10000; - resultsBuf.append(dummy.intValue()); - } else if (gc instanceof PolarStereoGridCoverage) { - /* - * PolarStereoGridCoverage - */ - PolarStereoGridCoverage psgc = (PolarStereoGridCoverage) gc; - resultsBuf.append("STR"); - resultsBuf.append(";"); - resultsBuf.append(psgc.getNx()); - resultsBuf.append(";"); - resultsBuf.append(psgc.getNy()); - resultsBuf.append(";"); - Double dummy = psgc.getLa1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = psgc.getLo1() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = -9999.0; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = -9999.0; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = psgc.getLov() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = psgc.getDx() * 10000; - resultsBuf.append(dummy.intValue()); - resultsBuf.append(";"); - dummy = psgc.getDy() * 10000; - resultsBuf.append(dummy.intValue()); - } + /* + * YYYY-MM-DD HH:MM:SS.S -> YYMMDD/HHMM 2009-01-20 02:25:00.0 -> + * 090120/0225 0123456789 0123456789 + */ + aDattim = inputStringArray[0].substring(2, 4) + + inputStringArray[0].substring(5, 7) + + inputStringArray[0].substring(8, 10) + "/" + + inputStringArray[1].substring(0, 2) + + inputStringArray[1].substring(3, 5); + } + return aDattim; + } - String content = resultsBuf.toString(); - return content; + /* + * Flips the data from CAVE order and changes the missing data value from + * CAVE -999999.0f to GEMPAK -9999.0f + */ + private float[] flipData(float[] inGrid, int nx, int ny) { - } - - private String executeScript(String scriptToRun) throws VizException { - long t0 = System.currentTimeMillis(); + float[] outGridFlipped = new float[inGrid.length]; - Object[] pdoList; - pdoList = conn.connect(scriptToRun, null, 60000); - String navStr = (String) pdoList[0]; - long t1 = System.currentTimeMillis(); - System.out.println("\texecuteScript(dataURI) took: " + (t1-t0)); - //logger.info("executeScript took: " + (t1-t0)); - return navStr; - } - - private String getDataURI(String parameters) throws VizException { - long t0 = System.currentTimeMillis(); - - String[] parmList = parameters.split("\\|"); - Map queryList = new HashMap(); - if ( !parmList[1].isEmpty()) { -// queryList = inventory.getRequestConstraintMap(parmList[0], parmList[1], -// parmList[2], parmList[3], parmList[4]); - } - else { -// queryList = inventory.getRequestConstraintMap(parmList[0], parmList[2], -// parmList[3], parmList[4]); - } - - String refTimeg = parmList[5].toUpperCase().split("F")[0]; - String refTime = GempakGrid.dattimToDbtime(refTimeg); - refTime = refTime.substring(0, refTime.length()-2); - String fcstTimeg = parmList[5].toUpperCase().split("F")[1]; - String fcstTime = Integer.toString(((Integer.parseInt(fcstTimeg))*3600)); - - - if ( queryList == null ) - return null; - - queryList.put("dataTime.refTime", new RequestConstraint(refTime)); - queryList.put("dataTime.fcstTime", new RequestConstraint(fcstTime)); + int kk = 0; - LayerProperty prop = new LayerProperty(); - prop.setDesiredProduct(ResourceType.PLAN_VIEW); - prop.setEntryQueryParameters(queryList, false); - prop.setNumberOfImages(1); - - String script = null; - script = ScriptCreator.createScript(prop); + for (int jj = 0; jj < ny; jj++) { + int m1 = nx * ny - nx * (jj + 1); + int m2 = nx * ny - nx * jj; + for (int ii = m1; ii < m2; ii++) { + if (inGrid[ii] < -900000.0) { + outGridFlipped[kk] = -9999.0f; + kk++; + } else { + outGridFlipped[kk] = inGrid[ii]; + kk++; + } + } + } - if (script == null) - return null; + return outGridFlipped; + } - Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + /* + * Flops the data from GEMPAK order and changes the missing data value from + * GEMPAK -9999.0f to CAVE -999999.0f + */ + private float[] flopData(float[] inGrid, int nx, int ny) { - GridRecord rec = (GridRecord) pdoList[0]; - long t1 = System.currentTimeMillis(); - System.out.println("\tgetDataURI took: " + (t1-t0)); - //logger.info("getDataURI took: " + (t1-t0)); - return rec.getDataURI(); - } + float[] outGridFlopped = new float[inGrid.length]; + int kk = 0; + for (int jj = ny - 1; jj >= 0; jj--) { + int m1 = nx * jj; + int m2 = m1 + (nx - 1); + for (int ii = m1; ii <= m2; ii++) { + if (inGrid[ii] == -9999.0f) { + outGridFlopped[kk] = -999999.0f; + kk++; + } else { + outGridFlopped[kk] = inGrid[ii]; + kk++; + } + } + + } + return outGridFlopped; + } + + private String getEnsTimes() { + String tmp1 = this.gdfile.substring(this.gdfile.indexOf("{") + 1, + this.gdfile.indexOf("}")); + String[] tmp = tmp1.split(","); + String tmp2 = ""; + for (String st : tmp) { + String tmp3[] = st.split("\\|"); + tmp2 = tmp2 + tmp3[1]; + tmp2 = tmp2 + "|"; + + } + String returnStr = tmp2.substring(0, tmp2.length() - 1); + return returnStr; + } + + private void printInfoMessage(long t) { + String gdFile; + if (this.gdfile.startsWith("{") && this.gdfile.endsWith("}")) { + gdFile = this.gdfile.substring(this.gdfile.indexOf("{") + 1, + this.gdfile.indexOf("}")); + } else { + gdFile = this.gdfile; + } + StringBuilder toprint = new StringBuilder(); + // System.out.print ( "\nCalculating " + gdFile.toUpperCase() + " "); + toprint.append("Requesting " + gdFile.toUpperCase() + " "); + + /* + * if (this.vector) { // System.out.print(this.gvect.toUpperCase()); + * toprint.append(this.gvect.toUpperCase()); } else { // + * System.out.print(this.gfunc.toUpperCase()); + * toprint.append(this.gfunc.trim().toUpperCase()); } + */ + toprint.append(this.gdpfun.trim().toUpperCase()); + + // System.out.print ( " ^" + this.gdattim + " @" + this.glevel + " %" + + // this.gvcord.toUpperCase()); + // System.out.print (" has taken --> " + t + " ms\n"); + // //System.out.println("\nMin: " + resultMin + " Max: " + resultMax + // + "\n"); + toprint.append(" ^" + this.gdattim + " @" + this.glevel + " %" + + this.gvcord.toUpperCase()); + toprint.append(" from " + this.dataSource + " took: " + t + " ms\n"); + // toprint.append("\nMin: " + resultMin + " Max: " + resultMax + + // "\n"); + System.out.println(toprint.toString()); + // logger.info(toprint.toString()); + + } + + private static float[] retrieveData(String dataURI) throws VizException { + + long t001 = System.currentTimeMillis(); + IDataRecord dr = null; + try { + String fileName = getFilename(dataURI); + String dataset = "Data"; + Request request = Request.ALL; + + IDataStore ds = DataStoreFactory.getDataStore(new File(fileName)); + dr = ds.retrieve("", dataURI + "/" + dataset, request); + float[] data = (float[]) dr.getDataObject(); + long t002 = System.currentTimeMillis(); + // ogger.info("Reading " + dataURI + " from hdf5 took: " + + // (t002-t001)); + // System.out.println("Reading from hdf5 took: " + (t002-t001)); + return data; + } catch (Exception e) { + throw new VizException("Error retrieving data for record:" + + dataURI, e); + } + } + + public static String getFilename(String dataURI) { + String filename = null; + File file = null; + String path = dataURI.split("/")[3]; + StringBuffer sb = new StringBuffer(64); + String dataDateStr = dataURI.split("/")[2].split("_")[0]; + String dataTimeStr = dataURI.split("/")[2].split("_")[1].split(":")[0] + + dataURI.split("/")[2].split("_")[1].split(":")[1]; + sb.append(dataDateStr); + sb.append("-"); + sb.append(dataTimeStr); + sb.append(".h5"); + + // if (DataMode.getSystemMode() == DataMode.THRIFT) { + // file = new File(File.separator + dataURI.split("/")[1] + // + File.separator + path + File.separator + sb.toString()); + // } else if (DataMode.getSystemMode() == DataMode.PYPIES) { + file = new File(dataURI.split("/")[1] + File.separator + path + + File.separator + sb.toString()); + // } else { + // file = new File(VizApp.getDataDir() + File.separator + // + dataURI.split("/")[1] + File.separator + path + // + File.separator + sb.toString()); + // } + + if (file != null) + filename = file.getPath(); + return filename; + } + + private static String getGridNavigationContent(ISpatialObject obj) { + + GridCoverage gc = (GridCoverage) obj; + StringBuffer resultsBuf = new StringBuffer(); + + if (gc instanceof LatLonGridCoverage) { + /* + * LatLonGridCoverage + */ + LatLonGridCoverage llgc = (LatLonGridCoverage) gc; + resultsBuf.append("CED"); + resultsBuf.append(";"); + resultsBuf.append(llgc.getNx()); + resultsBuf.append(";"); + resultsBuf.append(llgc.getNy()); + resultsBuf.append(";"); + Double dummy = llgc.getLa1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = llgc.getLo1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = llgc.getLa2() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = llgc.getLo2() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = -9999.0; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = llgc.getDx() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = llgc.getDy() * 10000; + resultsBuf.append(dummy.intValue()); + } else if (gc instanceof LambertConformalGridCoverage) { + resultsBuf.append("LCC"); + resultsBuf.append(";"); + LambertConformalGridCoverage lcgc = (LambertConformalGridCoverage) gc; + resultsBuf.append(lcgc.getNx()); + resultsBuf.append(";"); + resultsBuf.append(lcgc.getNy()); + resultsBuf.append(";"); + Double dummy = lcgc.getLa1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getLo1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getLatin1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getLatin2() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getLov() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getDx() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = lcgc.getDy() * 10000; + resultsBuf.append(dummy.intValue()); + } else if (gc instanceof MercatorGridCoverage) { + MercatorGridCoverage mgc = (MercatorGridCoverage) gc; + resultsBuf.append("MER"); + resultsBuf.append(";"); + resultsBuf.append(mgc.getNx()); + resultsBuf.append(";"); + resultsBuf.append(mgc.getNy()); + resultsBuf.append(";"); + Double dummy = mgc.getLa1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getLo1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getLatin() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getLa2() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getLo2() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getDx() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = mgc.getDy() * 10000; + resultsBuf.append(dummy.intValue()); + } else if (gc instanceof PolarStereoGridCoverage) { + /* + * PolarStereoGridCoverage + */ + PolarStereoGridCoverage psgc = (PolarStereoGridCoverage) gc; + resultsBuf.append("STR"); + resultsBuf.append(";"); + resultsBuf.append(psgc.getNx()); + resultsBuf.append(";"); + resultsBuf.append(psgc.getNy()); + resultsBuf.append(";"); + Double dummy = psgc.getLa1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = psgc.getLo1() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = -9999.0; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = -9999.0; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = psgc.getLov() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = psgc.getDx() * 10000; + resultsBuf.append(dummy.intValue()); + resultsBuf.append(";"); + dummy = psgc.getDy() * 10000; + resultsBuf.append(dummy.intValue()); + } + + String content = resultsBuf.toString(); + return content; + + } + + private String executeScript(String scriptToRun) throws VizException { + long t0 = System.currentTimeMillis(); + + Object[] pdoList; + pdoList = conn.connect(scriptToRun, null, 60000); + String navStr = (String) pdoList[0]; + long t1 = System.currentTimeMillis(); + System.out.println("\texecuteScript(dataURI) took: " + (t1 - t0)); + // logger.info("executeScript took: " + (t1-t0)); + return navStr; + } + + private String getDataURI(String parameters) throws VizException { + long t0 = System.currentTimeMillis(); + + String[] parmList = parameters.split("\\|"); + Map queryList = new HashMap(); + if (!parmList[1].isEmpty()) { + // queryList = inventory.getRequestConstraintMap(parmList[0], + // parmList[1], + // parmList[2], parmList[3], parmList[4]); + } else { + // queryList = inventory.getRequestConstraintMap(parmList[0], + // parmList[2], + // parmList[3], parmList[4]); + } + + String refTimeg = parmList[5].toUpperCase().split("F")[0]; + String refTime = CommonDateFormatUtil.dattimToDbtime(refTimeg); + refTime = refTime.substring(0, refTime.length() - 2); + String fcstTimeg = parmList[5].toUpperCase().split("F")[1]; + String fcstTime = Integer + .toString(((Integer.parseInt(fcstTimeg)) * 3600)); + + if (queryList == null) + return null; + + queryList.put("dataTime.refTime", new RequestConstraint(refTime)); + queryList.put("dataTime.fcstTime", new RequestConstraint(fcstTime)); + + LayerProperty prop = new LayerProperty(); + prop.setDesiredProduct(ResourceType.PLAN_VIEW); + prop.setEntryQueryParameters(queryList, false); + prop.setNumberOfImages(1); + + String script = null; + script = ScriptCreator.createScript(prop); + + if (script == null) + return null; + + Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + + GridRecord rec = (GridRecord) pdoList[0]; + long t1 = System.currentTimeMillis(); + System.out.println("\tgetDataURI took: " + (t1 - t0)); + // logger.info("getDataURI took: " + (t1-t0)); + return rec.getDataURI(); + } + + public void setCycleForecastTimes(ArrayList dataTimes) { + this.dataForecastTimes = dataTimes; + } - public void setCycleForecastTimes(ArrayList dataTimes) { - this.dataForecastTimes = dataTimes; - } - - } - diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java index 7c4da410dc..a4bf48f37f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncgrid/src/gov/noaa/nws/ncep/viz/rsc/ncgrid/rsc/NcgridResource.java @@ -15,6 +15,7 @@ import gov.noaa.nws.ncep.viz.common.preferences.GraphicsAreaPreferences; import gov.noaa.nws.ncep.viz.common.ui.HILORelativeMinAndMaxLocator; import gov.noaa.nws.ncep.viz.common.ui.ModelListInfo; import gov.noaa.nws.ncep.viz.common.ui.color.GempakColor; +import gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil; import gov.noaa.nws.ncep.viz.gempak.util.GempakGrid; import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource; @@ -2970,7 +2971,7 @@ public class NcgridResource extends */ if (posF > posV && posV != 0) { cal = cTime.getRefTimeAsCalendar(); - timestampFormat = "%02d%02d%02d/%02d%02dF%03d"; + timestampFormat = "%02d%02d%02d/%02d%02dF%s"; /* * Legacy behavior will put the forcast time at the next * position after the ^ when there is both ~ and ^ the ^ is @@ -2985,9 +2986,11 @@ public class NcgridResource extends } } else { cal = currFrameTm.getValidTime(); - timestampFormat = "%02d%02d%02d/%02d%02dV%03d"; + timestampFormat = "%02d%02d%02d/%02d%02dV%s"; } - int vTm = cTime.getFcstTime() / 3600; + String forecastTime = CommonDateFormatUtil + .getForecastTimeString(cTime.getFcstTime()); + /* * check '?' flag for day of week */ @@ -3004,7 +3007,7 @@ public class NcgridResource extends (cal.get(Calendar.MONTH) + 1), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), - vTm)); + forecastTime)); deleteWildcard(titleBuilder, "^"); deleteWildcard(titleBuilder, "~"); diff --git a/tests/unit/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtilTest.java b/tests/unit/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtilTest.java new file mode 100644 index 0000000000..3b0aa39878 --- /dev/null +++ b/tests/unit/gov/noaa/nws/ncep/viz/common/util/CommonDateFormatUtilTest.java @@ -0,0 +1,341 @@ +/** + * 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 gov.noaa.nws.ncep.viz.common.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 28, 2014            jbernier     Initial creation
+ * 
+ * 
+ * + * @author jbernier + * @version 1.0 + */ + +public class CommonDateFormatUtilTest { + + private static final int MIN15_IN_SECONDS = 900; + + private static final int HR6_IN_SECONDS = 21600; + + private static final int HR6_15MIN_IN_SECONDS = 22500; + + private static final int HR30_45MIN_IN_SECONDS = 110700; + + private static final int HR36_30MIN_IN_SECONDS = 131400; + + private static final int HR120_IN_SECONDS = 432000; + + private static final int HR136_30MIN_IN_SECONDS = 491400; + + /** + * Test method for + * {@link gov.noaa.nws.ncep.viz.common.util.GempakGrid#dbtimeToDattim(java.lang.String)} + * . + */ + @Test + public void testDbTimeToDattim() { + System.out + .println("------------------Test-case DbTimeToDattim----------------"); + String dbTime1 = "2014-07-24 12:00:00.0"; + String dattim1 = CommonDateFormatUtil.dbtimeToDattim(dbTime1); + System.out.println("AWIPS: " + dbTime1 + " to GEMPAK: " + dattim1); + assertEquals("Actual time did not equal expected time string!", + "140724/120000", dattim1); + + String dbTime2 = "2014-07-25 12:00:00.0 (6)"; + String dattim2 = CommonDateFormatUtil.dbtimeToDattim(dbTime2); + System.out.println("AWIPS: " + dbTime2 + " to GEMPAK: " + dattim2); + assertEquals("Actual time did not equal expected time string!", + "140725/120000f006", dattim2); + + String dbTime3 = "2014-07-26 12:00:00.0 (36)"; + String dattim3 = CommonDateFormatUtil.dbtimeToDattim(dbTime3); + System.out.println("AWIPS: " + dbTime3 + " to GEMPAK: " + dattim3); + assertEquals("Actual time did not equal expected time string!", + "140726/120000f036", dattim3); + + String dbTime4 = "2014-07-27_12:00:00.0 (120)"; + String dattim4 = CommonDateFormatUtil.dbtimeToDattim(dbTime4); + System.out.println("AWIPS: " + dbTime4 + " to GEMPAK: " + dattim4); + assertEquals("Actual time did not equal expected time string!", + "140727/120000f120", dattim4); + + String dbTime5 = "2014-07-30_12:00:00.0 (0:15)"; + String dattim5 = CommonDateFormatUtil.dbtimeToDattim(dbTime5); + System.out.println("AWIPS: " + dbTime5 + " to GEMPAK: " + dattim5); + assertEquals("Actual time did not equal expected time string!", + "140730/120000f00015", dattim5); + + String dbTime6 = "2014-08-08 12:00:00.0 (30:45)"; + String dattim6 = CommonDateFormatUtil.dbtimeToDattim(dbTime6); + System.out.println("AWIPS: " + dbTime6 + " to GEMPAK: " + dattim6); + assertEquals("Actual time did not equal expected time string!", + "140808/120000f03045", dattim6); + + String dbTime7 = "2014-08-07 12:00:00.0 (036:30)"; + String dattim7 = CommonDateFormatUtil.dbtimeToDattim(dbTime7); + System.out.println("AWIPS: " + dbTime7 + " to GEMPAK: " + dattim7); + assertEquals("Actual time did not equal expected time string!", + "140807/120000f03630", dattim7); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#dattimToDbtime(java.lang.String)} + * . + */ + @Test + public void testDattimToDbTime() { + System.out + .println("------------------Test-case DattimToDbTime----------------"); + String dattim1 = "140724/120000"; + String dbTime1 = CommonDateFormatUtil.dattimToDbtime(dattim1); + System.out.println("GEMPAK: " + dattim1 + " to AWIPS: " + dbTime1); + assertEquals("Actual time did not equal expected time string!", + "2014-07-24 12:00:00.0", dbTime1); + // Note: if there is no forecast time the date time is separated with a + // space and not an underscore! + + String dattim2 = "140725/120000f006"; + String dbTime2 = CommonDateFormatUtil.dattimToDbtime(dattim2); + System.out.println("GEMPAK: " + dattim2 + " to AWIPS: " + dbTime2); + assertEquals("Actual time did not equal expected time string!", + "2014-07-25_12:00:00.0_(6)", dbTime2); + + String dattim3 = "140726/120000f036"; + String dbTime3 = CommonDateFormatUtil.dattimToDbtime(dattim3); + System.out.println("GEMPAK: " + dattim3 + " to AWIPS: " + dbTime3); + assertEquals("Actual time did not equal expected time string!", + "2014-07-26_12:00:00.0_(36)", dbTime3); + + String dattim4 = "140727/120000f120"; + String dbTime4 = CommonDateFormatUtil.dattimToDbtime(dattim4); + System.out.println("GEMPAK: " + dattim4 + " to AWIPS: " + dbTime4); + assertEquals("Actual time did not equal expected time string!", + "2014-07-27_12:00:00.0_(120)", dbTime4); + + String dattim5 = "140730/120000f00615"; + String dbTime5 = CommonDateFormatUtil.dattimToDbtime(dattim5); + System.out.println("GEMPAK: " + dattim5 + " to AWIPS: " + dbTime5); + assertEquals("Actual time did not equal expected time string!", + "2014-07-30_12:00:00.0_(6:15)", dbTime5); + + String dattim6 = "140808/120000f03045"; + String dbTime6 = CommonDateFormatUtil.dattimToDbtime(dattim6); + System.out.println("GEMPAK: " + dattim6 + " to AWIPS: " + dbTime6); + assertEquals("Actual time did not equal expected time string!", + "2014-08-08_12:00:00.0_(30:45)", dbTime6); + + String dattim7 = "140807/120000f13630"; + String dbTime7 = CommonDateFormatUtil.dattimToDbtime(dattim7); + System.out.println("GEMPAK: " + dattim7 + " to AWIPS: " + dbTime7); + assertEquals("Actual time did not equal expected time string!", + "2014-08-07_12:00:00.0_(136:30)", dbTime7); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#getForecastTimeInSec(java.lang.String)} + * . + */ + @Test + public void testGetForecastTimeInSec() { + System.out + .println("------------------Test-case GetForecastTimeInSec----------------"); + String aTime1 = "140724/120000"; + int forecastTimeInSec1 = CommonDateFormatUtil + .getForecastTimeInSec(aTime1); + System.out.println("Forecast time: " + aTime1 + " in Seconds: " + + forecastTimeInSec1); + assertEquals("Actual time in seconds did not equal expected time!", 0, + forecastTimeInSec1); + // Note: if there is no forecast time this method returns 0 + + String aTime2 = "2014-07-25_12:00:00.0_(6)"; + int forecastTimeInSec2 = CommonDateFormatUtil + .getForecastTimeInSec(aTime2); + System.out.println("Forecast time: " + aTime2 + " in Seconds: " + + forecastTimeInSec2); + assertEquals("Actual time in seconds did not equal expected time!", + HR6_IN_SECONDS, forecastTimeInSec2); + + String aTime3 = "140730/120000f00615"; + int forecastTimeInSec3 = CommonDateFormatUtil + .getForecastTimeInSec(aTime3); + System.out.println("Forecast time: " + aTime3 + " in Seconds: " + + forecastTimeInSec3); + assertEquals("Actual time in seconds did not equal expected time!", + HR6_15MIN_IN_SECONDS, forecastTimeInSec3); + + String aTime4 = "2014-08-08_12:00:00.0_(30:45)"; + int forecastTimeInSec4 = CommonDateFormatUtil + .getForecastTimeInSec(aTime4); + System.out.println("Forecast time: " + aTime4 + " in Seconds: " + + forecastTimeInSec4); + assertEquals("Actual time in seconds did not equal expected time!", + HR30_45MIN_IN_SECONDS, forecastTimeInSec4); + + String aTime5 = "140807/120000f13630"; + int forecastTimeInSec5 = CommonDateFormatUtil + .getForecastTimeInSec(aTime5); + System.out.println("Forecast time: " + aTime5 + " in Seconds: " + + forecastTimeInSec5); + assertEquals("Actual time in seconds did not equal expected time!", + HR136_30MIN_IN_SECONDS, forecastTimeInSec5); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#getForecastTimeString(java.lang.String)} + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#getForecastTimeString(int)} + * . + */ + @Test + public void testGetForecastTimeString() { + System.out + .println("------------------Test-case GetForecastTimeString----------------"); + String aTime = "140725/120000f006"; + int secTime = HR6_IN_SECONDS; + String forecastTimeFromString = CommonDateFormatUtil + .getForecastTimeString(aTime); + String forecastTimeFromInt = CommonDateFormatUtil + .getForecastTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", "006", + forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", "006", + forecastTimeFromInt); + + aTime = "2014-07-27_12:00:00.0 (120)"; + secTime = HR120_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", "120", + forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", "120", + forecastTimeFromInt); + + aTime = "140730/120000f00015"; + secTime = MIN15_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", + "00015", forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", + "00015", forecastTimeFromInt); + + aTime = "2014-08-07 12:00:00.0 (036:30)"; + secTime = HR36_30MIN_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", + "03630", forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", + "03630", forecastTimeFromInt); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#getForecastColonTimeString(java.lang.String)} + * {@link gov.noaa.nws.ncep.viz.common.util.CommonDateFormatUtil#getForecastColonTimeString(int)} + * . + */ + @Test + public void testGetForecastColonTimeString() { + System.out + .println("------------------Test-case GetForecastColonTimeString----------------"); + String aTime = "140725/120000f006"; + int secTime = HR6_IN_SECONDS; + String forecastTimeFromString = CommonDateFormatUtil + .getForecastColonTimeString(aTime); + String forecastTimeFromInt = CommonDateFormatUtil + .getForecastColonTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", "6", + forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", "6", + forecastTimeFromInt); + + aTime = "2014-07-27_12:00:00.0 (120)"; + secTime = HR120_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastColonTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastColonTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", "120", + forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", "120", + forecastTimeFromInt); + + aTime = "140730/120000f00015"; + secTime = MIN15_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastColonTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastColonTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", "0:15", + forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", "0:15", + forecastTimeFromInt); + + aTime = "2014-08-07 12:00:00.0 (036:30)"; + secTime = HR36_30MIN_IN_SECONDS; + forecastTimeFromString = CommonDateFormatUtil + .getForecastColonTimeString(aTime); + forecastTimeFromInt = CommonDateFormatUtil + .getForecastColonTimeString(secTime); + System.out.println("Time: " + aTime + " forecast in seconds: " + + secTime + " to time string: " + forecastTimeFromInt); + assertEquals("Actual time did not equal expected time string!", + "36:30", forecastTimeFromString); + assertEquals("Actual time did not equal expected time string!", + "36:30", forecastTimeFromInt); + } +} \ No newline at end of file From f7516386a89fb762adde3c7a00e75cb79a7402fc Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Fri, 10 Oct 2014 08:58:46 -0400 Subject: [PATCH 07/19] VLab Issue #4078 - Initial check in for Real Time Kp Monitor Change-Id: I00ec615c17cb0f1de9ee156781b285ff069758ba Former-commit-id: ea95039dbe1f706c0753249a0dd9903183b435e1 [formerly ea95039dbe1f706c0753249a0dd9903183b435e1 [formerly 3fe7fad9e949f70c31b709084d2ff1c4dd34435c]] Former-commit-id: 9c531b20ec2696135173a58f66f6171138f3cc55 Former-commit-id: 43c5278a4bbe659c8c02990ba208beee1a3c5d1f --- .../feature.xml | 7 + ...f.common.serialization.ISerializableObject | 13 +- .../res/scripts/state.sql | 3 + .../common/dataplugin/geomag/GeoMagK1min.java | 14 +- .../dataplugin/geomag/GeoMagK3hrState.java | 126 ++ .../common/dataplugin/geomag/GeoMagState.java | 102 ++ .../geomag/GeoMagStationStateChange.java | 134 ++ .../geomag/calculation/CalcUtil.java | 6 +- .../dataplugin/geomag/dao/GeoMagAvgDao.java | 4 +- .../dataplugin/geomag/dao/GeoMagDao.java | 73 +- .../dataplugin/geomag/dao/GeoMagK1minDao.java | 289 +++- .../dataplugin/geomag/dao/GeoMagK3hrDao.java | 70 +- .../geomag/dao/GeoMagK3hrStateDao.java | 457 ++++++ .../dataplugin/geomag/dao/GeoMagStateDao.java | 107 ++ .../dao/GeoMagStationStateChangeDao.java | 110 ++ .../request/ChangeStationStateRequest.java | 81 + .../geomag/request/DatabaseUtil.java | 2 +- .../request/RetrieveGeoMagDataRequest.java | 102 ++ .../geomag/request/RetrieveK1minRequest.java | 51 +- .../request/RetrieveStationStateRequest.java | 90 ++ .../geomag/table/GeoMagStation.java | 460 +++--- .../geomag/table/GeoMagStationList.java | 82 +- .../table/GeoMagStationTableReaderWriter.java | 93 ++ .../geomag/table/TestGeoMagStationsTable.java | 4 +- .../geomag/util/GeoMagStationLookup.java | 179 ++- .../geomag/util/TableTimeStamp.java | 48 +- .../res/spring/geomag-request.xml | 24 + .../edex/plugin/geomag/TrigKCalculation.java | 22 +- .../ChangeStationStateRequestHandler.java | 116 ++ .../RetrieveGeoMagDataRequestHandler.java | 67 + .../handler/RetrieveK1minRequestHandler.java | 41 +- .../RetrieveStationStateRequestHandler.java | 73 + .../base/ncep/geomag/geoMagStations.xml | 87 +- .../viz/common/display/NcDisplayType.java | 9 +- .../ncep/Bundles/GeoMagHDQdcPlots.xml | 223 +++ .../ncep/Bundles/GeoMagRTKpMonitorPlots.xml | 110 ++ .../ncep/DefaultRBDs/defaultRTKpRBD.xml | 220 +++ .../ncep/ResourceDefns/ResourceFilters.xml | 30 +- .../ncep/viz/localization/NcPathManager.java | 7 + .../icons/patt0.gif | Bin 0 -> 824 bytes .../icons/patt1.gif | Bin 0 -> 964 bytes .../icons/patt2.gif | Bin 0 -> 959 bytes .../icons/patt3.gif | Bin 0 -> 1081 bytes .../icons/patt4.gif | Bin 0 -> 1323 bytes .../icons/patt5.gif | Bin 0 -> 893 bytes .../icons/patt6.gif | Bin 0 -> 1005 bytes .../icons/patt7.gif | Bin 0 -> 92 bytes .../icons/patt8.gif | Bin 0 -> 95 bytes .../DayNightTerminatorOverlay.xml | 25 + .../gov.noaa.nws.ncep.viz.overlays/plugin.xml | 131 ++ ...ngeDayNightTerminatorAttributesDialog.java | 1377 ++++++++++++++++ .../DayNightTerminatorOverlayResource.java | 1403 +++++++++++++++++ ...DayNightTerminatorOverlayResourceData.java | 365 +++++ .../viz/overlays/resources/SunPosition.java | 435 +++++ .../timeline/GraphTimelineControl.java | 127 +- .../ui/createRbd/CreateRbdControl.java | 89 +- .../ui/loadRbd/EditRbdDialog.java | 109 +- .../ui/loadRbd/LoadRbdControl.java | 185 +-- .../viz/resources/manager/AbstractRBD.java | 7 + .../resources/manager/ResourceBndlLoader.java | 11 +- .../resources/manager/ResourceCategory.java | 2 +- .../resources/manager/ResourceDefinition.java | 9 +- .../resources/time_match/NCTimeMatcher.java | 15 +- .../ncep/resourceTemplates/GeoMag.xml | 6 +- .../plugin.xml | 18 +- .../viz/rsc/timeseries/GeoMagDescriptor.java | 69 + .../ncep/viz/rsc/timeseries/GeoMagGraph.java | 28 +- .../rsc/EditTimeSeriesAttrsDialog.java | 8 +- .../rsc/timeseries/rsc/GeoMagResource.java | 156 +- .../timeseries/rsc/GeoMagResourceData.java | 25 + .../timeseries/rsc/SamplingInputAdapter.java | 94 +- ncep/gov.noaa.nws.ncep.viz.rtkp/.classpath | 7 + ncep/gov.noaa.nws.ncep.viz.rtkp/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 11 + .../META-INF/MANIFEST.MF | 43 + .../build.properties | 5 + .../gov.noaa.nws.ncep.viz.rtkp.ecl | 0 ncep/gov.noaa.nws.ncep.viz.rtkp/plugin.xml | 152 ++ .../gov/noaa/nws/ncep/viz/rtkp/Activator.java | 79 + .../ncep/viz/rtkp/GeoMagRTKpDescriptor.java | 57 + .../nws/ncep/viz/rtkp/GeoMagRTKpGraph.java | 626 ++++++++ .../viz/rtkp/GeoMagRTKpTimeSeriesAdapter.java | 135 ++ .../nws/ncep/viz/rtkp/KpPlotCapability.java | 153 ++ .../nws/ncep/viz/rtkp/KsPlotCapability.java | 361 +++++ .../ncep/viz/rtkp/MagActivityCapability.java | 378 +++++ .../rtkp/RTKpTimeSeriesRenderableDisplay.java | 48 + .../actions/EditKpPlotAttributesAction.java | 86 + .../actions/EditKsPlotAttributesAction.java | 86 + .../EditMagActivityAttributesAction.java | 105 ++ .../viz/rtkp/actions/GeoMagRTKpAction.java | 120 ++ .../actions/GeoMagRTKpDataBlockAction.java | 65 + .../actions/GeoMagRTKpRecentKpEstAction.java | 65 + .../controls/EditKpPlotAttributesDialog.java | 305 ++++ .../controls/EditKsPlotAttributesDialog.java | 476 ++++++ .../EditMagActivityAttributesDialog.java | 504 ++++++ .../viz/rtkp/controls/EditNetworkDialog.java | 398 +++++ .../rtkp/controls/GeoMagAnalysisPlotDlg.java | 569 +++++++ .../rtkp/controls/GeoMagRTKpPlotDialog.java | 329 ++++ .../palette/GeoMagRTKpDataBlockWindow.java | 861 ++++++++++ .../palette/GeoMagRTKpRecentKpWindow.java | 334 ++++ .../palette/IGeoMagRTKpDataBlockListener.java | 31 + .../ncep/viz/rtkp/rsc/GeoMagRTKpResource.java | 523 ++++++ .../viz/rtkp/rsc/GeoMagRTKpResourceData.java | 264 ++++ .../nws/ncep/viz/rtkp/rsc/GeoMagSampling.java | 466 ++++++ .../rsc/GeoMagWorldActivityMouseHandler.java | 263 +++ .../rtkp/rsc/GeoMagWorldActivityResource.java | 822 ++++++++++ .../rsc/GeoMagWorldActivityResourceData.java | 209 +++ .../GeoMagWorldActivityTitleDateResource.java | 152 ++ ...MagWorldActivityTitleDateResourceData.java | 140 ++ .../util/GeoMagTimeSeriesDataException.java | 68 + .../rtkp/util/RTKpTimeSeriesZoomHandler.java | 46 + .../noaa/nws/ncep/viz/rtkp/util/RTKpUtil.java | 1136 +++++++++++++ .../viz/ui/display/AbstractNcPaneManager.java | 15 +- .../NCTimeSeriesRenderableDisplay.java | 25 +- .../plugin.xml | 14 +- .../viz/ui/perspectives/NCPerspective.java | 7 + 116 files changed, 18229 insertions(+), 768 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/res/scripts/state.sql create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK3hrState.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagState.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagStationStateChange.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrStateDao.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStateDao.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStationStateChangeDao.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/ChangeStationStateRequest.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveGeoMagDataRequest.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveStationStateRequest.java create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationTableReaderWriter.java create mode 100644 ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/ChangeStationStateRequestHandler.java create mode 100644 ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveGeoMagDataRequestHandler.java create mode 100644 ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveStationStateRequestHandler.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagHDQdcPlots.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagRTKpMonitorPlots.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/DefaultRBDs/defaultRTKpRBD.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt0.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt1.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt2.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt3.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt4.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt5.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt6.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt7.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt8.gif create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/localization/ncep/resourceTemplates/DayNightTerminatorOverlay.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/dialogs/ChangeDayNightTerminatorAttributesDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResource.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResourceData.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/SunPosition.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/.classpath create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/.project create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/.settings/org.eclipse.jdt.core.prefs create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/META-INF/MANIFEST.MF create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/build.properties create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/gov.noaa.nws.ncep.viz.rtkp.ecl create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/plugin.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/Activator.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpDescriptor.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpGraph.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpTimeSeriesAdapter.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KpPlotCapability.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KsPlotCapability.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/MagActivityCapability.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/RTKpTimeSeriesRenderableDisplay.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKpPlotAttributesAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKsPlotAttributesAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditMagActivityAttributesAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpDataBlockAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpRecentKpEstAction.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKpPlotAttributesDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKsPlotAttributesDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditMagActivityAttributesDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditNetworkDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagAnalysisPlotDlg.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagRTKpPlotDialog.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpDataBlockWindow.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpRecentKpWindow.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/IGeoMagRTKpDataBlockListener.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResource.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResourceData.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagSampling.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityMouseHandler.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResource.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResourceData.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResource.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResourceData.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/GeoMagTimeSeriesDataException.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpTimeSeriesZoomHandler.java create mode 100644 ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpUtil.java diff --git a/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml b/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml index bad6bb8bac..635e3b0427 100644 --- a/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml @@ -328,4 +328,11 @@ version="0.0.0" unpack="false"/> + + diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject index 475d3540f3..2e011df45a 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -1,4 +1,15 @@ gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagAvg gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min -gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hr \ No newline at end of file +gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hr +gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagState +gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hrState +gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagStationStateChange +gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStationList +gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation +gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagSource +gov.noaa.nws.ncep.common.dataplugin.geomag.table.Location +gov.noaa.nws.ncep.common.dataplugin.geomag.table.DataFormat +gov.noaa.nws.ncep.common.dataplugin.geomag.table.RawDataFormat +gov.noaa.nws.ncep.common.dataplugin.geomag.table.HeaderFormat +gov.noaa.nws.ncep.common.dataplugin.geomag.table.Group diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/res/scripts/state.sql b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/res/scripts/state.sql new file mode 100644 index 0000000000..af0662453f --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/res/scripts/state.sql @@ -0,0 +1,3 @@ +INSERT INTO awips.geomag_states VALUES (1,'Process'); +INSERT INTO awips.geomag_states VALUES (2,'Algorithm'); +INSERT INTO awips.geomag_states VALUES (3,'Active'); \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK1min.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK1min.java index dcc15f244d..2e19bd0442 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK1min.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK1min.java @@ -29,7 +29,9 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * Date Ticket# Engineer Description * ------------ ---------- ---------------- -------------------------- * 08/14/2013 T989 qzhou Initial creation. - * 03/03/2014 #1110 qzhou modified get/set + * 03/03/2014 #1110 qzhou modified get/set + * 04/05/2014 R4078 sgurung Added method match(). + * * * * @author qzhou @@ -365,4 +367,14 @@ public class GeoMagK1min extends PersistableDataObject { public void setStationCode(String stationCode) { this.stationCode = stationCode; } + + public boolean match(Date refTime, String stationCode) { + if (this.refTime.compareTo(refTime) == 0 + && this.stationCode.equals(stationCode)) { + return true; + } else { + return false; + } + + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK3hrState.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK3hrState.java new file mode 100644 index 0000000000..a99516e3ef --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagK3hrState.java @@ -0,0 +1,126 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Record implementation for geomag_K3hr_state. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +@Entity +@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "geomagk3hrstateseq") +@Table(name = "geomag_k3hr_state", uniqueConstraints = { @UniqueConstraint(columnNames = { + "k3hrId", "stateId" }) }) +@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class GeoMagK3hrState extends PersistableDataObject { + + private static final long serialVersionUID = 1L; + + public static final String ID_GEN = "idgen"; + + /** The id */ + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_GEN) + private Integer id; + + /** + * station state id + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private Integer stateId; + + @Column + @XmlAttribute + @DynamicSerializeElement + private Integer k3hrId; + + /** + * + * @return id + */ + public Integer getId() { + return id; + } + + /** + * + * @param id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * + * @return stateId + */ + public Integer getStateId() { + return stateId; + } + + /** + * + * @param stateId + */ + public void setStateId(Integer stateId) { + this.stateId = stateId; + } + + /** + * + * @return k3hrId + */ + public Integer getK3hrId() { + return k3hrId; + } + + /** + * + * @param k3hrStateId + */ + public void setK3hrId(Integer k3hrId) { + this.k3hrId = k3hrId; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagState.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagState.java new file mode 100644 index 0000000000..a8740fbb8f --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagState.java @@ -0,0 +1,102 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Record implementation for geomag station state. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +@Entity +@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "geomagstateseq") +@Table(name = "geomag_states", uniqueConstraints = { @UniqueConstraint(columnNames = { "processingState" }) }) +@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class GeoMagState extends PersistableDataObject { + + private static final long serialVersionUID = 1L; + + public static final String ID_GEN = "idgen"; + + /** The id */ + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_GEN) + private Integer stateId; + + /** + * processing state + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private String processingState; + + /** + * @return the stateId + */ + public Integer getStateId() { + return stateId; + } + + /** + * @param stateId + */ + public void setStateId(Integer stateId) { + this.stateId = stateId; + } + + /** + * + * @return processingState + */ + public String getProcessingState() { + return processingState; + } + + /** + * + * @param processingState + */ + public void setProcessingState(String processingState) { + this.processingState = processingState; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagStationStateChange.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagStationStateChange.java new file mode 100644 index 0000000000..a8e8d1697c --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/GeoMagStationStateChange.java @@ -0,0 +1,134 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Record implementation for geomag station state. Tracks all the magnetometers + * station state changes. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +@Entity +@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "geomagstatechangeseq") +@Table(name = "geomag_station_state_changes") +@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class GeoMagStationStateChange extends PersistableDataObject { + + private static final long serialVersionUID = 1L; + + public static final String ID_GEN = "idgen"; + + /** The id */ + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_GEN) + private Integer id; + + /** + * station code + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private String stationCode; + + /** + * issued action + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private String issuedAction; + + /** + * insert time tag + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private Date insertTime; + + public String getStationCode() { + return stationCode; + } + + /** + * + * @param stationCode + */ + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } + + /** + * + * @return issuedAction + */ + public String getIssuedAction() { + return issuedAction; + } + + /** + * + * @param issuedAction + */ + public void setIssuedAction(String issuedAction) { + this.issuedAction = issuedAction; + } + + /** + * + * @return insertTime + */ + public Date getInsertTime() { + return insertTime; + } + + /** + * + * @param insertTime + */ + public void setInsertTime(Date insertTime) { + this.insertTime = insertTime; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java index 3028d96a35..d31e20738c 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java @@ -23,7 +23,6 @@ import java.util.Map; * ----------- ---------- ---------- -------------------------- * 05/14/2013 #989 qzhou Initial Creation * 06/23/2014 R4152 qzhou Touched up 3 functions - * 07/22/2014 R4152 qzhou Fixed getMedian. This func. is uesd very rare if ever * * * @author qzhou @@ -535,10 +534,11 @@ public class CalcUtil { // remove missing data List newArray = new ArrayList(); - for (int k = 0; k < arraySort.length; k++) { + for (int k = 0; k < arraySort.length - 1; k++) if (arraySort[k] != MISSING_VAL) newArray.add(arraySort[k]); - } + else + break; // to sorted arraySort int size = newArray.size(); if (size % 2 == 0) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagAvgDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagAvgDao.java index cc410a9ab2..db67fad82b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagAvgDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagAvgDao.java @@ -96,8 +96,8 @@ public class GeoMagAvgDao extends CoreDao { public int purgeDataByRefTime(Date refTime) throws DataAccessLayerException { DatabaseQuery deleteStmt = new DatabaseQuery(this.daoClass); - // add 30 minutes to get hourly average reference time - Date avgTime = new Date(refTime.getTime() + (30 * 60000)); + // subtract 30 minutes to get hourly average reference time + Date avgTime = new Date(refTime.getTime() - (30 * 60000)); deleteStmt.addQueryParam("avgTime", avgTime); return this.deleteByCriteria(deleteStmt); } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagDao.java index 5de25009b1..e02611489e 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagDao.java @@ -9,6 +9,15 @@ import java.util.Date; import java.util.List; import java.util.Map; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; + import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.common.dataplugin.persist.IPersistable; import com.raytheon.uf.common.datastorage.IDataStore; @@ -30,6 +39,7 @@ import com.raytheon.uf.edex.database.purge.PurgeLogger; * ------------ ---------- ----------- -------------------------- * 04/2013 975 S. Gurung Initial Creation * 07/16/2013 975 Q. Zhou Added fields. + * 07/02/2014 R4078 S. Gurung Added k3hrStateDao, methods getGeoMagRecords() and getGeoMagRecordsCount() * * * @author sgurung @@ -44,6 +54,8 @@ public class GeoMagDao extends PluginDao { private GeoMagK1minDao k1minDao = new GeoMagK1minDao(); + private GeoMagK3hrStateDao k3hrStateDao = new GeoMagK3hrStateDao(); + public GeoMagDao(String pluginName) throws PluginException { super(pluginName); } @@ -61,12 +73,21 @@ public class GeoMagDao extends PluginDao { int results = super.purgeDataByRefTime(refTime, productKeys, trackHdf5, trackToUri, hdf5FileToUriPurged); - // delete expired data from geomag_k1min, geomag_houravg and geomag_k3hr + // delete expired data from geomag_k1min, geomag_houravg, geomag_k3hr + // and geomag_k3hr_state // tables try { avgDao.purgeDataByRefTime(refTime); k1minDao.purgeDataByRefTime(refTime); + + // purge states associated with k3hr record with the given refTime + List k3hrList = k3hrDao.getK3hr(null, refTime); + for (GeoMagK3hr k3hr : k3hrList) { + k3hrStateDao.purgeDataByK3hrId(k3hr.getId()); + } + k3hrDao.purgeDataByRefTime(refTime); + } catch (Exception e) { PurgeLogger .logError( @@ -298,4 +319,54 @@ public class GeoMagDao extends PluginDao { public void setGeoMagK3hrDao(GeoMagK3hrDao k3hrDao) { this.k3hrDao = k3hrDao; } + + @SuppressWarnings("unchecked") + public List getGeoMagRecords(final String stationCode, + final Date start, final Date end, final int sourceId) { + + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess.createCriteria(GeoMagRecord.class); + Criterion where1 = Restrictions.eq("stationCode", + stationCode); + crit.add(where1); + Criterion where2 = Restrictions + .eq("sourceId", sourceId); + crit.add(where2); + Criterion where3 = Restrictions.between( + "dataTime.refTime", start, end); + crit.add(where3); + crit.addOrder(Order.asc("dataTime.refTime")); + return crit.list(); + } + }); + } + + @SuppressWarnings("unchecked") + public Integer getGeoMagRecordsCount(final String stationCode, + final Date start, final Date end, final int sourceId) { + + return (Integer) txTemplate.execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory().getCurrentSession(); + Criteria crit = sess.createCriteria(GeoMagRecord.class); + Criterion where1 = Restrictions.eq("stationCode", stationCode); + crit.add(where1); + Criterion where2 = Restrictions.eq("sourceId", sourceId); + crit.add(where2); + + if (crit.list() != null) + return crit.list().size(); + else + return 0; + } + }); + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK1minDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK1minDao.java index 454c24d1c2..9df66c4a5a 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK1minDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK1minDao.java @@ -2,12 +2,18 @@ package gov.noaa.nws.ncep.common.dataplugin.geomag.dao; import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.transaction.TransactionStatus; @@ -27,7 +33,9 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; * ------------ ---------- ---------------- -------------------------- * 08/14/2013 T989 qzhou Initial creation. * 03/03/2014 #1110 qzhou Added method getRangeK1min(), Cleaned code - * 03/13/2014 sgurung Added method purgeDataByRefTime() + * 03/13/2014 sgurung Added method purgeDataByRefTime() * + * 04/05/2014 R4078 sgurung Added methods getEstKIndex1min(), getEstKpIndex1min(), + * getLatestEstKIndex() and getLastDataDate(). * * * @author qzhou @@ -35,6 +43,10 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; */ public class GeoMagK1minDao extends CoreDao { + + /** The logger */ + protected transient Log logger = LogFactory.getLog(getClass()); + /** * Creates a new GeoMagK1minDao */ @@ -66,6 +78,7 @@ public class GeoMagK1minDao extends CoreDao { crit.add(where2); Criterion where3 = Restrictions.lt("refTime", end); crit.add(where3); + crit.addOrder(Order.asc("refTime")); return crit.list(); } @@ -94,6 +107,280 @@ public class GeoMagK1minDao extends CoreDao { }); } + @SuppressWarnings("unchecked") + public List getEstKIndex1min(final List stations, + final Date start, final Date end) { + + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess.createCriteria(GeoMagK1min.class); + if (stations != null) { + Criterion where1 = Restrictions.in("stationCode", + stations); + crit.add(where1); + } + Criterion where2 = Restrictions.gt("refTime", start); + crit.add(where2); + Criterion where3 = Restrictions.le("refTime", end); + crit.add(where3); + // Criterion where4 = Restrictions.ge("ks", 9.0); + // crit.add(where4); + crit.addOrder(Order.asc("refTime")); + crit.addOrder(Order.asc("stationCode")); + return crit.list(); + } + }); + } + + /** + * Retrieves data from geomag_k1min table for the provided list of stations, + * given start date and end date.
+ * + * @param stations + * A list of stations + * @param start + * start date + * @param end + * end date + * @return List of data map containing "reftime", "ks_avg", "station_count" + * @throws Exception + */ + public List> getEstKpIndex1min( + final List stations, final Date start, final Date end) + throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT a.reftime, AVG(a.ks) ks_avg, COUNT(a.stationcode) station_count FROM geomag_k1min a "); + sql.append(" INNER JOIN geomag_k3hr b ON b.stationcode = a.stationcode "); + sql.append(" INNER JOIN geomag_k3hr_state c ON c.k3hrid = b.id "); + sql.append(" INNER JOIN geomag_states d ON d.stateid = c.stateid "); + sql.append(" WHERE "); + if (stations != null) { + sql.append(" a.stationcode IN ('"); + + String station = null; + for (int i = 0; i < stations.size(); i++) { + station = stations.get(i); + sql.append(station).append("'"); + if (i != (stations.size() - 1)) { + sql.append(",'"); + } + + } + sql.append(") AND"); + } + sql.append(" a.reftime > '"); + sql.append(start).append("' AND a.reftime <= '").append(end) + .append("'"); + sql.append(" AND a.ks <= 9.0 "); + sql.append(" AND d.processingstate <= 'Active' "); + sql.append(" AND b.reftime = date_trunc('hour', a.reftime - cast(date_part('HOUR',a.reftime) as bigint) % 3 * INTERVAL '1 hour' + interval '0 hour') "); + sql.append(" GROUP BY a.reftime ORDER BY a.reftime ASC"); + + // logger.info(" Inside GeoMagK1minDao.getEstKpIndex1min(), sql = " + // + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return new ArrayList>(); + } + + String[] fieldNames = { "reftime", "ks_avg", "station_count" }; + List> resultMaps = new ArrayList>( + results.length); + for (Object obj : results) { + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + Map resultMap = new HashMap( + objs.length * 2); + for (int i = 0; i < fieldNames.length; ++i) { + resultMap.put(fieldNames[i], objs[i]); + } + resultMaps.add(resultMap); + } + + return resultMaps; + + } + + /** + * Get a list of maps containing the latest estimate kindex and ks values + * for a given list of station codes, start and end dates. + * + * @param stationCodes + * A list of station codes + * @param startTime + * start date + * @param endTime + * end date + * @return List + */ + public List> getLatestEstKIndex( + final List stationCodes, final Date start, final Date end) + throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" select a.stationcode, a.reftime, a.kestindex, ks from geomag_k1min a " + + " inner join (SELECT max(reftime) as latestreftime, stationcode FROM geomag_k1min "); + + if (stationCodes != null || (start != null && end != null)) { + sql.append(" WHERE "); + + if (stationCodes != null) { + sql.append(" stationcode IN ('"); + + String station = null; + for (int i = 0; i < stationCodes.size(); i++) { + station = stationCodes.get(i); + sql.append(station).append("'"); + if (i != (stationCodes.size() - 1)) { + sql.append(",'"); + } + + } + sql.append(" ) "); + } + + if ((stationCodes != null) && (start != null && end != null)) { + sql.append(" AND "); + } + + if (start != null && end != null) { + sql.append(" reftime > '"); + sql.append(start).append("' AND reftime <= '").append(end) + .append("'"); + } + } + + sql.append(" group by stationcode) b " + + " ON a.stationcode = b.stationcode " + + " AND a.reftime = b.latestreftime"); + + sql.append(" order by a.stationcode asc "); + + // logger.info(" Inside GeoMagK1minDao.getLatestEstKIndex(), sql = " + // + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return new ArrayList>(); + } + + String[] fieldNames = { "stationcode", "reftime", "kestindex", "ks" }; + List> resultMaps = new ArrayList>( + results.length); + for (Object obj : results) { + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + Map resultMap = new HashMap( + objs.length * 2); + for (int i = 0; i < fieldNames.length; ++i) { + resultMap.put(fieldNames[i], objs[i]); + + } + resultMaps.add(resultMap); + } + + return resultMaps; + + } + + /** + * Get a list of maps containing the latest estimate kindex and ks values + * for a given list of station codes, start and end dates. + * + * @param stationCodes + * A list of station codes + * @param startTime + * start date + * @param endTime + * end date + * @return List + */ + public Date getLastDataDate(final List stationCodes, + final Date start, final Date end) throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" select max(reftime) as lastDataDate from geomag_k1min "); + + if (stationCodes != null || (start != null && end != null)) { + sql.append(" WHERE "); + + if (stationCodes != null) { + sql.append(" stationcode IN ('"); + + String station = null; + for (int i = 0; i < stationCodes.size(); i++) { + station = stationCodes.get(i); + sql.append(station).append("'"); + if (i != (stationCodes.size() - 1)) { + sql.append(",'"); + } + + } + sql.append(" ) "); + } + + if ((stationCodes != null) && (start != null && end != null)) { + sql.append(" AND "); + } + + if (start != null && end != null) { + sql.append(" reftime > '"); + sql.append(start).append("' AND reftime <= '").append(end) + .append("'"); + } + + sql.append(" AND ks <= 9.0 "); + } + + // logger.info(" Inside GeoMagK1minDao.getLastDataDate(), sql = " + // + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return new Date(); + } + + Date lastDataDate = new Date(); + String[] fieldNames = { "lastDataDate" }; + for (Object obj : results) { + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + lastDataDate = (Date) objs[0]; + } + + return lastDataDate; + + } + public int purgeDataByRefTime(Date refTime) throws DataAccessLayerException { DatabaseQuery deleteStmt = new DatabaseQuery(this.daoClass); deleteStmt.addQueryParam("refTime", refTime); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrDao.java index 7fb3100db0..f56a19d098 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrDao.java @@ -5,6 +5,8 @@ import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hr; import java.util.Date; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Criterion; @@ -27,6 +29,7 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; * ------------ ---------- ---------------- -------------------------- * 08/14/2013 T989 qzhou Initial creation. * 03/13/2014 sgurung Added method purgeDataByRefTime() + * 07/01/2014 R4078 sgurung Added method getStationMaxPrevTime() * * * @author qzhou @@ -34,6 +37,10 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; */ public class GeoMagK3hrDao extends CoreDao { + + /** The logger */ + protected transient Log logger = LogFactory.getLog(getClass()); + /** * Creates a new GribModelDao */ @@ -68,26 +75,77 @@ public class GeoMagK3hrDao extends CoreDao { } @SuppressWarnings("unchecked") - public List getSingleK3hr(final String stationCode, - final Date time) { + public List getK3hr(final String stationCode, final Date time) { return (List) txTemplate.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { HibernateTemplate ht = getHibernateTemplate(); Session sess = ht.getSessionFactory().getCurrentSession(); Criteria crit = sess.createCriteria(GeoMagK3hr.class); - Criterion where1 = Restrictions.eq("stationCode", stationCode); - crit.add(where1); - Criterion where2 = Restrictions.eq("refTime", time); - crit.add(where2); + if (stationCode != null) { + Criterion where1 = Restrictions.eq("stationCode", + stationCode); + crit.add(where1); + } + if (time != null) { + Criterion where2 = Restrictions.eq("refTime", time); + crit.add(where2); + } return crit.list(); } }); } + /** + * Returns the record with the max previous time for a given station and + * time tag
+ * + * @param stationCode + * stationCode + * @param reftime + * time tag + * @return GeoMagK3hr + * @throws Exception + */ + public Date getStationMaxPrevTime(final String stationCode, + final Date reftime) throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT reftime FROM geomag_k3hr " + + " WHERE stationcode = '" + stationCode + "'" + + " AND reftime < '" + reftime + "'"); + sql.append(" ORDER BY reftime DESC"); + sql.append(" LIMIT 1"); + + // logger.info("Inside GeoMagK3hrDao.getStationMaxPrevTime(), sql = " + // + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return null; + } + + String[] fieldNames = { "reftime" }; + Object obj = results[0]; + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + Date previousTime = (Date) objs[0]; + + return previousTime; + + } + public int purgeDataByRefTime(Date refTime) throws DataAccessLayerException { DatabaseQuery deleteStmt = new DatabaseQuery(this.daoClass); deleteStmt.addQueryParam("refTime", refTime); + return this.deleteByCriteria(deleteStmt); } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrStateDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrStateDao.java new file mode 100644 index 0000000000..dbd3310f64 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagK3hrStateDao.java @@ -0,0 +1,457 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.dao; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hrState; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation; +import gov.noaa.nws.ncep.common.dataplugin.geomag.util.GeoMagStationLookup; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; + +import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.dao.CoreDao; +import com.raytheon.uf.edex.database.dao.DaoConfig; +import com.raytheon.uf.edex.database.query.DatabaseQuery; + +/** + * Dao class for GeoMagK3hrState. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class GeoMagK3hrStateDao extends CoreDao { + + /** The logger */ + protected transient Log logger = LogFactory.getLog(getClass()); + + /** + * Creates a new GeoMagK3hrStateDao + */ + public GeoMagK3hrStateDao() { + super(DaoConfig.forClass(GeoMagK3hrState.class)); + } + + /** + * Retrieves a GeoMagK3hrState based on the given id + * + * @param id + * The given ID number + * @return The GeoMagK3hrState object associated with the given id + */ + public GeoMagK3hrState queryById(int id) { + return (GeoMagK3hrState) super.queryById(id); + } + + /** + * Retrieves list of all GeoMagK3hrState objects + * + * @return list of GeoMagK3hrState objects + */ + @SuppressWarnings("unchecked") + public List getAllStationStateChanges() { + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess + .createCriteria(GeoMagK3hrState.class); + return crit.list(); + } + }); + } + + /** + * Returns the processing states for a list of magnetometer stations (for a + * given synoptic period, if provided)
+ * + * @param stations + * A list of stations + * @param reftime + * time tag + * @return List of data map containing "reftime", "stationCode", + * "processingState" + * @throws Exception + */ + public List> getKpStationsStates( + final List stations, final Date reftime) throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT a.reftime as reftime, a.stationcode as stationcode, c.processingState as processingstate FROM geomag_k3hr AS a" + + " INNER JOIN geomag_k3hr_state AS b ON b.k3hrId = a.id " + + " INNER JOIN geomag_states AS c ON c.stateid = b.stateid"); + + sql.append(" WHERE "); + + if (stations != null) { + sql.append(" a.stationcode IN ('"); + + String station = null; + for (int i = 0; i < stations.size(); i++) { + station = stations.get(i); + sql.append(station).append("'"); + if (i != (stations.size() - 1)) { + sql.append(",'"); + } + + } + sql.append(") AND"); + } + sql.append(" a.reftime = '" + reftime + "'"); + // sql.append(" AND a.kestreal <= 9.0 "); + sql.append("ORDER BY a.stationcode ASC, c.processingState ASC"); + + logger.info("Inside GeoMagK3hrStateDao.getKpStationsStates(), sql = " + + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return new ArrayList>(); + } + + String[] fieldNames = { "reftime", "stationcode", "processingstate" }; + List> resultMaps = new ArrayList>( + results.length); + for (Object obj : results) { + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + Map resultMap = new HashMap( + objs.length * 2); + for (int i = 0; i < fieldNames.length; ++i) { + resultMap.put(fieldNames[i], objs[i]); + } + resultMaps.add(resultMap); + } + + return resultMaps; + + } + + /** + * Returns the processing states for a given magnetometer station (for a + * given synoptic period, if provided)
+ * + * @param station + * Station code + * @param reftime + * time tag + * @return List of strings containing "processingstate" + * @throws Exception + */ + public List getKpStationStates(final String station, + final Date reftime) throws Exception { + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT c.processingState as processingstate FROM geomag_k3hr AS a" + + " INNER JOIN geomag_k3hr_state AS b ON b.k3hrId = a.id " + + " INNER JOIN geomag_states AS c ON c.stateid = b.stateid"); + sql.append(" WHERE stationcode = '" + station + "'"); + sql.append(" AND"); + sql.append(" a.reftime = '" + reftime + "'"); + // sql.append(" AND a.kestreal <= 9.0 "); + sql.append("ORDER BY c.processingState ASC"); + + logger.info("Inside GeoMagK3hrStateDao.getKpStationStates(), sql = " + + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return new ArrayList(); + } + + String[] fieldNames = { "processingstate" }; + List resultLst = new ArrayList(results.length); + for (Object obj : results) { + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + resultLst.add((String) objs[0]); + } + + return resultLst; + + } + + /** + * Returns the processing state id for a given station code, reftime and + * processing state.
+ * + * @param stationCode + * Station code + * @param prevTime + * time tag + * @param state + * processing state + * @return stateId + * @throws Exception + */ + public Integer getStationK3hrStateId(final String stationCode, + final Date prevTime, String state) throws Exception { + Integer stateId = null; + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT b.k3hrId FROM geomag_k3hr AS a" + + " INNER JOIN geomag_k3hr_state AS b ON b.k3hrId = a.id " + + " INNER JOIN geomag_states AS c ON c.stateid = b.stateid"); + sql.append(" WHERE a.stationcode = '" + stationCode + "'"); + sql.append(" AND a.reftime = '" + prevTime + "'"); + + if (state != null) { + sql.append(" AND c.processingState = '" + state + "'"); + } + + logger.info("Inside GeoMagK3hrStateDao.getStationK3hrStateId(), sql = " + + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return null; + } + + String[] fieldNames = { "stateid" }; + Object obj = results[0]; + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + stateId = (Integer) objs[0]; + + return stateId; + } + + /** + * Returns the processing state id for a given station code, reftime and + * processing state.
+ * + * @param stationCode + * Station code + * @param prevTime + * time tag + * @param state + * processing state + * @return stateId + * @throws Exception + */ + public Integer getStationStateId(final String stationCode, + final Date prevTime, String state) throws Exception { + Integer stateId = null; + + StringBuffer sql = new StringBuffer(); + sql.append(" SELECT c.stateid FROM geomag_k3hr AS a" + + " INNER JOIN geomag_k3hr_state AS b ON b.k3hrId = a.id " + + " INNER JOIN geomag_states AS c ON c.stateid = b.stateid"); + sql.append(" WHERE a.stationcode = '" + stationCode + "'"); + sql.append(" AND a.reftime = '" + prevTime + "'"); + + if (state != null) { + sql.append(" AND c.processingState = '" + state + "'"); + } + + logger.info("Inside GeoMagK3hrStateDao.getStationStateId(), sql = " + + sql.toString()); + + Object[] results = executeSQLQuery(sql.toString()); + + if (results.length == 0) { + return null; + } + + System.out.println(" results.length = " + results.length); + + String[] fieldNames = { "stateid" }; + Object obj = results[0]; + if (obj instanceof Object[] == false) { + obj = new Object[] { obj }; + } + Object[] objs = (Object[]) obj; + if (objs.length != fieldNames.length) { + throw new Exception( + "Column count returned does not match expected column count"); + } + stateId = (Integer) objs[0]; + + return stateId; + } + + /** + * Updates the processing states when a new record is inserted for a + * magnetometer station in the geomag_k3hr table.
+ * + * @param k3hrId + * k3hrId + * @param stationCode + * stationCode + * @return reftime time tag + * @throws Exception + */ + public void updateStates(final Integer k3hrId, final String stationCode, + final Date refTime) throws TransactionException { + + GeoMagK3hrDao k3hrDao = new GeoMagK3hrDao(); + GeoMagStateDao stateDao = new GeoMagStateDao(); + + boolean kpStation = false; + + Map> allStations = GeoMagStationLookup + .getInstance().getStationsByCodeMap(); + if (allStations != null) { + ArrayList geomagStnsSameCode = allStations + .get(stationCode); + + if (geomagStnsSameCode != null) { + for (int i = 0; i < geomagStnsSameCode.size(); i++) { + GeoMagStation stn = geomagStnsSameCode.get(i); + if (stn.getKpStation() == 1) { + kpStation = true; + } + } + } + } + + try { + Date previousTime = k3hrDao.getStationMaxPrevTime(stationCode, + refTime); + + // logger.info("Inside GeoMagK3hrStateDao.updateStates(), previousTime = " + // + previousTime); + + Integer stateId = stateDao.getStateByProcessingState("Process") + .getStateId(); + + if (stateId != null) { + + // To get here it would have already been set to Process. + GeoMagK3hrState k3hrStateRec = new GeoMagK3hrState(); + k3hrStateRec.setK3hrId(k3hrId); + k3hrStateRec.setStateId(stateId); + persist(k3hrStateRec); + + if (kpStation) { + // if station is a kpstation, set to Algorithm + stateId = stateDao.getStateByProcessingState("Algorithm") + .getStateId(); + + k3hrStateRec = new GeoMagK3hrState(); + k3hrStateRec.setK3hrId(k3hrId); + k3hrStateRec.setStateId(stateId); + persist(k3hrStateRec); + + if (previousTime != null) { + // if previous period exists and if station state is + // active for that period, + // insert as active + stateId = getStationStateId(stationCode, previousTime, + "Active"); + + // logger.info("Inside GeoMagK3hrStateDao.updateStates(), stateId = " + // + stateId); + + // if there is no data for previous synoptic period, + // then look for stateId + // based on the last data date + // if (stateId == null) { + // List stnList = new ArrayList(); + // stnList.add(stationCode); + // GeoMagK1minDao dao = new GeoMagK1minDao(); + // Date lastDataDate = dao.getLastDataDate(stnList, + // null, null); + // logger.info("Inside GeoMagK3hrStateDao.updateStates(), lastDataDate = " + // + lastDataDate); + // + // if (lastDataDate != null) { + // stateId = getStationStateId(stationCode, + // lastDataDate, "Active"); + // + // logger.info("Inside GeoMagK3hrStateDao.updateStates(), new stateId = " + // + stateId); + // + // } + // } + + if (stateId != null) { + k3hrStateRec = new GeoMagK3hrState(); + k3hrStateRec.setK3hrId(k3hrId); + k3hrStateRec.setStateId(stateId); + persist(k3hrStateRec); + } + } + + } + + } + + } catch (DataIntegrityViolationException de) { + // logger.info("Record with given stateId and k3hr combination exists."); + } catch (Exception e) { + logger.error("Error while updating processing states.", e); + } + + } + + public int delete(Integer stateId, Integer k3hrId) + throws DataAccessLayerException { + DatabaseQuery deleteStmt = new DatabaseQuery(this.daoClass); + deleteStmt.addQueryParam("stateId", stateId); + deleteStmt.addQueryParam("k3hrId", k3hrId); + + return this.deleteByCriteria(deleteStmt); + } + + public int purgeDataByK3hrId(Integer k3hrId) + throws DataAccessLayerException { + DatabaseQuery deleteStmt = new DatabaseQuery(this.daoClass); + deleteStmt.addQueryParam("k3hrId", k3hrId); + + return this.deleteByCriteria(deleteStmt); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStateDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStateDao.java new file mode 100644 index 0000000000..16f9918ae7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStateDao.java @@ -0,0 +1,107 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.dao; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagState; + +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Restrictions; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; + +import com.raytheon.uf.edex.database.dao.CoreDao; +import com.raytheon.uf.edex.database.dao.DaoConfig; + +/** + * Dao class for GeoMagState. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class GeoMagStateDao extends CoreDao { + + /** + * Creates a new GeoMagStateDao + */ + public GeoMagStateDao() { + super(DaoConfig.forClass(GeoMagState.class)); + } + + /** + * Retrieves a GeoMagState based on the given id + * + * @param id + * The given ID number + * @return The GeoMagState object associated with the given id + */ + public GeoMagState queryById(int id) { + return (GeoMagState) super.queryById(id); + } + + /** + * Retrieves list of all GeoMagState objects + * + * @return list of GeoMagState objects + */ + @SuppressWarnings("unchecked") + public List getAllStates() { + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess.createCriteria(GeoMagState.class); + return crit.list(); + } + }); + } + + /** + * Retrieves a GeoMagState object based on the given processing state + * + * @param procState + * The processing state + * @return The GeoMagState object associated with the processing state + */ + @SuppressWarnings("unchecked") + public GeoMagState getStateByProcessingState(final String procState) { + return (GeoMagState) txTemplate.execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory().getCurrentSession(); + Criteria crit = sess.createCriteria(GeoMagState.class); + Criterion where1 = Restrictions + .eq("processingState", procState); + crit.add(where1); + if (crit.list() != null && crit.list().size() > 0) + return crit.list().get(0); + else + return null; + } + }); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStationStateChangeDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStationStateChangeDao.java new file mode 100644 index 0000000000..e92ae98ede --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/dao/GeoMagStationStateChangeDao.java @@ -0,0 +1,110 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.dao; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagStationStateChange; + +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Restrictions; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; + +import com.raytheon.uf.edex.database.dao.CoreDao; +import com.raytheon.uf.edex.database.dao.DaoConfig; + +/** + * Dao class for GeoMagStationStateChange. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer           Description
+ * ------------ ---------- ----------------   --------------------------
+ * 06/27/2014   R4078       sgurung            Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class GeoMagStationStateChangeDao extends CoreDao { + + /** + * Creates a new GeoMagStationStateChangeDao + */ + public GeoMagStationStateChangeDao() { + super(DaoConfig.forClass(GeoMagStationStateChange.class)); + } + + /** + * Retrieves a GeoMagStationStateChange based on the given id + * + * @param id + * The given ID number + * @return The GeoMagStationStateChange object associated with the given id + */ + public GeoMagStationStateChange queryById(int id) { + return (GeoMagStationStateChange) super.queryById(id); + } + + /** + * Retrieves list of all GeoMagStationStateChange objects + * + * @return list of GeoMagStationStateChange objects + */ + @SuppressWarnings("unchecked") + public List getAllStationStateChanges() { + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess + .createCriteria(GeoMagStationStateChange.class); + return crit.list(); + } + }); + } + + /** + * Retrieves list of all GeoMagStationStateChange objects for a given + * stationCode + * + * @param stationCode + * The Station code + * @return list of GeoMagStationStateChange objects + */ + @SuppressWarnings("unchecked") + public List getAllStationStateChangesByStation( + final String stationCode) { + return (List) txTemplate + .execute(new TransactionCallback() { + @Override + public Object doInTransaction(TransactionStatus status) { + HibernateTemplate ht = getHibernateTemplate(); + Session sess = ht.getSessionFactory() + .getCurrentSession(); + Criteria crit = sess + .createCriteria(GeoMagStationStateChange.class); + Criterion where1 = Restrictions.eq("stationCode", + stationCode); + crit.add(where1); + return crit.list(); + } + }); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/ChangeStationStateRequest.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/ChangeStationStateRequest.java new file mode 100644 index 0000000000..72c98d18b4 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/ChangeStationStateRequest.java @@ -0,0 +1,81 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.request; + +import java.util.Date; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.serialization.comm.IServerRequest; + +/** + * + * ChangeStationStateRequest + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/01/2014   R4078      sgurung     Initial Creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@DynamicSerialize +public class ChangeStationStateRequest implements IServerRequest { + + @DynamicSerializeElement + private String stationCode; + + @DynamicSerializeElement + private Date synopticTime; + + @DynamicSerializeElement + private Integer prevPeriod; + + public ChangeStationStateRequest() { + } + + public ChangeStationStateRequest(String stationCode, Integer prevPeriod, + Date timeTag) { + super(); + this.stationCode = stationCode; + this.synopticTime = timeTag; + this.prevPeriod = prevPeriod; + } + + public Integer getPrevPeriod() { + return prevPeriod; + } + + public void setPrevPeriod(Integer prevPeriod) { + this.prevPeriod = prevPeriod; + } + + public String getStationCode() { + return stationCode; + } + + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } + + public Date getSynopticTime() { + return synopticTime; + } + + public void setSynopticTime(Date synopticTime) { + this.synopticTime = synopticTime; + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/DatabaseUtil.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/DatabaseUtil.java index 020119f907..4b91c5dfab 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/DatabaseUtil.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/DatabaseUtil.java @@ -196,7 +196,7 @@ public class DatabaseUtil { String station = CalcUtil.getStationFromUri(dataUri); List resultsList = null; - resultsList = k3hrDao.getSingleK3hr(station, epTime); + resultsList = k3hrDao.getK3hr(station, epTime); return resultsList; } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveGeoMagDataRequest.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveGeoMagDataRequest.java new file mode 100644 index 0000000000..cea9a95137 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveGeoMagDataRequest.java @@ -0,0 +1,102 @@ +package gov.noaa.nws.ncep.common.dataplugin.geomag.request; + +import java.util.Date; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.serialization.comm.IServerRequest; + +/** + * + * Request for GeoMag data + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/31/2014   R4078      sgurung     Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@DynamicSerialize +public class RetrieveGeoMagDataRequest implements IServerRequest { + + public static enum RetrieveGeoMagDataRequestType { + DATA_LIST, COUNT + } + + @DynamicSerializeElement + private String stationCode; + + @DynamicSerializeElement + private Date startTime; + + @DynamicSerializeElement + private Date endTime; + + @DynamicSerializeElement + private int sourceId; + + @DynamicSerializeElement + private RetrieveGeoMagDataRequestType requestType = RetrieveGeoMagDataRequestType.DATA_LIST; + + public RetrieveGeoMagDataRequest() { + } + + public RetrieveGeoMagDataRequest(String stationCode, Date startTime, + Date endTime, int sourceId, + RetrieveGeoMagDataRequestType requestType) { + super(); + this.stationCode = stationCode; + this.startTime = startTime; + this.endTime = endTime; + this.sourceId = sourceId; + this.requestType = requestType; + } + + public String getStationCode() { + return stationCode; + } + + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public int getSourceId() { + return sourceId; + } + + public void setSourceId(int sourceId) { + this.sourceId = sourceId; + } + + public RetrieveGeoMagDataRequestType getRequestType() { + return requestType; + } + + public void setRequestType(RetrieveGeoMagDataRequestType requestType) { + this.requestType = requestType; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveK1minRequest.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveK1minRequest.java index c71100793f..ca3c6bc273 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveK1minRequest.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveK1minRequest.java @@ -1,6 +1,17 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ package gov.noaa.nws.ncep.common.dataplugin.geomag.request; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -8,7 +19,7 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest; /** * - * Request for a GeoMagk1min for the given dataURI + * Request for a GeoMagk1min * *
  * 
@@ -17,6 +28,7 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * 2014/02/12   #1110      qzhou       Init
+ * 03/05/2014   R4078      sgurung     Added requestType and stationCodeList.
  * 
  * 
* @@ -26,6 +38,10 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest; @DynamicSerialize public class RetrieveK1minRequest implements IServerRequest { + public static enum RetrieveK1minRequestType { + K, KP, LATEST_K, LAST_DATA_DATE + } + @DynamicSerializeElement private String stationCode; @@ -35,6 +51,12 @@ public class RetrieveK1minRequest implements IServerRequest { @DynamicSerializeElement private Date endTime; + @DynamicSerializeElement + private List stationCodeList; + + @DynamicSerializeElement + private RetrieveK1minRequestType requestType = RetrieveK1minRequestType.K; + public RetrieveK1minRequest() { } @@ -43,6 +65,17 @@ public class RetrieveK1minRequest implements IServerRequest { this.stationCode = stationCode; this.startTime = startTime; this.endTime = endTime; + stationCodeList = new ArrayList(); + } + + public RetrieveK1minRequest(List stationCodeList, Date startTime, + Date endTime, RetrieveK1minRequestType reqType) { + super(); + this.stationCode = null; + this.startTime = startTime; + this.endTime = endTime; + this.stationCodeList = stationCodeList; + requestType = reqType; } public String getStationCode() { @@ -69,4 +102,20 @@ public class RetrieveK1minRequest implements IServerRequest { this.endTime = endTime; } + public List getStationCodeList() { + return stationCodeList; + } + + public void setStationCodeList(List stationCodeList) { + this.stationCodeList = stationCodeList; + } + + public RetrieveK1minRequestType getRequestType() { + return requestType; + } + + public void setRequestType(RetrieveK1minRequestType requestType) { + this.requestType = requestType; + } + } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveStationStateRequest.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveStationStateRequest.java new file mode 100644 index 0000000000..fbc0746518 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/request/RetrieveStationStateRequest.java @@ -0,0 +1,90 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.request; + +import java.util.Date; +import java.util.List; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.serialization.comm.IServerRequest; + +/** + * + * RetrieveStationStateRequest + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/01/2014   R4078      sgurung     Initial Creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@DynamicSerialize +public class RetrieveStationStateRequest implements IServerRequest { + + @DynamicSerializeElement + private String stationCode; + + @DynamicSerializeElement + private Date refTime; + + @DynamicSerializeElement + private List stationCodeList; + + public RetrieveStationStateRequest() { + } + + public RetrieveStationStateRequest(String stationCode, Date timeTag) { + super(); + this.stationCode = stationCode; + this.refTime = timeTag; + this.stationCodeList = null; + } + + public RetrieveStationStateRequest(List stationCodeList, + Date timeTag) { + super(); + this.stationCode = null; + this.refTime = timeTag; + this.stationCodeList = stationCodeList; + } + + public String getStationCode() { + return stationCode; + } + + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } + + public Date getRefTime() { + return refTime; + } + + public void setRefTime(Date refTime) { + this.refTime = refTime; + } + + public List getStationCodeList() { + return stationCodeList; + } + + public void setStationCodeList(List stationCodeList) { + this.stationCodeList = stationCodeList; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStation.java index 20853c8ebb..2dbbdde6f7 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStation.java @@ -1,3 +1,12 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ package gov.noaa.nws.ncep.common.dataplugin.geomag.table; import java.util.ArrayList; @@ -9,236 +18,289 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - /** * Defines a magnetometer station. * - *
+ * 
  * SOFTWARE HISTORY
  * 
  * Date         Ticket#    Engineer     Description
  * ------------ ---------- ----------- --------------------------
  * 03/29/2013   975        sgurung     Initial Creation 
  * 07/17/2013   975        qzhou       Changed source type for reading source attributes
+ * 04/28/2014   R4078      sgurung      Added field kStation and method compareTo().
  * 
* * @author sgurung * @version 1 */ @XmlRootElement(name = "geoMagStation") -@XmlAccessorType(XmlAccessType.NONE) -public class GeoMagStation { +@XmlAccessorType(XmlAccessType.FIELD) +public class GeoMagStation implements Comparable { - /** - * Station Code - */ - @XmlElement - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - private String stationCode; - - /** - * Provider - */ - @XmlElement - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - private String provider; - - /** - * Data sources for the station - */ - @XmlElement - protected ArrayList source; - - /** - * Indicates whether the station should be included - * in the K-index processing (if set to true). - */ - @XmlElement - protected Boolean processKQDC; - - /** - * Indicates whether the Ks value (station estimate of kp) - * should be calculated for the station (if set to true). - */ - @XmlElement - protected Boolean kpStation; - - /** - * Indicates whether the station has a header. - * Same station data may have or have no header. - */ - @XmlElement - protected String hasHeader; - - /** - * Data order (e.g. HDZF or XYZF) - */ - @XmlElement - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - private String dataOrder; - /** - * Location (latitude/longitude) of the station - */ - @XmlElement - protected Location location; - - /** - * Raw data format of the input data for the station - */ - @XmlElement - protected RawDataFormat rawDataFormat; - - - - public GeoMagStation() { - source = new ArrayList(); - } - - /** - * Gets the stationCode of this station - * @return the stationCode - */ - public String getStationCode() { - return stationCode; - } + * Station Code + */ + @XmlElement + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + private String stationCode; - /** - * Sets the stationCode of this station - * @param stationCode the stationCode to set - */ - public void setStationCode(String stationCode) { - this.stationCode = stationCode; - } + /** + * Provider + */ + @XmlElement + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + private String provider; - /** - * Gets the provider of this station - * @return the provider - */ - public String getProvider() { - return provider; - } + /** + * Data sources for the station + */ + @XmlElement + protected ArrayList source; - /** - * Sets the provider of this station - * @param provider the provider to set - */ - public void setProvider(String provider) { - this.provider = provider; - } + /** + * Indicates whether the station should process K quiet day curve (1=yes, + * 0=no). + */ + @XmlElement + protected Integer processKQDC; - /** - * Gets the stationCode of this station - * @return the stationCode - */ - public ArrayList getSource() { - return source; - } + /** + * Indicates whether station is an approved part of Kp network (1=yes, + * 0=no). + */ + @XmlElement + protected Integer kpStation; - /** - * Sets the source of this station - * @param source the source to set - */ - public void setSource(ArrayList source) { - this.source = source; - } + /** + * Indicates whether station will have k-index processing (1=yes, 0=no). + */ + @XmlElement + protected Integer kStation; - - /** - * Gets the processKQDC value of this station - * @return the processKQDC - */ - public boolean getProcessKQDC() { - return processKQDC; - } + /** + * Indicates whether the station has a header. Same station data may have or + * have no header. + */ + @XmlElement + protected String hasHeader; - /** - * Sets the processKQDC value of this station - * @param processKQDC the processKQDC to set - */ - public void setProcessKQDC(boolean processKQDC) { - this.processKQDC = processKQDC; - } + /** + * Data order (e.g. HDZF or XYZF) + */ + @XmlElement + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + private String dataOrder; - - /** - * Gets the kpStation value of this station - * @return the kpStation - */ - public boolean getKpStation() { - return kpStation; - } + /** + * Location (latitude/longitude) of the station + */ + @XmlElement + protected Location location; - /** - * Sets the kpStation value of this station - * @param kpStation the kpStation to set - */ - public void setKpStation(boolean kpStation) { - this.kpStation = kpStation; - } + /** + * Raw data format of the input data for the station + */ + @XmlElement + protected RawDataFormat rawDataFormat; - /** - * Gets the header true or false - * @return the hasHeader - */ - public String getHasHeader() { - return hasHeader; - } + public GeoMagStation() { + source = new ArrayList(); + } - /** - * Sets the hasHeader value of this station - * @param hasHeader the hasHeader to set - */ - public void setHasHeader(String hasHeader) { - this.hasHeader = hasHeader; - } - - /** - * Gets the dataOrder of this station - * @return the dataOrder - */ - public String getDataOrder() { - return dataOrder; - } + /** + * Gets the stationCode of this station + * + * @return the stationCode + */ + public String getStationCode() { + return stationCode; + } - /** - * Sets the dataOrder of this station - * @param dataOrder the dataOrder to set - */ - public void setDataOrder(String dataOrder) { - this.dataOrder = dataOrder; - } + /** + * Sets the stationCode of this station + * + * @param stationCode + * the stationCode to set + */ + public void setStationCode(String stationCode) { + this.stationCode = stationCode; + } - /** - * Gets the longitude of this station - * @return the longitude - */ - public Location getLocation() { - return location; - } + /** + * Gets the provider of this station + * + * @return the provider + */ + public String getProvider() { + return provider; + } - /** - * Sets the longitude of this station - * @param longitude the longitude to set - */ - public void setLocation(Location location) { - this.location = location; - } - - /** - * Gets the rawDataFormat of this station - * @return the rawDataFormat - */ - public RawDataFormat getRawDataFormat() { - return rawDataFormat; - } + /** + * Sets the provider of this station + * + * @param provider + * the provider to set + */ + public void setProvider(String provider) { + this.provider = provider; + } - /** - * Sets the rawDataFormat of this station - * @param rawDataFormat the rawDataFormat to set - */ - public void setRawDataFormat(RawDataFormat rawDataFormat) { - this.rawDataFormat = rawDataFormat; - } + /** + * Gets the stationCode of this station + * + * @return the stationCode + */ + public ArrayList getSource() { + return source; + } + + /** + * Sets the source of this station + * + * @param source + * the source to set + */ + public void setSource(ArrayList source) { + this.source = source; + } + + /** + * Gets the processKQDC value of this station + * + * @return the processKQDC + */ + public Integer getProcessKQDC() { + return processKQDC; + } + + /** + * Sets the processKQDC value of this station + * + * @param processKQDC + * the processKQDC to set + */ + public void setProcessKQDC(Integer processKQDC) { + this.processKQDC = processKQDC; + } + + /** + * Gets the kpStation value of this station + * + * @return the kpStation + */ + public Integer getKpStation() { + return kpStation; + } + + /** + * Sets the kpStation value of this station + * + * @param kpStation + * the kpStation to set + */ + public void setKpStation(Integer kpStation) { + this.kpStation = kpStation; + } + + /** + * Gets the kStation value of this station + * + * @return the kStation + */ + public Integer getkStation() { + return kStation; + } + + /** + * Sets the kStation value of this station + * + * @param kStation + * the kStation to set + */ + public void setkStation(Integer kStation) { + this.kStation = kStation; + } + + /** + * Gets the header true or false + * + * @return the hasHeader + */ + public String getHasHeader() { + return hasHeader; + } + + /** + * Sets the hasHeader value of this station + * + * @param hasHeader + * the hasHeader to set + */ + public void setHasHeader(String hasHeader) { + this.hasHeader = hasHeader; + } + + /** + * Gets the dataOrder of this station + * + * @return the dataOrder + */ + public String getDataOrder() { + return dataOrder; + } + + /** + * Sets the dataOrder of this station + * + * @param dataOrder + * the dataOrder to set + */ + public void setDataOrder(String dataOrder) { + this.dataOrder = dataOrder; + } + + /** + * Gets the longitude of this station + * + * @return the longitude + */ + public Location getLocation() { + return location; + } + + /** + * Sets the longitude of this station + * + * @param longitude + * the longitude to set + */ + public void setLocation(Location location) { + this.location = location; + } + + /** + * Gets the rawDataFormat of this station + * + * @return the rawDataFormat + */ + public RawDataFormat getRawDataFormat() { + return rawDataFormat; + } + + /** + * Sets the rawDataFormat of this station + * + * @param rawDataFormat + * the rawDataFormat to set + */ + public void setRawDataFormat(RawDataFormat rawDataFormat) { + this.rawDataFormat = rawDataFormat; + } + + @Override + public int compareTo(GeoMagStation o) { + return stationCode.compareTo(o.stationCode); + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationList.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationList.java index 594c4f41aa..957ac966a4 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationList.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationList.java @@ -1,11 +1,17 @@ - +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ package gov.noaa.nws.ncep.common.dataplugin.geomag.table; import java.io.File; import java.io.InputStream; import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -14,20 +20,22 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSeeAlso; import com.raytheon.uf.common.serialization.ISerializableObject; /** - * This object contains a list of magnetometer stations. - * An object of this class is used by JAXB when marshaling/unmarshaling a list of GeoMagStations - * to/from an XML file. - * - *
+ * This object contains a list of magnetometer stations. An object of this class
+ * is used by JAXB when marshaling/unmarshaling a list of GeoMagStations to/from
+ * an XML file.
+ * 
+ * 
  * SOFTWARE HISTORY
  * 
  * Date         Ticket#    Engineer     Description
  * ------------ ---------- ----------- --------------------------
- * 03/29/2013   975        sgurung     Initial Creation 
+ * 03/29/2013   975        sgurung     Initial Creation
+ * 04/29/2014   R4078       sgurung     Added constructor GeoMagStationList(ArrayList)
  * 
* * @author sgurung @@ -35,43 +43,49 @@ import com.raytheon.uf.common.serialization.ISerializableObject; */ @XmlRootElement(name = "GeoMagStationList") @XmlAccessorType(XmlAccessType.NONE) +@XmlSeeAlso({ GeoMagStation.class }) public class GeoMagStationList implements ISerializableObject { - /** - * A list of the available GeoMagStaions - */ - @XmlElement(name="geoMagStation") - private ArrayList stationList; - - /** - * Default constructor. - */ - public GeoMagStationList() { - stationList = new ArrayList(); - } - - /** - * Gets the list of GeoMagStaions - * @return the stationList - */ - public ArrayList getGeoMagStationList() { - return stationList; - } + /** + * A list of the available GeoMagStaions + */ + @XmlElement(name = "geoMagStation") + private ArrayList stationList; - /** + /** + * Default constructor. + */ + public GeoMagStationList() { + stationList = new ArrayList(); + } + + public GeoMagStationList(ArrayList stnsList) { + stationList = stnsList; + } + + /** + * Gets the list of GeoMagStaions + * + * @return the stationList + */ + public ArrayList getGeoMagStationList() { + return stationList; + } + + /** * * @param file * @return * @throws JAXBException */ public static GeoMagStationList fromFile(File file) throws JAXBException { - GeoMagStationList gml = null; + GeoMagStationList gml = null; JAXBContext ctx = JAXBContext.newInstance(GeoMagStationList.class); if (ctx != null) { Unmarshaller um = ctx.createUnmarshaller(); if (um != null) { - gml = (GeoMagStationList) um.unmarshal(file); + gml = (GeoMagStationList) um.unmarshal(file); } } @@ -86,13 +100,13 @@ public class GeoMagStationList implements ISerializableObject { */ public static GeoMagStationList fromStream(InputStream is) throws JAXBException { - GeoMagStationList gml = null; + GeoMagStationList gml = null; JAXBContext ctx = JAXBContext.newInstance(GeoMagStationList.class); if (ctx != null) { Unmarshaller um = ctx.createUnmarshaller(); if (um != null) { - gml = (GeoMagStationList) um.unmarshal(is); + gml = (GeoMagStationList) um.unmarshal(is); } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationTableReaderWriter.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationTableReaderWriter.java new file mode 100644 index 0000000000..702e6f505f --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/GeoMagStationTableReaderWriter.java @@ -0,0 +1,93 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.common.dataplugin.geomag.table; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + *
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer     Description
+ * ------------ ---------- ----------- --------------------------
+ * 04/29/2014   R4078       sgurung      Initial Creation
+ * 
+ * + * @author sgurung + * @version 1 + */ +public class GeoMagStationTableReaderWriter { + private final String PACKAGE = "gov.noaa.nws.ncep.common.dataplugin.geomag.table"; + + /** The logger */ + protected transient Log logger = LogFactory.getLog(getClass()); + + private String xmlFile = null; + + public GeoMagStationTableReaderWriter(String file) { + xmlFile = file; + } + + public List readGeoMagStationList() throws JAXBException { + + JAXBContext context = JAXBContext.newInstance(PACKAGE); + Unmarshaller unmarshaller = context.createUnmarshaller(); + GeoMagStationList sfstnlist = null; + + File file = new File(xmlFile); + + try { + if (file.exists()) { + sfstnlist = (GeoMagStationList) unmarshaller + .unmarshal(new FileReader(xmlFile)); + List listOfItems = sfstnlist + .getGeoMagStationList(); + return listOfItems; + } + } catch (FileNotFoundException e) { + logger.error(xmlFile + " not found!", e); + } + + return null; + + } + + public void writeGeoMagStationList(GeoMagStationList sfstnlist) + throws JAXBException { + + JAXBContext context = JAXBContext.newInstance(PACKAGE); + Marshaller marshaller = context.createMarshaller(); + + File file = new File(xmlFile); + + try { + if (file.exists()) { + marshaller.marshal(sfstnlist, file); + } + + } catch (JAXBException e) { + logger.error("Error marshalling " + xmlFile, e); + } + + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/TestGeoMagStationsTable.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/TestGeoMagStationsTable.java index 695969eb9e..45baab11c7 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/TestGeoMagStationsTable.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/table/TestGeoMagStationsTable.java @@ -15,8 +15,8 @@ public class TestGeoMagStationsTable { public static void main(String args[]) throws Exception{ - GeoMagStationTableReader gmstr = new GeoMagStationTableReader("/awips2/edex/data/utility/edex_static/base/ncep/geomagstns/GeoMagStations.xml"); - List list = gmstr.getStationList();//gml.getGeoMagStationList(); + GeoMagStationTableReaderWriter gmstr = new GeoMagStationTableReaderWriter("/awips2/edex/data/utility/edex_static/base/ncep/geomagstns/GeoMagStations.xml"); + List list = gmstr.readGeoMagStationList();//gml.getGeoMagStationList(); System.out.println(" Station count: " + list.size()); for(GeoMagStation itm : list){ System.out.println(" *******************************************************"); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/GeoMagStationLookup.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/GeoMagStationLookup.java index 3539a8f8a1..0f3fdcc0a8 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/GeoMagStationLookup.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/GeoMagStationLookup.java @@ -1,9 +1,9 @@ package gov.noaa.nws.ncep.common.dataplugin.geomag.util; - import gov.noaa.nws.ncep.common.dataplugin.geomag.exception.GeoMagException; import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation; -import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStationTableReader; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStationList; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStationTableReaderWriter; import java.io.File; import java.io.IOException; @@ -28,6 +28,7 @@ import com.raytheon.uf.common.localization.PathManagerFactory; * ------------ ---------- ----------- -------------------------- * 04/2013 975 sgurung Initial creation * 07/2013 975 qzhou Change Map stnsByCode to + * 04/2014 R4078 sgurung Modified methods initStationList() and saveGeoMagStationList() *
* * @author sgurung @@ -72,20 +73,23 @@ public class GeoMagStationLookup { } public GeoMagStation getStationByCode(String stnCode, boolean hasHeader) { - ArrayList stationList = null; - - stationList = stnsByCode.get(stnCode); - - int i = 0; - for (i = 0; i stationList = null; + + stationList = stnsByCode.get(stnCode); + + int i = 0; + for (i = 0; i < stationList.size(); i++) { + + if (hasHeader == true + && stationList.get(i).getRawDataFormat().getHeaderFormat() != null) + break; + else if (hasHeader == false + && stationList.get(i).getRawDataFormat().getHeaderFormat() == null) + break; + else if (hasHeader == true + && stationList.get(i).getRawDataFormat().getHeaderFormat() == null) + break; + } return stationList.get(i); } @@ -95,62 +99,121 @@ public class GeoMagStationLookup { } private void initStationList() throws GeoMagException { - IPathManager pathMgr = PathManagerFactory.getPathManager(); - - LocalizationContext commonStaticBase = pathMgr.getContext( + IPathManager pathMgr = PathManagerFactory.getPathManager(); + + LocalizationContext commonStaticBase = pathMgr.getContext( LocalizationContext.LocalizationType.COMMON_STATIC, LocalizationContext.LocalizationLevel.BASE); - - /*LocalizationContext commonStaticSite = pathMgr.getContext( - LocalizationContext.LocalizationType.COMMON_STATIC, - LocalizationContext.LocalizationLevel.SITE);*/ - String path = ""; - //String sitePath = ""; + LocalizationContext commonStaticSite = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.SITE); + + String path = ""; + String sitePath = ""; try { - path = pathMgr.getFile(commonStaticBase, - "ncep" + File.separator + "geomag" + File.separator + "geoMagStations.xml") - .getCanonicalPath(); - //sitePath = pathMgr.getFile(commonStaticSite, NcPathConstants.GEOMAG_STNS_TBL).getCanonicalPath(); + path = pathMgr.getFile( + commonStaticBase, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); + sitePath = pathMgr.getFile( + commonStaticSite, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); + } catch (IOException e) { - logger.error("Error reading geomag stations table. ", e); + logger.error("Error reading geomag stations table. ", e); } - File stnsFile = new File(path); - //File siteStnsFile = new File(sitePath); - GeoMagStationTableReader geoMagStationsTbl = null; + File siteStnsFile = new File(sitePath); + GeoMagStationTableReaderWriter geoMagStationsTbl = null; try { - if (stnsFile.exists()) { - geoMagStationsTbl = new GeoMagStationTableReader(stnsFile.getPath()); - } - // if site version exists, use it instead - /*if (siteStnsFile.exists()) { - geoMagStationsTbl = new GeoMagStationTableReader(stnsFile.getPath()); - }*/ - - List list = (geoMagStationsTbl!=null)?geoMagStationsTbl.getStationList():new ArrayList(); - //System.out.println("**list "+list.size()); - for(GeoMagStation station : list){ - ArrayList stationList = null; - if (stnsByCode.containsKey(station.getStationCode())) { - stationList = stnsByCode.get(station.getStationCode()); - if(stationList==null) - stationList=new ArrayList(); + if (siteStnsFile.exists()) { + geoMagStationsTbl = new GeoMagStationTableReaderWriter( + siteStnsFile.getPath()); + } else if (stnsFile.exists()) { + geoMagStationsTbl = new GeoMagStationTableReaderWriter( + stnsFile.getPath()); + } - stationList.add(station); + List list = (geoMagStationsTbl != null) ? geoMagStationsTbl + .readGeoMagStationList() : new ArrayList(); - }else{ - stationList=new ArrayList(); - stationList.add(station); - } - stnsByCode.put(station.getStationCode(), stationList);//station); - } + for (GeoMagStation station : list) { + ArrayList stationList = null; + if (stnsByCode.containsKey(station.getStationCode())) { + stationList = stnsByCode.get(station.getStationCode()); + if (stationList == null) + stationList = new ArrayList(); + + stationList.add(station); + + } else { + stationList = new ArrayList(); + stationList.add(station); + } + stnsByCode.put(station.getStationCode(), stationList);// station); + } } catch (Exception e) { - throw new GeoMagException("Unable to unmarshal ncep geomag stations file"); + throw new GeoMagException( + "Unable to unmarshal ncep geomag stations file"); + } + + } + + public void saveGeoMagStationList(GeoMagStationList sfstnlist) + throws GeoMagException { + IPathManager pathMgr = PathManagerFactory.getPathManager(); + + LocalizationContext commonStaticBase = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.BASE); + + LocalizationContext commonStaticSite = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.SITE); + + String basePath = ""; + String sitePath = ""; + try { + basePath = pathMgr.getFile( + commonStaticBase, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); + sitePath = pathMgr.getFile( + commonStaticSite, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); + + } catch (IOException e) { + logger.error("Error reading geomag stations table. ", e); + throw new GeoMagException("Error reading geoMagStations.xml file. " + + e); + } + + File stnsTableBase = new File(basePath); + File stnsTableSite = new File(sitePath); + + GeoMagStationTableReaderWriter geoMagStationsTbl = null; + try { + + if (stnsTableSite.exists()) { + geoMagStationsTbl = new GeoMagStationTableReaderWriter( + stnsTableSite.getPath()); + geoMagStationsTbl.writeGeoMagStationList(sfstnlist); + } else { + if (stnsTableBase.exists()) { + geoMagStationsTbl = new GeoMagStationTableReaderWriter( + stnsTableBase.getPath()); + geoMagStationsTbl.writeGeoMagStationList(sfstnlist); + } + } + } catch (Exception e) { + throw new GeoMagException( + "Unable to marshal ncep geomag stations file"); } - } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/TableTimeStamp.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/TableTimeStamp.java index 0d7909cc18..73aff11563 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/TableTimeStamp.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/util/TableTimeStamp.java @@ -1,6 +1,7 @@ package gov.noaa.nws.ncep.common.dataplugin.geomag.util; import gov.noaa.nws.ncep.common.dataplugin.geomag.exception.GeoMagException; + import java.io.File; import com.raytheon.uf.common.localization.IPathManager; @@ -8,13 +9,15 @@ import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.PathManagerFactory; /** - * TableTimeStamp - A Java class to update geoMagStations.xml. - * + * TableTimeStamp - A Java class to update geoMagStations.xml. + * + *
  * SOFTWARE HISTORY
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * 04/2013  	975		   S. Gurung   Initial creation
+ * 04/2013      975        S. Gurung   Initial creation
+ * 06/2014      R4078      S. Gurung   Added support for site level geoMagStations.xml file
  * 
  * 
* @@ -34,33 +37,56 @@ public class TableTimeStamp { long geoMagStationFileTime = 0; IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext commonStaticBase = pathMgr.getContext( LocalizationContext.LocalizationType.COMMON_STATIC, LocalizationContext.LocalizationLevel.BASE); + LocalizationContext commonStaticSite = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.SITE); + /* check geoMagStations.xml file */ - String path = ""; + String basePath = ""; + String sitePath = ""; try { - path = pathMgr.getFile(commonStaticBase, - "ncep" + File.separator + "geomag" + File.separator + "geoMagStations.xml") - .getCanonicalPath(); + basePath = pathMgr.getFile( + commonStaticBase, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); + + sitePath = pathMgr.getFile( + commonStaticSite, + "ncep" + File.separator + "geomag" + File.separator + + "geoMagStations.xml").getCanonicalPath(); } catch (Exception e) { throw new GeoMagException( "Unable to unmarshal geoMagStations.xml file"); } - File stnsTable = new File(path); + File stnsTableBase = new File(basePath); + File stnsTableSite = new File(sitePath); try { - if (stnsTable.exists()) { - geoMagStationFileTime = stnsTable.lastModified(); + if (stnsTableSite.exists()) { + geoMagStationFileTime = stnsTableSite.lastModified(); if (geoMagStationFileTime != getGeoMagStationsTimeStamp()) { System.out - .println("geoMagStations.xml has been modified or the first time, so load it ..."); + .println("Site level geoMagStations.xml has been modified or the first time, so load it ..."); GeoMagStationLookup.ReloadInstance(); setGeoMagStationsTimeStamp(geoMagStationFileTime); } + } else { + if (stnsTableBase.exists()) { + geoMagStationFileTime = stnsTableBase.lastModified(); + if (geoMagStationFileTime != getGeoMagStationsTimeStamp()) { + System.out + .println("Base level geoMagStations.xml has been modified or the first time, so load it ..."); + GeoMagStationLookup.ReloadInstance(); + setGeoMagStationsTimeStamp(geoMagStationFileTime); + } + } } } catch (Exception e) { throw new GeoMagException("Unable to read geoMagStations.xml file"); diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/res/spring/geomag-request.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/res/spring/geomag-request.xml index 912ea2ad4a..9e1af0e8d9 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/res/spring/geomag-request.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/res/spring/geomag-request.xml @@ -61,4 +61,28 @@ value="gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveSingleK1minRequest" /> + + + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/TrigKCalculation.java b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/TrigKCalculation.java index 48bfcdf679..0314826bcf 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/TrigKCalculation.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/TrigKCalculation.java @@ -12,6 +12,7 @@ import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagAvgDao; import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagDao; import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK1minDao; import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK3hrDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK3hrStateDao; import gov.noaa.nws.ncep.common.dataplugin.geomag.request.DatabaseUtil; import java.io.FileNotFoundException; @@ -44,6 +45,8 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory; * 06/07/2013 #989 qzhou Initial Creation, event driven * 03/18/2014 #1123 qzhou Move some functions to common. Modified FillAvgTimeGap in the moved functions * 06/26/2014 #1136 qzhou Calculate hourly average when min>=55 instead of min=59 + * 07/16/2014 R4078 sgurung Modified method calcK3hr() to add states when a k3hr record is inserted + * *
* * @author qzhou @@ -465,7 +468,7 @@ public class TrigKCalculation { // int h = d.getHours(); // int m = d.getMinutes(); // if (h == 10 && m == 41) { // && day == 14 - // System.out.println("**dataURI " + dataURI); + // System.out.println("***********dataURI " + dataURI); // teststr = dataURI; // } // } catch (ParseException e1) { @@ -531,11 +534,12 @@ public class TrigKCalculation { float[] qdaQdc = CalcEach1min.getQHAQDC(dQdc); // test hQdc // if (!teststr.equals("")) { - // System.out.println("\n**qhaQdc length " + teststr); + // System.out.println("\n**qhaQdctest2 length " + // + qhaQdc.length); // for (int i = 0; i < qhaQdc.length; i++) // System.out.print((float) qhaQdc[i] + " "); - // System.out - // .println("\n**qdaQdc length " + qdaQdc.length); + // System.out.println("\n**qdaQdctest2 length " + // + qdaQdc.length); // for (int i = 0; i < qdaQdc.length; i++) // System.out.print((float) qdaQdc[i] + " "); // teststr = ""; @@ -908,6 +912,11 @@ public class TrigKCalculation { GeoMagK3hrDao k3hrDao = new GeoMagK3hrDao(); k3hrDao.persist(recK3hr); + + if (recK3hr.getId() != null) { + GeoMagK3hrStateDao k3hrStateDao = new GeoMagK3hrStateDao(); + k3hrStateDao.updateStates(recK3hr.getId(), stationCode, epTime); + } } else { @@ -980,6 +989,11 @@ public class TrigKCalculation { GeoMagK3hrDao k3hrDao = new GeoMagK3hrDao(); k3hrDao.persist(recK3hr); + + if (recK3hr.getId() != null) { + GeoMagK3hrStateDao k3hrStateDao = new GeoMagK3hrStateDao(); + k3hrStateDao.updateStates(recK3hr.getId(), stationCode, epTime); + } } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/ChangeStationStateRequestHandler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/ChangeStationStateRequestHandler.java new file mode 100644 index 0000000000..f59ddd78ca --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/ChangeStationStateRequestHandler.java @@ -0,0 +1,116 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.edex.plugin.geomag.handler; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK3hrState; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagStationStateChange; +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK3hrStateDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagStateDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagStationStateChangeDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.ChangeStationStateRequest; + +import java.util.Date; +import java.util.List; +import java.util.logging.Logger; + +import com.raytheon.uf.common.serialization.comm.IRequestHandler; + +/** + * + * Handler for ChangeStationStateRequest. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/01/2014   R4078      sgurung     Initial Creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class ChangeStationStateRequestHandler implements + IRequestHandler { + + private static Logger logger = Logger + .getLogger(ChangeStationStateRequestHandler.class.toString()); + + private GeoMagK3hrStateDao dao; + + @Override + public Object handleRequest(ChangeStationStateRequest request) + throws Exception { + + Boolean rval = Boolean.TRUE; + + logger.info("ChangeStationStateRequest for " + request.getStationCode()); + + try { + dao = new GeoMagK3hrStateDao(); + GeoMagStateDao stateDao = new GeoMagStateDao(); + GeoMagStationStateChangeDao stateChangeDao = new GeoMagStationStateChangeDao(); + + Integer stateId = stateDao.getStateByProcessingState("Active") + .getStateId(); + Integer k3hrId = dao.getStationK3hrStateId( + request.getStationCode(), request.getSynopticTime(), null); + + logger.info("Inside ChangeStationStateRequest for " + + request.getStationCode() + " stateId = " + stateId + + " k3hrId = " + k3hrId); + + // Check if station is active for the Kp calculation + // If so, delete the record from the station_indices_states table + // if not, add the record for this period + List processingStates = dao.getKpStationStates( + request.getStationCode(), request.getSynopticTime()); + if (processingStates != null) { + if (processingStates.contains("Active")) { + + int numRowsDel = dao.delete(stateId, k3hrId); + + if (numRowsDel > 0) { + // add record to table geomag_state_changes + GeoMagStationStateChange stateChange = new GeoMagStationStateChange(); + stateChange.setStationCode(request.getStationCode()); + stateChange + .setIssuedAction("Deactivated from Algorithm"); + stateChange.setInsertTime(new Date()); + stateChangeDao.persist(stateChange); + } + } else { + + // add record to table geomag_k3hr_state + GeoMagK3hrState k3hrState = new GeoMagK3hrState(); + k3hrState.setK3hrId(k3hrId); + k3hrState.setStateId(stateId); + dao.persist(k3hrState); + + // add record to table geomag_station_state_changes + GeoMagStationStateChange stateChange = new GeoMagStationStateChange(); + stateChange.setStationCode(request.getStationCode()); + stateChange.setIssuedAction("Activated in Algorithm"); + stateChange.setInsertTime(new Date()); + stateChangeDao.persist(stateChange); + } + } + } catch (Exception e) { + rval = Boolean.FALSE; + logger.warning("Error while changing station state for " + + request.getStationCode() + " Exception = " + + e.getMessage() + " \n" + e.getStackTrace()); + } + + return rval; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveGeoMagDataRequestHandler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveGeoMagDataRequestHandler.java new file mode 100644 index 0000000000..97759d4c9b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveGeoMagDataRequestHandler.java @@ -0,0 +1,67 @@ +package gov.noaa.nws.ncep.edex.plugin.geomag.handler; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveGeoMagDataRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveGeoMagDataRequest.RetrieveGeoMagDataRequestType; + +import java.util.logging.Logger; + +import com.raytheon.uf.common.serialization.comm.IRequestHandler; + +/** + * + * Handler for RetrieveGeoMagDataRequest. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/31/2014   R4078      sgurung     Initial creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class RetrieveGeoMagDataRequestHandler implements + IRequestHandler { + + private static Logger logger = Logger + .getLogger(RetrieveGeoMagDataRequestHandler.class.toString()); + + private GeoMagDao dao; + + @Override + public Object handleRequest(RetrieveGeoMagDataRequest request) + throws Exception { + + logger.info("RetrieveGeoMagDataRequest for " + request.getStationCode()); + + try { + dao = new GeoMagDao("geomag"); // PluginFactory.getInstance().getPluginDao(GeoMag); + + if (RetrieveGeoMagDataRequestType.DATA_LIST.equals(request + .getRequestType())) { + return dao.getGeoMagRecords(request.getStationCode(), + request.getStartTime(), request.getEndTime(), + request.getSourceId()); + } else if (RetrieveGeoMagDataRequestType.COUNT.equals(request + .getRequestType())) { + return dao.getGeoMagRecordsCount(request.getStationCode(), + request.getStartTime(), request.getEndTime(), + request.getSourceId()); + } + + } catch (Exception e) { + logger.warning("Error during RetrieveGeoMagDataRequestHandler request " + + request.getStationCode() + + ". Error: " + + e.getMessage() + + "\n" + e.getStackTrace()); + } + + return null; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveK1minRequestHandler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveK1minRequestHandler.java index 12190bce7c..27a66e0cb2 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveK1minRequestHandler.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveK1minRequestHandler.java @@ -1,12 +1,14 @@ package gov.noaa.nws.ncep.edex.plugin.geomag.handler; -import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min; import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK1minDao; import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveK1minRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveK1minRequest.RetrieveK1minRequestType; import java.util.List; +import java.util.Map; import java.util.logging.Logger; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; import com.raytheon.uf.common.serialization.comm.IRequestHandler; /** @@ -21,6 +23,8 @@ import com.raytheon.uf.common.serialization.comm.IRequestHandler; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 2014/02/12 #1110 qzhou Init + * 03/05/2014 R4078 sgurung Modified method handleRequest() to handle additional + * requests based on RetrieveK1minRequestTypes. * * * @@ -37,20 +41,47 @@ public class RetrieveK1minRequestHandler implements @Override public Object handleRequest(RetrieveK1minRequest request) throws Exception { - List resultsList = null; + logger.info("RetrieveK1minRequest for " + request.getStationCode()); try { dao = new GeoMagK1minDao(); - resultsList = dao.getRangeK1min(request.getStationCode(), - request.getStartTime(), request.getEndTime()); + if (RetrieveK1minRequestType.KP.equals(request.getRequestType())) { + List> resultMaps = dao.getEstKpIndex1min( + request.getStationCodeList(), request.getStartTime(), + request.getEndTime()); + DbQueryResponse response = new DbQueryResponse(); + response.setResults(resultMaps); + return response; + } else if (RetrieveK1minRequestType.K.equals(request + .getRequestType())) { + return dao.getEstKIndex1min(request.getStationCodeList(), + request.getStartTime(), request.getEndTime()); + + } else if (RetrieveK1minRequestType.LATEST_K.equals(request + .getRequestType())) { + List> resultMaps = dao.getLatestEstKIndex( + request.getStationCodeList(), request.getStartTime(), + request.getEndTime()); + DbQueryResponse response = new DbQueryResponse(); + response.setResults(resultMaps); + return response; + } else if (RetrieveK1minRequestType.LAST_DATA_DATE.equals(request + .getRequestType())) { + return dao.getLastDataDate(request.getStationCodeList(), + request.getStartTime(), request.getEndTime()); + + } else { + return dao.getRangeK1min(request.getStationCode(), + request.getStartTime(), request.getEndTime()); + } } catch (Exception e) { logger.warning("Error retrieving K1min record for " + request.getStationCode()); } - return resultsList; + return null; } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveStationStateRequestHandler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveStationStateRequestHandler.java new file mode 100644 index 0000000000..bae636b8c9 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/src/gov/noaa/nws/ncep/edex/plugin/geomag/handler/RetrieveStationStateRequestHandler.java @@ -0,0 +1,73 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.edex.plugin.geomag.handler; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK3hrStateDao; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveStationStateRequest; + +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; +import com.raytheon.uf.common.serialization.comm.IRequestHandler; + +/** + * + * Handler for RetrieveStationStateRequest. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/01/2014   R4078      sgurung     Initial Creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class RetrieveStationStateRequestHandler implements + IRequestHandler { + + private static Logger logger = Logger + .getLogger(RetrieveStationStateRequestHandler.class.toString()); + + private GeoMagK3hrStateDao dao; + + @Override + public Object handleRequest(RetrieveStationStateRequest request) + throws Exception { + + logger.info("RetrieveStationStateRequest..."); + + try { + dao = new GeoMagK3hrStateDao(); + + if (request.getStationCodeList() != null) { + List> resultMaps = dao.getKpStationsStates( + request.getStationCodeList(), request.getRefTime()); + DbQueryResponse response = new DbQueryResponse(); + response.setResults(resultMaps); + return response; + } else if (request.getStationCode() != null) { + List results = dao.getKpStationStates( + request.getStationCode(), request.getRefTime()); + return results; + } + } catch (Exception e) { + logger.warning("Error retrieving station state request..."); + } + + return null; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/utility/common_static/base/ncep/geomag/geoMagStations.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/utility/common_static/base/ncep/geomag/geoMagStations.xml index 8716bf9fcc..2c4baa09e4 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/utility/common_static/base/ncep/geomag/geoMagStations.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.geomag/utility/common_static/base/ncep/geomag/geoMagStations.xml @@ -3,8 +3,9 @@ BOU USGS - true - true + 1 + 0 + 1 @@ -36,8 +37,9 @@ SIT USGS - true - true + 1 + 1 + 1 @@ -69,8 +71,9 @@ NEW USGS - true - true + 1 + 0 + 1 @@ -102,8 +105,9 @@ FRN USGS - true - true + 1 + 0 + 1 @@ -135,8 +139,9 @@ FRD USGS - true - true + 1 + 1 + 1 @@ -168,8 +173,9 @@ MEA USGS - true - true + 1 + 1 + 1 @@ -201,8 +207,9 @@ OTT USGS - true - true + 1 + 1 + 1 @@ -234,8 +241,9 @@ HAD USGS - true - true + 1 + 1 + 1 @@ -267,8 +275,9 @@ CL2 USGS - true - true + 1 + 0 + 1 @@ -300,14 +309,15 @@ HAD BGS - true - true + 1 + 1 + 1 HDZF - ^(\d{4})\s*(\d{3})\s(\d{2})\s*(\d{2})\s*(-?\d+\.?\d*)\s*(-?\d+\.?\d*)\s*(-?\d+\.?\d*) + ^(\d{4})\s*(\d{3})\s*(\d{2})\s*(\d{2})\s*(-?\d+\.?\d*)\s*(-?\d+\.?\d*)\s*(-?\d+\.?\d*) @@ -321,8 +331,9 @@ CNB GA - true - true + 1 + 1 + 1 XYZF @@ -342,8 +353,9 @@ NGK GFZ - true - true + 1 + 1 + 1 XYZF @@ -363,8 +375,9 @@ WNG GFZ - true - true + 1 + 1 + 1 XYZF @@ -384,8 +397,9 @@ CL2 IPGP - true - true + 1 + 0 + 1 @@ -417,8 +431,9 @@ OTT NRCAN - true - true + 1 + 1 + 1 XYZF @@ -439,8 +454,9 @@ MEA NRCAN - true - true + 1 + 1 + 1 XYZF @@ -461,8 +477,9 @@ JEJ KOREA - false - false + 0 + 0 + 1 XYZF diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java index 4c357abdc2..b95538ca3e 100644 --- a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java +++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java @@ -14,6 +14,7 @@ import javax.xml.bind.annotation.XmlRootElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 02/10/13 #972 Greg Hull Created + * 05/14/14 R4078 S. Gurung Added NMAP_RTKP_WORLD_DISPLAY (T1122) * * * @@ -47,7 +48,13 @@ public enum NcDisplayType { "BasicWX_US", "OVERLAY/GeoPolitical/default", false), GRAPH_DISPLAY("GRAPH", "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", - "DefaultCanvas", "", true); + "DefaultCanvas", "", true), + + // FOR GEOMAG RTKP WORLD ACTIVITY MAP + NMAP_RTKP_WORLD_DISPLAY("NC-MAP-GEOMAG", + "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", "World", + "OVERLAY/GeoPolitical/default", true); + // NC_TIME_SERIES_DISPLAY, // NC_CROSS_SECTION_DISPLAY; diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagHDQdcPlots.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagHDQdcPlots.xml new file mode 100644 index 0000000000..f003699216 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagHDQdcPlots.xml @@ -0,0 +1,223 @@ + + + GRAPH_DISPLAY + + + false + true + 0 + + + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + + + + + + RGB {255, 255, 255} + + 1 + USE_DATA_TIMES + EXACT + 1 + 12 + 3 + 24 + H + Time (hr) + H (nT) + Baseline + red + false + false + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + + + + + + RGB {255, 255, 255} + + 1 + USE_DATA_TIMES + EXACT + 1 + 12 + 3 + 24 + HQdc + Time (hr) + HQdc (nT) + Baseline + pink + false + false + + + 2147483647 + + LOCAL_CS["Cartesian 2D", + LOCAL_DATUM["Unknow", 0], + UNIT["m", 1.0], + AXIS["x", EAST], + AXIS["y", NORTH]] + + 720 + + true + false + + + + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + + + + + + RGB {255, 255, 255} + + 1 + USE_DATA_TIMES + EXACT + 1 + 12 + 3 + 24 + D + Time (hr) + D (nT) + Baseline + dodger blue + false + false + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + + + + + + RGB {255, 255, 255} + + 1 + USE_DATA_TIMES + EXACT + 1 + 12 + 3 + 24 + DQdc + Time (hr) + DQdc (nT) + Baseline + green + false + false + + + 2147483647 + + LOCAL_CS["Cartesian 2D", + LOCAL_DATUM["Unknow", 0], + UNIT["m", 1.0], + AXIS["x", EAST], + AXIS["y", NORTH]] + + 720 + + true + false + + + + + false + diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagRTKpMonitorPlots.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagRTKpMonitorPlots.xml new file mode 100644 index 0000000000..6f779a518e --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/Bundles/GeoMagRTKpMonitorPlots.xml @@ -0,0 +1,110 @@ + + + + + + + + PLAN_VIEW + + + + + + + + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + Real-time K-index + + + time + Universal Time + + + + + + PLAN_VIEW + + + + + + + + + + + + PLAN_VIEW + + + + + + + + + + + + + + + + + + + Real-time K-index + + + time + Universal Time + + + + + + 2147483647 + 4320 + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/DefaultRBDs/defaultRTKpRBD.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/DefaultRBDs/defaultRTKpRBD.xml new file mode 100644 index 0000000000..a6fcef3fd9 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/DefaultRBDs/defaultRTKpRBD.xml @@ -0,0 +1,220 @@ + + + NMAP_RTKP_DISPLAY + + + true + false + 0 + + + + + + + + + + RGB {255, 255, 255} + 14 + Monospace + LATLON + 1 + degrees + omit + + 1 + omit + omit + None + 1 + omit + omit + None + 1 + omit + omit + None + 1 + omit + omit + + + + + PLAN_VIEW + + + + + + + RGB {255, 255, 255} + + + PLAN_VIEW + + + + + + + RGB {255, 255, 255} + World + maps + mapdata.world
+ the_geom + name + RGB {255, 228, 220} + 1 + SOLID +
+
+ + + PLAN_VIEW + + + + + + + RGB {255, 255, 255} + State Boundaries + maps + mapdata.states
+ the_geom + RGB {255, 228, 220} + 1 + SOLID +
+
+ + + PLAN_VIEW + + + + + + + RGB {255, 255, 255} + Canada + maps + mapdata.canada
+ the_geom + RGB {255, 228, 220} + 1 + SOLID +
+
+ + + PLAN_VIEW + + + + + + + RGB {255, 255, 255} + Mexico + maps + mapdata.mexico
+ the_geom + name + RGB {255, 228, 220} + 1 + SOLID +
+
+ Geo-Political + RGB {255, 228, 220} + 1 + SOLID +
+
+ + + + + + RGB {255, 255, 255} + RGB {0, 0, 255} + 1 + SOLID + RGB {255, 165, 79} + ASTERISK + 1.3 + 2 + RGB {30, 30, 163} + RGB {0, 0, 0} + 0.4 + SOLID + RGB {127, 127, 127} + 1 + SHORT_DASHED + true + true + true + + + 2147483647 + + PROJCS["Equidistant_Cylindrical", + GEOGCS["WGS84(DD)", + DATUM["WGS84", + SPHEROID["WGS84", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH]], + PROJECTION["Equidistant_Cylindrical"], + PARAMETER["semi_major", 6371200.0], + PARAMETER["semi_minor", 6371200.0], + PARAMETER["central_meridian", 0.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["false_easting", 0.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH]] + + 4320 + + false + false +
+ + + NMAP_DISPLAY + PREDEFINED_AREA + 1.0 + N/A + + PROJCS["Equidistant_Cylindrical", + GEOGCS["WGS84(DD)", + DATUM["WGS84", + SPHEROID["WGS84", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH]], + PROJECTION["Equidistant_Cylindrical"], + PARAMETER["semi_major", 6371200.0], + PARAMETER["semi_minor", 6371200.0], + PARAMETER["central_meridian", 0.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["false_easting", 0.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH]] + + +
+
+ false +
+ + diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml index 50449cf3f0..94c370e4af 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml @@ -393,6 +393,9 @@ Observed + +Observed + Observed @@ -753,10 +756,10 @@ Forecast - + Forecast - + Forecast @@ -807,7 +810,7 @@ Forecast - + Forecast @@ -819,7 +822,7 @@ Forecast - + Forecast @@ -984,10 +987,10 @@ Forecast,SBN - + Forecast - + Forecast @@ -1065,7 +1068,7 @@ Forecast - + Forecast @@ -1083,13 +1086,13 @@ Forecast - + Forecast Forecast - + Forecast @@ -1230,7 +1233,7 @@ Forecast,SBN - + Forecast,Global @@ -1251,7 +1254,7 @@ Forecast - + Forecast @@ -1269,7 +1272,7 @@ Forecast - + Forecast @@ -1455,4 +1458,7 @@ Forecast,SWPC + +Misc + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java b/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java index 719cae6492..cb100d3b30 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java +++ b/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java @@ -51,6 +51,8 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager; * 05/15/2013 #862 Greg Hull AreaMenus tbl to xml * 11/15/2013 #1051 Greg Hull createDeskLevel() called from NmapCommon and triggered by spring. * 06/18/2014 #1131 qzhou Added DFLT_GRAPH_RBD + * 05/14/2014 R4078 S. Gurung Added DFLT_RTKP_RBD (T1122) + * 09/15/2014 R4508 S. Gurung Added TIME_SERIES_DIR * * * @author ghull @@ -141,6 +143,9 @@ public class NcPathManager { public static final String DFLT_GRAPH_RBD = NCEP_ROOT + "DefaultRBDs" + File.separator + "defaultGraphRBD.xml"; + public static final String DFLT_RTKP_RBD = NCEP_ROOT + "DefaultRBDs" + + File.separator + "defaultRTKpRBD.xml"; + public static final String LOCATOR_TBL = NCEP_ROOT + "Locator" + File.separator + "locator_tbl.xml"; @@ -326,6 +331,8 @@ public class NcPathManager { public static final String NSHARP_CONFIG = NCEP_ROOT + "nsharp" + File.separator + "nsharpConfig.xml"; + public static final String TIME_SERIES_DIR = NCEP_ROOT + "TimeSeries"; + } public static synchronized NcPathManager getInstance() { diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt0.gif b/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt0.gif new file mode 100644 index 0000000000000000000000000000000000000000..c3e2b132608aa32f00fcf5808a3321424a998833 GIT binary patch literal 824 zcmV-81IPSFNk%w1VORhd0Q46C000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh^78Wa_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~000000000000000 z000000000000000A^8LV00000EC2ui09XJR000I4-~j{#PzFGX3TeBxD!{@oEyLq& z&#vC{fC6BUB3=rN!Ub?4Lk*3X{2LT?|ozq@Z3p z0`ofHo?r9net3X(f_i_3g@Jv94pU457Xk(o0S#*tPy|s*nVT1#Oq@-gphushp{JUu zrJ}2*1`ulxFck`?j!|p6yt}@=z`w%5#A_C>0ZY3BvP%?D0TxOC&ll0t)z{9@(%aVE z)ZEzO-rC{c(-Qy{0&dY~%RuU^Bpe6?nc9tk*IGPS05 zSAe!r-Xd5lmoD72bKTx$oA(qGH~tjIJadWf(jOJ;3o|}m|!RpM#vzA7cK}Ph8r#c!51m~ zM8I0DmH1jzQ$V4B8Z9J8n<>_vGR-JZ%&19?ambh>jxq8`BaA=V_(_2PG!Vc920$`X z0(UUSSpgCR;N&_`N@-S=Q&xcGl~HE7<&#} z7B;7yb;_CNCwJ<(NfJvCF+>nBuz*6LIUssy3x?v*sG^Q0%BZ9%JeorZ1fXz02mm|k ChhO>t literal 0 HcmV?d00001 diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt1.gif b/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt1.gif new file mode 100644 index 0000000000000000000000000000000000000000..973037c6c720726cc6a13e38c04568c7dd7bc869 GIT binary patch literal 964 zcmV;#13UajNk%w1VORhd0Q4OI000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+}e z3k?ko4h{|w5D@3*=kW0G@$vEV^Yird^!4@i_V)Jo_xJet`1$$y`uh6&`}_R-{Qdp? z{{H^||Nj6000000A^8LV00000EC2ui09XJR000I4U;zNgSOmlfh+}H1?h30c5ZCwo zwzMv*h``98>TCc;3?S3#2rSKI^BHA2p&jY9I>ld3%6tM19TXQxQ5sQi0Ge5xo|svopqrVdqo|## zq^cPJ0UeP98g`fz2Nx7aO}M(emASjO!oa@6y~V`8%gDjZ9ZUclPM81}noCR!4^0CZ z+ua@C;ojgK+~(!u=jrV0bbo}zgQm|@_Xf@=;MY=RJ=!h{SL z3WPY(P6r2502tt)iJy^J(wb}l`RQY{k|X|4VoDj(WJ{JPNv@PBGJ!ZGl%NFIkd2d1 zRXY2vj zf{+Ug<7D{fi343YchTgv`=;*RzkTrrma_q_kq#&TP-ts_+DHu?HVD`dIRIqIlpjZ) zT=_C*&6qoH&TM(K=+K}!YcSA6LM%#J72uKFinb}+CNrkiWR$(Kk% z?h_O(vV0Q=PGppgnh m2=ML@`^@{UyhPB8FTC~Ud#}Cm0^BdZ0}25E0{~1C0suRsr?2n; literal 0 HcmV?d00001 diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt2.gif b/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt2.gif new file mode 100644 index 0000000000000000000000000000000000000000..fa555b5d0ceceea633ac37ed1c129a36b47c1971 GIT binary patch literal 959 zcmV;w13>&oNk%w1VORhd0Q4IG000010RaL60s{jB1Ox;H1qB8M1_%fU2?+@c3kwVk z4DRmk@9*#M@bL2T^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~ z000000000000000A^8LV00000EC2ui09XJR000I4paBpgP@1So41mz4@W{GujIM8O z%lU2wEg;FYiEK8O4dBRRUNDyp=D2J+p;D^#8l5V)$7fdy)@(b&jExy-Oae!aj*v%^ikQL*a~*@$%>N^%P%BCIzw^QGA_=(#lmE00hO|L3l*r9EJrK zzLUbjiZ3(zENG~bVTuM?7?Et8KjnGAs*7!eWys5ULo#pvWLVQd*^Sy$bfo*0D~?I^$Y2 zZC0~KBuF8G^CXjI8x|aafaHz7yGQhr>TCB1Ucr2i748;zFX6w2k1#l*FT(}8cu2`z zB7v4hIvW&0*bK+BnKz}fgxFz2;FS1M6!~>DfFu_fp@@1I@b!i(sFg>fjcw(q&yJws7@Ce2)EH!h6%c9U zjYljqpb`UM-~}pXoK@5&12SagX^;dH#g=q*$T6t+q(K1y zlcKUj0vb3u#d$`WA&eE!Kk_B5SM5n*trFN)Thz2yg=Zv1aG_8D01B8O0t$w#OMnX` hu#iH#D!>bXyzBztuD$r0K<^0r!tgH%K)etF06V4Otc(Bv literal 0 HcmV?d00001 diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt3.gif b/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt3.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3542fa2be58f48cd33f08561db1e5b6178d5157 GIT binary patch literal 1081 zcmZ?wbhEHbj9`#p_^QYN1dNP~OiWD7%*-q-EUc`oY;0`o?CcyI9Gsk-TwGi{JUqO- zynK9of`WoVLPD=!zkdJz{f7@9K7Rc8>C>mrpFe;3^5yH-uiw6X`~Lm=j~_pN{`~pt z*RS8dfB*UO=kMRY|Ni~^|NlS88rlHGpDbX5bwDJ@PYi7T92goH97Gt{4ipMVa7<-b z7Q7?JZgudAFH&2Bc1P-z|K{O1dnUl+z{(blR{{!0I#)k0wZ5mf{PXv!y2i@FhSsJm zX$CoYIX{JB`TD|w@+s|EQ)_3=$e%l_c+Rv%v*(E`a!F*#F{CLQ^r+1$` zdi7kKRc3?YS*J&e(qgRN6(!C}a{vCdmuW}ieETLgb~c+G0f~-{|E1h&DlQye%FFbj zVZ#Z9!^VD$dNp4}id5!InjX+3GIP>XugQublWbJaB~1yCS9tm`VWY^u^MNH*ZCqSm zmisR(?BNTYC9-nX#9{`G1v{TNt60jYMDCqzdL(R3)Ow~Dze;l=)}^In7)e?B5InZdHufWbGsP~c=| z36JEGiCG+#k0yGnb*4=8by_)fvP<3;Pwhxqg9WaW&oVlx#-3w-W|Xu_@Y(dVNuAHM zv-(~xot?Vr=Q0aP2@gj$9*KrVW(k)B3HDz(1){Qzd|WSV+r(x~S>$QtrLm~n>DG!R z=VUHSm0{3PI3FyYA$iYsZr*ms74!REy)0fZFRFdzqDfs^tC#NDm8B`gVJSBKnncAN z^If+VI<7DLlf}ROa2&JF#@$lUYc`zBdZ5ao;GrbWQORS<*ui|H@U7|1RU6l`-EI4j zyW??I_u8G2cNTH4+jUc^xQm5Jgn^0eyu+nNSCg-e?-hSXU0T2I&Nysuzw zS6XPp)VeW~A$3=_xd^{@G9bsOKo0Egd~%L@o8Dw2vI@Tw7NVQY!9od6vYX^E+)tW0O?n5R5x<+bcpQNT1W z*}6;|Xfx6>ht9N`VP++(jh2?3wzRu*W~8Z!id*{|_I&t#e17K%TPNWMC2j^>fhidH z7Z3zdC=?ov#$Yg5EEa+w91e%a;|TEfjWK2=n=xVE=FXo1^WFW35wb+#s8^^QNc zC8wXOtYzduKdD0#{}F%+MI6e{@EQp z&1IQkqKol#$nCLD0n(ZbpThIZX=bH@9ZI{8C@R=l96{@_}U+(KAO^NL&@bRqio zG&}+zXB>|6y=ehja-$&L9D`z+2Sy({IrioqR<^%+(i{{d@3?39Egsc=Z;RP0Dh%*U z;m!ma)NkM1-w|<}Z@SVae=Kj6U?Q?l%et;?Y~4FT^v>~=PWi-ey5OH6Zu zrFe_T%dCCr#@)(9WPwliSh{iS1D~sWnL^h3FjlgQX04MgC-xcDnxNMS-~-Y`e_|bpyZB{Zl1mXVP-YP$0jy9;SZLIF*#br?h-LumKLs)m(a2KEA-|K(r3_;I6CVt_s#WHZKnypnJ4^Ekf5kXLW;77bcf*8PTp@ z>rZiTq zb_0;5#{tfS1<6~@qg^yp`+m;LaD&YWt283Q*b!_+GhM8}Y8Q4XKop@dvh=)9Pf1ny zb3s8@-f&0RG6RYx20{iqRdl*=XA~YMB|EP1k{?uQLbn^=_+G2&IbLmYN0FAf7uWQ% zyx^>fz_`BT+kBGQwV;J={OknY&!1_EmJAM5a*hcnBk&0ahs$#k4>D!x6!sG2_rFiY zs2&s}`*^i9&dV@BN{OoJvl;t|IO!?P{VZ;=K^CSz90{OP;2QxeJg$BD;~%7iZcS;x zsA{ULePQY~3{D4v+>{%-pzZqNZASjx*h1#4xxVG>7#kfeN1hk@RmfqpdhgcV z?0#;+(avG9DZC|V&`n$qm9TSV&HXC~<0Y|T5sdbTr^9Kgup?6`o6=qD>m15}&7~ zq^YB;uBND}v#+6{Zm9|g8WS1{ZWncVb#B9w8pe9a%EZaY&dtow)5pcs*8mSqb&{7% z3si1-OoGeh%jD_j>+0t2>*(h4?B*G3rY*=!-5K2${r&}H0+5M6f&-x>ESOB7L5B?y z+7Y0^L53o3LTPzoY9kYlA47WVC=z5xlN|n0iY%!G9Rwy7Mj*^1tlXt1-S%MGrxT~m zojGsv6dDxhPoIB`CcQ9%lOA7M)U}ivwPjVS?51MPdetgbJyK0H05kwmFaS^XoJ~84 z8{4&i;Hq^Sm+o9)Z|Tt2fWS(|3O+l10(DwZ8rP z`19*Wr+fsJ3I~ugkTMYwc#whFJpA;`fcqTSV1fmTcS;==2q1tJ3AnJIL>I}jyc|_V~@QAkcg{KmZvD;86i3AzhGxaEmt4C?`)S%4npIHY#Z{mR3sXq>gfW zsZ+->Ac>HET#!H%Kc?#AsywRNDyzt(G5`drv;aT>mb_pB9J}Ufgs!~u;KHxI_PQ&v T#~M4VvcaZcVGkw*5CQ-@Ut^Fx literal 0 HcmV?d00001 diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt6.gif b/ncep/gov.noaa.nws.ncep.viz.overlays/icons/patt6.gif new file mode 100644 index 0000000000000000000000000000000000000000..8d448f1b83b073b414ee517d844fdabfa84a20e2 GIT binary patch literal 1005 zcmV{r>*` z|Ns900000000000A^8LV00000EC2ui09XJR000I4ATR(VV2FVT6auQU?g$U5+|ut| zuX-NyzgbCeOK>Ct&gMeMa54Z6rvh+7rBrKlT77P_UTpWu)r!sKFxMhIK%^uMLdl6@ zGzF<8z`5r+dwqC%e13$2e}RU8g@cTUhl_!55r6;z1ppcs7z9!rO&k*k8xo*Sqot>! zq^6;%uBff6u(Y$Ux3a2R90PSxO9-4C0uxFH7*fT@$;8GR$jZ;r&dk!*)zHn$+SlE6 zfOQoX2n8D!0~*Ny%>Wl(?e9?W@Nn|%_Vso5^z-@t`@(1-gMkDGK5#T7g!4%g!-e1= z@^Tolj>3u*CtlR}(1HRDl?G%gWbxsZ3K9NKri_Aei%OR)S5A@HQp!u4EGaZ_V9y|j z3j&CmD_n?{Aol0O7n3oVT7nK5_)rB&RFDAzoC!vNDG|-(L|;*S zD20a|hFIbgCyI!diX?*gL?=IiLIDA^btMG`1Ner4Sa#)D9*-LMxMOKT0$C)HIvSZI zl0Pyzq+Lm1pwv4C&BZ|k419tBhrDe05C>jX6lRxPYFVZfW19J8nhbGe5IYuZkiZ)e z05fAUbt-Y^m39(-~~M5t8f;y_G$&h-g6ax@dK^`JJfR`~03IG9>LfML|GPf#7Os};9o2#(A?)s~- zx`Ojg02)xRKoWy(M3j{WZB5Hd0M>qjtzOk~yDhcfUYl*D;~vydWKr;;!30}GaDZJB z2y^AT8pQjKyYR}3Z@v1`Ywx`I-s^9_0RznMI}l8?zzLTS5C8!rFiZf%CrC`O2_#I6 bvBeu_d@;urd)%>hAB%hfZULl#TL=Ip3As+jxg)-cNc%$ wTvyP*(HFmS?uwb~);KmL-8uWNd-}HB>urBsUfJNBcshNdhURv)6$}j40Pa5}hyVZp literal 0 HcmV?d00001 diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/localization/ncep/resourceTemplates/DayNightTerminatorOverlay.xml b/ncep/gov.noaa.nws.ncep.viz.overlays/localization/ncep/resourceTemplates/DayNightTerminatorOverlay.xml new file mode 100644 index 0000000000..5f6578f53b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.overlays/localization/ncep/resourceTemplates/DayNightTerminatorOverlay.xml @@ -0,0 +1,25 @@ + + + + + ${termLineColor} + ${termLineColor} + ${termLineWidth} + ${termLineStyle} + ${sunMarkerColor} + ${sunMarkerType} + ${sunMarkerSize} + ${sunMarkerWidth} + ${midnightMeridianLineColor} + ${midnightMeridianLineWidth} + ${midnightMeridianLineStyle} + ${dayShadeColor} + ${nightShadeColor} + ${shadeAlpha} + ${shadePattern} + ${displaySun} + ${applyShading} + ${displayMidnightMeridian} + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.overlays/plugin.xml index 60fe9ad693..1bfc8d0c94 100644 --- a/ncep/gov.noaa.nws.ncep.viz.overlays/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.overlays/plugin.xml @@ -37,6 +37,11 @@ name="DbOverlay" renderingOrderId="MAP_OUTLINE"> + + @@ -70,6 +75,11 @@ editDialogClass="gov.noaa.nws.ncep.viz.overlays.dialogs.PointOverlayAttributesDialog" name="PointOverlay"> + + @@ -377,7 +387,128 @@ paramName="mapName" paramType="IMPLEMENTATION_PARAM" ncResourceName="PointOverlay"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * SOFTWARE HISTORY + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 04/29/2014 1130 S. Gurung Initial creation + * + * @author sgurung + * @version 1.0 + */ + +public class ChangeDayNightTerminatorAttributesDialog extends + AbstractEditResourceAttrsDialog { + + private final static org.apache.log4j.Logger log = org.apache.log4j.Logger + .getLogger(ChangeDayNightTerminatorAttributesDialog.class); + + protected ResourceAttrSet prevRscAttrSet = null; + + private RscAttrValue termLineColor = null; + + private RscAttrValue termLineWidth = null; + + private RscAttrValue termLineStyle = null; + + private RscAttrValue sunMarkerColor = null; + + private RscAttrValue sunMarkerType = null; + + private RscAttrValue sunMarkerSize = null; + + private RscAttrValue sunMarkerWidth = null; + + private RscAttrValue displaySun = null; + + private MarkerType selSunMarkerType = null; // working copy + + private RscAttrValue midnightMeridianLineStyle = null; + + private RscAttrValue midnightMeridianLineColor = null; + + private RscAttrValue midnightMeridianLineWidth = null; + + private RscAttrValue displayMidnightMeridian = null; + + private RscAttrValue dayShadeColor = null; + + private RscAttrValue nightShadeColor = null; + + private RscAttrValue shadeAlpha = null; + + private RscAttrValue shadePattern = null; + + private RscAttrValue applyShading = null; + + private FillPattern selFillPatternType = null; // working copy + + private float lineLengthFactor = 1; + + private Button[] selectLineWidthButtons; + + private Map termLineStyleButtonMap; + + private Button[] selectMmLineWidthButtons; + + private Map mmLineStyleButtonMap; + + private final LineStyle[] lineStyleButtonSequence = { // ...for 2-column + // grid layout + LineStyle.DOTS, LineStyle.LONG_DASHED, LineStyle.SOLID, + LineStyle.LONG_DASH_THREE_SHORT_DASHES, LineStyle.SHORT_DASHED, + LineStyle.LONG_DASH_DOT, LineStyle.MEDIUM_DASHED, + LineStyle.LONG_DASH_THREE_DOTS, LineStyle.LONG_DASH_SHORT_DASH, + LineStyle.MEDIUM_DASH_DOT, }; + + public ChangeDayNightTerminatorAttributesDialog(Shell parentShell, + INatlCntrsResourceData rd, Boolean apply) { + super(parentShell, rd, apply); + } + + @Override + public Composite createDialog(Composite composite) { + final Display display = composite.getDisplay(); + + FormLayout layout0 = new FormLayout(); + composite.setLayout(layout0); + + prevRscAttrSet = new ResourceAttrSet(editedRscAttrSet); + + termLineStyle = editedRscAttrSet.getRscAttr("termLineStyle"); + termLineColor = editedRscAttrSet.getRscAttr("termLineColor"); + termLineWidth = editedRscAttrSet.getRscAttr("termLineWidth"); + + sunMarkerColor = editedRscAttrSet.getRscAttr("sunMarkerColor"); + sunMarkerType = editedRscAttrSet.getRscAttr("sunMarkerType"); + sunMarkerSize = editedRscAttrSet.getRscAttr("sunMarkerSize"); + sunMarkerWidth = editedRscAttrSet.getRscAttr("sunMarkerWidth"); + + midnightMeridianLineColor = editedRscAttrSet + .getRscAttr("midnightMeridianLineColor"); + midnightMeridianLineWidth = editedRscAttrSet + .getRscAttr("midnightMeridianLineWidth"); + midnightMeridianLineStyle = editedRscAttrSet + .getRscAttr("midnightMeridianLineStyle"); + + dayShadeColor = editedRscAttrSet.getRscAttr("dayShadeColor"); + nightShadeColor = editedRscAttrSet.getRscAttr("nightShadeColor"); + shadeAlpha = editedRscAttrSet.getRscAttr("shadeAlpha"); + shadePattern = editedRscAttrSet.getRscAttr("shadePattern"); + + displaySun = editedRscAttrSet.getRscAttr("displaySun"); + applyShading = editedRscAttrSet.getRscAttr("applyShading"); + displayMidnightMeridian = editedRscAttrSet + .getRscAttr("displayMidnightMeridian"); + + selSunMarkerType = (MarkerType) sunMarkerType.getAttrValue(); + selFillPatternType = (FillPattern) getFillPattern(shadePattern + .getAttrValue().toString()); + + // confirm the classes of the attributes.. + if (termLineStyle.getAttrClass() != LineStyle.class) { + System.out.println("termLineStyle is not of expected class? " + + termLineStyle.getAttrClass().toString()); + } else if (termLineColor.getAttrClass() != RGB.class) { + System.out.println("termLineColor is not of expected class? " + + termLineColor.getAttrClass().toString()); + } else if (termLineWidth.getAttrClass() != Integer.class) { + System.out.println("termLineWidth is not of expected class? " + + termLineWidth.getAttrClass().toString()); + } else if (sunMarkerColor.getAttrClass() != RGB.class) { + System.out.println("sunMarkerColor is not of expected class? " + + sunMarkerColor.getAttrClass().toString()); + } else if (sunMarkerType.getAttrClass() != MarkerType.class) { + System.out.println("sunMarkerType is not of expected class? " + + sunMarkerType.getAttrClass().toString()); + } else if (sunMarkerSize.getAttrClass() != Float.class) { + System.out.println("sunMarkerSize is not of expected class? " + + sunMarkerSize.getAttrClass().toString()); + } else if (sunMarkerWidth.getAttrClass() != Integer.class) { + System.out.println("sunMarkerWidth is not of expected class? " + + sunMarkerWidth.getAttrClass().toString()); + } else if (midnightMeridianLineWidth.getAttrClass() != Integer.class) { + System.out + .println("midnightMeridianLineWidth is not of expected class? " + + midnightMeridianLineWidth.getAttrClass() + .toString()); + } else if (midnightMeridianLineWidth.getAttrClass() != Integer.class) { + System.out + .println("midnightMeridianLineWidth is not of expected class? " + + midnightMeridianLineWidth.getAttrClass() + .toString()); + } else if (midnightMeridianLineColor.getAttrClass() != RGB.class) { + System.out + .println("midnightMeridianLineColor is not of expected class? " + + midnightMeridianLineColor.getAttrClass() + .toString()); + } else if (midnightMeridianLineStyle.getAttrClass() != LineStyle.class) { + System.out + .println("midnightMeridianLineStyle is not of expected class? " + + midnightMeridianLineStyle.getAttrClass() + .toString()); + } else if (dayShadeColor.getAttrClass() != RGB.class) { + System.out.println("dayShadeColor is not of expected class? " + + dayShadeColor.getAttrClass().toString()); + } else if (nightShadeColor.getAttrClass() != RGB.class) { + System.out.println("nightShadeColor is not of expected class? " + + nightShadeColor.getAttrClass().toString()); + + } else if (shadeAlpha.getAttrClass() != Float.class) { + System.out.println("shadeAlpha is not of expected class? " + + shadeAlpha.getAttrClass().toString()); + } else if (shadePattern.getAttrClass() != String.class) { + System.out.println("shadePattern is not of expected class? " + + shadePattern.getAttrClass().toString()); + } else if (displaySun.getAttrClass() != Boolean.class) { + System.out.println("displaySun is not of expected class? " + + displaySun.getAttrClass().toString()); + } else if (applyShading.getAttrClass() != Boolean.class) { + System.out.println("applyShading is not of expected class? " + + applyShading.getAttrClass().toString()); + } else if (displayMidnightMeridian.getAttrClass() != Boolean.class) { + System.out + .println("displayMidnightMeridian is not of expected class? " + + displayMidnightMeridian.getAttrClass().toString()); + } + + // Lay out the various groups within the dialog + + composite.setLayout(new GridLayout(2, true)); + GridData gd = new GridData(); + + // Sub-solar Point + + Group sunMarkerGroup = new Group(composite, SWT.SHADOW_NONE); + sunMarkerGroup.setText("Sub-solar Point"); + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + sunMarkerGroup.setLayoutData(gd); + sunMarkerGroup.setLayout(new FormLayout()); + + createSunMarkerControls(sunMarkerGroup, display); + + // Day/Night Shading + + Group shadingGroup = new Group(composite, SWT.SHADOW_NONE); + shadingGroup.setText("Day/Night Shading"); + + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + shadingGroup.setLayoutData(gd); + shadingGroup.setLayout(new FormLayout()); + + createShadingControls(shadingGroup, composite); + + // Terminator Line + + Group termGroup = new Group(composite, SWT.SHADOW_NONE); + termGroup.setText("Terminator Line"); + // GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + + termGroup.setLayoutData(gd); + termGroup.setLayout(new FormLayout()); + + createTerminatorControls(termGroup, display); + + // Midnight Meridian Line + + Group midnightMeriLineGroup = new Group(composite, SWT.SHADOW_NONE); + midnightMeriLineGroup.setText("Midnight Meridian Line"); + + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + midnightMeriLineGroup.setLayoutData(gd); + midnightMeriLineGroup.setLayout(new FormLayout()); + + createMidnightMeridianControls(midnightMeriLineGroup, display); + + return composite; + } + + public void createTerminatorControls(Group termGroup, final Display display) { + + Group linePreviewAreaGroup = new Group(termGroup, SWT.SHADOW_NONE); + linePreviewAreaGroup.setLayout(new FillLayout()); + + FormData formData0 = new FormData(); + formData0.top = new FormAttachment(5, 0); + formData0.left = new FormAttachment(2, 0); + formData0.width = 196; + formData0.height = 30; + linePreviewAreaGroup.setLayoutData(formData0); + + Group selectLineWidthGroup = new Group(termGroup, SWT.SHADOW_NONE); + selectLineWidthGroup.setText("Width"); + GridLayout lineWidthGridLayout = new GridLayout(); + lineWidthGridLayout.numColumns = 2; + lineWidthGridLayout.marginHeight = 18; + lineWidthGridLayout.marginWidth = 18; + lineWidthGridLayout.horizontalSpacing = 8; + lineWidthGridLayout.verticalSpacing = 8; + selectLineWidthGroup.setLayout(lineWidthGridLayout); + + FormData formData1 = new FormData(); + formData1.top = new FormAttachment(linePreviewAreaGroup, 7); + formData1.left = new FormAttachment(2, 0); + selectLineWidthGroup.setLayoutData(formData1); + + Group selectLineStyleGroup = new Group(termGroup, SWT.SHADOW_NONE); + selectLineStyleGroup.setText("Style"); + GridLayout lineStyleGridLayout = new GridLayout(); + lineStyleGridLayout.numColumns = 2; + lineStyleGridLayout.marginHeight = 18; + lineStyleGridLayout.marginWidth = 18; + lineStyleGridLayout.horizontalSpacing = 8; + lineStyleGridLayout.verticalSpacing = 8; + selectLineStyleGroup.setLayout(lineStyleGridLayout); + + FormData formData2 = new FormData(); + formData2.left = new FormAttachment(linePreviewAreaGroup, 16); + formData2.top = new FormAttachment(2, 7); + selectLineStyleGroup.setLayoutData(formData2); + + Group selectLineColorGroup = new Group(termGroup, SWT.SHADOW_NONE); + selectLineColorGroup.setText("Color"); + GridLayout lineColorGridLayout = new GridLayout(); + lineColorGridLayout.numColumns = 1; + lineColorGridLayout.marginHeight = 7; + lineColorGridLayout.marginWidth = 55; + lineColorGridLayout.horizontalSpacing = 0; + lineColorGridLayout.verticalSpacing = 10; + selectLineColorGroup.setLayout(lineColorGridLayout); + + FormData formData3 = new FormData(); + formData3.top = new FormAttachment(selectLineWidthGroup, 7); + formData3.left = new FormAttachment(2, 0); + formData3.width = 196; + formData3.height = 40; + selectLineColorGroup.setLayoutData(formData3); + + final Color black = display.getSystemColor(SWT.COLOR_BLACK); + final Color white = display.getSystemColor(SWT.COLOR_WHITE); + + // Associate with each line style a list of segment lengths (in pixels) + // of the repeating pattern. Numbers are pixels on, pixels off, on, off, + // ... + // (Derived from similar structure in NMAP NxmLineA.c) + // CAUTION: Duplication (of a sort). This governs only local display of + // line patterns in this dialog (preview and line style selector + // buttons). + // Actual drawing of lines with these styles is up to the implementation + // of IGraphicsTarget being used. + + final Map styleMap = new EnumMap( + LineStyle.class); + styleMap.put(LineStyle.SOLID, new int[] { 4 }); // GEMPAK line type 1 + styleMap.put(LineStyle.SHORT_DASHED, new int[] { 4, 4 }); // GEMPAK line + // type 2 + styleMap.put(LineStyle.MEDIUM_DASHED, new int[] { 8, 8 }); // GEMPAK + // line type + // 3 + styleMap.put(LineStyle.LONG_DASH_SHORT_DASH, new int[] { 16, 8, 4, 8 }); // GEMPAK + // line + // type + // 4 + styleMap.put(LineStyle.LONG_DASHED, new int[] { 16, 8 }); // GEMPAK line + // type 5 + styleMap.put(LineStyle.LONG_DASH_THREE_SHORT_DASHES, new int[] { 16, 8, + 4, 8, 4, 8, 4, 8 }); // GEMPAK line type 6 + styleMap.put(LineStyle.LONG_DASH_DOT, new int[] { 16, 8, 2, 8 }); // GEMPAK + // line + // type + // 7 + styleMap.put(LineStyle.LONG_DASH_THREE_DOTS, new int[] { 16, 8, 2, 8, + 2, 8, 2, 8 }); // GEMPAK line type 8 + styleMap.put(LineStyle.MEDIUM_DASH_DOT, new int[] { 8, 8, 2, 8 }); // GEMPAK + // line + // type + // 9 + styleMap.put(LineStyle.DOTS, new int[] { 2, 4 }); // GEMPAK line type 10 + + // Line Preview Area + + final Canvas linePreviewAreaCanvas = new Canvas(linePreviewAreaGroup, + SWT.NONE); + + final int previewLineXmin = 16; + final int previewLineXmax = 180; + final int previewLineYctr = 16; + + linePreviewAreaCanvas.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + gc.setLineWidth((Integer) termLineWidth.getAttrValue()); + gc.setForeground(new Color(display, (RGB) termLineColor + .getAttrValue())); + linePreviewAreaCanvas.setBackground(((RGB) termLineColor + .getAttrValue()).getHSB()[2] > 0.2 ? black : white); + int x1 = previewLineXmin; + int x2 = previewLineXmin; + int[] segLengths = styleMap.get((LineStyle) termLineStyle + .getAttrValue()); + if (segLengths == null) { + return; + } + while (x2 < previewLineXmax) { + boolean draw = true; + for (int eachLineLength : segLengths) { + int calculatedLineLength = (int) (eachLineLength * lineLengthFactor); + x2 = Math.min(x1 + calculatedLineLength, + previewLineXmax); + if (draw) { + gc.drawLine(x1, previewLineYctr, x2, + previewLineYctr); + } + if (x2 >= previewLineXmax) { + break; + } + draw = !draw; + x1 = x2; + } + } + } + }); + + // Parameters to give a uniform look to all line width/style buttons + + final int lineButtonHeight = 75; + final int lineButtonWidth = 15; + final int buttonLineXmin = 8; + final int buttonLineXmax = 68; + final int buttonLineYctr = 7; + + // Line Width + + selectLineWidthButtons = new Button[4]; + final int[] lineWidthButtonSequence = { 0, 2, // ...for 2-column grid + // layout + 1, 3 }; + for (int i : lineWidthButtonSequence) { + selectLineWidthButtons[i] = new Button(selectLineWidthGroup, + SWT.TOGGLE); + GridData gridData = new GridData(); + gridData.heightHint = lineButtonWidth; + gridData.widthHint = lineButtonHeight; + selectLineWidthButtons[i].setLayoutData(gridData); + selectLineWidthButtons[i].setData(i + 1); + selectLineWidthButtons[i].setToolTipText("Width " + (i + 1)); + selectLineWidthButtons[i].addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + int width = (Integer) event.widget.getData(); + gc.setLineWidth(width); + gc.setForeground(black); + gc.drawLine(buttonLineXmin, buttonLineYctr, buttonLineXmax, + buttonLineYctr); + } + }); + selectLineWidthButtons[i] + .addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + selectLineWidthButtons[(Integer) termLineWidth + .getAttrValue() - 1].setSelection(false); + termLineWidth.setAttrValue((Integer) event.widget + .getData()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + } + selectLineWidthButtons[(Integer) termLineWidth.getAttrValue() - 1] + .setSelection(true); // set initial state + + // Line Style + termLineStyleButtonMap = new EnumMap(LineStyle.class); + + for (LineStyle ls : lineStyleButtonSequence) { + Button lineStyleButton = new Button(selectLineStyleGroup, + SWT.TOGGLE); + termLineStyleButtonMap.put(ls, lineStyleButton); + GridData gridData = new GridData(); + gridData.heightHint = lineButtonWidth; + gridData.widthHint = lineButtonHeight; + lineStyleButton.setLayoutData(gridData); + lineStyleButton.setData(ls); + lineStyleButton.setToolTipText(ls.name()); + lineStyleButton.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + gc.setLineWidth(1); + gc.setForeground(black); + LineStyle ls = (LineStyle) event.widget.getData(); + int[] segLengths = styleMap.get(ls); + if (segLengths == null) + return; + int x1 = buttonLineXmin; + int x2 = buttonLineXmin; + while (x2 < buttonLineXmax) { + boolean draw = true; + for (int i : segLengths) { + x2 = Math.min(x1 + i, buttonLineXmax); + if (draw) { + gc.drawLine(x1, buttonLineYctr, x2, + buttonLineYctr); + } + if (x2 >= buttonLineXmax) { + break; + } + draw = !draw; + x1 = x2; + } + } + } + }); + lineStyleButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + termLineStyleButtonMap.get( + (LineStyle) termLineStyle.getAttrValue()) + .setSelection(false); + termLineStyle.setAttrValue((LineStyle) event.widget + .getData()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + } + termLineStyleButtonMap.get((LineStyle) termLineStyle.getAttrValue()) + .setSelection(true); + + // Line Color + + final ColorButtonSelector cms = new ColorButtonSelector( + selectLineColorGroup, 85, 25); + cms.setColorValue((RGB) termLineColor.getAttrValue()); + cms.addListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + termLineColor.setAttrValue(cms.getColorValue()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + + } + + public void createSunMarkerControls(Group sunMarkerGroup, + final Display display) { + + Group displaySunGroup = new Group(sunMarkerGroup, SWT.SHADOW_NONE); + displaySunGroup.setLayout(new FillLayout()); + + FormData formData0 = new FormData(); + formData0.top = new FormAttachment(5, 0); + formData0.left = new FormAttachment(2, 0); + formData0.width = 190; + formData0.height = 30; + displaySunGroup.setLayoutData(formData0); + + Group selectMarkerTypeGroup = new Group(sunMarkerGroup, SWT.SHADOW_NONE); + selectMarkerTypeGroup.setText("Marker Type"); + GridLayout markerTypeGridLayout = new GridLayout(); + markerTypeGridLayout.numColumns = 1; + markerTypeGridLayout.marginLeft = 30; + selectMarkerTypeGroup.setLayout(markerTypeGridLayout); + + FormData formData2 = new FormData(); + formData2.top = new FormAttachment(displaySunGroup, 10); + formData2.left = new FormAttachment(2, 0); + formData2.right = new FormAttachment(47, 0); + formData2.height = 60; + selectMarkerTypeGroup.setLayoutData(formData2); + + Group selectMarkerSizeGroup = new Group(sunMarkerGroup, SWT.SHADOW_NONE); + selectMarkerSizeGroup.setText("Marker Size"); + GridLayout markerSizeGridLayout = new GridLayout(); + markerSizeGridLayout.numColumns = 1; + markerSizeGridLayout.marginLeft = 35; + selectMarkerSizeGroup.setLayout(markerSizeGridLayout); + + FormData formData3 = new FormData(); + formData3.top = new FormAttachment(2, 0); + formData3.left = new FormAttachment(selectMarkerTypeGroup, 16); + formData3.right = new FormAttachment(98, 0); + formData3.height = 50; + selectMarkerSizeGroup.setLayoutData(formData3); + + Group selectMarkerWidthGroup = new Group(sunMarkerGroup, + SWT.SHADOW_NONE); + selectMarkerWidthGroup.setText("Marker Width"); + GridLayout markerWidthGridLayout = new GridLayout(); + markerWidthGridLayout.numColumns = 1; + markerWidthGridLayout.marginLeft = 35; + selectMarkerWidthGroup.setLayout(markerWidthGridLayout); + + FormData formData4 = new FormData(); + formData4.top = new FormAttachment(selectMarkerSizeGroup, 7); + formData4.left = new FormAttachment(selectMarkerTypeGroup, 16); + formData4.right = new FormAttachment(98, 0); + formData3.height = 50; + selectMarkerWidthGroup.setLayoutData(formData4); + + Group selectMarkerColorGroup = new Group(sunMarkerGroup, + SWT.SHADOW_NONE); + selectMarkerColorGroup.setText("Color"); + GridLayout markerColorGridLayout = new GridLayout(); + markerColorGridLayout.numColumns = 1; + markerColorGridLayout.marginHeight = 7; + markerColorGridLayout.marginWidth = 55; + markerColorGridLayout.horizontalSpacing = 0; + markerColorGridLayout.verticalSpacing = 10; + selectMarkerColorGroup.setLayout(markerColorGridLayout); + + FormData formData7 = new FormData(); + formData7.top = new FormAttachment(selectMarkerTypeGroup, 4); + formData7.left = new FormAttachment(2, 0); + formData7.right = new FormAttachment(48, 0); + formData7.height = 40; + formData7.width = 196; + selectMarkerColorGroup.setLayoutData(formData7); + + // Display Marker or not + + final Button displaySunTog = new Button(displaySunGroup, SWT.CHECK); + displaySunTog.setText("Display Marker"); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.CENTER; + gd.verticalAlignment = SWT.FILL; + displaySunTog.setLayoutData(gd); + displaySunTog.setSelection((Boolean) displaySun.getAttrValue()); + + displaySunTog.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + displaySun.setAttrValue(displaySunTog.getSelection()); + } + }); + + // Marker Type + + /* + * Use a toolbar with a single drop-down button item that pops up a + * menu, to simulate a combo that works for images. + */ + final ToolBar tb = new ToolBar(selectMarkerTypeGroup, SWT.HORIZONTAL); + final ToolItem ti = new ToolItem(tb, SWT.DROP_DOWN); + final Menu mu = new Menu(shell, SWT.POP_UP); + for (MarkerType mt : MarkerType.values()) { + MenuItem mi = new MenuItem(mu, SWT.PUSH); + mi.setData(mt); + mi.setText(mt.getDesignator()); + // TODO: Use PGEN icons via extension points; avoid ordinal + Integer ord1 = mt.ordinal() + 1; + String iconString = "icons/marker" + ord1.toString() + ".gif"; + ImageDescriptor id = Activator.imageDescriptorFromPlugin( + Activator.PLUGIN_ID, iconString); + if (id != null) { + Image icon = id.createImage(); + mi.setImage(icon); + } + mi.addListener(SWT.Selection, new Listener() { + /* + * A new marker type has been chosen off the pop-up menu: + * Remember it AND set its icon back on the main button. + */ + public void handleEvent(Event event) { + selSunMarkerType = (MarkerType) event.widget.getData(); + sunMarkerType.setAttrValue(selSunMarkerType); + Image icon = mu.getItem(selSunMarkerType.ordinal()) + .getImage(); + ti.setImage(icon); + ti.setToolTipText(selSunMarkerType.getDesignator()); + } + }); + + } + ti.addListener(SWT.Selection, new Listener() { + /* Main button clicked: Pop up the menu showing all the symbols. */ + public void handleEvent(Event event) { + Rectangle bounds = ti.getBounds(); + Point point = tb.toDisplay(bounds.x, bounds.y + bounds.height); + mu.setLocation(point); + mu.setVisible(true); + } + }); + + // Set initial state + + Image icon = mu.getItem(selSunMarkerType.ordinal()).getImage(); + ti.setImage(icon); + ti.setToolTipText(selSunMarkerType.getDesignator()); + + // Marker Size + + final Label selectMarkerSizeSliderText = new Label( + selectMarkerSizeGroup, SWT.NONE); + GridData gridData1 = new GridData(); + gridData1.horizontalIndent = 50; + selectMarkerSizeSliderText.setLayoutData(gridData1); + final Slider selectMarkerSizeSlider = new Slider(selectMarkerSizeGroup, + SWT.HORIZONTAL); + selectMarkerSizeSlider.setMinimum(5); + selectMarkerSizeSlider.setMaximum(31); + selectMarkerSizeSlider.setIncrement(1); + selectMarkerSizeSlider.setThumb(1); + selectMarkerSizeSlider.setSelection(10); + float mSize = ((Float) sunMarkerSize.getAttrValue()).floatValue(); + selectMarkerSizeSlider.setSelection((int) (mSize * 10f + 0.5)); + selectMarkerSizeSlider.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + sunMarkerSize + .setAttrValue((Float) ((float) selectMarkerSizeSlider + .getSelection() / 10)); + selectMarkerSizeSliderText.setText(sunMarkerSize.getAttrValue() + .toString()); + selectMarkerSizeSliderText.redraw(); + selectMarkerSizeSliderText.update(); + } + }); + selectMarkerSizeSliderText.setText(sunMarkerSize.getAttrValue() + .toString()); + + // Marker Width + + final Label selectMarkerWidthSliderText = new Label( + selectMarkerWidthGroup, SWT.NONE); + GridData gridData2 = new GridData(); + gridData2.horizontalIndent = 55; + selectMarkerWidthSliderText.setLayoutData(gridData2); + final Slider selectMarkerWidthSlider = new Slider( + selectMarkerWidthGroup, SWT.HORIZONTAL); + selectMarkerWidthSlider.setMinimum(1); + selectMarkerWidthSlider.setMaximum(6); + selectMarkerWidthSlider.setIncrement(1); + selectMarkerWidthSlider.setThumb(1); + selectMarkerWidthSlider.setSelection(1); + selectMarkerWidthSlider.setSelection((Integer) sunMarkerWidth + .getAttrValue()); + selectMarkerWidthSlider.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + selectMarkerWidthSliderText.setText(new Integer( + selectMarkerWidthSlider.getSelection()).toString()); + sunMarkerWidth.setAttrValue((Integer) selectMarkerWidthSlider + .getSelection()); + } + }); + selectMarkerWidthSliderText.setText(new Integer(selectMarkerWidthSlider + .getSelection()).toString()); + + // Marker Color + + final ColorButtonSelector cms = new ColorButtonSelector( + selectMarkerColorGroup, 85, 25); + cms.setColorValue((RGB) sunMarkerColor.getAttrValue()); + cms.addListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + sunMarkerColor.setAttrValue(cms.getColorValue()); + } + }); + + } + + public void createMidnightMeridianControls(Group mmGroup, + final Display display) { + + Group linePreviewAreaGroup = new Group(mmGroup, SWT.SHADOW_NONE); + linePreviewAreaGroup.setLayout(new FillLayout()); + + FormData formData0 = new FormData(); + formData0.top = new FormAttachment(2, 0); + formData0.left = new FormAttachment(2, 0); + formData0.width = 196; + formData0.height = 30; + linePreviewAreaGroup.setLayoutData(formData0); + + Group displayMMLineGroup = new Group(mmGroup, SWT.SHADOW_NONE); + displayMMLineGroup.setLayout(new FillLayout()); + + FormData formData00 = new FormData(); + formData00.top = new FormAttachment(2, 0); + formData00.left = new FormAttachment(linePreviewAreaGroup, 15); + formData00.width = 190; + formData00.height = 30; + displayMMLineGroup.setLayoutData(formData00); + + Group selectLineWidthGroup = new Group(mmGroup, SWT.SHADOW_NONE); + selectLineWidthGroup.setText("Width"); + GridLayout lineWidthGridLayout = new GridLayout(); + lineWidthGridLayout.numColumns = 2; + lineWidthGridLayout.marginHeight = 18; + lineWidthGridLayout.marginWidth = 18; + lineWidthGridLayout.horizontalSpacing = 8; + lineWidthGridLayout.verticalSpacing = 8; + selectLineWidthGroup.setLayout(lineWidthGridLayout); + + FormData formData1 = new FormData(); + formData1.top = new FormAttachment(linePreviewAreaGroup, 7); + formData1.left = new FormAttachment(2, 0); + selectLineWidthGroup.setLayoutData(formData1); + + Group selectLineStyleGroup = new Group(mmGroup, SWT.SHADOW_NONE); + selectLineStyleGroup.setText("Style"); + GridLayout lineStyleGridLayout = new GridLayout(); + lineStyleGridLayout.numColumns = 2; + lineStyleGridLayout.marginHeight = 18; + lineStyleGridLayout.marginWidth = 18; + lineStyleGridLayout.horizontalSpacing = 8; + lineStyleGridLayout.verticalSpacing = 8; + selectLineStyleGroup.setLayout(lineStyleGridLayout); + + FormData formData2 = new FormData(); + formData2.left = new FormAttachment(selectLineWidthGroup, 16); + formData2.top = new FormAttachment(displayMMLineGroup, 7); + selectLineStyleGroup.setLayoutData(formData2); + + Group selectLineColorGroup = new Group(mmGroup, SWT.SHADOW_NONE); + selectLineColorGroup.setText("Color"); + GridLayout lineColorGridLayout = new GridLayout(); + lineColorGridLayout.numColumns = 1; + lineColorGridLayout.marginHeight = 7; + lineColorGridLayout.marginWidth = 55; + lineColorGridLayout.horizontalSpacing = 0; + lineColorGridLayout.verticalSpacing = 10; + selectLineColorGroup.setLayout(lineColorGridLayout); + + FormData formData3 = new FormData(); + formData3.top = new FormAttachment(selectLineWidthGroup, 7); + formData3.left = new FormAttachment(2, 0); + formData3.width = 196; + formData3.height = 40; + selectLineColorGroup.setLayoutData(formData3); + + // Display Midnight Meridian Line or not + + final Button displayMMLineTog = new Button(displayMMLineGroup, + SWT.CHECK); + displayMMLineTog.setText("Display Meridian Line"); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.CENTER; + gd.verticalAlignment = SWT.FILL; + displayMMLineTog.setLayoutData(gd); + displayMMLineTog.setSelection((Boolean) displayMidnightMeridian + .getAttrValue()); + + displayMMLineTog.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + displayMidnightMeridian.setAttrValue(displayMMLineTog + .getSelection()); + } + }); + + final Color black = display.getSystemColor(SWT.COLOR_BLACK); + final Color white = display.getSystemColor(SWT.COLOR_WHITE); + + // Associate with each line style a list of segment lengths (in pixels) + // of the repeating pattern. Numbers are pixels on, pixels off, on, off, + // ... + // (Derived from similar structure in NMAP NxmLineA.c) + // CAUTION: Duplication (of a sort). This governs only local display of + // line patterns in this dialog (preview and line style selector + // buttons). + // Actual drawing of lines with these styles is up to the implementation + // of IGraphicsTarget being used. + + final Map styleMap = new EnumMap( + LineStyle.class); + styleMap.put(LineStyle.SOLID, new int[] { 4 }); // GEMPAK line type 1 + styleMap.put(LineStyle.SHORT_DASHED, new int[] { 4, 4 }); // GEMPAK line + // type 2 + styleMap.put(LineStyle.MEDIUM_DASHED, new int[] { 8, 8 }); // GEMPAK + // line type + // 3 + styleMap.put(LineStyle.LONG_DASH_SHORT_DASH, new int[] { 16, 8, 4, 8 }); // GEMPAK + // line + // type + // 4 + styleMap.put(LineStyle.LONG_DASHED, new int[] { 16, 8 }); // GEMPAK line + // type 5 + styleMap.put(LineStyle.LONG_DASH_THREE_SHORT_DASHES, new int[] { 16, 8, + 4, 8, 4, 8, 4, 8 }); // GEMPAK line type 6 + styleMap.put(LineStyle.LONG_DASH_DOT, new int[] { 16, 8, 2, 8 }); // GEMPAK + // line + // type + // 7 + styleMap.put(LineStyle.LONG_DASH_THREE_DOTS, new int[] { 16, 8, 2, 8, + 2, 8, 2, 8 }); // GEMPAK line type 8 + styleMap.put(LineStyle.MEDIUM_DASH_DOT, new int[] { 8, 8, 2, 8 }); // GEMPAK + // line + // type + // 9 + styleMap.put(LineStyle.DOTS, new int[] { 2, 4 }); // GEMPAK line type 10 + + // Line Preview Area + + final Canvas linePreviewAreaCanvas = new Canvas(linePreviewAreaGroup, + SWT.NONE); + + final int previewLineXmin = 16; + final int previewLineXmax = 180; + final int previewLineYctr = 16; + + linePreviewAreaCanvas.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + gc.setLineWidth((Integer) midnightMeridianLineWidth + .getAttrValue()); + gc.setForeground(new Color(display, + (RGB) midnightMeridianLineColor.getAttrValue())); + linePreviewAreaCanvas + .setBackground(((RGB) midnightMeridianLineColor + .getAttrValue()).getHSB()[2] > 0.2 ? black + : white); + int x1 = previewLineXmin; + int x2 = previewLineXmin; + int[] segLengths = styleMap + .get((LineStyle) midnightMeridianLineStyle + .getAttrValue()); + if (segLengths == null) { + return; + } + while (x2 < previewLineXmax) { + boolean draw = true; + for (int eachLineLength : segLengths) { + int calculatedLineLength = (int) (eachLineLength * lineLengthFactor); + x2 = Math.min(x1 + calculatedLineLength, + previewLineXmax); + if (draw) { + gc.drawLine(x1, previewLineYctr, x2, + previewLineYctr); + } + if (x2 >= previewLineXmax) { + break; + } + draw = !draw; + x1 = x2; + } + } + } + }); + + // Parameters to give a uniform look to all line width/style buttons + + final int lineButtonHeight = 75; + final int lineButtonWidth = 15; + final int buttonLineXmin = 8; + final int buttonLineXmax = 68; + final int buttonLineYctr = 7; + + // Line Width + + selectMmLineWidthButtons = new Button[4]; + final int[] lineWidthButtonSequence = { 0, 2, // ...for 2-column grid + // layout + 1, 3 }; + for (int i : lineWidthButtonSequence) { + selectMmLineWidthButtons[i] = new Button(selectLineWidthGroup, + SWT.TOGGLE); + GridData gridData = new GridData(); + gridData.heightHint = lineButtonWidth; + gridData.widthHint = lineButtonHeight; + selectMmLineWidthButtons[i].setLayoutData(gridData); + selectMmLineWidthButtons[i].setData(i + 1); + selectMmLineWidthButtons[i].setToolTipText("Width " + (i + 1)); + selectMmLineWidthButtons[i].addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + int width = (Integer) event.widget.getData(); + gc.setLineWidth(width); + gc.setForeground(black); + gc.drawLine(buttonLineXmin, buttonLineYctr, buttonLineXmax, + buttonLineYctr); + } + }); + selectMmLineWidthButtons[i] + .addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + selectMmLineWidthButtons[(Integer) midnightMeridianLineWidth + .getAttrValue() - 1].setSelection(false); + midnightMeridianLineWidth + .setAttrValue((Integer) event.widget + .getData()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + } + selectMmLineWidthButtons[(Integer) midnightMeridianLineWidth + .getAttrValue() - 1].setSelection(true); // set initial state + + // Line Style + mmLineStyleButtonMap = new EnumMap(LineStyle.class); + + for (LineStyle ls : lineStyleButtonSequence) { + Button lineStyleButton = new Button(selectLineStyleGroup, + SWT.TOGGLE); + mmLineStyleButtonMap.put(ls, lineStyleButton); + GridData gridData = new GridData(); + gridData.heightHint = lineButtonWidth; + gridData.widthHint = lineButtonHeight; + lineStyleButton.setLayoutData(gridData); + lineStyleButton.setData(ls); + lineStyleButton.setToolTipText(ls.name()); + lineStyleButton.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + GC gc = event.gc; + gc.setLineWidth(1); + gc.setForeground(black); + LineStyle ls = (LineStyle) event.widget.getData(); + int[] segLengths = styleMap.get(ls); + if (segLengths == null) + return; + int x1 = buttonLineXmin; + int x2 = buttonLineXmin; + while (x2 < buttonLineXmax) { + boolean draw = true; + for (int i : segLengths) { + x2 = Math.min(x1 + i, buttonLineXmax); + if (draw) { + gc.drawLine(x1, buttonLineYctr, x2, + buttonLineYctr); + } + if (x2 >= buttonLineXmax) { + break; + } + draw = !draw; + x1 = x2; + } + } + } + }); + lineStyleButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + mmLineStyleButtonMap.get( + (LineStyle) midnightMeridianLineStyle + .getAttrValue()).setSelection(false); + midnightMeridianLineStyle + .setAttrValue((LineStyle) event.widget.getData()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + } + + mmLineStyleButtonMap.get( + (LineStyle) midnightMeridianLineStyle.getAttrValue()) + .setSelection(true); + + // Line Color + + final ColorButtonSelector cms = new ColorButtonSelector( + selectLineColorGroup, 85, 25); + cms.setColorValue((RGB) midnightMeridianLineColor.getAttrValue()); + cms.addListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + midnightMeridianLineColor.setAttrValue(cms.getColorValue()); + linePreviewAreaCanvas.redraw(); + linePreviewAreaCanvas.update(); + } + }); + + } + + public void createShadingControls(Group shadeGroup, + final Composite composite) { + + Group applyShadingGroup = new Group(shadeGroup, SWT.SHADOW_NONE); + applyShadingGroup.setLayout(new FillLayout()); + + FormData formData0 = new FormData(); + formData0.top = new FormAttachment(5, 0); + formData0.left = new FormAttachment(2, 0); + formData0.width = 190; + formData0.height = 30; + applyShadingGroup.setLayoutData(formData0); + + Group selectDayShadeColorGroup = new Group(shadeGroup, SWT.SHADOW_NONE); + selectDayShadeColorGroup.setText("Day Color"); + GridLayout dayShadeColorGridLayout = new GridLayout(); + dayShadeColorGridLayout.numColumns = 1; + dayShadeColorGridLayout.marginHeight = 7; + dayShadeColorGridLayout.marginWidth = 45; + dayShadeColorGridLayout.horizontalSpacing = 0; + dayShadeColorGridLayout.verticalSpacing = 10; + selectDayShadeColorGroup.setLayout(dayShadeColorGridLayout); + + FormData formData2 = new FormData(); + formData2.top = new FormAttachment(applyShadingGroup, 7); + formData2.left = new FormAttachment(2, 0); + formData2.right = new FormAttachment(48, 0); + formData2.height = 45; + selectDayShadeColorGroup.setLayoutData(formData2); + + Group selectNightShadeColorGroup = new Group(shadeGroup, + SWT.SHADOW_NONE); + selectNightShadeColorGroup.setText("Night Color"); + GridLayout nightShadeColorGridLayout = new GridLayout(); + nightShadeColorGridLayout.numColumns = 1; + nightShadeColorGridLayout.marginHeight = 7; + nightShadeColorGridLayout.marginWidth = 45; + nightShadeColorGridLayout.horizontalSpacing = 0; + nightShadeColorGridLayout.verticalSpacing = 10; + selectNightShadeColorGroup.setLayout(nightShadeColorGridLayout); + + FormData formData4 = new FormData(); + formData4.top = new FormAttachment(selectDayShadeColorGroup, 7); + formData4.left = new FormAttachment(2, 0); + formData4.right = new FormAttachment(48, 0); + formData4.height = 45; + selectNightShadeColorGroup.setLayoutData(formData4); + + Group selectFillPatternGroup = new Group(shadeGroup, SWT.SHADOW_NONE); + selectFillPatternGroup.setText("Fill Pattern"); + GridLayout fillPatternGridLayout = new GridLayout(); + fillPatternGridLayout.numColumns = 1; + fillPatternGridLayout.marginLeft = 30; + selectFillPatternGroup.setLayout(fillPatternGridLayout); + + FormData formData1 = new FormData(); + formData1.top = new FormAttachment(5, 0); + formData1.left = new FormAttachment(selectDayShadeColorGroup, 16); + formData1.right = new FormAttachment(98, 0); + formData1.height = 55; + selectFillPatternGroup.setLayoutData(formData1); + + Group selectAlphaGroup = new Group(shadeGroup, SWT.SHADOW_NONE); + selectAlphaGroup.setText("Alpha"); + GridLayout selectAlphaGridLayout = new GridLayout(); + selectAlphaGridLayout.numColumns = 1; + selectAlphaGridLayout.marginLeft = 25; + selectAlphaGroup.setLayout(selectAlphaGridLayout); + + FormData formData3 = new FormData(); + formData3.top = new FormAttachment(selectFillPatternGroup, 7); + formData3.left = new FormAttachment(selectDayShadeColorGroup, 16); + formData3.right = new FormAttachment(98, 0); + formData3.height = 50; + selectAlphaGroup.setLayoutData(formData3); + + // Apply Shading + + final Button applyShadingTog = new Button(applyShadingGroup, SWT.CHECK); + applyShadingTog.setText("Apply Shading"); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.CENTER; + gd.verticalAlignment = SWT.FILL; + applyShadingTog.setLayoutData(gd); + applyShadingTog.setSelection((Boolean) applyShading.getAttrValue()); + + applyShadingTog.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + applyShading.setAttrValue(applyShadingTog.getSelection()); + } + }); + + // Fill Pattern + + createFillPatternAttr(selectFillPatternGroup, composite); + + // Shade Alpha + + final Label selectAlphaSliderText = new Label(selectAlphaGroup, + SWT.NONE); + GridData gridData1 = new GridData(); + gridData1.horizontalIndent = 50; + selectAlphaSliderText.setLayoutData(gridData1); + final Slider selectAlphaSizeSlider = new Slider(selectAlphaGroup, + SWT.HORIZONTAL); + selectAlphaSizeSlider.setMinimum(0); + selectAlphaSizeSlider.setMaximum(11); + selectAlphaSizeSlider.setIncrement(1); + selectAlphaSizeSlider.setThumb(1); + selectAlphaSizeSlider.setSelection(2); + float alpha = ((Float) shadeAlpha.getAttrValue()).floatValue(); + selectAlphaSizeSlider.setSelection((int) (alpha * 10f)); + selectAlphaSizeSlider.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + shadeAlpha.setAttrValue((Float) ((float) selectAlphaSizeSlider + .getSelection()) / 10.0f); + selectAlphaSliderText.setText(shadeAlpha.getAttrValue() + .toString()); + selectAlphaSliderText.redraw(); + selectAlphaSliderText.update(); + } + }); + selectAlphaSliderText.setText(shadeAlpha.getAttrValue().toString()); + + // Day Shading Color + + final ColorButtonSelector dayCms = new ColorButtonSelector( + selectDayShadeColorGroup, 85, 25); + dayCms.setColorValue((RGB) dayShadeColor.getAttrValue()); + dayCms.addListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + dayShadeColor.setAttrValue(dayCms.getColorValue()); + } + }); + + // Night Shading Color + + final ColorButtonSelector nightCms = new ColorButtonSelector( + selectNightShadeColorGroup, 85, 25); + nightCms.setColorValue((RGB) nightShadeColor.getAttrValue()); + nightCms.addListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + nightShadeColor.setAttrValue(nightCms.getColorValue()); + } + }); + } + + /* + * Create widgets for the fill patterns attribute + */ + private void createFillPatternAttr(Group group, Composite composite) { + + final ToolBar fpTb = new ToolBar(group, SWT.HORIZONTAL); + final ToolItem fpTi = new ToolItem(fpTb, SWT.DROP_DOWN); + final Menu fpMu = new Menu(shell, SWT.POP_UP); + for (FillPattern fp : FillPatternList.FillPattern.values()) { + + if (fp.equals(FillPattern.TRANSPARENCY)) + continue; + + MenuItem mi = new MenuItem(fpMu, SWT.PUSH); + mi.setData(fp); + mi.setText(fp.name()); + Integer ord1 = fp.ordinal(); + String iconString = "icons/patt" + ord1.toString() + ".gif"; + ImageDescriptor id = Activator.imageDescriptorFromPlugin( + Activator.PLUGIN_ID, iconString); + if (id != null) { + Image icon = id.createImage(); + mi.setImage(icon); + } + mi.addListener(SWT.Selection, new Listener() { + /* + * A new fill pattern has been chosen off the pop-up menu: + * Remember it AND set its icon back on the main button. + */ + public void handleEvent(Event event) { + selFillPatternType = (FillPattern) event.widget.getData(); + shadePattern.setAttrValue(selFillPatternType.name()); + Image icon = fpMu.getItem(selFillPatternType.ordinal()) + .getImage(); + fpTi.setImage(icon); + fpTi.setToolTipText(selFillPatternType.name()); + } + }); + } + fpTi.addListener(SWT.Selection, new Listener() { + /* Main button clicked: Pop up the menu showing all the symbols. */ + public void handleEvent(Event event) { + Rectangle bounds = fpTi.getBounds(); + Point point = fpTb + .toDisplay(bounds.x, bounds.y + bounds.height); + fpMu.setLocation(point); + fpMu.setVisible(true); + } + }); + + // Set initial state + + Image icon = fpMu.getItem(selFillPatternType.ordinal()).getImage(); + fpTi.setImage(icon); + fpTi.setToolTipText(selFillPatternType.name()); + + } + + public FillPattern getFillPattern(String fillPattern) { + return FillPattern.valueOf(fillPattern); + } + + @Override + public void initWidgets() { + + } + + @Override + public void createShell() { + int style = SWT.DIALOG_TRIM | SWT.RESIZE; + if (!hasApplyBtn) { + style |= SWT.APPLICATION_MODAL; + } + + shell = new Shell(getParent(), style); + shell.setText(dlgTitle); + // shell.setSize( 600, 800 ); // pack later + + GridLayout mainLayout = new GridLayout(1, true); + mainLayout.marginHeight = 1; + mainLayout.marginWidth = 1; + shell.setLayout(mainLayout); + + Composite topComp = new Composite(shell, SWT.NONE); + topComp.setLayout(new GridLayout()); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + gd.verticalAlignment = SWT.FILL; + topComp.setLayoutData(gd); + + Composite editComp = createDialog(topComp); + Label sep = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.horizontalAlignment = SWT.FILL; + sep.setLayoutData(gd); + + Composite okCanComp = new Composite(shell, SWT.NONE); + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.horizontalAlignment = SWT.CENTER; + okCanComp.setLayoutData(gd); + + okCanComp.setLayout(new GridLayout((hasApplyBtn ? 3 : 2), true)); + + Button canBtn = new Button(okCanComp, SWT.PUSH); + canBtn.setText(" Cancel "); + + canBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + ok = false; + rscData.setRscAttrSet(new ResourceAttrSet(prevRscAttrSet)); + shell.dispose(); + } + }); + + if (hasApplyBtn) { + Button applyBtn = new Button(okCanComp, SWT.PUSH); + applyBtn.setText(" Apply "); + + applyBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + rscData.setRscAttrSet(editedRscAttrSet); + rscData.setIsEdited(true); + NcDisplayMngr.getActiveNatlCntrsEditor().refresh(); + } + }); + } + + Button okBtn = new Button(okCanComp, SWT.PUSH); + okBtn.setText(" OK "); + + okBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + ok = true; + shell.dispose(); + } + }); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResource.java b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResource.java new file mode 100644 index 0000000000..997c628d7b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResource.java @@ -0,0 +1,1403 @@ +package gov.noaa.nws.ncep.viz.overlays.resources; + +import gov.noaa.nws.ncep.ui.pgen.display.DisplayElementFactory; +import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList; +import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; +import gov.noaa.nws.ncep.ui.pgen.display.IDisplayable; +import gov.noaa.nws.ncep.ui.pgen.elements.Symbol; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; +import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; + +import org.eclipse.swt.graphics.RGB; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.geospatial.MapUtil; +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.common.time.DataTime; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; +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.IMapDescriptor; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.viz.core.rsc.jts.JTSCompiler; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; + +/** + * Implements a drawing layer to draw day/night terminator line, sub-solar point + * and the midnight meridian line. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 04/24/14     1130       S. Gurung	Initial Creation
+ * 
+ * 
+ * + * @author sgurung + * + */ +public class DayNightTerminatorOverlayResource + extends + AbstractVizResource + implements INatlCntrsResource { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(DayNightTerminatorOverlayResource.class); + + private DayNightTerminatorOverlayResourceData dayNightTermOverlayResourceData; + + /** Map containing wireframeShape objects for drawing terminator line */ + private HashMap wireframeShapesMap = new HashMap(); + + /** Map containing coordinates for the terminator line */ + private HashMap terminatorCoordsMap = new HashMap(); + + private double offset = 0; + + private double viewMinX; + + private double viewMaxY; + + private double viewMinY; + + private double viewMaxX; + + private boolean needsUpdate = true; + + private double sun_lat_gse; + + private double sun_long_gse; + + private Coordinate sunPosCoord; + + protected DayNightTerminatorOverlayResource( + DayNightTerminatorOverlayResourceData llRscData, + LoadProperties props) { + super(llRscData, props); + this.dayNightTermOverlayResourceData = llRscData; + } + + private void initializeViewMinAndMaxXAndY(PaintProperties paintProps) { + viewMinX = paintProps.getView().getExtent().getMinX(); + viewMaxX = paintProps.getView().getExtent().getMaxX(); + viewMinY = paintProps.getView().getExtent().getMinY(); + viewMaxY = paintProps.getView().getExtent().getMaxY(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.core.rsc.IVizResource#dispose() + */ + public void disposeInternal() { + clearWireFrameShapesArray(wireframeShapesMap); + } + + private void clearWireFrameShapesArray( + HashMap wireframeShapesMap) { + + for (Date date : wireframeShapesMap.keySet()) { + IWireframeShape wireframeShape = wireframeShapesMap.get(date); + if (wireframeShape != null) { + wireframeShape.dispose(); + wireframeShape = null; + } + } + } + + public double getViewMinX() { + return viewMinX; + } + + public double getViewMaxY() { + return viewMaxY; + } + + public double getViewMinY() { + return viewMinY; + } + + public double getViewMaxX() { + return viewMaxX; + } + + @Override + public void resourceAttrsModified() { + needsUpdate = true; + } + + @Override + public void project(CoordinateReferenceSystem mapData) throws VizException { + needsUpdate = true; + } + + /*** + * Draws a shaded polygon with the given line color, line style and line + * width Also, clips the polygons, if necessary. + * + * @param polygonCoordinatesList + * - the list of polygon coordinates in Lat/Lon + * @param target + * - the graphics target + * @param color + * - the color of the polygon in RGB + * @param alpha + * - the alpha value + * @throws VizException + */ + private void drawShadedPolygon(Coordinate[] polygonCoordinatesList, + IGraphicsTarget target, RGB color, float alpha) throws VizException { + + if (polygonCoordinatesList != null) { + IWireframeShape wireframeShape = target.createWireframeShape(false, + descriptor, 4.0f, false, new PixelExtent(getViewMinX() + + offset, getViewMaxX() - offset, getViewMinY() + + offset, getViewMaxY() - offset)); + // JTSCompiler jtsCompiler = new JTSCompiler(null, wireframeShape, + // descriptor); + GeometryFactory gf = new GeometryFactory(); + LineString ls = gf.createLineString(polygonCoordinatesList); + + // jtsCompiler.handle(ls, color, true); + // wireframeShape.compile(); + // target.drawWireframeShape(wireframeShape, + // dayNightTermOverlayResourceData.getTermLineColor(), + // dayNightTermOverlayResourceData.getTermLineWidth(), + // dayNightTermOverlayResourceData.getTermLineStyle()); + IShadedShape shadedShape = target.createShadedShape(false, + descriptor.getGridGeometry(), true); + shadedShape.addPolygonPixelSpace(new LineString[] { ls }, color); + shadedShape.addPolygon(new LineString[] { ls }, color); + shadedShape.compile(); + + if (getFillPatternFromString(dayNightTermOverlayResourceData + .getShadePattern()) != FillPattern.TRANSPARENCY + && getFillPatternFromString(dayNightTermOverlayResourceData + .getShadePattern()) != FillPattern.SOLID) { + FillPatternList fpl = FillPatternList.getInstance(); + byte[] fpattern = fpl + .getFillPattern(getFillPatternFromString(dayNightTermOverlayResourceData + .getShadePattern())); + shadedShape.setFillPattern(fpattern); + } + target.drawShadedShape(shadedShape, alpha); + wireframeShape.dispose(); + } + + } + + /** + * Returns the fill pattern given a string. + */ + public FillPattern getFillPatternFromString(String fillPattern) { + + return FillPattern.valueOf(fillPattern); + } + + /*** + * Checks whether a point lies within a polygon. + * + * @param polygonCoordList + * - the coordinates for the main polygon + * @param toCheckCoord + * - the coordinates for the point + * @return boolean - whether a point lies within a polygon + */ + public boolean isPointWithinPolygon(Coordinate[] polygonCoordList, + Coordinate toCheckCoord) { + int[] xpoints = new int[polygonCoordList.length]; + int[] ypoints = new int[polygonCoordList.length]; + for (int ii = 0; ii < polygonCoordList.length; ii++) { + xpoints[ii] = (int) polygonCoordList[ii].x; + ypoints[ii] = (int) polygonCoordList[ii].y; + } + + java.awt.Polygon poly = new java.awt.Polygon(xpoints, ypoints, + polygonCoordList.length); + + return poly.contains(toCheckCoord.x, toCheckCoord.y); + + } + + /*** + * Checks whether a polygon is within another polygon. + * + * @param mainPolygonCoordList + * - the coordinates for the main polygon + * @param toCheckPolygonCoordList + * - the coordinates for the smaller polygon + * @return boolean - whether the polygon lies within another polygon + */ + public boolean isPolygonWithinPolygon(Coordinate[] mainPolygonCoordList, + Coordinate[] toCheckPolygonCoordList) { + + for (int ii = 0; ii < toCheckPolygonCoordList.length; ii++) { + if (isPointWithinPolygon(mainPolygonCoordList, + toCheckPolygonCoordList[ii])) { + return true; + } + } + + return false; + + } + + /*** + * Draws a midnight meridian line with the given line color, line style and + * line width. + * + * @param graphicsTarget + * - the graphics target + * @param sunPositionLon + * - longitude of the sub-solar point + * @param lineColor + * - the color of the line in RGB + * @param lineWidth + * - the width of the line in int + * @param lineStyle + * - the type of line to drawn + * @throws VizException + */ + private void drawMidnightMeridianLine(IGraphicsTarget target, + double sunPositionLon, RGB lineColor, int lineWidth, + LineStyle lineStyle) { + + // meridian for local midnight + double midnightlong = sunPositionLon + 180.0; + if (midnightlong > 180.0) { + midnightlong = midnightlong - 360.0; + } + + double[] midnightlats = new double[179]; + for (int j = 0; j < 179; j++) { + midnightlats[j] = -89 + j; + } + double[] midnightlongs = new double[179]; + for (int j = 0; j < 179; j++) { + midnightlongs[j] = midnightlong; + + } + + Coordinate[] meridianCoords = new Coordinate[179]; + for (int i = 0; i < 179; i++) { + meridianCoords[i] = new Coordinate(midnightlongs[i], + midnightlats[i]); + } + + if (meridianCoords != null) { + IWireframeShape wireframeShape = target.createWireframeShape(false, + descriptor); + + JTSCompiler jtsCompiler = new JTSCompiler(null, wireframeShape, + descriptor); + GeometryFactory gf = new GeometryFactory(); + LineString ls = gf.createLineString(meridianCoords); + + try { + jtsCompiler.handle(ls, lineColor, true); + wireframeShape.compile(); + target.drawWireframeShape(wireframeShape, lineColor, lineWidth, + lineStyle); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error when drawing midnight meridian line: " + e); + } + wireframeShape.dispose(); + } + + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#paintInternal() + */ + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + initializeViewMinAndMaxXAndY(paintProps); + // Only need to recreate the wireframeShapes if attributes or area + // changed. + if (needsUpdate) { + needsUpdate = false; + initInternal(target); + } + + Date currentFrameTime = getCurrentFrameTime(); + + if (wireframeShapesMap != null && wireframeShapesMap.size() == 1) { + currentFrameTime = (Date) (wireframeShapesMap.keySet().toArray()[0]); + } + + IWireframeShape wireframeShape = wireframeShapesMap + .get(currentFrameTime); + + Coordinate[] terminatorCoords = terminatorCoordsMap + .get(currentFrameTime); + + if (wireframeShape == null || terminatorCoords == null) { + terminatorCoords = calulateDayNightTerminator(currentFrameTime); + wireframeShape = createWireframeShape(terminatorCoords, target); + } + + if (wireframeShape != null) { + + // draw terminator line + try { + target.drawWireframeShape(wireframeShape, + dayNightTermOverlayResourceData.getTermLineColor(), + dayNightTermOverlayResourceData.getTermLineWidth(), + dayNightTermOverlayResourceData.getTermLineStyle()); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error when drawing day/night terminator line: " + e); + } + + // draw sub-solar point + sunPosCoord = SunPosition.sunPosition(currentFrameTime.getTime()); + sunPosCoord.x = MapUtil.correctLon(sunPosCoord.x); + sunPosCoord.y = MapUtil.correctLat(sunPosCoord.y); + + if (dayNightTermOverlayResourceData.getDisplaySun()) { + + Symbol sunSymbol = new Symbol(null, + new Color[] { new Color(dayNightTermOverlayResourceData + .getSunMarkerColor().red, + dayNightTermOverlayResourceData + .getSunMarkerColor().green, + dayNightTermOverlayResourceData + .getSunMarkerColor().blue) }, + dayNightTermOverlayResourceData.getSunMarkerWidth(), + dayNightTermOverlayResourceData.getSunMarkerSize(), + false, sunPosCoord, new String("Marker"), + dayNightTermOverlayResourceData.getSunMarkerType() + .toString()); + + DisplayElementFactory df = new DisplayElementFactory(target, + this.descriptor); + + ArrayList elements = df.createDisplayElements( + sunSymbol, paintProps); + for (IDisplayable each : elements) { + try { + each.draw(target, paintProps); + each.dispose(); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error when drawing sub-solar point: " + e); + } + } + + } + + // draw midnight meridian line + if (dayNightTermOverlayResourceData.getDisplayMidnightMeridian()) { + drawMidnightMeridianLine(target, sunPosCoord.x, + dayNightTermOverlayResourceData + .getMidnightMeridianLineColor(), + dayNightTermOverlayResourceData + .getMidnightMeridianLineWidth(), + dayNightTermOverlayResourceData + .getMidnightMeridianLineStyle()); + } + + // apply shading to day/night side + if (dayNightTermOverlayResourceData.getApplyShading()) { + // get polygon coordinates for the upper two and lower two + // polygons + // divided by the terminator line + terminatorCoords = calulateDayNightTerminator(currentFrameTime); + + Coordinate[] termCoordsFrom0to180 = divideTerminatorCoords( + terminatorCoords, "0to180"); + Coordinate[] termCoordsForMinus180to0 = divideTerminatorCoords( + terminatorCoords, "-180to-0"); + + Coordinate[] lowerPoly1Coords = createLowerPolygon0to180Coords(termCoordsFrom0to180); + Coordinate[] lowerPoly2Coords = createLowerPolygonMinus180to0Coords(termCoordsForMinus180to0); + Coordinate[] upperPoly1Coords = createUpperPolygon0to180Coords(termCoordsFrom0to180); + Coordinate[] upperPoly2Coords = createUpperPolygonMinus180to0Coords(termCoordsForMinus180to0); + + boolean sunInLowerPolygon = true; + if (isPointWithinPolygon(lowerPoly1Coords, sunPosCoord) + || isPointWithinPolygon(lowerPoly2Coords, sunPosCoord)) { + sunInLowerPolygon = true; + + // day side + drawShadedPolygon(lowerPoly1Coords, target, + dayNightTermOverlayResourceData.getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + drawShadedPolygon(lowerPoly2Coords, target, + dayNightTermOverlayResourceData.getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + + // night side + drawShadedPolygon(upperPoly1Coords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + drawShadedPolygon(upperPoly2Coords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + + } else if (isPointWithinPolygon(upperPoly1Coords, sunPosCoord) + || isPointWithinPolygon(upperPoly2Coords, sunPosCoord)) { + + sunInLowerPolygon = false; + + // day side + drawShadedPolygon(upperPoly1Coords, target, + dayNightTermOverlayResourceData.getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + drawShadedPolygon(upperPoly2Coords, target, + dayNightTermOverlayResourceData.getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + + // night side + drawShadedPolygon(lowerPoly1Coords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + drawShadedPolygon(lowerPoly2Coords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + } + + // get polygon coordinates for the north pole and the south pole + Coordinate[] northPolygonCoords = createNorthPolePolygonCoords( + target, terminatorCoords); + Coordinate[] southPolygonCoords = createSouthPolePolygonCoords( + target, terminatorCoords); + + // apply shading (based on day or night) to the north and south + // pole polygons + if (isPolygonWithinPolygon(lowerPoly1Coords, southPolygonCoords) + || isPolygonWithinPolygon(lowerPoly2Coords, + southPolygonCoords)) { + + if (sunInLowerPolygon) { + // polygon in the south pole is in the day side + drawShadedPolygon(southPolygonCoords, target, + dayNightTermOverlayResourceData + .getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + // polygon in the north pole is in the night side + drawShadedPolygon(northPolygonCoords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + } else { + // polygon in the south pole is in the night side + drawShadedPolygon(southPolygonCoords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + // polygon in the north pole is in the day side + drawShadedPolygon(northPolygonCoords, target, + dayNightTermOverlayResourceData + .getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + } + } + if (isPolygonWithinPolygon(upperPoly1Coords, northPolygonCoords) + || isPolygonWithinPolygon(upperPoly2Coords, + northPolygonCoords)) { + + if (sunInLowerPolygon) { + // polygon in the north pole is in the day side + drawShadedPolygon(northPolygonCoords, target, + dayNightTermOverlayResourceData + .getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + // polygon in the south pole is in the day side + drawShadedPolygon(southPolygonCoords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + } else { + // polygon in the north pole is in the night side + drawShadedPolygon(northPolygonCoords, target, + dayNightTermOverlayResourceData + .getNightShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + // polygon in the south pole is in the day side + drawShadedPolygon(southPolygonCoords, target, + dayNightTermOverlayResourceData + .getDayShadeColor(), + dayNightTermOverlayResourceData.getShadeAlpha()); + } + } + + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal() + */ + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + + // get frame times from the current active editor + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + + if (editor == null + || NcEditorUtil.getNcDisplayType(editor) != NcDisplayType.NMAP_DISPLAY) { + throw new VizException("The active editor is not an NMAP display."); + } + + IDisplayPane activePane = editor.getActiveDisplayPane(); + FramesInfo info = activePane.getDescriptor().getFramesInfo(); + DataTime[] frameTimes = info.getFrameTimes(); + + if (frameTimes != null) { + + // For each frameTime, calculate the coordinates for the day/night + // terminator line , create wireframe shape + // and put the wireframe shape and the terminator coordinates in + // appropriate maps. + for (DataTime frameTime : frameTimes) { + Coordinate[] terminatorCoords = calulateDayNightTerminator(frameTime + .getRefTime()); + terminatorCoordsMap.put(frameTime.getRefTime(), + terminatorCoords); + + IWireframeShape wireframeShape = createWireframeShape( + terminatorCoords, target); + wireframeShapesMap.put(frameTime.getRefTime(), wireframeShape); + } + } + + } + + /*** + * Divide the terminator curve coordinates into two sections (from lon 0 to + * 180 and -180 to 0) and return the coordinates based on the type + * requested. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * @param type + * - the requested type (0to180 or -180to0) + * @return the list of coordinates based on the type passed (0to180 or + * -180to0) + */ + private Coordinate[] divideTerminatorCoords(Coordinate[] terminatorCoords, + String type) { + + List terminatorCoordList = new ArrayList(); + for (int i = 0; i < terminatorCoords.length; i++) { + terminatorCoordList.add(terminatorCoords[i]); + } + // sort by longitude + Collections.sort(terminatorCoordList, CoordLonComparator); + + List polygon1CoordList = new ArrayList(); + List polygon2CoordList = new ArrayList(); + + for (int i = 0; i < terminatorCoordList.size(); i++) { + if (terminatorCoordList.get(i).x >= 0) { + // coordinates with longitude from 0 to 180 + polygon1CoordList.add(terminatorCoordList.get(i)); + } else { + // coordinates with longitude from -180 to 0 + polygon2CoordList.add(terminatorCoordList.get(i)); + } + } + + if ("0to180".equals(type)) { + Coordinate[] poly1CoordArray = new Coordinate[polygon1CoordList + .size()]; + + for (int i = 0; i < polygon1CoordList.size(); i++) { + poly1CoordArray[i] = polygon1CoordList.get(i); + } + return poly1CoordArray; + } else { + Coordinate[] poly2CoordArray = new Coordinate[polygon2CoordList + .size()]; + for (int i = 0; i < polygon2CoordList.size(); i++) { + poly2CoordArray[i] = polygon2CoordList.get(i); + } + + return poly2CoordArray; + } + } + + /*** + * Creates the list of coordinates for the lower polygon (from lon 0 to 180) + * that needs to be shaded. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the for the lower polygon (from lon 0 + * to 180) + */ + private Coordinate[] createLowerPolygon0to180Coords( + Coordinate[] terminatorCoords) { + List polyCoordList = new ArrayList(); + + for (int i = 0; i < terminatorCoords.length; i++) { + polyCoordList.add(terminatorCoords[i]); + } + + Coordinate polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + double lastLat = polyLastCoord.y; + double lastLon = polyLastCoord.x; + double startLat = polyCoordList.get(0).y; + double startLon = polyCoordList.get(0).x; + + polyCoordList.add(0, new Coordinate(0.0, startLat)); + polyCoordList.add(new Coordinate(180, lastLat)); + + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLat = polyLastCoord.y; + lastLon = polyLastCoord.x; + startLat = polyCoordList.get(0).y; + startLon = polyCoordList.get(0).x; + + while (lastLat >= -80) { + double tmpLat = lastLat--; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyLastCoord.x, -80.0)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLon >= 0) { + double tmpLon = lastLon--; + Coordinate tmp = new Coordinate(tmpLon, polyLastCoord.y); + polyCoordList.add(tmp); + } + + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLat <= startLat) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyCoordList.get(0).x, polyCoordList + .get(0).y)); + + Coordinate[] polyCoordArray = new Coordinate[polyCoordList.size()]; + for (int i = 0; i < polyCoordList.size(); i++) { + polyCoordArray[i] = polyCoordList.get(i); + } + + return polyCoordArray; + } + + /*** + * Creates the list of coordinates for the lower polygon (from lon 180 to 0) + * that needs to be shaded. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the lower polygon (from lon -180 to + * 0) + */ + private Coordinate[] createLowerPolygonMinus180to0Coords( + Coordinate[] terminatorCoords) { + List polyCoordList = new ArrayList(); + + for (int i = 0; i < terminatorCoords.length; i++) { + polyCoordList.add(terminatorCoords[i]); + } + + Coordinate polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + double lastLat = polyLastCoord.y; + double lastLon = polyLastCoord.x; + double startLat = polyCoordList.get(0).y; + double startLon = polyCoordList.get(0).x; + + polyCoordList.add(0, new Coordinate(-180.0, startLat)); + polyCoordList.add(new Coordinate(-0.01, lastLat)); + + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLat = polyLastCoord.y; + lastLon = polyLastCoord.x; + startLat = polyCoordList.get(0).y; + startLon = polyCoordList.get(0).x; + + while (lastLat >= -80) { + double tmpLat = lastLat--; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + polyCoordList.add(new Coordinate(polyLastCoord.x, -80.0)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLon >= -180) { + double tmpLon = lastLon--; + Coordinate tmp = new Coordinate(tmpLon, polyLastCoord.y); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(-180.00, polyLastCoord.y)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLat <= startLat) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyCoordList.get(0).x, polyCoordList + .get(0).y)); + + Coordinate[] polyCoordArray = new Coordinate[polyCoordList.size()]; + for (int i = 0; i < polyCoordList.size(); i++) { + polyCoordArray[i] = polyCoordList.get(i); + } + + return polyCoordArray; + } + + /*** + * Creates the list of coordinates for the upper polygon (from lon 0 to 180) + * that needs to be shaded. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the for the upper polygon (from lon 0 + * to 180) + */ + private Coordinate[] createUpperPolygon0to180Coords( + Coordinate[] terminatorCoords) { + List polyCoordList = new ArrayList(); + + for (int i = 0; i < terminatorCoords.length; i++) { + polyCoordList.add(terminatorCoords[i]); + } + + Coordinate polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + double lastLat = polyLastCoord.y; + double lastLon = polyLastCoord.x; + double startLat = polyCoordList.get(0).y; + double startLon = polyCoordList.get(0).x; + + polyCoordList.add(0, new Coordinate(0.001, startLat)); + polyCoordList.add(new Coordinate(180, lastLat)); + + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLat = polyLastCoord.y; + lastLon = polyLastCoord.x; + startLat = polyCoordList.get(0).y; + startLon = polyCoordList.get(0).x; + + while (lastLat <= 80) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyLastCoord.x, 80.0)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLon >= 0) { + double tmpLon = lastLon--; + Coordinate tmp = new Coordinate(tmpLon, polyLastCoord.y); + polyCoordList.add(tmp); + } + + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + while (lastLat >= startLat) { + double tmpLat = lastLat--; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyCoordList.get(0).x, polyCoordList + .get(0).y)); + + Coordinate[] polyCoordArray = new Coordinate[polyCoordList.size()]; + for (int i = 0; i < polyCoordList.size(); i++) { + polyCoordArray[i] = polyCoordList.get(i); + } + + return polyCoordArray; + } + + /*** + * Creates the list of coordinates for the upper polygon (from lon 180 to 0) + * that needs to be shaded. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the upper polygon (from lon -180 to + * 0) + */ + private Coordinate[] createUpperPolygonMinus180to0Coords( + Coordinate[] terminatorCoords) { + List polyCoordList = new ArrayList(); + + for (int i = 0; i < terminatorCoords.length; i++) { + polyCoordList.add(terminatorCoords[i]); + } + + Coordinate polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + double lastLat = polyLastCoord.y; + double lastLon = polyLastCoord.x; + double startLat = polyCoordList.get(0).y; + double startLon = polyCoordList.get(0).x; + + polyCoordList.add(0, new Coordinate(-180.00, startLat)); + polyCoordList.add(new Coordinate(-0.001, lastLat)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLat = polyLastCoord.y; + lastLon = polyLastCoord.x; + startLat = polyCoordList.get(0).y; + startLon = polyCoordList.get(0).x; + + while (lastLat <= 80) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyLastCoord.x, 80.0)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLon >= -180) { + double tmpLon = lastLon--; + Coordinate tmp = new Coordinate(tmpLon, polyLastCoord.y); + polyCoordList.add(tmp); + } + polyCoordList.add(new Coordinate(-180.0, polyLastCoord.y)); + polyLastCoord = polyCoordList.get(polyCoordList.size() - 1); + lastLon = polyLastCoord.x; + lastLat = polyLastCoord.y; + + while (lastLat <= startLat) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyLastCoord.x, tmpLat); + polyCoordList.add(tmp); + } + + polyCoordList.add(new Coordinate(polyCoordList.get(0).x, polyCoordList + .get(0).y)); + + Coordinate[] polyCoordArray = new Coordinate[polyCoordList.size()]; + for (int i = 0; i < polyCoordList.size(); i++) { + polyCoordArray[i] = polyCoordList.get(i); + } + + return polyCoordArray; + } + + /*** + * Creates the list of coordinates for the area (from lat 80 to 90) in the + * north pole that needs to be shaded. + * + * @param target + * - the graphics target + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the area in the north pole + */ + private Coordinate[] createNorthPolePolygonCoords(IGraphicsTarget target, + Coordinate[] terminatorCoordList) { + List polyNorthCoordList = new ArrayList(); + polyNorthCoordList.add(new Coordinate(0.0, 90.0)); + + Coordinate polyNorthLastCoord = polyNorthCoordList + .get(polyNorthCoordList.size() - 1); + + double lastLat = polyNorthLastCoord.y; + double lastLon = polyNorthLastCoord.x; + double startLat = polyNorthCoordList.get(0).y; + double startLon = polyNorthCoordList.get(0).x; + + while (lastLat >= 80) { + double tmpLat = lastLat--; + Coordinate tmp = new Coordinate(polyNorthLastCoord.x, tmpLat); + polyNorthCoordList.add(tmp); + } + + polyNorthLastCoord = polyNorthCoordList + .get(polyNorthCoordList.size() - 1); + lastLon = polyNorthLastCoord.x; + lastLat = polyNorthLastCoord.y; + + polyNorthCoordList.add(new Coordinate(lastLon, lastLat)); + polyNorthLastCoord = polyNorthCoordList + .get(polyNorthCoordList.size() - 1); + lastLon = polyNorthLastCoord.x; + lastLat = polyNorthLastCoord.y; + + while (lastLon <= 360) { + double tmpLon = lastLon++; + Coordinate tmp = new Coordinate(MapUtil.correctLon(tmpLon), + polyNorthLastCoord.y); + polyNorthCoordList.add(tmp); + } + + polyNorthLastCoord = polyNorthCoordList + .get(polyNorthCoordList.size() - 1); + lastLon = polyNorthLastCoord.x; + lastLat = polyNorthLastCoord.y; + + while (lastLat <= startLat) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polyNorthLastCoord.x, tmpLat); + polyNorthCoordList.add(tmp); + } + + polyNorthCoordList.add(new Coordinate(polyNorthCoordList.get(0).x, + polyNorthCoordList.get(0).y)); + + Coordinate[] polyNorthCoordArray = new Coordinate[polyNorthCoordList + .size()]; + for (int i = 0; i < polyNorthCoordList.size(); i++) { + polyNorthCoordArray[i] = polyNorthCoordList.get(i); + } + + return polyNorthCoordArray; + } + + /*** + * Creates the list of coordinates for the area (from lat -80 to -90) in the + * south pole that needs to be shaded. + * + * @param target + * - the graphics target + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * + * @return the list of coordinates for the area in the south pole + */ + private Coordinate[] createSouthPolePolygonCoords(IGraphicsTarget target, + Coordinate[] terminatorCoordList) { + List polySouthCoordList = new ArrayList(); + polySouthCoordList.add(0, new Coordinate(0.0, -90.0)); + + Coordinate polySouthLastCoord = polySouthCoordList + .get(polySouthCoordList.size() - 1); + + double lastLat = polySouthLastCoord.y; + double lastLon = polySouthLastCoord.x; + double startLat = polySouthCoordList.get(0).y; + double startLon = polySouthCoordList.get(0).x; + + while (lastLat <= -80) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polySouthLastCoord.x, tmpLat); + polySouthCoordList.add(tmp); + } + + polySouthLastCoord = polySouthCoordList + .get(polySouthCoordList.size() - 1); + lastLon = polySouthLastCoord.x; + lastLat = polySouthLastCoord.y; + + polySouthCoordList.add(new Coordinate(lastLon, lastLat)); + polySouthLastCoord = polySouthCoordList + .get(polySouthCoordList.size() - 1); + lastLon = polySouthLastCoord.x; + lastLat = polySouthLastCoord.y; + + while (lastLon <= 360) { + double tmpLon = lastLon++; + Coordinate tmp = new Coordinate(MapUtil.correctLon(tmpLon), + polySouthLastCoord.y); + polySouthCoordList.add(tmp); + } + + polySouthLastCoord = polySouthCoordList + .get(polySouthCoordList.size() - 1); + lastLon = polySouthLastCoord.x; + lastLat = polySouthLastCoord.y; + + while (lastLat <= startLat) { + double tmpLat = lastLat++; + Coordinate tmp = new Coordinate(polySouthLastCoord.x, tmpLat); + polySouthCoordList.add(tmp); + } + + polySouthCoordList.add(new Coordinate(polySouthCoordList.get(0).x, + polySouthCoordList.get(0).y)); + + Coordinate[] polySouthCoordArray = new Coordinate[polySouthCoordList + .size()]; + for (int i = 0; i < polySouthCoordList.size(); i++) { + polySouthCoordArray[i] = polySouthCoordList.get(i); + } + + return polySouthCoordArray; + } + + /*** + * Creates the wireframe shape given the list of coordinates. + * + * @param terminatorCoords + * - the lat/lon coordinates for the terminator curve + * @param target + * - the graphics target + * + * @return wireframeShape + */ + private IWireframeShape createWireframeShape(Coordinate[] terminatorCoords, + IGraphicsTarget target) { + + IWireframeShape wireframeShape = target.createWireframeShape(false, + descriptor); + + JTSCompiler jtsCompiler = new JTSCompiler(null, wireframeShape, + descriptor); + GeometryFactory gf = new GeometryFactory(); + LineString ls = gf.createLineString(terminatorCoords); + + try { + jtsCompiler.handle(ls, new RGB(255, 255, 255), true); + wireframeShape.compile(); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error when creating wireframes." + e); + return null; + } + return wireframeShape; + + } + + /*** + * Returns the current frame time for the active NCMap display. If current + * active NCMap display does not have any frame times, returns the current + * date. + * + * @return date + */ + public Date getCurrentFrameTime() { + + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + + FramesInfo info = activePane.getDescriptor().getFramesInfo(); + DataTime[] frameTimes = info.getFrameTimes(); + + if (frameTimes != null && frameTimes.length > 0) { + return info.getCurrentFrame().getRefTime(); + } + + return new Date(); + } + + /*** + * Calculates the lat/lon coordinates for the day/night terminator line for + * a given date + * + * @param date + * - the date for which the coordinates for the terminator line + * is to be calculated + * @return Coordinate[] - array of lat/lon coordinates for the day/night + * terminator line + */ + public Coordinate[] calulateDayNightTerminator(Date date) { + + // Calculate the number of days between what was input + // and January 1, 1974 00:00:00 + // (example, so that January 1, 1974 12:00:00 is 0.5) + + // begin by setting some variables that are relevant to + // the passed in current time + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTime(date); + + int hh = cal.get(Calendar.HOUR_OF_DAY); + int mm = cal.get(Calendar.MINUTE); + int ss = cal.get(Calendar.SECOND); + int doy = cal.get(Calendar.DAY_OF_YEAR); + + double curday = getJulianDate(cal); + + double frac_hr = (hh + mm / 60d + ss / 3600d) - 6d; + + double DTOR = 0.0174532925199433; + // + // Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // cal1.set(Calendar.YEAR, 1975); + // cal1.set(Calendar.MONTH, Calendar.JANUARY); + // cal1.set(Calendar.DAY_OF_YEAR, 1); + // cal1.set(Calendar.HOUR_OF_DAY, 0); + // cal1.set(Calendar.MINUTE, 0); + // cal1.set(Calendar.SECOND, 0); + // + // // Duffet-Smith time + // double duffday = getJulianDate(cal1); + // double days_between = curday + (hh + mm / 60d + ss / 3600d) / 24d + // - duffday; + // + // // Mean anomaly - Subtract full rotations + // double xm = days_between * (0.017202424d) - 6.0544180138855d - 2; + // + // // Number of full rotations + // double iyr = Math.floor(xm / (2 * Math.PI)); + // + // // Mean anomaly in radians + // double xmean = xm - 2d * Math.PI * iyr; + // + // // double N = ORBIT_RADS_PER_DAY * daysSinceEpoch; + // // N %= TWO_PI; + // // if (N < 0) + // // N += TWO_PI; + // // + // // double M0 = N + epsilon_g - omega_bar_g; + // // if (M0 < 0) + // // M0 += TWO_PI; + // + // // System.out.println(" --- swpc algorithm mean anomaly = " + xmean); + // + // // Eccentric anomaly + // double xecc = xmean + (0.016720 * Math.sin(xmean)) + // + (0.5 * (2.795584d - 4) * Math.sin(xmean * 2)); + // double x = 1.0168621 * Math.tan(0.5 * xecc); + // + // // True anomaly + // double xtrue = 2 * Math.atan(x); + // + // // Safe keeping while checking if xtrue is off by PI + // double xt = xtrue; + // + // // True anomaly + // double xta = xmean - (2 * 0.0168621 * Math.sin(xmean)); + // + // // if xtrue/2 is off by PI, xtrue will be off by 2*PI + // if (Math.abs(xtrue * xta) > (Math.PI / 10d)) { + // if (xtrue > xta) { + // xtrue = xtrue - 2 * Math.PI; + // } else { + // xtrue = xtrue + 2 * Math.PI; + // } + // } + // // Lambda is the angle between solar radius vector and celestial + // x-axis + // double xlam = xtrue - 1.3524488; + // double clam = Math.cos(xlam); + // double slam = Math.sin(xlam); + // double cs_th_sun = slam * 0.397681215556; + // + // double sn_th_sun = Math.pow((1.0 - cs_th_sun * cs_th_sun), 0.5); + // double cs_ph_sun = clam / sn_th_sun; + // double sn_ph_sun = slam * (0.917523651354d / sn_th_sun); + // + // // Calcluate Greenwich Mean Sidereal time + // double n_days_elapsed = Math.floor(days_between); + // double frac_days_elapsed = days_between - n_days_elapsed; + // double elapsed_years = Math.floor(n_days_elapsed / 365); + // double day_defect = n_days_elapsed - elapsed_years * 365d; + // double gmst = (frac_days_elapsed * 24.06588) + (day_defect * + // 0.065709) + // - (elapsed_years * 0.015917) - 17.397221; + // if (gmst < 24) + // gmst = gmst + 24; + // gmst = gmst * Math.PI / 12d; + // + // // Rotate the x-axis from Geocentric Ecliptic coordinates to + // Geographic + // // coordinates + // double[][] rot_mat1 = new double[3][3]; + // rot_mat1[0][0] = sn_th_sun * cs_ph_sun; + // rot_mat1[0][1] = -1.0 + // * (0.397681215556 * cs_th_sun + 0.917523651354 * sn_th_sun + // * sn_ph_sun); + // rot_mat1[0][2] = 0.0; + // rot_mat1[1][0] = sn_th_sun * sn_ph_sun; + // rot_mat1[1][1] = 0.917523651354 * sn_th_sun * cs_ph_sun; + // rot_mat1[1][2] = -0.397681215556d; + // rot_mat1[2][0] = cs_th_sun; + // rot_mat1[2][1] = 0.397681215556 * sn_th_sun * cs_ph_sun; + // rot_mat1[2][2] = 0.917523651354; + // + // double[][] gam_mat = new double[3][3]; + // gam_mat[0][0] = Math.cos(gmst); + // gam_mat[0][1] = Math.sin(gmst); + // gam_mat[0][2] = 0; + // gam_mat[1][0] = -Math.sin(gmst); + // gam_mat[1][1] = Math.cos(gmst); + // gam_mat[1][2] = 0; + // gam_mat[2][0] = 0; + // gam_mat[2][1] = 0; + // gam_mat[2][2] = 1; + // + // double[][] rot_mat = new double[3][3]; + // for (int i = 0; i <= 2; i++) { + // rot_mat[i][0] = gam_mat[i][0] * rot_mat1[0][0] + gam_mat[i][1] + // * rot_mat1[1][0] + gam_mat[i][2] * rot_mat1[2][0]; + // } + // + // // rotate only the x-axis with position vector [1,0,0] + // double xprim = rot_mat[0][0]; + // double yprim = rot_mat[1][0]; + // double zprim = rot_mat[2][0]; + // + // + // + // double dist = Math.pow((xprim * xprim + yprim * yprim + zprim * + // zprim), + // 0.5); + // sun_lat_gse = 90 - Math.asin(zprim / dist) / DTOR; + // sun_long_gse = Math.atan2(yprim, xprim) / DTOR; + // + // + // if (sun_long_gse < 0) { + // sun_long_gse = 360 + sun_long_gse; + // } + // + // sun_lat_gse = 90 - sun_lat_gse; + // if (sun_long_gse > 180) { + // sun_long_gse = sun_long_gse - 360; + // } + + // Calculate the zenith angle and eccentricity + double delta = 23.44 * Math.sin((0.9856 * (doy - 80.7)) * DTOR); + + Coordinate sunPosCoord = SunPosition.sunPosition(date.getTime()); + sun_long_gse = sunPosCoord.x; + sun_lat_gse = sunPosCoord.y; + + Coordinate[] terminatorCoordArray = new Coordinate[360]; + + // formula for the terminator line + for (int d = 0; d <= 359; d++) { + double param = Math.sin(d * DTOR) * Math.cos(sun_lat_gse * DTOR); + double theta_t = Math.asin(param) / DTOR; + + double param1 = Math.sin(theta_t * DTOR) + * Math.sin(sun_lat_gse * DTOR); + double param2 = Math.cos(sun_lat_gse * DTOR) * Math.cos(d * DTOR); + double lambda_t = Math.atan2(-param1, param2) / DTOR; + lambda_t = lambda_t - frac_hr * 15.0; + if (lambda_t < -180) { + lambda_t = lambda_t + 360; + } + terminatorCoordArray[d] = new Coordinate( + MapUtil.correctLon(lambda_t), MapUtil.correctLat(theta_t)); + + } + + return terminatorCoordArray; + + } + + /*** + * Converts a date to julian date + * + * @param calendarDate + * - the date for which needs to be converted + * @return double - converted julian date in ms + */ + public static double getJulianDate(Calendar calendarDate) { + + int year = calendarDate.get(Calendar.YEAR); + int month = calendarDate.get(Calendar.MONTH) + 1; + int day = calendarDate.get(Calendar.DAY_OF_MONTH); + double hour = calendarDate.get(Calendar.HOUR_OF_DAY); + double minute = calendarDate.get(Calendar.MINUTE); + double second = calendarDate.get(Calendar.SECOND); + int isGregorianCal = 1; + int A; + int B; + int C; + int D; + double fraction = day + + ((hour + (minute / 60) + (second / 60 / 60)) / 24); + + if (year < 1582) { + isGregorianCal = 0; + } + + if (month < 3) { + year = year - 1; + month = month + 12; + } + + A = year / 100; + B = (2 - A + (A / 4)) * isGregorianCal; + + if (year < 0) { + C = (int) ((365.25 * year) - 0.75); + } else { + C = (int) (365.25 * year); + } + + D = (int) (30.6001 * (month + 1)); + double JD = B + C + D + 1720994.5 + fraction; + + // test + if (month <= 2) { + year -= 1; + month += 12; + } + double Aa = Math.floor(year / 100); + double Bb = 2 - Aa + Math.floor(Aa / 4); + + JD = Math.floor(365.25 * (year + 4716)) + + Math.floor(30.6001 * (month + 1)) + day + Bb - 1524.5; + // end test + + return JD; + } + + /** + * Comparator class to compare longitudes of two coordinates + */ + Comparator CoordLonComparator = new Comparator() { + @Override + public int compare(Coordinate o1, Coordinate o2) { + return new Double(o1.x).compareTo(o2.x); + } + }; + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResourceData.java b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResourceData.java new file mode 100644 index 0000000000..730cfbd6d4 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/DayNightTerminatorOverlayResourceData.java @@ -0,0 +1,365 @@ +package gov.noaa.nws.ncep.viz.overlays.resources; + +import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerType; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResourceData; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * Resource to draw day/night terminator line, sub-solar point marker and + * midnight meridian line + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date           Ticket#    Engineer    Description
+ * ------------   ---------- ----------- --------------------------
+ * 04/24/2014     1130       S. Gurung   Initial creation
+ * 
+ * 
+ * + * + * @author sgurung + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "NC-DayNightTerminatorOverlayResourceData") +public class DayNightTerminatorOverlayResourceData extends + AbstractNatlCntrsResourceData { + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB termLineColor = new RGB(0, 0, 255); + + @XmlElement + private int termLineWidth = 1; + + @XmlElement + private LineStyle termLineStyle; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB sunMarkerColor = new RGB(255, 165, 79); + + @XmlElement + private MarkerType sunMarkerType = MarkerType.ASTERISK; + + @XmlElement + private Float sunMarkerSize = 1.3f; + + @XmlElement + private Integer sunMarkerWidth = 2; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB dayShadeColor = new RGB(255, 165, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB nightShadeColor = new RGB(30, 30, 163); + + @XmlElement + private Float shadeAlpha = 0.5f; + + @XmlElement + private String shadePattern; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB midnightMeridianLineColor = new RGB(127, 127, 127); + + @XmlElement + private int midnightMeridianLineWidth = 1; + + @XmlElement + private LineStyle midnightMeridianLineStyle; + + @XmlElement + private boolean displaySun = true; + + @XmlElement + private boolean applyShading = false; + + @XmlElement + private boolean displayMidnightMeridian = false; + + public DayNightTerminatorOverlayResourceData() { + super(); + this.nameGenerator = new AbstractNameGenerator() { + @Override + public String getName(AbstractVizResource resource) { + return "Day/Night Terminator"; + } + }; + } + + @Override + public DayNightTerminatorOverlayResource constructResource( + LoadProperties loadProperties, IDescriptor descriptor) + throws VizException { + DayNightTerminatorOverlayResource resource = new DayNightTerminatorOverlayResource( + this, loadProperties); + return resource; + } + + public int getTermLineWidth() { + return termLineWidth; + } + + public void setTermLineWidth(int lineWidth) { + this.termLineWidth = lineWidth; + } + + public RGB getTermLineColor() { + return termLineColor; + } + + public void setTermLineColor(RGB color) { + this.termLineColor = color; + this.legendColor = termLineColor; + } + + public LineStyle getTermLineStyle() { + return termLineStyle; + } + + public void setTermLineStyle(LineStyle termLineStyle) { + this.termLineStyle = termLineStyle; + } + + public RGB getSunMarkerColor() { + return sunMarkerColor; + } + + public void setSunMarkerColor(RGB sunColor) { + this.sunMarkerColor = sunColor; + } + + public MarkerType getSunMarkerType() { + return sunMarkerType; + } + + public void setSunMarkerType(MarkerType sunMarkerType) { + this.sunMarkerType = sunMarkerType; + } + + public Float getSunMarkerSize() { + return sunMarkerSize; + } + + public void setSunMarkerSize(Float sunMarkerSize) { + this.sunMarkerSize = sunMarkerSize; + } + + public Integer getSunMarkerWidth() { + return sunMarkerWidth; + } + + public void setSunMarkerWidth(Integer sunMarkerWidth) { + this.sunMarkerWidth = sunMarkerWidth; + } + + public RGB getDayShadeColor() { + return dayShadeColor; + } + + public void setDayShadeColor(RGB dayShadeColor) { + this.dayShadeColor = dayShadeColor; + } + + public RGB getNightShadeColor() { + return nightShadeColor; + } + + public void setNightShadeColor(RGB nightShadeColor) { + this.nightShadeColor = nightShadeColor; + } + + public RGB getMidnightMeridianLineColor() { + return midnightMeridianLineColor; + } + + public void setMidnightMeridianLineColor(RGB midnightMeridianLineColor) { + this.midnightMeridianLineColor = midnightMeridianLineColor; + } + + public int getMidnightMeridianLineWidth() { + return midnightMeridianLineWidth; + } + + public void setMidnightMeridianLineWidth(int midnightMeridianLineWidth) { + this.midnightMeridianLineWidth = midnightMeridianLineWidth; + } + + public LineStyle getMidnightMeridianLineStyle() { + return midnightMeridianLineStyle; + } + + public void setMidnightMeridianLineStyle(LineStyle midnightMeridianLineStyle) { + this.midnightMeridianLineStyle = midnightMeridianLineStyle; + } + + public boolean getDisplaySun() { + return displaySun; + } + + public void setDisplaySun(boolean displaySun) { + this.displaySun = displaySun; + } + + public boolean getApplyShading() { + return applyShading; + } + + public void setApplyShading(boolean applyShading) { + this.applyShading = applyShading; + } + + public boolean getDisplayMidnightMeridian() { + return displayMidnightMeridian; + } + + public void setDisplayMidnightMeridian(boolean displayMidnightMeridian) { + this.displayMidnightMeridian = displayMidnightMeridian; + } + + public Float getShadeAlpha() { + return shadeAlpha; + } + + public void setShadeAlpha(Float shadeAlpha) { + this.shadeAlpha = shadeAlpha; + } + + public String getShadePattern() { + return shadePattern; + } + + public void setShadePattern(String shadePattern) { + this.shadePattern = shadePattern; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + DayNightTerminatorOverlayResourceData other = (DayNightTerminatorOverlayResourceData) obj; + if (termLineColor == null) { + if (other.termLineColor != null) + return false; + } else if (!termLineColor.equals(other.termLineColor)) + return false; + if (termLineWidth != other.termLineWidth) + return false; + if (termLineStyle == null) { + if (other.termLineStyle != null) + return false; + } else if (!termLineStyle.equals(other.termLineStyle)) + return false; + if (sunMarkerColor == null) { + if (other.sunMarkerColor != null) + return false; + } else if (!sunMarkerColor.equals(other.sunMarkerColor)) + return false; + + if (sunMarkerType == null) { + if (other.sunMarkerType != null) + return false; + } else if (!sunMarkerType.equals(other.sunMarkerType)) + return false; + if (sunMarkerSize != other.sunMarkerSize) + return false; + if (sunMarkerWidth != other.sunMarkerWidth) + return false; + + if (dayShadeColor == null) { + if (other.dayShadeColor != null) + return false; + } else if (!dayShadeColor.equals(other.dayShadeColor)) + return false; + if (nightShadeColor == null) { + if (other.nightShadeColor != null) + return false; + } else if (!nightShadeColor.equals(other.nightShadeColor)) + return false; + if (shadeAlpha != other.shadeAlpha) + return false; + if (shadePattern != other.shadePattern) + return false; + + if (midnightMeridianLineColor == null) { + if (other.termLineColor != null) + return false; + } else if (!midnightMeridianLineColor + .equals(other.midnightMeridianLineColor)) + return false; + if (midnightMeridianLineWidth != other.midnightMeridianLineWidth) + return false; + if (midnightMeridianLineStyle == null) { + if (other.midnightMeridianLineStyle != null) + return false; + } else if (!midnightMeridianLineStyle + .equals(other.midnightMeridianLineStyle)) + return false; + + if (displaySun != other.displaySun) + return false; + + if (applyShading != other.applyShading) + return false; + + if (displayMidnightMeridian != other.displayMidnightMeridian) + return false; + + return true; + } + + /** + * Returns the fill pattern given a string. + */ + public FillPattern getFillPattern(String fillPattern) { + + return FillPattern.valueOf(fillPattern); + } + + @Override + public String toString() { + return "DayNightTerminatorResource: \n Terminator Line: color= " + + termLineColor.toString() + " width= " + termLineWidth + + " style= " + termLineStyle.toString() + + "\n Sub-solar Point: color= " + sunMarkerColor.toString() + + " width= " + sunMarkerWidth + " marker= " + + sunMarkerType.toString() + + "\n Midnight Meridian Line: color= " + + midnightMeridianLineColor.toString() + " width= " + + midnightMeridianLineWidth + " style= " + + midnightMeridianLineStyle.toString() + + "\n Shading Color: day= " + dayShadeColor.toString() + + " night= " + nightShadeColor.toString() + " alpha= " + + shadeAlpha + " pattern=" + shadePattern.toString() + + "\n Display Sub-solar Point: " + displaySun + + "\n Apply Shading: " + applyShading + + "\n Display Midnight Meridian: " + displayMidnightMeridian; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/SunPosition.java b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/SunPosition.java new file mode 100644 index 0000000000..007743e624 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.overlays/src/gov/noaa/nws/ncep/viz/overlays/resources/SunPosition.java @@ -0,0 +1,435 @@ +package gov.noaa.nws.ncep.viz.overlays.resources; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import com.vividsolutions.jts.geom.Coordinate; + +public class SunPosition { + + /** 2*Math.PI */ + final public static transient float TWO_PI = (float) Math.PI * 2.0f; + + /** Epoch Julian Date. */ + public final static double EPOCH_JULIAN_DATE = 2447891.5; + + /** Epoch start time in seconds. */ + public final static double EPOCH_TIME_SECS = 631065600; + + /** + * Constant denoting the number of radians an object would travel if it + * orbited around the earth in a day. + */ + public static double ORBIT_RADS_PER_DAY = TWO_PI / 365.242191; + + /** + * Ecliptic Longitude of earth at 1990 January epoch. From Duffett-Smith, + * chapter 46, table 6. (279.403303 degrees converted to radians). + */ + public static final double ECLIPTIC_LONGITUDE_EPOCH = 4.87650757893409; + + /** + * Variable notation of ECLIPTIC_LONGITUDE_EPOCH from Duffett-Smith. + */ + public static final double epsilon_g = ECLIPTIC_LONGITUDE_EPOCH; + + /** + * Ecliptic Longitude of of perigee. From Duffett-Smith, chapter 46, table + * 6. (282.768422 degrees converted to radians). + */ + public static final double ECLIPTIC_LONGITUDE_PERIGEE = 4.935239985213178; + + /** + * Variable notation of ECLIPTIC_LONGITUDE_PERIGEE from Duffett-Smith. + */ + public static final double omega_bar_g = ECLIPTIC_LONGITUDE_PERIGEE; + + /** + * Eccentricity of orbit, from Duffett-Smith, chapter 46, table 6. + */ + public static final double ECCENTRICITY = 0.016713; + + /** + * MEAN_OBLIQUITY_OF_EPOCH gives the mean obliquity of the ecliptic, which + * is the angle between the planes of the equator and the ecliptic. Using + * the algorithm described in Duffett-Smith, chapter 27, this is calculated + * for the 1990 January epoch to be .4091155 radians (23.440592 degrees). + */ + public static final double MEAN_OBLIQUITY_OF_EPOCH = .4091155; + + // These parameters are used in the Moon position calculations. + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double MOON_EPOCH_MEAN_LONGITUDE = 318.351648 * Math.PI / 180.0; + + /** + * The algorithm representation for the moon MOON_EPOCH_MEAN_LONGITUDE, "l". + */ + public static final double el0 = MOON_EPOCH_MEAN_LONGITUDE; + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double PERIGEE_EPOCH_MEAN_LONGITUDE = 36.340410 * Math.PI / 180.0; + + /** + * The algorithm representation for the moon PERIGEE_EPOCH_MEAN_LONGITUDE. + */ + public static final double P0 = PERIGEE_EPOCH_MEAN_LONGITUDE; + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double NODE_EPOCH_MEAN_LONGITUDE = 318.510107 * Math.PI / 180.0; + + /** + * The algorithm representation for the moon NODE_EPOCH_MEAN_LONGITUDE. + */ + public static final double N0 = NODE_EPOCH_MEAN_LONGITUDE; + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double MOON_ORBIT_INCLINATION = 5.145396 * Math.PI / 180.0; + + /** + * The algorithm representation for the moon MOON_ORBIT_INCLINATION, "i". + */ + public static final double eye = MOON_ORBIT_INCLINATION; + + /** Moon parameter, from Duffett-Smith, chapter 65, table 10. */ + public static final double MOON_ECCENTRICITY = .054900; + + /** Moon parameter, from Duffett-Smith, chapter 65, table 10. */ + public static final double MAJOR_AXIS_MOON_ORBIT = 384401; // km + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double MOON_ANGULAR_SIZE = .5181 * Math.PI / 180.0; + + /** + * Moon parameter, from Duffett-Smith, chapter 65, table 10. In radians. + */ + public static final double MOON_PARALLAX = .9507 * Math.PI / 180.0; + + /** + * Use Kepllers's equation to find the eccentric anomaly. From + * Duffett-Smith, chapter 47. + * + * @param M + * the angle that the Sun has moved since it passed through + * perigee. + */ + public static double eccentricAnomaly(double M) { + double delta; + double E = M; + while (true) { + delta = E - (ECCENTRICITY * Math.sin(E)) - M; + + if (Math.abs(delta) <= 1E-10) + break; + E -= (delta / (1.0 - (ECCENTRICITY * Math.cos(E)))); + } + return E; + } + + /** + * Calculate the mean anomaly of sun, in radians. From Duffett-Smith, + * chapter 47. + * + * @param daysSinceEpoch + * number of days since 1990 January epoch. + */ + protected static double sunMeanAnomaly(double daysSinceEpoch) { + + double N = ORBIT_RADS_PER_DAY * daysSinceEpoch; + N %= TWO_PI; + if (N < 0) + N += TWO_PI; + + double M0 = N + epsilon_g - omega_bar_g; + if (M0 < 0) + M0 += TWO_PI; + return M0; + } + + /** + * Calculate the ecliptic longitude of sun, in radians. From Duffett-Smith, + * chapter 47. + * + * @param M0 + * sun's mean anomaly, calculated for the requested time relative + * to the 1990 epoch. + */ + protected static double sunEclipticLongitude(double M0) { + double E = eccentricAnomaly(M0); + double v = 2 * Math.atan(Math.sqrt((1 + ECCENTRICITY) + / (1 - ECCENTRICITY)) + * Math.tan(E / 2.0)); + double ret = v + omega_bar_g; + ret = adjustWithin2PI(ret); + return ret; + } + + /** + * Conversion from ecliptic to equatorial coordinates for ascension. From + * Duffett-Smith, chapter 27. + * + * @param lambda + * ecliptic longitude + * @param beta + * ecliptic latitude + */ + protected static double eclipticToEquatorialAscension(double lambda, + double beta) { + double sin_e = Math.sin(MEAN_OBLIQUITY_OF_EPOCH); + double cos_e = Math.cos(MEAN_OBLIQUITY_OF_EPOCH); + + return Math.atan2(Math.sin(lambda) * cos_e - Math.tan(beta) * sin_e, + Math.cos(lambda)); + } + + /** + * Conversion from ecliptic to equatorial coordinates for declination. From + * Duffett-Smith, chapter 27. + * + * @param lambda + * ecliptic longitude + * @param beta + * ecliptic latitude + */ + protected static double eclipticToEquatorialDeclination(double lambda, + double beta) { + double sin_e = Math.sin(MEAN_OBLIQUITY_OF_EPOCH); + double cos_e = Math.cos(MEAN_OBLIQUITY_OF_EPOCH); + + return Math.asin(Math.sin(beta) * cos_e + Math.cos(beta) * sin_e + * Math.sin(lambda)); + } + + /** + * Given a date from a gregorian calendar, give back a julian date. From + * Duffett-Smith, chapter 4. + * + * @param cal + * Gregorian calendar for requested date. + * @return julian date of request. + */ + public static double calculateJulianDate(GregorianCalendar cal) { + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int day = cal.get(Calendar.DAY_OF_MONTH); + + // Algorithm expects that the January is = 1, which is + // different from the Java representation + month++; + + if ((month == 1) || (month == 2)) { + year -= 1; + month += 12; + } + + int A = year / 100; + int B = (int) (2 - A + (A / 4)); + int C = (int) (365.25 * (float) year); + int D = (int) (30.6001 * (float) (month + 1)); + + double julianDate = (double) (B + C + D + day) + 1720994.5; + + return julianDate; + } + + /** + * Calculate the greenwich sidereal time (GST). From Duffett-Smith, chapter + * 12. + * + * @param julianDate + * julian date of request + * @param time + * calendar reflecting local time zone change to greenwich + * @return GST relative to unix epoch. + */ + public static double greenwichSiderealTime(double julianDate, + GregorianCalendar time) { + + double T = (julianDate - 2451545.0) / 36525.0; + double T0 = 6.697374558 + (T * (2400.051336 + (T + 2.5862E-5))); + + T0 %= 24.0; + if (T0 < 0) { + T0 += 24.0; + } + + double UT = time.get(Calendar.HOUR_OF_DAY) + + (time.get(Calendar.MINUTE) + time.get(Calendar.SECOND) / 60.0) + / 60.0; + + T0 += UT * 1.002737909; + + T0 %= 24.0; + if (T0 < 0) { + T0 += 24.0; + } + + return T0; + } + + /** + * Given the number of milliseconds since the unix epoch, compute position + * on the earth (lat, lon) such that sun is directly overhead. From + * Duffett-Smith, chapter 46-47. + * + * @param mssue + * milliseconds since unix epoch + * @return LatLonPoint of the point on the earth that is closest. + */ + public static Coordinate sunPosition(long mssue) { + + // Set the date and clock, based on the millisecond count: + GregorianCalendar cal = new GregorianCalendar(); + cal.setTime(new Date(mssue)); + + double julianDate = calculateJulianDate(cal); + + // Need to correct time to GMT + long gmtOffset = cal.get(Calendar.ZONE_OFFSET); + // thanks to Erhard... + long dstOffset = cal.get(Calendar.DST_OFFSET); // ins. + // 12.04.99 + cal.setTime(new Date(mssue - (gmtOffset + dstOffset))); // rep. + // 12.04.99 + + double numDaysSinceEpoch = ((mssue / 1000) - EPOCH_TIME_SECS) + / (24.0f * 3600.0f); + + // M0 - mean anomaly of the sun + double M0 = sunMeanAnomaly(numDaysSinceEpoch); + // lambda + double sunLongitude = sunEclipticLongitude(M0); + // alpha + double sunAscension = eclipticToEquatorialAscension(sunLongitude, 0.0); + // delta + double sunDeclination = eclipticToEquatorialDeclination(sunLongitude, + 0.0); + + double tmpAscension = sunAscension - (TWO_PI / 24) + * greenwichSiderealTime(julianDate, cal); + + return new Coordinate(Math.toDegrees(tmpAscension), + Math.toDegrees(sunDeclination)); + } + + /** + * Given the number of milliseconds since the unix epoch, compute position + * on the earth (lat, lon) such that moon is directly overhead. From + * Duffett-Smith, chapter 65. Note: This is acting like it works, but I + * don't have anything to test it against. No promises. + * + * @param mssue + * milliseconds since unix epoch + * @return LatLonPoint of the point on the earth that is closest. + */ + public static Coordinate moonPosition(long mssue) { + + // Set the date and clock, based on the millisecond count: + GregorianCalendar cal = new GregorianCalendar(); + cal.setTime(new Date(mssue)); + + double julianDate = calculateJulianDate(cal); + + // Need to correct time to GMT + long gmtOffset = cal.get(Calendar.ZONE_OFFSET); + cal.setTime(new Date(mssue - gmtOffset)); + + // Step 1,2 + double numDaysSinceEpoch = ((mssue / 1000) - EPOCH_TIME_SECS) + / (24.0f * 3600.0f); + // Step 3 + // M0 - mean anomaly of the sun + double M0 = sunMeanAnomaly(numDaysSinceEpoch); + // lambda + double sunLongitude = sunEclipticLongitude(M0); + // Step 4 + double el = (13.1763966 * numDaysSinceEpoch * Math.PI / 180) + el0; + el = adjustWithin2PI(el); + // Step 5 + double Mm = el - (.1114041 * numDaysSinceEpoch * Math.PI / 180) - P0; + Mm = adjustWithin2PI(Mm); + // Step 6 + double N = N0 - (.0529539 * numDaysSinceEpoch * Math.PI / 180); + N = adjustWithin2PI(N); + // Step 7 + double C = el - sunLongitude; + double Ev = 1.2739 * Math.sin(2 * C - Mm); + // Step 8 + double Ae = .1858 * Math.sin(M0); + double A3 = .37 * Math.sin(M0); + // Step 9 + double Mmp = Mm + Ev - Ae - A3; + // Step 10 + double Ec = 6.2886 * Math.sin(Mmp); + // Step 11 + double A4 = 0.214 * Math.sin(2 * Mmp); + // Step 12 + double elp = el + Ev + Ec - Ae + A4; + // Step 13 + double V = .6583 * Math.sin(2 * (elp - sunLongitude)); + // Step 14 + double elpp = elp + V; + // Step 15 + double Np = N - (.16 * Math.sin(M0)); + // Step 16 + double y = Math.sin(elpp - Np) * Math.cos(eye); + // Step 17 + double x = Math.cos(elpp - Np); + // Step 18 + double amb = Math.atan2(y, x); + // Step 19 + double lambda_m = amb + Np; + // Step 20 + double beta_m = Math.asin(Math.sin(elpp - Np) * Math.sin(eye)); + // Step 21 + // alpha + double moonAscension = eclipticToEquatorialAscension(lambda_m, beta_m); + // delta + double moonDeclination = eclipticToEquatorialDeclination(lambda_m, + beta_m); + + double tmpAscension = moonAscension - (TWO_PI / 24) + * greenwichSiderealTime(julianDate, cal); + + return new Coordinate(Math.toDegrees(tmpAscension), + Math.toDegrees(moonDeclination)); + } + + /** + * Little function that resets the input to be within 0 - 2*PI, by adding or + * subtracting 2PI as needed. + * + * @param num + * The number to be modified, if needed. + */ + protected static double adjustWithin2PI(double num) { + if (num < 0) { + do + num += TWO_PI; + while (num < 0); + } else if (num > TWO_PI) { + do + num -= TWO_PI; + while (num > TWO_PI); + } + return num; + } + + public static void main(String[] arg) { + System.out.println("Sun is over " + + SunPosition.sunPosition(System.currentTimeMillis())); + System.out.println("Moon is over " + + SunPosition.moonPosition(System.currentTimeMillis())); + } +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java index 4fe373da13..7c06d51dfd 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java @@ -17,6 +17,7 @@ import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -81,6 +82,7 @@ import com.raytheon.uf.common.time.DataTime; * Add functions to get position from time and vice versa * Modified updateTimeline, updateSelectedTimes, calculateSlider, calculateAvailableBoxes * 06/10/2014 #1136 qzhou Modified getSelectedTimes and updateTimeline + * 08/13/2014 R4079 sgurung Added code changes from TimeLineControl (related to TTR1032) * * * @@ -163,15 +165,16 @@ public class GraphTimelineControl extends TimelineControl { private int availFrameIntervalMins[] = { -1, 1, 2, 5, 10, 15, 20, 30, 60, 90, 120, 180, 360, 720, 1440 }; - private String availGraphRangeStrings[] = { "3 hrs", "6 hrs", "12 hrs", - "24 hrs", "3 days", "7 days" }; + private String availGraphRangeStrings[] = { "1 hr", "2 hrs", "3 hrs", + "6 hrs", "12 hrs", "24 hrs", "3 days", "7 days", "30 days" }; - private int availGraphRangeHrs[] = { 3, 6, 12, 24, 72, 168 }; + private int availGraphRangeHrs[] = { 1, 2, 3, 6, 12, 24, 72, 168, 720 }; // extend refTime to next snap point - private String availHourSnapStrings[] = { "0", "1", "3", "6", "12", "24" }; + private String availHourSnapStrings[] = { "0", "1", "2", "3", "6", "12", + "24" }; - private int availHourSnapHrs[] = { 0, 1, 3, 6, 12, 24 }; + private int availHourSnapHrs[] = { 0, 1, 2, 3, 6, 12, 24 }; // keep this in order since code is referencing the index into this list. private String refTimeSelectionOptions[] = { "Current", "Latest ", @@ -287,6 +290,13 @@ public class GraphTimelineControl extends TimelineControl { timeMatcher = tm; + /* + * loadTimes will adjust time line with "false" - it updates available + * times from DB but keeps selected frame times intact. If "true" is + * used, the time line will be completely rebuilt - available times are + * updated, the selected frames times are cleared and then re-built with + * "numFrames" and "skip" factor. + */ timeMatcher.loadTimes(false); if (timeMatcher.getDominantResourceName() != null) { @@ -613,6 +623,38 @@ public class GraphTimelineControl extends TimelineControl { timeData = new TimelineData(availTimes); + /* + * TTR 1034+: Force the timeline to start from a given time and + * extend backward to with a time range, regardless of the actual + * data availability - only for obs. For forecast data, always use + * actually data time (cycle time). + */ + if (!timeMatcher.isForecast()) { + long refTimeMillisecs; + if (timeMatcher.isCurrentRefTime()) { + refTimeMillisecs = Calendar.getInstance().getTimeInMillis(); + } else { + refTimeMillisecs = timeMatcher.getRefTime().getValidTime() + .getTimeInMillis(); + } + + long timeRangeMillisecs = ((long) timeMatcher.getTimeRange()) * 60 * 60 * 1000; + + DataTime endRefTime = timeMatcher + .getNormalizedTime(new DataTime(new Date( + refTimeMillisecs))); + DataTime startRefTime = timeMatcher + .getNormalizedTime(new DataTime(new Date( + refTimeMillisecs - timeRangeMillisecs))); + + timeData.setStartTime(startRefTime.getValidTime()); + timeData.setEndTime(endRefTime.getValidTime()); + } + // End of TTR1034+ change. + + // update widgets from default resource definition. + updateTimelineWidgets(timeMatcher); + removeSpinnerListeners(); // these can trigger the modify listeners too... @@ -636,23 +678,8 @@ public class GraphTimelineControl extends TimelineControl { } - // if this is a forecast dominant resource, the reference time - // is not needed since the cycle time is the reference time. - refTimeCombo.setVisible(!timeMatcher.isForecast()); - refTimeLbl.setVisible(!timeMatcher.isForecast()); - - setGraphRangeCombo(timeMatcher.getGraphRange()); - - setHourSnapCombo(timeMatcher.getHourSnap()); - - setFrameInterval(timeMatcher.getFrameInterval()); - - setTimeRangeHrs(timeMatcher.getTimeRange()); - - addSpinnerListeners(); - - resetSlider(); - canvas.redraw(); + // update widgets from default resource definition. + updateTimelineWidgets(timeMatcher); } } @@ -729,8 +756,8 @@ public class GraphTimelineControl extends TimelineControl { if (firstSelected == null) return list; - firstSelected = GraphTimelineUtil.snapTimeToClosest(firstSelected, - timeMatcher.getHourSnap()); + // firstSelected = GraphTimelineUtil.snapTimeToClosest(firstSelected, + // timeMatcher.getHourSnap()); // firstSelected.add(Calendar.HOUR_OF_DAY, selectedRange / 60); timeData.deselectAll(); @@ -1458,7 +1485,8 @@ public class GraphTimelineControl extends TimelineControl { return new Rectangle(0, 0, 0, 0); Calendar prev = timeData.getPreviousTime(time1); - if (prev != null) + if (prev != null && timeLocations.get(prev) != null + && timeLocations.get(time1) != null) ulX = (timeLocations.get(prev) + timeLocations.get(time1)) / 2; else ulX = sliderMin + 5; @@ -1539,8 +1567,8 @@ public class GraphTimelineControl extends TimelineControl { dayLocation = new ArrayList(); int lineLength = end.x - beg.x; - Calendar first = timeData.getFirstTime(); - Calendar last = timeData.getLastTime(); + Calendar first = timeData.getStartTime(); + Calendar last = timeData.getEndTime(); long timeLength = timeData.getTotalMillis(); Calendar cal = (Calendar) first.clone(); @@ -1672,8 +1700,8 @@ public class GraphTimelineControl extends TimelineControl { SimpleDateFormat sdf = new SimpleDateFormat("HH"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - Calendar first = timeData.getFirstTime(); - Calendar last = timeData.getLastTime(); + Calendar first = timeData.getStartTime(); + Calendar last = timeData.getEndTime(); int textHeight = gc.getFontMetrics().getHeight(); int width = gc.getCharWidth('0'); @@ -1765,7 +1793,7 @@ public class GraphTimelineControl extends TimelineControl { int lineLength = end.x - beg.x; - Calendar first = timeData.getFirstTime(); + Calendar first = timeData.getStartTime(); long timeLength = timeData.getTotalMillis(); @@ -1925,6 +1953,15 @@ public class GraphTimelineControl extends TimelineControl { timeRangeHrsSpnr.setSelection(timeRangeHrs % 24); } + /** + * Sets the number of times that should be selected + * + * @param num + */ + public void setNumberofFrames(int num) { + timeMatcher.setNumFrames(num); + } + /* * resets the slider bar so that it is recalculated using the selected times */ @@ -2044,4 +2081,34 @@ public class GraphTimelineControl extends TimelineControl { } + /* + * Re-draws timeline-related widgets based on a given NCTimeMatcher. + */ + private void updateTimelineWidgets(NCTimeMatcher tm) { + + if (tm.getDominantResource() != null && tm.isForecast()) { + refTimeCombo.setVisible(false); + + refTimeLbl.setVisible(false); + } else { + refTimeCombo.setVisible(true); + refTimeLbl.setVisible(true); + } + + setNumberofFrames(tm.getNumFrames()); + + setGraphRangeCombo(tm.getGraphRange()); + + setHourSnapCombo(tm.getHourSnap()); + + setFrameInterval(tm.getFrameInterval()); + + setTimeRangeHrs(tm.getTimeRange()); + + addSpinnerListeners(); + + resetSlider(); + canvas.redraw(); + } + } diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java index a66c11e867..4376d005b4 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java @@ -167,6 +167,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * Modified creating new timelineControl in const and updateGUI * 08/14/2014 ? B. Yin Added power legend (resource group) support. * 09/092014 ? B. Yin Fixed NumPad enter issue and the "ResetToDefault" issue for groups. + * 07/28/2014 R4079 sgurung Fixed the issue related to CreateRbd dialog size (bigger than usual). + * Also, added code to set geosync to true for graphs. * * * @author ghull @@ -379,9 +381,6 @@ public class CreateRbdControl extends Composite implements IPartListener2 { @Override public void dominantResourceChanged( AbstractNatlCntrsRequestableResourceData newDomRsc) { - // System.out.println("**createRbd " - // + rbdMngr.isAutoUpdate() + " " - // + newDomRsc.isAutoUpdateable()); if (newDomRsc == null) { auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); auto_update_btn.setEnabled(false); @@ -390,6 +389,11 @@ public class CreateRbdControl extends Composite implements IPartListener2 { // auto_update_btn.setSelection( // rbdMngr.isAutoUpdate() ); auto_update_btn.setSelection(true); + if (rbdMngr.getRbdType().equals( + NcDisplayType.GRAPH_DISPLAY)) { + geo_sync_panes.setSelection(true); + rbdMngr.syncPanesToArea(); + } } else { auto_update_btn.setSelection(false); auto_update_btn.setEnabled(false); @@ -882,7 +886,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { @Override public void keyPressed(KeyEvent ke) { Text txt = (Text) ke.widget; - if ((ke.keyCode == SWT.CR || ke.keyCode == SWT.KEYPAD_CR) && !txt.getText().isEmpty()) { + if ((ke.keyCode == SWT.CR || ke.keyCode == SWT.KEYPAD_CR) + && !txt.getText().isEmpty()) { if (txt.getText().equalsIgnoreCase(ungrpStr)) { curGrp = -1; @@ -2464,6 +2469,45 @@ public class CreateRbdControl extends Composite implements IPartListener2 { updateAreaGUI(); + // create new GraphTimelineControl if loading a Graph Display + timelineControl.dispose(); + if (rbdMngr.getRbdType().equals(NcDisplayType.GRAPH_DISPLAY)) { + + timelineControl = (GraphTimelineControl) new GraphTimelineControl( + timeline_grp); + } else { + timelineControl = new TimelineControl(timeline_grp); + } + + timelineControl + .addDominantResourceChangedListener(new IDominantResourceChangedListener() { + @Override + public void dominantResourceChanged( + AbstractNatlCntrsRequestableResourceData newDomRsc) { + if (newDomRsc == null) { + auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); + auto_update_btn.setEnabled(false); + } else if (newDomRsc.isAutoUpdateable()) { + auto_update_btn.setEnabled(true); + auto_update_btn.setSelection(true); + // auto_update_btn.setSelection( + // rbdMngr.isAutoUpdate() );top_comp + if (rbdMngr.getRbdType().equals( + NcDisplayType.GRAPH_DISPLAY)) { + geo_sync_panes.setSelection(true); + rbdMngr.syncPanesToArea(); + } + } else { + auto_update_btn.setSelection(false); + auto_update_btn.setEnabled(false); + } + } + }); + + timeline_grp.pack(); + shell.pack(); + shell.setSize(initDlgSize); + geo_sync_panes.setSelection(rbdMngr.isGeoSyncPanes()); multi_pane_tog.setSelection(rbdMngr.isMultiPane()); @@ -2479,41 +2523,6 @@ public class CreateRbdControl extends Composite implements IPartListener2 { // timelineControl.clearTimeline(); - // create new timelineControl if is Graph - timelineControl.dispose(); - - if (rbdMngr.getRbdType().equals(NcDisplayType.GRAPH_DISPLAY)) - - timelineControl = (GraphTimelineControl) new GraphTimelineControl( - timeline_grp); - else - timelineControl = new TimelineControl(timeline_grp); - - timelineControl - .addDominantResourceChangedListener(new IDominantResourceChangedListener() { - @Override - public void dominantResourceChanged( - AbstractNatlCntrsRequestableResourceData newDomRsc) { - // System.out.println("**createRbd2 " - // + rbdMngr.isAutoUpdate() + " " - // + newDomRsc.isAutoUpdateable()); - if (newDomRsc == null) { - auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); - auto_update_btn.setEnabled(false); - } else if (newDomRsc.isAutoUpdateable()) { - auto_update_btn.setEnabled(true); - // auto_update_btn.setSelection( - // rbdMngr.isAutoUpdate() );top_comp - auto_update_btn.setSelection(true); - } else { - auto_update_btn.setSelection(false); - auto_update_btn.setEnabled(false); - } - } - }); - - // timelineControl.setTimeMatcher(new NCTimeMatcher()); - INcPaneLayout paneLayout = rbdMngr.getPaneLayout(); // set the list of available resources for the timeline @@ -2571,7 +2580,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { auto_update_btn.setEnabled(false); } - shell.pack(); + // shell.pack(); } // TODO : we could have the pane buttons indicate whether diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/EditRbdDialog.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/EditRbdDialog.java index 4594cd00fe..08ef0f9bee 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/EditRbdDialog.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/EditRbdDialog.java @@ -15,7 +15,7 @@ import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.viz.core.exception.VizException; /** - * Main Dialog to manage and load RBDs. + * Main Dialog to manage and load RBDs. * *
  * SOFTWARE HISTORY
@@ -23,82 +23,87 @@ import com.raytheon.uf.viz.core.exception.VizException;
  * ------------	----------	-----------	--------------------------
  * 02/16/11      #408       Greg Hull    Created
  * 02/22/2013    #972       Greg Hull    work with AbstractRBD
- *                                       
+ * 
  * 
* - * @author ghull + * @author ghull * @version 1 */ public class EditRbdDialog extends Dialog { private Shell shell; + private boolean isOpen = false; private RscBundleDisplayMngr rbdMngr = null; - + private CreateRbdControl createRbdCntr = null; - - public EditRbdDialog( Shell parShell, AbstractRBD seldRbd ) throws VizException { - super(parShell); - rbdMngr = new RscBundleDisplayMngr( new NcPaneLayout(6,6), seldRbd.getDisplayType() ); + public EditRbdDialog(Shell parShell, AbstractRBD seldRbd) + throws VizException { + super(parShell); - shell = new Shell( parShell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL ); - shell.setText( "Edit RBD "+seldRbd.getRbdName() ); + rbdMngr = new RscBundleDisplayMngr(new NcPaneLayout(6, 6), + seldRbd.getDisplayType()); - GridLayout mainLayout = new GridLayout(1, true); - mainLayout.marginHeight = 1; - mainLayout.marginWidth = 1; - shell.setLayout( mainLayout ); - - shell.setLocation( parShell.getLocation().x+20, parShell.getLocation().y + 20 ); - - rbdMngr.initFromRbdBundle( seldRbd ); - - createRbdCntr = new CreateRbdControl( shell, rbdMngr ); + shell = new Shell(parShell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL); + shell.setText("Edit RBD " + seldRbd.getRbdName()); - createRbdCntr.configureForEditRbd(); + GridLayout mainLayout = new GridLayout(1, true); + mainLayout.marginHeight = 1; + mainLayout.marginWidth = 1; + shell.setLayout(mainLayout); - GridData gd = new GridData(); - gd.grabExcessHorizontalSpace = true; - gd.grabExcessVerticalSpace = true; - gd.horizontalAlignment = SWT.FILL; - - createRbdCntr.setLayoutData(gd); - - shell.setMinimumSize(400,320); - - shell.pack(); + shell.setLocation(parShell.getLocation().x + 20, + parShell.getLocation().y + 20); - createRbdCntr.updateDialog(); - } - - - public boolean isOpen() { + rbdMngr.initFromRbdBundle(seldRbd); + + createRbdCntr = new CreateRbdControl(shell, rbdMngr); + + createRbdCntr.configureForEditRbd(); + + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + + createRbdCntr.setLayoutData(gd); + + shell.setMinimumSize(400, 320); + + // shell.pack(); + + createRbdCntr.updateDialog(); + } + + public boolean isOpen() { return isOpen; // shell != null && !shell.isDisposed(); } public AbstractRBD open() { - Shell parent = getParent(); - Display display = parent.getDisplay(); + Shell parent = getParent(); + Display display = parent.getDisplay(); - shell.open(); + shell.setSize(550, 500); + shell.pack(); + shell.open(); - isOpen = true; + isOpen = true; - // Don't let the user do anything else while the Edit Rbd Dialog is up. - parent.setEnabled(false); - - while( !shell.isDisposed() ) { - if( !display.readAndDispatch() ) { - display.sleep(); - } - } - parent.setEnabled(true); + // Don't let the user do anything else while the Edit Rbd Dialog is up. + parent.setEnabled(false); - isOpen = false; - - return createRbdCntr.getEditedRbd(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + parent.setEnabled(true); + + isOpen = false; + + return createRbdCntr.getEditedRbd(); } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java index 7e0d865465..cbccfeacab 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java @@ -3,9 +3,9 @@ package gov.noaa.nws.ncep.viz.resourceManager.ui.loadRbd; //import gov.noaa.nws.ncep.viz.common.EditorManager; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; -import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; import gov.noaa.nws.ncep.viz.resourceManager.timeline.GraphTimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl; +import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl.IDominantResourceChangedListener; import gov.noaa.nws.ncep.viz.resourceManager.ui.createRbd.CreateRbdControl; import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; @@ -103,6 +103,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 08/01/2012 #836 G. Hull check for paneLayout when using empty editor * 02/22/2013 #972 G. Hull work with AbstractRBD * 05/07/2014 TTR991 D. Sushon if a different NCP editor is selected, the CreateRDB tab should now adjust. + * 07/28/2014 R4079 sgurung Load graph RBDs. * * * @@ -331,15 +332,7 @@ public class LoadRbdControl extends Composite { timeline_grp.setLayout(new GridLayout()); - if (!seldRbdsList.isEmpty() - && seldRbdsList.get(0).getDisplayType() - .equals(NcDisplayType.GRAPH_DISPLAY)) { // .getRbdName().equals("Graph")) - // { - timelineControl = new GraphTimelineControl(timeline_grp); - System.out.println("HERE"); - } else { - timelineControl = new TimelineControl(timeline_grp);// quan - } + timelineControl = new TimelineControl(timeline_grp);// quan sash_form.setWeights(new int[] { 3, 2 }); @@ -703,101 +696,15 @@ public class LoadRbdControl extends Composite { seldRbdsList.clear(); AbstractRBD rbdSel = null; - // INcPaneLayout paneLayout = rbdMngr.getPaneLayout(); - // - // // set the list of available resources for the timeline - // for (int paneIndx = 0; paneIndx < paneLayout.getNumberOfPanes(); - // paneIndx++) { - // for (ResourceSelection rscSel : rbdMngr - // .getRscsForPane((NcPaneID) paneLayout - // .createPaneId(paneIndx))) { - // - // if (rscSel.getResourceData() instanceof - // AbstractNatlCntrsRequestableResourceData) { - // timelineControl - // .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) - // rscSel - // .getResourceData()); - // } - // } - // } + boolean first = true; while (sel_iter.hasNext()) { rbdSel = (AbstractRBD) sel_iter.next(); - // if (rbdSel.getTimeMatcher().getDominantResource() == null) { - // System.out.println("Dominant Resource is null?"); - // } else { - // rbdSel.getTimeMatcher().loadTimes(true); - // } - // timelineControl.dispose(); - if (rbdSel instanceof GraphRBD) { - updateGUI(rbdSel); - // rbdSel.getDisplayType().equals(NcDisplayType.GRAPH_DISPLAY)) - // {// - // timelineControl = (GraphTimelineControl) new - // GraphTimelineControl( - // timeline_grp); - // - // timelineControl - // .addDominantResourceChangedListener(new - // IDominantResourceChangedListener() { - // @Override - // public void dominantResourceChanged( - // AbstractNatlCntrsRequestableResourceData newDomRsc) { - // if (newDomRsc == null) { - // // auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); - // auto_update_btn.setEnabled(false); - // } else if (newDomRsc.isAutoUpdateable()) { - // auto_update_btn.setEnabled(true); - // // auto_update_btn.setSelection( - // // rbdMngr.isAutoUpdate() ); - // auto_update_btn.setSelection(true); - // } else { - // auto_update_btn.setSelection(false); - // auto_update_btn.setEnabled(false); - // } - // } - // }); - // - // // set the list of available resources for the timeline - // // INcPaneLayout paneLayout = rbdSel.getPaneLayout(); - // // - // // for (int paneIndx = 0; paneIndx < - // paneLayout.getNumberOfPanes(); - // // paneIndx++) { - // // for (ResourceSelection rscSel : rbdMngr - // // .getRscsForPane((NcPaneID) paneLayout - // // .createPaneId(paneIndx))) { - // // - // // if (rbdSel.getrscSel.getResourceData() instanceof - // // AbstractNatlCntrsRequestableResourceData) { - // // timelineControl - // // - // .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) - // // rscSel - // // .getResourceData()); - // // } - // // } - // // } - // - // NCTimeMatcher timeMatcher = rbdSel.getTimeMatcher(); - // // ArrayList list = new ArrayList(); - // // DataTime time = timeMatcher.getRefTime(); - // // System.out.println("***time " + time); - // // Calendar cal = (Calendar) time.getValidTime(); - // // for (int i = 0; i < 720; i++) { - // // cal.add(Calendar.MINUTE, -1); - // // list.add(new DataTime((Calendar) cal.clone())); - // // } - // // timeMatcher.setFrameTimes(list); - // - // timelineControl.setTimeMatcher(timeMatcher); - // timelineControl.addAvailDomResource(timeMatcher - // .getDominantResource()); - - } else { - timelineControl = new TimelineControl(timeline_grp); + if (first && rbdSel instanceof GraphRBD + && !(timelineControl instanceof GraphTimelineControl)) { + updateTimeLineControl(rbdSel); + first = false; } rbdSel.initTimeline(); @@ -820,6 +727,15 @@ public class LoadRbdControl extends Composite { rbdSel = seldRbdsList.get(0); + if (rbdSel instanceof GraphRBD + && !(timelineControl instanceof GraphTimelineControl)) { + updateTimeLineControl(rbdSel); + } + // else { + // timelineControl.dispose(); + // timelineControl = new TimelineControl(timeline_grp); + // } + NCTimeMatcher timeMatcher = rbdSel.getTimeMatcher(); timelineControl.clearTimeline(); // removeAllAvailDomResources(); @@ -1100,40 +1016,41 @@ public class LoadRbdControl extends Composite { editRbdDlg = null; } - public void updateGUI(final AbstractRBD rbdSel) { - if (rbdSel instanceof GraphRBD) { - timelineControl.dispose(); - // shell.pack(); - timelineControl = (GraphTimelineControl) new GraphTimelineControl( - timeline_grp); + public void updateTimeLineControl(final AbstractRBD rbdSel) { - // timelineControl - // .addDominantResourceChangedListener(new - // IDominantResourceChangedListener() { - // @Override - // public void dominantResourceChanged( - // AbstractNatlCntrsRequestableResourceData newDomRsc) { - // if (newDomRsc == null) { - // auto_update_btn.setSelection(rbdSel - // .isAutoUpdate()); - // auto_update_btn.setEnabled(false); - // } else if (newDomRsc.isAutoUpdateable()) { - // auto_update_btn.setEnabled(true); - // // auto_update_btn.setSelection( - // // rbdMngr.isAutoUpdate() );top_comp - // auto_update_btn.setSelection(true); - // } else { - // auto_update_btn.setSelection(false); - // auto_update_btn.setEnabled(false); - // } - // } - // }); - // - // timelineControl.setTimeMatcher(rbdSel.getTimeMatcher()); - // timelineControl.addAvailDomResource(rbdSel.getTimeMatcher() - // .getDominantResource()); - // shell.pack(); - } + timelineControl.dispose(); + shell.pack(); + timelineControl = (GraphTimelineControl) new GraphTimelineControl( + timeline_grp); + timeline_grp.pack(); + timelineControl + .addDominantResourceChangedListener(new IDominantResourceChangedListener() { + @Override + public void dominantResourceChanged( + AbstractNatlCntrsRequestableResourceData newDomRsc) { + if (newDomRsc == null) { + auto_update_btn.setSelection(rbdSel.isAutoUpdate()); + auto_update_btn.setEnabled(false); + } else if (newDomRsc.isAutoUpdateable()) { + auto_update_btn.setEnabled(true); + // auto_update_btn.setSelection( + // rbdMngr.isAutoUpdate() ); + auto_update_btn.setSelection(true); + } else { + auto_update_btn.setSelection(false); + auto_update_btn.setEnabled(false); + } + } + }); + + timelineControl.setTimeMatcher(rbdSel.getTimeMatcher()); + timelineControl.addAvailDomResource(rbdSel.getTimeMatcher() + .getDominantResource()); + timelineControl + .setDominantResource((AbstractNatlCntrsRequestableResourceData) rbdSel + .getTimeMatcher().getDominantResource()); + shell.pack(); + shell.setSize(initDlgSize); } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java index 440ec8bcce..87af44b62c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java @@ -72,6 +72,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 11/21/13 #1066 Greg Hull save off Native gridGeometries during clone() * 10/29/13 #2491 bsteffen Use custom JAXB context instead of SerializationUtil. * 05/15/2014 #1131 Quan Zhou Added GRAPH_DISPLAY. + * 05/24/14 R4078 S. Gurung Added NMAP_RTKP_WORLD_DISPLAY in getDefaultRBD(). + * * * * @author ghull @@ -583,6 +585,11 @@ public abstract class AbstractRBD dfltRbdName = null; return AbstractRBD.createEmptyRbdForDisplayType(displayType, new NcPaneLayout(1, 1)); + + case NMAP_RTKP_WORLD_DISPLAY: + dfltRbdName = NcPathConstants.DFLT_RTKP_RBD; + break; + default: throw new VizException("Unable to find the default RBD name for " + displayType.toString()); diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java index e1c80f7eda..8abd2f3d1c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java @@ -68,7 +68,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 02/01/13 #972 Greg Hull RbdBundleEditorWrapper doesn't need to be a generic * 02/12/13 #972 Greg Hull NcDisplayType and NatlCntrsEditor * 11/26/13 #1078 Greg Hull Size Of Image fix (PixelExtent constructor) - * + * 04/24/14 #1122 S. Gurung Modified method addDefaultRBD()to support any NcDisplayType(s). + * Zoom slightly for graph displays. * * * @version 1 @@ -118,7 +119,7 @@ public class ResourceBndlLoader implements Runnable { // extends Job { public void addDefaultRBD(NcDisplayType dt, AbstractEditor theEditor) throws VizException { - AbstractRBD rbd = NcMapRBD.getDefaultRBD(NcDisplayType.NMAP_DISPLAY); + AbstractRBD rbd = NcMapRBD.getDefaultRBD(dt); // NcMapRBD.getDefaultRBD(NcDisplayType.NMAP_DISPLAY); rbd.resolveLatestCycleTimes(); // shouldn't be needed but just in case seldRBDs.add(new RbdBundleEditorWrapper(rbd, theEditor, false)); @@ -274,6 +275,12 @@ public class ResourceBndlLoader implements Runnable { // extends Job { seldPane = displayPane; } + if (rbdBndl.getPaneLayout().getNumberOfPanes() > 1 + && NcDisplayType.GRAPH_DISPLAY.equals(rbdBndl + .getDisplayType())) { + displayPane.zoom(7); + } + // if the editor was just created and there was an error, // close the editor. // TODO: if there is an error, prompt if the user wishes to diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java index ea44005c11..c8aaf731cd 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java @@ -19,7 +19,7 @@ import javax.xml.bind.annotation.adapters.XmlAdapter; * 02/13/13 #972 Greg Hull Created * 03/06/13 #958 Greg Hull Added SpaceRscCategory * 05/15/2014 #1131 Quan Zhou Added resource category GraphRscCategory. - * 09/10/2014 B. Hebbard Added NtransRscCategory + * 09/10/2014 rm4705 B. Hebbard Added NtransRscCategory * * * @author diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java index 1cc1a2ccf5..9feb6f8fdc 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java @@ -894,7 +894,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // if the needed param is not set in the resource defn or is // set to empty String paramValue = paramValues.get(implPrm); - + if (paramValue == null || paramValue.isEmpty()) { // paramValue = dfltParamValues.get( implPrm ); @@ -1813,8 +1813,11 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, + subTypeGenerator); } } else if (getResourceCategory() == ResourceCategory.GraphRscCategory) { - GeoMagRecord magRec = (GeoMagRecord) pdo; - subType = magRec.getStationCode(); + + if (pdo instanceof GeoMagRecord) { + GeoMagRecord magRec = (GeoMagRecord) pdo; + subType = magRec.getStationCode(); + } } // doing this will cause the dataTime query to fail because diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java index 6df6526ac1..d4fee60257 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java @@ -62,6 +62,7 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties; * 05/14/14 1131 Quan Zhou Added graphRange and hourSnap. MouModified generateTimeline * 07/11/14 TTR1032 J. Wu No timeline needed if no data times available. * 07/28/14 TTR1034+ J. Wu Build timeline only from available datatimes.. + * 07/29/14 R4078 s. Gurung Commented out code that sets numFrames=1 for graph/timeseries display * * * @@ -584,9 +585,11 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements /* * For graph display, numFrames = 1 */ - if (this.getDominantResourceName().getRscCategory() - .getCategoryName().equals("TIMESERIES")) - numFrames = 1; + /* + */ + // if (this.getDominantResourceName().getRscCategory() + // .getCategoryName().equals("TIMESERIES")) + // numFrames = 1; for (skipCount = 0; skipCount < selectableDataTimes.size(); skipCount++) { if (skipCount % (skipValue + 1) == 0) { @@ -1268,9 +1271,9 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements /* * For graph display, numFrames = 1 */ - if (this.getDominantResourceName().getRscCategory() - .getCategoryName().equals("TIMESERIES")) - numFrames = 1; + // if (this.getDominantResourceName().getRscCategory() + // .getCategoryName().equals("TIMESERIES")) + // numFrames = 1; for (skipCount = 0; skipCount < selectableDataTimes.size(); skipCount++) { if (skipCount % (skipValue + 1) == 0) { diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml index 8ed9e1d4d9..5d12cd801b 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml @@ -20,8 +20,10 @@ ${dataColor} ${xAxesTitle} ${yAxesTitle} - ${yDescription} - + ${yDescription} + ${showReadoutView} + ${showKTableView} + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml index 3a3d579996..39a0082b69 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml @@ -94,6 +94,20 @@ defaultValue="RGB {200, 200, 200}" paramType="IMPLEMENTATION_PARAM"> + + + +
diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java index 3e6831f6e3..26fa9bfb35 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java @@ -36,6 +36,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.drawables.AbstractDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.xy.graph.IGraph; @@ -52,6 +53,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * ------------ ---------- ---------- -------------------------- * 06/13/2014 #1136 qzhou Initial creation * Added functions to set it up. + * 07/28/2014 R4079 sgurung Added new constructor * * * @author qzhou @@ -72,6 +74,41 @@ public class GeoMagDescriptor extends NCTimeSeriesDescriptor implements super(pixelExtent); } + public GeoMagDescriptor(NCTimeSeriesDescriptor desc) throws VizException { + super(); + + List rlist = desc.getResourceList(); + if (rlist != null) { + ResourcePair[] rp = rlist.toArray(new ResourcePair[rlist.size()]); + this.setSerializableResources(rp); + } + + IRenderableDisplay rendDisp = desc.getRenderableDisplay(); + if (!(rendDisp instanceof NCTimeSeriesRenderableDisplay)) { + throw new VizException("Error: Renderable display is not of type " + + rendDisp.getClass().getName()); + } + + rendDisp.setDescriptor(desc); + this.setRenderableDisplay(rendDisp); + + NCTimeMatcher tm = (NCTimeMatcher) desc.getTimeMatcher(); + + if (tm == null) { + tm = (NCTimeMatcher) desc.getRenderableDisplay().getDescriptor() + .getTimeMatcher(); + } + + desc.setTimeMatcher(tm); + + this.setAutoUpdate(true); + // this.setDataTimes(desc.getDataTimes()); + this.setFramesInfo(desc.getFramesInfo()); + this.setNumberOfFrames(desc.getNumberOfFrames()); + this.setGridGeometry(desc.getGridGeometry()); + + } + /* * (non-Javadoc) * @@ -110,6 +147,24 @@ public class GeoMagDescriptor extends NCTimeSeriesDescriptor implements } + public void addDescriptor(NCTimeSeriesDescriptor desc, + IRenderableDisplay rendDisp) { + + if (!(rendDisp instanceof NCTimeSeriesRenderableDisplay)) { + try { + throw new VizException( + "Error: can't zoom to resource in the renderable display : " + + rendDisp.getClass().getName()); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + + rendDisp.setDescriptor(desc); + + } + public void setResourcePair(GeoMagDescriptor desc, IDisplayPane pane) { List rlist = pane.getRenderableDisplay().getDescriptor() @@ -123,6 +178,16 @@ public class GeoMagDescriptor extends NCTimeSeriesDescriptor implements } + public void setResourcePair(List rlist) { + + if (rlist != null) { + + ResourcePair[] rp = rlist.toArray(new ResourcePair[rlist.size()]); + this.setSerializableResources(rp); + } + + } + public void setNCTimeMatcher(GeoMagDescriptor desc, IDisplayPane pane) { NCTimeMatcher tm = (NCTimeMatcher) pane.getDescriptor() @@ -131,4 +196,8 @@ public class GeoMagDescriptor extends NCTimeSeriesDescriptor implements desc.setTimeMatcher(tm); } + public void setNCTimeMatcher(NCTimeMatcher tm) { + this.setTimeMatcher(tm); + } + } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java index 03960ca2b7..d00c1fca90 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java @@ -72,6 +72,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 06/10/2014 1136 qzhou Changed graphExtent for time series 1000*400 * Added getStationLocalTime. Added paintBorderRect, Added paintMidnightNoon, * Added paintXTitle. Modified paintTitles. Added ticks on yAxes. + * 07/28/2014 R4079 sgurung Changed graphExtent, and x and y title coordinates. * * * @author qzhou @@ -100,7 +101,7 @@ public class GeoMagGraph extends NCTimeSeriesGraph { * Make the wide as 2.5 times of height. Make new extent graphExtent(0, * 1000, 300, 700). */ - graphExtent = new PixelExtent(0, 1000, 300, 700); + graphExtent = new PixelExtent(0, 1000, 275, 700); double minX = graphExtent.getMinX(); double maxX = graphExtent.getMaxX(); double minY = graphExtent.getMinY(); @@ -446,7 +447,30 @@ public class GeoMagGraph extends NCTimeSeriesGraph { titleString.magnification = this.currentMagnification; double x = graphExtent.getMinX() + graphExtent.getWidth() / 2; - double y = graphExtent.getMaxY() + 100; + double y = graphExtent.getMaxY() + 50; + titleString.setCoordinates(x, y); + + target.drawStrings(titleString); + } + + @Override + protected void paintYTitle(IGraphicsTarget target, + PaintProperties paintProps, String title, RGB titleColor, int index) + throws VizException { + // Paint the titles + double ratio = paintProps.getCanvasBounds().height + / paintProps.getView().getExtent().getHeight(); + DrawableString titleString = new DrawableString(title, titleColor); + titleString.textStyle = TextStyle.DROP_SHADOW; + titleString.horizontalAlignment = HorizontalAlignment.LEFT; + titleString.verticallAlignment = VerticalAlignment.BOTTOM; + titleString.rotation = 90; + titleString.magnification = this.currentMagnification; + int width = target.getStringsBounds(titleString).getBounds().width; + int height = target.getStringsBounds(titleString, "H").getBounds().height * 2; + double x = graphExtent.getMinX() - 50 - height * (index); + double y = graphExtent.getMaxY() + - ((graphExtent.getHeight() - (width / ratio)) / 2); titleString.setCoordinates(x, y); target.drawStrings(titleString); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java index ce5dd2e914..d2b3d94002 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java @@ -9,6 +9,7 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; /** @@ -53,7 +54,7 @@ public class EditTimeSeriesAttrsDialog extends top.setLayout(mainLayout); Group colorsGroup = new Group(top, SWT.SHADOW_NONE); - colorsGroup.setText("Colors"); + colorsGroup.setText("Info"); GridData gd = new GridData(); gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; @@ -67,8 +68,11 @@ public class EditTimeSeriesAttrsDialog extends public void initializeComponents(final Group colorsGroup) { - colorsGroup.setLayout(new GridLayout(2, true)); + colorsGroup.setLayout(new GridLayout(1, true)); + Label infoLabel = new Label(colorsGroup, SWT.NONE); + infoLabel + .setText("Currently, attributes cannot be edited using this dialog."); } @Override diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java index 12267bb83a..3b053cd84f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java @@ -57,6 +57,7 @@ import javax.measure.converter.UnitConverter; import org.eclipse.swt.graphics.RGB; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import com.raytheon.uf.common.dataplugin.PluginDataObject; @@ -115,6 +116,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 06/25/2014 #1136 qzhou Fixed graph painting duplicated errors. Qdc subtract component's median. * 07/03/2014 R4079 qzhou Added k-index view. * 07/10/2014 R4079 qzhou Added SamplingView and Sampling related classes. + * 07/28/2014 R4078 sgurung Added code changes to support loading GeoMagResource in a new window. * * * @author qzhou @@ -297,8 +299,14 @@ public class GeoMagResource extends super(resData, loadProperties); geoMagData = resData; - reopenKTableView(); - reopenSamplingView(); + + if (geoMagData.getShowKTableView()) { + reopenKTableView(); + } + + if (geoMagData.getShowReadoutView()) { + reopenSamplingView(); + } samplingRsc = new Sampling(); } @@ -316,6 +324,20 @@ public class GeoMagResource extends container.unregisterMouseHandler(inputAdapter); } + // close associated views + IWorkbenchWindow win = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (win == null) + return; + IWorkbenchPage wpage = win.getActivePage(); + if (wpage != null) { + IViewPart vpart1 = wpage.findView(KTableView.kTableId); + wpage.hideView(vpart1); + + IViewPart vpart2 = wpage.findView(SamplingView.samplingId); + wpage.hideView(vpart2); + } + if (samplingRsc != null) { samplingRsc.dispose(); } @@ -342,7 +364,11 @@ public class GeoMagResource extends } - NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) descriptor) + // NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) + // descriptor) + // .getTimeMatcher(); + + timeMatcher = (NCTimeMatcher) ((NCTimeSeriesDescriptor) descriptor) .getTimeMatcher(); IDisplayPaneContainer container = getResourceContainer(); @@ -383,7 +409,7 @@ public class GeoMagResource extends timelineEnd = new DataTime(end); // snap to synoptic point - timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + // timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); if (timelineStart.getRefTime().getMinutes() != 0) { Calendar tem = GraphTimelineUtil.snapTimeToClosest( @@ -528,16 +554,19 @@ public class GeoMagResource extends // qdcSize = 1440 } - NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) descriptor) - .getTimeMatcher(); - int graphSize = tm.getGraphRange() * 60; + // NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) + // descriptor) + // .getTimeMatcher(); + + int graphSize = timeMatcher.getGraphRange() * 60; /* * If load 12 hour record, calculate Qdc. To get Qdc, get 30 days * hourAvgs before the spTime. */ if (recordSize <= 721 - && ((geoMagType.equals("HQdc") || geoMagType.equals("DQdc")))) { + && ((geoMagType.equalsIgnoreCase("HQdc") || geoMagType + .equalsIgnoreCase("DQdc")))) { int i = 0; Float y = 0f; @@ -566,25 +595,26 @@ public class GeoMagResource extends // time. Not for others DataTime extent = recordsList.get(i - 1).getDataTime(); - int hour = ((Calendar) extent.getValidTime()) - .get(Calendar.HOUR_OF_DAY); + int hour = ((Calendar) extent.getValidTime()).get(Calendar.HOUR);// _OF_DAY); int minute = ((Calendar) extent.getValidTime()) .get(Calendar.MINUTE); - if (!(hour % 3 == 2 && minute == 59)) { + if (!(hour % 3 == 2 && minute == 59)) {// && !(hour == 0 && minute + // == 0)) { - int fillSize = 3 * 60 - (hour * 60 + minute); + int fillSize = 3 * 60 - minute;// (hour * 60 + minute); Calendar cal = extent.getValidTime(); - for (int j = 0; j < fillSize; j++) { + for (int j = 0; j < fillSize + && cal.getTime().before(timelineEnd.getRefTime()); j++) { cal.add(Calendar.MINUTE, 1); Calendar time = (Calendar) cal.clone(); DataTime x = new DataTime(time); - if (geoMagType.equals("HQdc")) { + if (geoMagType.equalsIgnoreCase("HQdc")) { y = hQdc[1440 - fillSize + j]; - } else if (geoMagType.equals("DQdc")) { + } else if (geoMagType.equalsIgnoreCase("DQdc")) { y = dQdc[1440 - fillSize + j]; } @@ -808,7 +838,7 @@ public class GeoMagResource extends } boolean changeExtent = false; - timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + // timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); if (timeMatcher.isAutoUpdateable()) { @@ -852,20 +882,26 @@ public class GeoMagResource extends * get gmDescriptor and graph */ IDisplayPane[] pane = GeoMagDescriptor.getDisplayPane(); - for (int i = 0; i < pane.length; i++) { - if (checkPaneId((NCTimeSeriesDescriptor) descriptor, pane[i])) { - GeoMagDescriptor gmDescriptor = new GeoMagDescriptor(); - gmDescriptor.setResourcePair(gmDescriptor, pane[i]); - gmDescriptor.setNCTimeMatcher(gmDescriptor, pane[i]); - gmDescriptor.addDescriptor(gmDescriptor, pane[i]); - gmDescriptor.setAutoUpdate(true);// - graph = gmDescriptor.getGraph(this); - currentPane = pane[i]; - break; + if (pane[0].getRenderableDisplay() instanceof NCTimeSeriesRenderableDisplay) { + for (int i = 0; i < pane.length; i++) { + if (checkPaneId((NCTimeSeriesDescriptor) descriptor, pane[i])) { + GeoMagDescriptor gmDescriptor = new GeoMagDescriptor(); + gmDescriptor.setResourcePair(gmDescriptor, pane[i]); + gmDescriptor.setNCTimeMatcher(gmDescriptor, pane[i]); + gmDescriptor.addDescriptor(gmDescriptor, pane[i]); + gmDescriptor.setAutoUpdate(true); + graph = gmDescriptor.getGraph(this); + currentPane = pane[i]; + break; + } } + } else { + GeoMagDescriptor gmDescriptor = new GeoMagDescriptor( + (NCTimeSeriesDescriptor) this.descriptor); + gmDescriptor.setAutoUpdate(true); + graph = gmDescriptor.getGraph(this); } - /* * Wait for graph to initialize before plotting to it, TODO: better */ @@ -975,49 +1011,60 @@ public class GeoMagResource extends /* * display k-index view */ - KTableView kTableWin = KTableView.getAccess(); - if (kTableWin != null && kTableWin.getEditorVisible()) { + if (geoMagData.getShowKTableView()) { + KTableView kTableWin = KTableView.getAccess(); + if (kTableWin != null && kTableWin.getEditorVisible()) { - KTableView kTableViewWin = KTableView.getAccess(); + KTableView kTableViewWin = KTableView.getAccess(); - if (kTableViewWin != null) { - AbstractEditor editor = NcDisplayMngr - .getActiveNatlCntrsEditor(); - IDisplayPane activePane = editor.getActiveDisplayPane(); - NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane - .getRenderableDisplay(); + if (kTableViewWin != null) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); - NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane - .getRenderableDisplay(); + if (activePane.getRenderableDisplay() instanceof NCTimeSeriesRenderableDisplay) { + NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane + .getRenderableDisplay(); - if (activeDisplay.getPaneId().equals(currDisplay.getPaneId())) + NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane + .getRenderableDisplay(); - kTableViewWin.paintKTable(magRecords); + if (activeDisplay.getPaneId().equals( + currDisplay.getPaneId())) + + kTableViewWin.paintKTable(magRecords); + } + } } } /* * display Readout view */ - SamplingView samplinWin = SamplingView.getAccess(); - if (samplinWin != null && samplinWin.getEditorVisible()) { + if (geoMagData.getShowReadoutView()) { + SamplingView samplinWin = SamplingView.getAccess(); + if (samplinWin != null && samplinWin.getEditorVisible()) { - SamplingView samplingViewWin = SamplingView.getAccess(); + SamplingView samplingViewWin = SamplingView.getAccess(); - if (samplingViewWin != null) { - AbstractEditor editor = NcDisplayMngr - .getActiveNatlCntrsEditor(); - IDisplayPane activePane = editor.getActiveDisplayPane(); - NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane - .getRenderableDisplay(); + if (samplingViewWin != null) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + if (activePane.getRenderableDisplay() instanceof NCTimeSeriesRenderableDisplay) { + NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane + .getRenderableDisplay(); - NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane - .getRenderableDisplay(); + NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane + .getRenderableDisplay(); - if (activeDisplay.getPaneId().equals(currDisplay.getPaneId())) { + if (activeDisplay.getPaneId().equals( + currDisplay.getPaneId())) { - samplingRsc.getResult(target, descriptor, paintProps, - sampleCoord); + samplingRsc.getResult(target, descriptor, + paintProps, sampleCoord); + } + } } } } @@ -1038,6 +1085,7 @@ public class GeoMagResource extends } else { return false; } + } private UnitConverter createDataConverter() { diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java index 986d8e6f4d..9bc122c577 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java @@ -50,6 +50,8 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 06/24/2014 #1136 qzhou Initial creation + * 07/28/2014 R4079 sgurung Added showReadoutView and showKTableView + * * * * @@ -87,6 +89,12 @@ public class GeoMagResourceData extends @XmlElement private Coordinate coordinate; + @XmlElement + private boolean showReadoutView; + + @XmlElement + private boolean showKTableView; + protected DataTime startTime; protected DataTime endTime; @@ -265,4 +273,21 @@ public class GeoMagResourceData extends public String getPointLetter() { return null; } + + public boolean getShowReadoutView() { + return showReadoutView; + } + + public void setShowReadoutView(boolean showReadoutView) { + this.showReadoutView = showReadoutView; + } + + public boolean getShowKTableView() { + return showKTableView; + } + + public void setShowKTableView(boolean showKTableView) { + this.showKTableView = showKTableView; + } + } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java index c6d53a49f7..3b81f4f502 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java @@ -43,6 +43,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 07/16/2014 R4079 qzhou Initial creation + * 07/28/2014 R4078 sgurung Added null check * * * @@ -63,74 +64,77 @@ public class SamplingInputAdapter extends public boolean handleMouseMove(int x, int y) { IDisplayPaneContainer container = resource.getResourceContainer(); - Coordinate c = container.translateClick(x, y); - boolean isActiveResource = false; + if (container != null) { + Coordinate c = container.translateClick(x, y); - AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); - IDisplayPane activePane = editor.getActiveDisplayPane(); + boolean isActiveResource = false; - ResourceList acResources = activePane.getDescriptor().getResourceList(); - int acRscSize = acResources.size(); + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); - for (int i = acRscSize - 1; i >= 0; i--) { - ResourcePair rp = acResources.get(i); - AbstractVizResource activeRsc = rp.getResource(); + ResourceList acResources = activePane.getDescriptor() + .getResourceList(); + int acRscSize = acResources.size(); - if (activeRsc != null - && activeRsc instanceof GeoMagResource - && rp.getProperties().isVisible() - && !((GeoMagResource) activeRsc).getLegendStr().equals( - "No Data")) { + for (int i = acRscSize - 1; i >= 0; i--) { + ResourcePair rp = acResources.get(i); + AbstractVizResource activeRsc = rp.getResource(); - if (activeRsc.equals(resource)) { - isActiveResource = true; + if (activeRsc != null + && activeRsc instanceof GeoMagResource + && rp.getProperties().isVisible() + && !((GeoMagResource) activeRsc).getLegendStr().equals( + "No Data")) { + + if (activeRsc.equals(resource)) { + isActiveResource = true; + } + break; } - break; } - } + if (resource.getResourceContainer().getDisplayPanes().length > 1) { + // Coordinate latLonCoord = ((GeoMagResource) resource) + // .getLatLonFromPixel(c); - if (resource.getResourceContainer().getDisplayPanes().length > 1) { - // Coordinate latLonCoord = ((GeoMagResource) resource) - // .getLatLonFromPixel(c); + for (IDisplayPane pane : resource.getResourceContainer() + .getDisplayPanes()) { - for (IDisplayPane pane : resource.getResourceContainer() - .getDisplayPanes()) { + if (!pane.equals(activePane) && isActiveResource) { - if (!pane.equals(activePane) && isActiveResource) { + ResourceList resources = pane.getDescriptor() + .getResourceList(); + int size = resources.size(); - ResourceList resources = pane.getDescriptor() - .getResourceList(); - int size = resources.size(); + for (int i = 0; i < size && size > 1; i++) { + ResourcePair rp = resources.get(i); + AbstractVizResource rsc = rp.getResource(); - for (int i = 0; i < size && size > 1; i++) { - ResourcePair rp = resources.get(i); - AbstractVizResource rsc = rp.getResource(); + if (rsc != null && rsc instanceof GeoMagResource + && rp.getProperties().isVisible()) { + // ((GeoMagResource) rsc) + // .setVirtualCursor(latLonCoord); - if (rsc != null && rsc instanceof GeoMagResource - && rp.getProperties().isVisible()) { - // ((GeoMagResource) rsc) - // .setVirtualCursor(latLonCoord); - - ((GeoMagResource) rsc).issueRefresh(); + ((GeoMagResource) rsc).issueRefresh(); + } } } } } - } - if (isActiveResource) { - if (c != null) { - resource.sampleCoord = new ReferencedCoordinate(c); - } else { - resource.sampleCoord = null; + if (isActiveResource) { + if (c != null) { + resource.sampleCoord = new ReferencedCoordinate(c); + } else { + resource.sampleCoord = null; + } } - } - // The sampling is always true for geomag - resource.issueRefresh(); + // The sampling is always true for geomag + resource.issueRefresh(); + } return false; } diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/.classpath b/ncep/gov.noaa.nws.ncep.viz.rtkp/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/.project b/ncep/gov.noaa.nws.ncep.viz.rtkp/.project new file mode 100644 index 0000000000..ceb0219225 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/.project @@ -0,0 +1,28 @@ + + + gov.noaa.nws.ncep.viz.rtkp + + + + + + 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/ncep/gov.noaa.nws.ncep.viz.rtkp/.settings/org.eclipse.jdt.core.prefs b/ncep/gov.noaa.nws.ncep.viz.rtkp/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..8000cd6ca6 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +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.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +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/ncep/gov.noaa.nws.ncep.viz.rtkp/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.rtkp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..a75eef4d82 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/META-INF/MANIFEST.MF @@ -0,0 +1,43 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Timeseries +Bundle-SymbolicName: gov.noaa.nws.ncep.viz.rtkp;singleton:=true +Eclipse-RegisterBuddy: com.raytheon.viz.core, com.raytheon.uf.viz.core, com.raytheon.viz.ui, com.raytheon.edex.common, com.raytheon.uf.common.serialization +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: gov.noaa.nws.ncep.viz.rtkp.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + javax.measure;bundle-version="1.0.0", + com.raytheon.edex.common;bundle-version="1.12.1174", + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + com.raytheon.uf.viz.xy.timeseries;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174", + com.raytheon.viz.core.graphing;bundle-version="1.12.1174", + com.raytheon.uf.common.time;bundle-version="1.12.1174", + gov.noaa.nws.ncep.viz.localization;bundle-version="1.0.0", + gov.noaa.nws.ncep.common.dataplugin.geomag;bundle-version="1.0.0", + org.geotools;bundle-version="2.6.4", + com.raytheon.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.viz.xy;bundle-version="1.12.1174", + com.raytheon.uf.common.style, + gov.noaa.nws.ncep.ui.pgen, + gov.noaa.nws.ncep.viz.common;bundle-version="1.0.0", + gov.noaa.nws.ncep.viz.resources, + gov.noaa.nws.ncep.viz.rsc.timeseries +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: com.raytheon.uf.viz.core.drawables, + com.raytheon.uf.viz.d2d.core, + com.raytheon.uf.viz.d2d.ui, + com.raytheon.uf.viz.xy.graph, + gov.noaa.nws.ncep.viz.common.display, + gov.noaa.nws.ncep.viz.resources.attributes, + gov.noaa.nws.ncep.viz.resources.manager, + gov.noaa.nws.ncep.viz.resources.time_match, + gov.noaa.nws.ncep.viz.ui.display +Export-Package: gov.noaa.nws.ncep.viz.rtkp, + gov.noaa.nws.ncep.viz.rtkp.rsc, + gov.noaa.nws.ncep.viz.rtkp.util, + gov.noaa.nws.ncep.viz.rtkp.palette + diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/build.properties b/ncep/gov.noaa.nws.ncep.viz.rtkp/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/gov.noaa.nws.ncep.viz.rtkp.ecl b/ncep/gov.noaa.nws.ncep.viz.rtkp/gov.noaa.nws.ncep.viz.rtkp.ecl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.rtkp/plugin.xml new file mode 100644 index 0000000000..43c7ae90a3 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/plugin.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/Activator.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/Activator.java new file mode 100644 index 0000000000..c2c10944d5 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/Activator.java @@ -0,0 +1,79 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * March 5, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "gov.noaa.nws.ncep.viz.rtkp"; //$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 + * ) + */ + 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 + * ) + */ + 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; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpDescriptor.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpDescriptor.java new file mode 100644 index 0000000000..641442a8f5 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpDescriptor.java @@ -0,0 +1,57 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.xy.graph.IGraph; +import com.raytheon.uf.viz.xy.timeseries.display.TimeSeriesDescriptor; + +/** + * RTKP Time Series descriptor, needed so loading bundles know what editor to + * load with this descriptor. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2014   1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +public class GeoMagRTKpDescriptor extends TimeSeriesDescriptor { + + public GeoMagRTKpDescriptor() { + super(); + } + + public GeoMagRTKpDescriptor(PixelExtent pixelExtent) { + super(pixelExtent); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.xy.graph.XyGraphDescriptor#constructGraph() + */ + @Override + public IGraph constructGraph() { + return new GeoMagRTKpGraph(this); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpGraph.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpGraph.java new file mode 100644 index 0000000000..e4eac94552 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpGraph.java @@ -0,0 +1,626 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagRTKpResource; +import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagRTKpResourceData; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import java.awt.Font; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IDisplayPane; +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.RGBColors; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +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.AbstractVizResource.ResourceStatus; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.xy.graph.GraphLabelComparator; +import com.raytheon.uf.viz.xy.graph.XyGraphDescriptor; +import com.raytheon.uf.viz.xy.graph.axis.GraphAxis; +import com.raytheon.uf.viz.xy.graph.axis.IAxis; +import com.raytheon.uf.viz.xy.graph.axis.LinearAxisPlacer; +import com.raytheon.uf.viz.xy.graph.labeling.DataTimeLabel; +import com.raytheon.uf.viz.xy.graph.labeling.IGraphLabel; +import com.raytheon.uf.viz.xy.map.rsc.IGraphableResource; +import com.raytheon.uf.viz.xy.timeseries.graph.TimeSeriesGraph; +import com.raytheon.uf.viz.xy.timeseries.rsc.TimeSeriesResource; +import com.raytheon.uf.viz.xy.timeseries.rsc.TimeSeriesResourceData; +import com.raytheon.viz.core.graphing.xy.XYImageData; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * The RTKP Time Series graph + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2014  1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpGraph extends TimeSeriesGraph { + + protected SimpleDateFormat sdf; + + protected SimpleDateFormat topLabelSdf = new SimpleDateFormat( + "dd-MMM-yyyy HH:mm:ss 'UTC'"); + + protected static final DecimalFormat df = new DecimalFormat("#"); + + protected RGB colorToUse = RGBColors.getRGBColor("white"); + + protected float fontSize = 14; + + protected String fontName = "Times"; + + protected String fontStyle = "Bold"; + + protected int fontStyleInt = Font.PLAIN; + + public GeoMagRTKpGraph(XyGraphDescriptor descriptor) { + super(descriptor); + sdf = new SimpleDateFormat("HH:mm"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + topLabelSdf.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + @Override + protected void createAxes() { + + graphExtent = new PixelExtent(0, 999, 150, 900); + + double minX = graphExtent.getMinX(); + double maxX = graphExtent.getMaxX(); + double minY = graphExtent.getMinY(); + double maxY = graphExtent.getMaxY(); + + // Set up the bounding box axes + minXAxis.setStartLoc(new Coordinate(minX, maxY, 0)); + minXAxis.setEndLoc(new Coordinate(maxX, maxY, 0)); + + maxXAxis.setStartLoc(new Coordinate(minX, minY, 0)); + maxXAxis.setEndLoc(new Coordinate(maxX, minY, 0)); + + minYAxis.setStartLoc(new Coordinate(minX, maxY, 0)); + minYAxis.setEndLoc(new Coordinate(minX, minY, 0)); + + maxYAxis.setStartLoc(new Coordinate(maxX, maxY, 0)); + maxYAxis.setEndLoc(new Coordinate(maxX, minY, 0)); + + // Create the Axis if they do not exist + xAxes = new IAxis[28]; + int index = 0; + for (int i = 0; i < 10; ++i) { + xAxes[index] = new GraphAxis(); + xAxes[index].setLineStyle(LineStyle.SOLID); + xAxes[index].setDrawAxis(true); + xAxes[index].setDiscreteValue(i); + index++; + + double tmp = i + (1 / 3.0); + for (int j = 0; j < 2 && i < 9; j++) { + xAxes[index] = new GraphAxis(); + xAxes[index].setLineStyle(LineStyle.DASHED); + xAxes[index].setDrawAxis(true); + xAxes[index].setDiscreteValue(tmp); + + tmp += (1 / 3.0); + index++; + } + } + + // Place them + xAxisPlacer.setPixelWidth(graphExtent.getHeight()); + yAxisPlacer.setPixelWidth(graphExtent.getWidth()); + + // Place the data axes + double[] offsets = xAxisPlacer.placeAxes(xAxes); + + for (int i = 0; i < offsets.length; ++i) { + double offset = offsets[i]; + xAxes[i].setStartLoc(new Coordinate(minX, maxY - offset, 0)); + xAxes[i].setEndLoc(new Coordinate(maxX, maxY - offset, 0)); + } + } + + @Override + protected boolean canHandleResoruce(IGraphableResource rsc) { + // Can only handle graphing of GeoMagRTKpMonitorResources + return (rsc instanceof GeoMagRTKpResource); + } + + @Override + protected void paintUnits(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + + unitsFont = target.initializeFont((String) null, 14.0f, + new IFont.Style[] { IFont.Style.BOLD }); + unitsFont.setSmoothing(false); + unitsFont.setScaleFont(false); + + List strings = new ArrayList(); + for (IGraphableResource grsc : graphResource) { + TimeSeriesResource rsc = (TimeSeriesResource) grsc; + if (rsc == null) { + continue; + } else if (rsc.getData() == null) { + continue; + } else if (rsc.getData().getData() == null) { + continue; + } else if (rsc.getData().getData().size() < 1) { + continue; + } + if (rsc.getProperties().isVisible()) { + // colorToUse = RGBColors.getRGBColor("white"); + // + // if + // (RTKpUtil.KS_PLOT.equals(rsc.getResourceData().getSource())) + // { + // colorToUse = rsc.getCapability(ColorableCapability.class) + // .getColor(); + // } + + if (rsc.getData() == null + || rsc.getData().getData().size() == 0 + || !(rsc.getData().getData().get(0) instanceof XYImageData)) { + for (int i = 0; i < xAxes.length; i++) { + Coordinate[] coords = xAxes[i].getCoordinates(); + if (coords[0].y < graphExtent.getMinY()) { + continue; + } + + DrawableString parameters = new DrawableString("", + colorToUse); + parameters.font = unitsFont; + parameters.textStyle = TextStyle.DROP_SHADOW; + parameters.horizontalAlignment = HorizontalAlignment.RIGHT; + parameters.magnification = this.currentMagnification; + + String valueDblStr = "" + xAxes[i].getDiscreteValue(); + if (valueDblStr.contains(".0")) { + String value = df.format(xAxes[i] + .getDiscreteValue()) + " "; + if (i == 0) { + parameters.verticallAlignment = VerticalAlignment.BOTTOM; + } else { + parameters.verticallAlignment = VerticalAlignment.MIDDLE; + } + parameters.setText(value, colorToUse); + parameters.setCoordinates(coords[0].x, coords[0].y, + coords[0].z); + strings.add(parameters); + } + } + } + } + } + target.drawStrings(strings); + + paintDataTimeUnits(target, paintProps, xLabels); + } + + @Override + protected void constructVirtualExtent() { + + // make sure all resources are initialized + for (IGraphableResource grsc : graphResource) { + GeoMagRTKpResource rsc = (GeoMagRTKpResource) grsc; + if (rsc.getStatus() != ResourceStatus.INITIALIZED) { + return; + } + } + + double[] minMaxY = new double[2]; + xLabels.clear(); + getXaxisIntervals(xLabels); + double minX1 = 0; + double maxX1 = 0; + minMaxY[0] = 0; + minMaxY[1] = 9; + + if (xLabels.size() > 0) { + minX1 = xLabels.get(0).getDiscreteValue(); + maxX1 = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + // normalizeAxis now takes into account data that will never be + // negative like wind speed. + // normalizeAxis(minMaxY); + + xAxisPlacer = new LinearAxisPlacer(graphExtent.getHeight(), minMaxY[0], + minMaxY[1]); + yAxisPlacer = new LinearAxisPlacer(graphExtent.getWidth(), minX1, maxX1); + + updateVirtualExtent(); + + newResources = false; + + } + + @Override + public void zoom(int index, Coordinate gridCoord) { + // yAxisPlacer.zoom(gridCoord.x - graphExtent.getMinX(), index); + // xAxisPlacer.zoom(graphExtent.getMaxY() - gridCoord.y, index); + // double inc = xAxisPlacer.getDataWidth() / 10; + // double newMin = (int) (xAxisPlacer.getMinDataValue() / inc) * inc; + // xAxisPlacer.pan(xAxisPlacer.getPixelLoc(newMin)); + // System.out.println("ZOOM"); + // updateVirtualExtent(); + } + + @Override + public void pan(double xDist, double yDist, boolean panning) { + yAxisPlacer.pan(xDist); + xAxisPlacer.pan(-yDist); + if (!panning) { + double inc = xAxisPlacer.getDataWidth() / 10; + double newMin = Math.round(xAxisPlacer.getMinDataValue() / inc) + * inc; + xAxisPlacer.pan(xAxisPlacer.getPixelLoc(newMin)); + } + updateVirtualExtent(); + } + + private void getXaxisIntervals(List> xLabels) { + for (IGraphableResource grsc : graphResource) { + if (grsc instanceof GeoMagRTKpResource) { + GeoMagRTKpResource rsc = (GeoMagRTKpResource) grsc; + DataTime start = rsc.getStartTime(); + xLabels.add(new DataTimeLabel(start)); + DataTime end = rsc.getEndTime(); + xLabels.add(new DataTimeLabel(end)); + + int hrs = ((GeoMagRTKpResourceData) rsc.getResourceData()) + .getPlotLengthInHours(); + int numInterval = 3; + if (hrs % 4 == 0) + numInterval = 4; + if (hrs % 6 == 0) + numInterval = 6; + if (hrs == 72) + numInterval = 3; + long diff = end.getRefTime().getTime() + - start.getRefTime().getTime(); + + for (int i = 1; i < numInterval; i++) { + long startTime = start.getRefTime().getTime(); + long newTime = startTime + (diff * i / numInterval); + DataTime dtime = new DataTime(new Date(newTime)); + xLabels.add(new DataTimeLabel(dtime)); + } + } + for (IGraphLabel label : xLabels) { + label.setResource((AbstractVizResource) grsc); + } + } + Collections.sort(xLabels, new GraphLabelComparator()); + } + + @Override + protected void paintTitles(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + titleFont = target.initializeFont((String) null, 14.0f, + new IFont.Style[] { IFont.Style.BOLD }); + titleFont.setSmoothing(false); + titleFont.setScaleFont(false); + + Date updatedDate = RTKpUtil.getCurrentTime(); + + AbstractEditor editor = (AbstractEditor) EditorUtil.getActiveEditor(); + + if (editor != null) { + IDisplayPane activePane = editor.getActiveDisplayPane(); + ResourceList acResources = activePane.getDescriptor() + .getResourceList(); + int acRscSize = acResources.size(); + + for (int i = acRscSize - 1; i >= 0; i--) { + ResourcePair rp = acResources.get(i); + AbstractVizResource activeRsc = rp.getResource(); + + if (activeRsc != null + && activeRsc instanceof GeoMagRTKpResource + && rp.getProperties().isVisible()) { + + KsPlotCapability ksCap = activeRsc + .getCapability(KsPlotCapability.class); + if (ksCap != null) { + if (RTKpUtil.KS_PLOT + .equals(((TimeSeriesResourceData) activeRsc + .getResourceData()).getSource())) { + colorToUse = activeRsc.getCapability( + KsPlotCapability.class).getTextColor(); + fontSize = (float) Integer.parseInt(activeRsc + .getCapability(KsPlotCapability.class) + .getTextSize()); + fontName = activeRsc.getCapability( + KsPlotCapability.class).getTextFont(); + fontStyle = activeRsc.getCapability( + KsPlotCapability.class).getTextStyle(); + updatedDate = ((GeoMagRTKpResource) activeRsc) + .getUpdatedDate(); + } else if (RTKpUtil.KP_PLOT + .equals(((TimeSeriesResourceData) activeRsc + .getResourceData()).getSource())) { + colorToUse = activeRsc.getCapability( + KpPlotCapability.class).getTextColor(); + fontSize = (float) Integer.parseInt(activeRsc + .getCapability(KpPlotCapability.class) + .getTextSize()); + fontName = activeRsc.getCapability( + KpPlotCapability.class).getTextFont(); + fontStyle = activeRsc.getCapability( + KpPlotCapability.class).getTextStyle(); + } + + if (fontStyle.compareTo("Italic") == 0) + fontStyleInt = Font.ITALIC; + else if (fontStyle.compareTo("Bold") == 0) + fontStyleInt = Font.BOLD; + else if (fontStyle.compareTo("Bold-Italic") == 0) { + fontStyleInt = Font.BOLD | Font.ITALIC; + } + + IFont derivedFont = target.initializeFont(fontName, + fontSize, + new IFont.Style[] { IFont.Style.BOLD }); + + if (derivedFont != null) { + titleFont = derivedFont; + titleFont.setSmoothing(false); + titleFont.setScaleFont(false); + } + + break; + } + } + + } + } + + int i = 0; + for (IGraphableResource grsc : graphResource) { + GeoMagRTKpResource rsc = (GeoMagRTKpResource) grsc; + if (rsc.getProperties().isVisible()) { + String[] rscTitle = rsc.getTitles(); + paintYTitle(target, paintProps, rscTitle[0], colorToUse, i++); + + if (rsc.getResourceData() != null) { + paintXTitle( + target, + paintProps, + "Start Time (" + + topLabelSdf.format(rsc.getStartTime() + .getRefTime()) + ")", colorToUse); + } + } + } + + DrawableString titleString = new DrawableString( + "Real-time Plot for Estimated Kp Index", colorToUse); + titleString.font = titleFont; + titleString.textStyle = TextStyle.DROP_SHADOW; + titleString.horizontalAlignment = HorizontalAlignment.LEFT; + titleString.horizontalAlignment = HorizontalAlignment.CENTER; + titleString.verticallAlignment = VerticalAlignment.TOP; + titleString.magnification = this.currentMagnification; + double x = graphExtent.getMinX() + graphExtent.getWidth() / 2; + titleString.setCoordinates(x, 100.0); + target.drawStrings(titleString); + + paintTopTimeLabels(target, paintProps, updatedDate); + } + + @Override + protected void paintYTitle(IGraphicsTarget target, + PaintProperties paintProps, String title, RGB titleColor, int index) + throws VizException { + + // Paint the titles + double ratio = paintProps.getCanvasBounds().height + / paintProps.getView().getExtent().getHeight(); + DrawableString titleString = new DrawableString(title, titleColor); + titleString.font = titleFont; + titleString.textStyle = TextStyle.DROP_SHADOW; + titleString.horizontalAlignment = HorizontalAlignment.LEFT; + titleString.verticallAlignment = VerticalAlignment.BOTTOM; + titleString.rotation = 90; + titleString.magnification = this.currentMagnification; + int width = target.getStringsBounds(titleString).getBounds().width; + int height = target.getStringsBounds(titleString, "N").getBounds().height * 2; + double x = graphExtent.getMinX() - 40.0 - height * (index); + double y = graphExtent.getMaxY() + - ((graphExtent.getHeight() - (width / ratio)) / 2.0) + 30.0; + titleString.setCoordinates(x, y); + + target.drawStrings(titleString); + } + + @Override + protected void paintDataTimeUnits(IGraphicsTarget target, + PaintProperties paintProps, List> xLabels) + throws VizException { + + unitsFont = target.initializeFont((String) null, 14.0f, + new IFont.Style[] { IFont.Style.BOLD }); + unitsFont.setSmoothing(false); + unitsFont.setScaleFont(false); + + List strings = new ArrayList( + xLabels.size()); + + for (IGraphLabel xLabel : xLabels) { + double val = xLabel.getDiscreteValue(); + Date date = xLabel.getUnderlyingObject().getRefTime(); + + // RGB labelColor = getColorToUse(); + // RGB labelColor = xLabel.getResource() + // .getCapability(ColorableCapability.class).getColor(); + DrawableString parameters = new DrawableString(sdf.format(date), + colorToUse); + parameters.font = unitsFont; + parameters.horizontalAlignment = HorizontalAlignment.CENTER; + parameters.verticallAlignment = VerticalAlignment.TOP; + parameters.magnification = this.currentMagnification; + + double offset = yAxisPlacer.getPixelLoc(val); + Coordinate loc = new Coordinate(graphExtent.getMinX() + offset, + graphExtent.getMaxY() + 5, 0); + parameters.setCoordinates(loc.x, loc.y, loc.z); + + strings.add(parameters); + } + target.drawStrings(strings); + + // paint x-axis tick marks + for (int i = 0; i < xLabels.size(); i++) { + + double val = xLabels.get(i).getDiscreteValue(); + double offset = yAxisPlacer.getPixelLoc(val); + + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMaxY() - 7, 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("white"), 1, LineStyle.SOLID); + + } + + } + + protected void paintTopTimeLabels(IGraphicsTarget target, + PaintProperties paintProps, Date updatedDate) throws VizException { + // Paint the top labels + + DrawableString lastDataString = new DrawableString("Last Data " + + topLabelSdf.format(RTKpUtil.getKpStationsLastDataDate(null, + null)), colorToUse); + lastDataString.font = titleFont; + lastDataString.textStyle = TextStyle.DROP_SHADOW; + lastDataString.horizontalAlignment = HorizontalAlignment.CENTER; + lastDataString.verticallAlignment = VerticalAlignment.BOTTOM; + lastDataString.magnification = this.currentMagnification; + double x = graphExtent.getMinX() + graphExtent.getWidth() / 1.3 + - titleFont.getFontSize(); + lastDataString.setCoordinates(x, 45.0); + + target.drawStrings(lastDataString); + + // Date updatedDate = ((GeoMagRTKpResource) graphResource.get(0)) + // .getUpdatedDate(); + + // System.out.println(" update date = " + updatedDate.toGMTString() + // + " size = " + graphResource.size()); + // if (graphResource.size() > 1) { + // if (((GeoMagRTKpResource) graphResource.get(1)).getUpdatedDate() + // .after(updatedDate)) { + // updatedDate = ((GeoMagRTKpResource) graphResource.get(1)) + // .getUpdatedDate(); + // + // } + // } + + DrawableString updatedString = new DrawableString("Updated " + + topLabelSdf.format(updatedDate), colorToUse); + updatedString.font = titleFont; + updatedString.textStyle = TextStyle.DROP_SHADOW; + updatedString.horizontalAlignment = HorizontalAlignment.CENTER; + updatedString.verticallAlignment = VerticalAlignment.BOTTOM; + updatedString.magnification = this.currentMagnification; + updatedString.setCoordinates(x, 75.0); + + target.drawStrings(updatedString); + + } + + protected void paintXTitle(IGraphicsTarget target, + PaintProperties paintProps, String title, RGB titleColor) + throws VizException { + // Paint the titles + double ratio = paintProps.getCanvasBounds().width + / paintProps.getView().getExtent().getWidth(); + DrawableString titleString = new DrawableString(title, titleColor); + titleString.font = titleFont; + titleString.textStyle = TextStyle.DROP_SHADOW; + titleString.horizontalAlignment = HorizontalAlignment.CENTER; + titleString.verticallAlignment = VerticalAlignment.TOP; + titleString.magnification = this.currentMagnification; + double x = graphExtent.getMinX() + graphExtent.getWidth() / 2; + double y = graphExtent.getMaxY() + 60.0; + + titleString.setCoordinates(x, y); + + target.drawStrings(titleString); + } + + protected RGB getColorToUse() { + RGB colorToUse = RGBColors.getRGBColor("white"); + AbstractEditor editor = (AbstractEditor) EditorUtil.getActiveEditor(); + + if (editor != null) { + IDisplayPane activePane = editor.getActiveDisplayPane(); + ResourceList acResources = activePane.getDescriptor() + .getResourceList(); + int acRscSize = acResources.size(); + + for (int i = acRscSize - 1; i >= 0; i--) { + ResourcePair rp = acResources.get(i); + AbstractVizResource activeRsc = rp.getResource(); + + if (activeRsc != null + && activeRsc instanceof GeoMagRTKpResource + && rp.getProperties().isVisible()) { + + KsPlotCapability ksCap = activeRsc + .getCapability(KsPlotCapability.class); + if (ksCap != null) { + if (RTKpUtil.KS_PLOT + .equals(((TimeSeriesResourceData) activeRsc + .getResourceData()).getSource())) { + colorToUse = activeRsc.getCapability( + ColorableCapability.class).getColor(); + } + break; + } + } + + } + } + return colorToUse; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpTimeSeriesAdapter.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpTimeSeriesAdapter.java new file mode 100644 index 0000000000..3786825dcb --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/GeoMagRTKpTimeSeriesAdapter.java @@ -0,0 +1,135 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.TimeZone; + +import javax.measure.unit.SI; +import javax.measure.unit.Unit; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.style.level.SingleLevel; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.xy.timeseries.adapter.AbstractTimeSeriesAdapter; +import com.raytheon.viz.core.graphing.xy.XYData; +import com.raytheon.viz.core.graphing.xy.XYDataList; + +/** + * RTKP Time Series adapter. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2014  1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpTimeSeriesAdapter extends + AbstractTimeSeriesAdapter { + + private static Unit unit = SI.NANO(SI.TESLA); + + static final long ONE_MINUTE_IN_MILLIS = 60000;// millisecs + + @Override + public XYDataList loadData() throws VizException { + GeoMagRecord[] recordsToLoad = null; + synchronized (records) { + recordsToLoad = new GeoMagRecord[records.size()]; + Iterator iter = records.iterator(); + for (int i = 0; i < recordsToLoad.length; ++i) { + recordsToLoad[i] = iter.next(); + } + } + return loadInternal(recordsToLoad); + } + + @Override + public XYDataList loadRecord(PluginDataObject pdo) throws VizException { + GeoMagRecord[] recordsToLoad = new GeoMagRecord[1]; + recordsToLoad[0] = (GeoMagRecord) pdo; + return loadInternal(recordsToLoad); + } + + private XYDataList loadInternal(GeoMagRecord[] recordsToLoad) { + + System.out.println(" ... recordsToLoad.length = " + + recordsToLoad.length); + ArrayList data = new ArrayList(); + + XYDataList list = new XYDataList(); + list.setData(data); + + return list; + } + + /** + * + */ + private void sortRecordsToLoad(GeoMagRecord[] recordsToLoad) { + List recordsList = Arrays.asList(recordsToLoad); + Collections.sort(recordsList, new Comparator() { + + @Override + public int compare(GeoMagRecord xy1, GeoMagRecord xy2) { + DataTime t1 = (DataTime) xy1.getDataTime(); + DataTime t2 = (DataTime) xy2.getDataTime(); + return t1.compareTo(t2); + } + + }); + + } + + private Date getUtcTime(Calendar cal) { + // cal in GMT timezone + TimeZone z = TimeZone.getDefault(); + int offset = z.getOffset(cal.getTimeInMillis()); + + Date date = new Date(cal.getTimeInMillis() - offset); + + return date; + } + + @Override + public SingleLevel getLevel() { + SingleLevel level = new SingleLevel("SURFACE"); + level.setValue(0.0); + return level; + } + + @Override + public Unit getDataUnit() { + return unit; + } + + @Override + public String getParameterName() { + return resourceData.getYParameter().name; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KpPlotCapability.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KpPlotCapability.java new file mode 100644 index 0000000000..a41fc9a67b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KpPlotCapability.java @@ -0,0 +1,153 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; + +/** + * Implementation for describing persistable capabilities for the Kp Plot + * attributes + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer      Description
+ * ------------ ---------- -----------   --------------------------
+ * 09-03-2014   R4078       sgurung       Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class KpPlotCapability extends AbstractCapability { + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColor = new RGB(0, 238, 238); + + @XmlAttribute + protected String textSize = "14"; + + @XmlAttribute + protected String textFont = "Times"; + + @XmlAttribute + protected String textStyle = "Bold"; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + protected RGB textColor = new RGB(255, 255, 255); + + @XmlAttribute + private String pointStyle = "POINT"; + + @XmlAttribute + private String pointSize = "1.75"; + + public KpPlotCapability() { + + } + + public KpPlotCapability(RGB plotColor, String textSize, String textFont, + String textStyle, RGB textColor, String pointStyle, String pointSize) { + + this.plotColor = plotColor; + this.textSize = textSize; + this.textFont = textFont; + this.textStyle = textStyle; + this.textColor = textColor; + this.pointStyle = pointStyle; + this.pointSize = pointSize; + } + + public RGB getPlotColor() { + return plotColor; + } + + public void setPlotColor(RGB plotColor) { + this.plotColor = plotColor; + } + + public String getTextSize() { + return textSize; + } + + public void setTextSize(String textSize) { + this.textSize = textSize; + } + + public String getTextFont() { + return textFont; + } + + public void setTextFont(String textFont) { + this.textFont = textFont; + } + + public String getTextStyle() { + return textStyle; + } + + public void setTextStyle(String textStyle) { + this.textStyle = textStyle; + } + + public RGB getTextColor() { + return textColor; + } + + public void setTextColor(RGB textColor) { + this.textColor = textColor; + } + + public String getPointStyle() { + return pointStyle; + } + + public void setPointStyle(String pointStyle) { + this.pointStyle = pointStyle; + } + + public String getPointSize() { + return pointSize; + } + + public void setPointSize(String pointSize) { + this.pointSize = pointSize; + } + + @Override + public AbstractCapability clone() { + KpPlotCapability kpc = new KpPlotCapability(); + kpc.plotColor = plotColor; + kpc.textSize = textSize; + kpc.textFont = textFont; + kpc.textStyle = textStyle; + kpc.textColor = textColor; + kpc.pointStyle = pointStyle; + kpc.pointSize = pointSize; + + return kpc; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KsPlotCapability.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KsPlotCapability.java new file mode 100644 index 0000000000..84fe0f71c8 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/KsPlotCapability.java @@ -0,0 +1,361 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; + +/** + * Implementation for describing persistable capabilities for the Ks Plot + * attributes. + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer      Description
+ * ------------ ---------- -----------   --------------------------
+ * May 30, 2014 1122       sgurung       Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class KsPlotCapability extends AbstractCapability { + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn0 = new RGB(0, 0, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn1 = new RGB(0, 255, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn2 = new RGB(78, 146, 88); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn3 = new RGB(255, 255, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn4 = new RGB(255, 136, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn5 = new RGB(255, 0, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn6 = new RGB(136, 136, 136); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn7 = new RGB(68, 68, 68); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB plotColorStn8 = new RGB(255, 255, 255); + + @XmlAttribute + protected String textSize = "14"; + + @XmlAttribute + protected String textFont = "Times"; + + @XmlAttribute + protected String textStyle = "Bold"; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + protected RGB textColor = new RGB(255, 255, 255); + + @XmlAttribute + private String pointStyle = "POINT"; + + @XmlAttribute + private String pointSize = "1.75"; + + public KsPlotCapability() { + + } + + public KsPlotCapability(RGB[] plotColorStns, String textSize, + String textFont, String textStyle, RGB textColor, + String pointStyle, String pointSize) { + if (plotColorStns != null && plotColorStns.length == 9) { + this.plotColorStn0 = plotColorStns[0]; + this.plotColorStn1 = plotColorStns[1]; + this.plotColorStn2 = plotColorStns[2]; + this.plotColorStn3 = plotColorStns[3]; + this.plotColorStn4 = plotColorStns[4]; + this.plotColorStn5 = plotColorStns[5]; + this.plotColorStn6 = plotColorStns[6]; + this.plotColorStn7 = plotColorStns[7]; + this.plotColorStn8 = plotColorStns[8]; + } + + this.textSize = textSize; + this.textFont = textFont; + this.textStyle = textStyle; + this.textColor = textColor; + this.pointStyle = pointStyle; + this.pointSize = pointSize; + } + + public RGB getPlotColorStn0() { + return plotColorStn0; + } + + public void setPlotColorStn0(RGB plotColorStn0) { + if ((this.plotColorStn0 == null) && (plotColorStn0 == null)) { + return; + } + if ((this.plotColorStn0 == null) + || !this.plotColorStn0.equals(plotColorStn0)) { + this.plotColorStn0 = plotColorStn0; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn1() { + return plotColorStn1; + } + + public void setPlotColorStn1(RGB plotColorStn1) { + if ((this.plotColorStn1 == null) && (plotColorStn1 == null)) { + return; + } + if ((this.plotColorStn1 == null) + || !this.plotColorStn1.equals(plotColorStn1)) { + this.plotColorStn1 = plotColorStn1; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn2() { + return plotColorStn2; + } + + public void setPlotColorStn2(RGB plotColorStn2) { + if ((this.plotColorStn2 == null) && (plotColorStn2 == null)) { + return; + } + if ((this.plotColorStn2 == null) + || !this.plotColorStn2.equals(plotColorStn2)) { + this.plotColorStn2 = plotColorStn2; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn3() { + return plotColorStn3; + } + + public void setPlotColorStn3(RGB plotColorStn3) { + if ((this.plotColorStn3 == null) && (plotColorStn3 == null)) { + return; + } + if ((this.plotColorStn3 == null) + || !this.plotColorStn3.equals(plotColorStn3)) { + this.plotColorStn3 = plotColorStn3; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn4() { + return plotColorStn4; + } + + public void setPlotColorStn4(RGB plotColorStn4) { + if ((this.plotColorStn4 == null) && (plotColorStn4 == null)) { + return; + } + if ((this.plotColorStn4 == null) + || !this.plotColorStn4.equals(plotColorStn4)) { + this.plotColorStn4 = plotColorStn4; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn5() { + return plotColorStn5; + } + + public void setPlotColorStn5(RGB plotColorStn5) { + if ((this.plotColorStn5 == null) && (plotColorStn5 == null)) { + return; + } + if ((this.plotColorStn5 == null) + || !this.plotColorStn5.equals(plotColorStn5)) { + this.plotColorStn5 = plotColorStn5; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn6() { + return plotColorStn6; + } + + public void setPlotColorStn6(RGB plotColorStn6) { + if ((this.plotColorStn6 == null) && (plotColorStn6 == null)) { + return; + } + if ((this.plotColorStn6 == null) + || !this.plotColorStn6.equals(plotColorStn6)) { + this.plotColorStn6 = plotColorStn6; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn7() { + return plotColorStn7; + } + + public void setPlotColorStn7(RGB plotColorStn7) { + if ((this.plotColorStn7 == null) && (plotColorStn7 == null)) { + return; + } + if ((this.plotColorStn7 == null) + || !this.plotColorStn7.equals(plotColorStn7)) { + this.plotColorStn7 = plotColorStn7; + this.capabilityChanged(); + } + } + + public RGB getPlotColorStn8() { + return plotColorStn8; + } + + public void setPlotColorStn8(RGB plotColorStn8) { + if ((this.plotColorStn8 == null) && (plotColorStn8 == null)) { + return; + } + if ((this.plotColorStn8 == null) + || !this.plotColorStn8.equals(plotColorStn8)) { + this.plotColorStn8 = plotColorStn8; + this.capabilityChanged(); + } + } + + public String getTextSize() { + return textSize; + } + + public void setTextSize(String textSize) { + this.textSize = textSize; + } + + public String getTextFont() { + return textFont; + } + + public void setTextFont(String textFont) { + this.textFont = textFont; + } + + public String getTextStyle() { + return textStyle; + } + + public void setTextStyle(String textStyle) { + this.textStyle = textStyle; + } + + public RGB getTextColor() { + return textColor; + } + + public void setTextColor(RGB textColor) { + this.textColor = textColor; + } + + public String getPointStyle() { + return pointStyle; + } + + public void setPointStyle(String pointStyle) { + this.pointStyle = pointStyle; + } + + public String getPointSize() { + return pointSize; + } + + public void setPointSize(String pointSize) { + this.pointSize = pointSize; + } + + public RGB[] getPlotColors() { + + RGB[] plotColorStns = new RGB[9]; + plotColorStns[0] = plotColorStn0; + plotColorStns[1] = plotColorStn1; + plotColorStns[2] = plotColorStn2; + plotColorStns[3] = plotColorStn3; + plotColorStns[4] = plotColorStn4; + plotColorStns[5] = plotColorStn5; + plotColorStns[6] = plotColorStn6; + plotColorStns[7] = plotColorStn7; + plotColorStns[8] = plotColorStn8; + + return plotColorStns; + } + + public void setPlotColors(RGB[] plotColorStns) { + if (plotColorStns != null && plotColorStns.length == 9) { + plotColorStn0 = plotColorStns[0]; + plotColorStn1 = plotColorStns[1]; + plotColorStn2 = plotColorStns[2]; + plotColorStn3 = plotColorStns[3]; + plotColorStn4 = plotColorStns[4]; + plotColorStn5 = plotColorStns[5]; + plotColorStn6 = plotColorStns[6]; + plotColorStn7 = plotColorStns[7]; + plotColorStn8 = plotColorStns[8]; + } + } + + @Override + public AbstractCapability clone() { + KsPlotCapability ksc = new KsPlotCapability(); + ksc.plotColorStn0 = plotColorStn0; + ksc.plotColorStn1 = plotColorStn1; + ksc.plotColorStn2 = plotColorStn2; + ksc.plotColorStn3 = plotColorStn3; + ksc.plotColorStn4 = plotColorStn4; + ksc.plotColorStn5 = plotColorStn5; + ksc.plotColorStn6 = plotColorStn6; + ksc.plotColorStn7 = plotColorStn7; + ksc.plotColorStn8 = plotColorStn8; + ksc.textSize = textSize; + ksc.textFont = textFont; + ksc.textStyle = textStyle; + ksc.textColor = textColor; + ksc.pointStyle = pointStyle; + ksc.pointSize = pointSize; + + return ksc; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/MagActivityCapability.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/MagActivityCapability.java new file mode 100644 index 0000000000..e943d2cf3a --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/MagActivityCapability.java @@ -0,0 +1,378 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerTextSize; + +import java.awt.Color; + +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.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; + +/** + * Implementation for describing persistable capabilities for the attributes + * used in the world-wide mag activity map (k-indices circle colors, marker + * color, marker size, text size etc.) + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer      Description
+ * ------------ ---------- -----------   --------------------------
+ * June 3, 2014 1122       sgurung       Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class MagActivityCapability extends AbstractCapability { + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB quiet = new RGB(0, 128, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB unsettled = new RGB(100, 228, 100); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB active = new RGB(9, 135, 205); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB minorstorm = new RGB(142, 53, 239);; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB moderatestorm = new RGB(205, 0, 205); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB strongstorm = new RGB(255, 255, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB severestorm = new RGB(215, 125, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB extremestorm = new RGB(255, 0, 0); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB nonNetwrkStnColor = new RGB(157, 114, 50); + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB[] kIndicesTextColors = { new RGB(255, 255, 255), + new RGB(255, 255, 255), new RGB(255, 255, 255), new RGB(0, 0, 0), + new RGB(255, 255, 255), new RGB(255, 255, 255), + new RGB(255, 255, 255), new RGB(0, 0, 0), new RGB(255, 255, 255), + new RGB(255, 255, 255) }; + + @XmlElement + private Float markerSize = 1.3f; + + @XmlElement + private MarkerTextSize markerTextSize = MarkerTextSize.MEDIUM; + + public MagActivityCapability() { + + } + + public MagActivityCapability(RGB[] kIndicesColors, + RGB[] kIndicesTextColors, RGB nonNetwrkStnColor, Float markerSize, + MarkerTextSize markerTextSize) { + if (kIndicesColors != null && kIndicesColors.length == 8) { + this.quiet = kIndicesColors[0]; + this.unsettled = kIndicesColors[1]; + this.active = kIndicesColors[2]; + this.minorstorm = kIndicesColors[3]; + this.moderatestorm = kIndicesColors[4]; + this.strongstorm = kIndicesColors[5]; + this.severestorm = kIndicesColors[6]; + this.extremestorm = kIndicesColors[7]; + } + this.kIndicesTextColors = kIndicesTextColors; + this.nonNetwrkStnColor = nonNetwrkStnColor; + this.markerSize = markerSize; + this.markerTextSize = markerTextSize; + } + + public RGB getQuiet() { + return quiet; + } + + public void setQuiet(RGB quiet) { + if ((this.quiet == null) && (quiet == null)) { + return; + } + if ((this.quiet == null) || !this.quiet.equals(quiet)) { + this.quiet = quiet; + this.capabilityChanged(); + } + } + + public RGB getUnsettled() { + return unsettled; + } + + public void setUnsettled(RGB unsettled) { + if ((this.unsettled == null) && (unsettled == null)) { + return; + } + if ((this.unsettled == null) || !this.unsettled.equals(unsettled)) { + this.unsettled = unsettled; + this.capabilityChanged(); + } + } + + public RGB getActive() { + return active; + } + + public void setActive(RGB active) { + if ((this.active == null) && (active == null)) { + return; + } + if ((this.active == null) || !this.active.equals(active)) { + this.active = active; + this.capabilityChanged(); + } + } + + public RGB getMinorstorm() { + return minorstorm; + } + + public void setMinorstorm(RGB minorstorm) { + if ((this.minorstorm == null) && (minorstorm == null)) { + return; + } + if ((this.minorstorm == null) || !this.minorstorm.equals(minorstorm)) { + this.minorstorm = minorstorm; + this.capabilityChanged(); + } + } + + public RGB getModeratestorm() { + return moderatestorm; + } + + public void setModeratestorm(RGB moderatestorm) { + if ((this.moderatestorm == null) && (moderatestorm == null)) { + return; + } + if ((this.moderatestorm == null) + || !this.moderatestorm.equals(moderatestorm)) { + this.moderatestorm = moderatestorm; + this.capabilityChanged(); + } + } + + public RGB getStrongstorm() { + return strongstorm; + } + + public void setStrongstorm(RGB strongstorm) { + if ((this.strongstorm == null) && (strongstorm == null)) { + return; + } + if ((this.strongstorm == null) || !this.strongstorm.equals(strongstorm)) { + this.strongstorm = strongstorm; + this.capabilityChanged(); + } + } + + public RGB getSeverestorm() { + return severestorm; + } + + public void setSeverestorm(RGB severestorm) { + if ((this.severestorm == null) && (severestorm == null)) { + return; + } + if ((this.severestorm == null) || !this.severestorm.equals(severestorm)) { + this.severestorm = severestorm; + this.capabilityChanged(); + } + } + + public RGB getExtremestorm() { + return extremestorm; + } + + public void setExtremestorm(RGB extremestorm) { + if ((this.extremestorm == null) && (extremestorm == null)) { + return; + } + if ((this.extremestorm == null) + || !this.extremestorm.equals(extremestorm)) { + this.extremestorm = extremestorm; + this.capabilityChanged(); + } + } + + public Float getMarkerSize() { + return markerSize; + } + + public void setMarkerSize(Float markerSize) { + if ((this.markerSize == null) && (markerSize == null)) { + return; + } + this.markerSize = markerSize; + this.capabilityChanged(); + } + + public MarkerTextSize getMarkerTextSize() { + return markerTextSize; + } + + public void setMarkerTextSize(MarkerTextSize markerTextSize) { + if ((this.markerTextSize == null) && (markerTextSize == null)) { + return; + } + this.markerTextSize = markerTextSize; + this.capabilityChanged(); + } + + public RGB getNonNetwrkStnColor() { + return nonNetwrkStnColor; + } + + public void setNonNetwrkStnColor(RGB nonNetwrkStnColor) { + if ((this.nonNetwrkStnColor == null) && (nonNetwrkStnColor == null)) { + return; + } + this.nonNetwrkStnColor = nonNetwrkStnColor; + this.capabilityChanged(); + } + + public RGB[] getkIndicesTextColors() { + return kIndicesTextColors; + } + + public void setkIndicesTextColors(RGB[] kIndicesTextColors) { + if ((this.kIndicesTextColors == null) && (kIndicesTextColors == null)) { + return; + } + this.kIndicesTextColors = kIndicesTextColors; + this.capabilityChanged(); + } + + public RGB[] getColors() { + + RGB[] colors = new RGB[8]; + colors[0] = this.quiet; + colors[1] = this.unsettled; + colors[2] = this.active; + colors[3] = this.minorstorm; + colors[4] = this.moderatestorm; + colors[5] = this.strongstorm; + colors[6] = this.severestorm; + colors[7] = this.extremestorm; + + return colors; + } + + public void setColors(RGB[] colors) { + if (colors != null && colors.length == 8) { + this.quiet = colors[0]; + this.unsettled = colors[1]; + this.active = colors[2]; + this.minorstorm = colors[3]; + this.moderatestorm = colors[4]; + this.strongstorm = colors[5]; + this.severestorm = colors[6]; + this.extremestorm = colors[7]; + } + } + + public Color[] getNOAAScaleColors() { + Color[] colors = new Color[10]; + colors[0] = new Color(this.quiet.red, this.quiet.green, this.quiet.blue); + colors[1] = colors[0]; + colors[2] = colors[0]; + colors[3] = new Color(this.unsettled.red, this.unsettled.green, + this.unsettled.blue); + colors[4] = new Color(this.active.red, this.active.green, + this.active.blue); + colors[5] = new Color(this.minorstorm.red, this.minorstorm.green, + this.minorstorm.blue); + colors[6] = new Color(this.moderatestorm.red, this.moderatestorm.green, + this.moderatestorm.blue); + colors[7] = new Color(this.strongstorm.red, this.strongstorm.green, + this.strongstorm.blue); + colors[8] = new Color(this.severestorm.red, this.severestorm.green, + this.severestorm.blue); + colors[9] = new Color(this.extremestorm.red, this.extremestorm.green, + this.extremestorm.blue); + + return colors; + } + + public RGB[] getNOAAScaleRGBColors() { + RGB[] colors = new RGB[10]; + colors[0] = new RGB(this.quiet.red, this.quiet.green, this.quiet.blue); + colors[1] = colors[0]; + colors[2] = colors[0]; + colors[3] = new RGB(this.unsettled.red, this.unsettled.green, + this.unsettled.blue); + colors[4] = new RGB(this.active.red, this.active.green, + this.active.blue); + colors[5] = new RGB(this.minorstorm.red, this.minorstorm.green, + this.minorstorm.blue); + colors[6] = new RGB(this.moderatestorm.red, this.moderatestorm.green, + this.moderatestorm.blue); + colors[7] = new RGB(this.strongstorm.red, this.strongstorm.green, + this.strongstorm.blue); + colors[8] = new RGB(this.severestorm.red, this.severestorm.green, + this.severestorm.blue); + colors[9] = new RGB(this.extremestorm.red, this.extremestorm.green, + this.extremestorm.blue); + + return colors; + } + + public Color getNonNetWorkStationMarkerColor() { + return new Color(this.nonNetwrkStnColor.red, + this.nonNetwrkStnColor.green, this.nonNetwrkStnColor.blue); + } + + @Override + public AbstractCapability clone() { + MagActivityCapability mac = new MagActivityCapability(); + mac.quiet = this.quiet; + mac.unsettled = this.unsettled; + mac.active = this.active; + mac.minorstorm = this.minorstorm; + mac.moderatestorm = this.moderatestorm; + mac.strongstorm = this.strongstorm; + mac.severestorm = this.severestorm; + mac.extremestorm = this.extremestorm; + mac.kIndicesTextColors = this.kIndicesTextColors; + mac.nonNetwrkStnColor = this.nonNetwrkStnColor; + mac.markerSize = this.markerSize; + mac.markerTextSize = this.markerTextSize; + return mac; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/RTKpTimeSeriesRenderableDisplay.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/RTKpTimeSeriesRenderableDisplay.java new file mode 100644 index 0000000000..7beb099c7f --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/RTKpTimeSeriesRenderableDisplay.java @@ -0,0 +1,48 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.xy.timeseries.display.TimeSeriesRenderableDisplay; + +/** + * RTKP Time series renderable display, plugs in the time series graph factory, + * descriptor and sets the graph resource + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2014  1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class RTKpTimeSeriesRenderableDisplay extends + TimeSeriesRenderableDisplay { + + @Override + public void paint(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + super.paint(target, paintProps); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKpPlotAttributesAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKpPlotAttributesAction.java new file mode 100644 index 0000000000..dc71d39dca --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKpPlotAttributesAction.java @@ -0,0 +1,86 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.rtkp.KpPlotCapability; +import gov.noaa.nws.ncep.viz.rtkp.controls.EditKpPlotAttributesDialog; + +import com.raytheon.viz.ui.VizWorkbenchManager; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * 09-03-2014    R4078       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class EditKpPlotAttributesAction extends AbstractRightClickAction { + + private static String title = "Edit Kp Attributes..."; + + public EditKpPlotAttributesAction() { + super(title); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + + EditKpPlotAttributesDialog pd = new EditKpPlotAttributesDialog( + VizWorkbenchManager.getInstance().getCurrentWindow().getShell(), + title, getTopMostSelectedResource().getCapability( + KpPlotCapability.class)); + + KpPlotCapability result = pd.open(); + + if (result != null) { + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setPlotColor(result.getPlotColor()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setTextFont(result.getTextFont()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setTextSize(result.getTextSize()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setTextStyle(result.getTextStyle()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setTextColor(result.getTextColor()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setPointStyle(result.getPointStyle()); + getTopMostSelectedResource().getCapability(KpPlotCapability.class) + .setPointSize(result.getPointSize()); + } + + getContainer().refresh(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return title; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKsPlotAttributesAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKsPlotAttributesAction.java new file mode 100644 index 0000000000..11ca6fe366 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditKsPlotAttributesAction.java @@ -0,0 +1,86 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.rtkp.KsPlotCapability; +import gov.noaa.nws.ncep.viz.rtkp.controls.EditKsPlotAttributesDialog; + +import com.raytheon.viz.ui.VizWorkbenchManager; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * June 2, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class EditKsPlotAttributesAction extends AbstractRightClickAction { + + private static String title = "Edit Ks Attributes..."; + + public EditKsPlotAttributesAction() { + super(title); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + + EditKsPlotAttributesDialog pd = new EditKsPlotAttributesDialog( + VizWorkbenchManager.getInstance().getCurrentWindow().getShell(), + title, getTopMostSelectedResource().getCapability( + KsPlotCapability.class)); + + KsPlotCapability result = pd.open(); + + if (result != null) { + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setPlotColors(result.getPlotColors()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setTextFont(result.getTextFont()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setTextSize(result.getTextSize()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setTextStyle(result.getTextStyle()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setTextColor(result.getTextColor()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setPointStyle(result.getPointStyle()); + getTopMostSelectedResource().getCapability(KsPlotCapability.class) + .setPointSize(result.getPointSize()); + } + + getContainer().refresh(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return title; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditMagActivityAttributesAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditMagActivityAttributesAction.java new file mode 100644 index 0000000000..0da07de437 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/EditMagActivityAttributesAction.java @@ -0,0 +1,105 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerTextSize; +import gov.noaa.nws.ncep.viz.rtkp.MagActivityCapability; +import gov.noaa.nws.ncep.viz.rtkp.controls.EditMagActivityAttributesDialog; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.viz.ui.VizWorkbenchManager; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * June 3, 2014  1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class EditMagActivityAttributesAction extends AbstractRightClickAction { + + private static String title = "Edit Mag Activity Attributes..."; + + public EditMagActivityAttributesAction() { + super(title); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + + RGB[] colors = getTopMostSelectedResource().getCapability( + MagActivityCapability.class).getColors(); + RGB[] textColors = getTopMostSelectedResource().getCapability( + MagActivityCapability.class).getkIndicesTextColors(); + Float markerSize = getTopMostSelectedResource().getCapability( + MagActivityCapability.class).getMarkerSize(); + RGB nonNetwrkStnColor = getTopMostSelectedResource().getCapability( + MagActivityCapability.class).getNonNetwrkStnColor(); + // Integer markerWidth = getTopMostSelectedResource().getCapability( + // MagActivityCapability.class).getMarkerWidth(); + MarkerTextSize markerTextSize = getTopMostSelectedResource() + .getCapability(MagActivityCapability.class).getMarkerTextSize(); + EditMagActivityAttributesDialog pd = new EditMagActivityAttributesDialog( + VizWorkbenchManager.getInstance().getCurrentWindow().getShell(), + title, colors, textColors, nonNetwrkStnColor, markerSize, + markerTextSize); + + MagActivityCapability result = pd.open(); + + if (result != null) { + + getTopMostSelectedResource().getCapability( + MagActivityCapability.class).setColors(result.getColors()); + getTopMostSelectedResource().getCapability( + MagActivityCapability.class).setkIndicesTextColors( + result.getkIndicesTextColors()); + getTopMostSelectedResource().getCapability( + MagActivityCapability.class).setNonNetwrkStnColor( + result.getNonNetwrkStnColor()); + getTopMostSelectedResource().getCapability( + MagActivityCapability.class).setMarkerSize( + result.getMarkerSize()); + // getTopMostSelectedResource().getCapability( + // MagActivityCapability.class).setMarkerWidth( + // result.getMarkerWidth()); + getTopMostSelectedResource().getCapability( + MagActivityCapability.class).setMarkerTextSize( + result.getMarkerTextSize()); + } + + getContainer().refresh(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return title; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpAction.java new file mode 100644 index 0000000000..3b0696cd1b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpAction.java @@ -0,0 +1,120 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.localization.NcPathManager; +import gov.noaa.nws.ncep.viz.rtkp.GeoMagRTKpDescriptor; +import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagRTKpResourceData; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +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.common.time.DataTime; +import com.raytheon.uf.viz.core.DescriptorMap; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.viz.ui.BundleLoader; +import com.raytheon.viz.ui.UiUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Handler to display Real-time Kp Monitor in national centers perspective. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 17, 2014  1122       sgurung     Initial creation
+ * 
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + * + */ +public class GeoMagRTKpAction extends AbstractHandler { + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagRTKpAction.class); + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands + * .ExecutionEvent) + */ + public Object execute(ExecutionEvent arg0) throws ExecutionException { + + File bundleFile = NcPathManager.getInstance().getStaticFile( + "ncep/Bundles/GeoMagRTKpMonitorPlots.xml"); + + Map vars = new HashMap(); + DataTime startTime = null; + DataTime endTime = null; + + Bundle b; + try { + b = Bundle.unmarshalBundle(bundleFile, vars); + + IRenderableDisplay renderableDisplay = b.getDisplays()[0]; + IDescriptor bundleDescriptor = renderableDisplay.getDescriptor(); + if (bundleDescriptor instanceof GeoMagRTKpDescriptor) { + GeoMagRTKpDescriptor geo = (GeoMagRTKpDescriptor) bundleDescriptor; + for (ResourcePair pair : geo.getSerializableResources()) { + if (pair.getResourceData() instanceof GeoMagRTKpResourceData) { + GeoMagRTKpResourceData rscData = (GeoMagRTKpResourceData) pair + .getResourceData(); + rscData.setPlotLengthInHours(6); + rscData.setUpdating(true); + // dataTime[] availableTimes = + // rscData.getAvailableTimes(); + startTime = new DataTime( + RTKpUtil.calcPrevSynPerStartTime()); + rscData.setStartTime(startTime); + endTime = rscData.getEndTime(); + } + } + } + String bundleEditorId = DescriptorMap.getEditorId(bundleDescriptor + .getClass().getName()); + + AbstractEditor editor = UiUtil.createOrOpenEditor(bundleEditorId, + renderableDisplay); + BundleLoader.loadTo(editor, b); + + // show the "Data Block" and "Recent Kp Estimates Block" view/window + RTKpUtil.showDataBlock( + RTKpUtil.calcDataBlockStartTime(RTKpUtil.calcCurTime()), + RTKpUtil.calcCurTime()); + } catch (VizException e) { + + statusHandler.handle(Priority.PROBLEM, + "Error loading RTKp Monitor", e); + + } + + return null; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpDataBlockAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpDataBlockAction.java new file mode 100644 index 0000000000..affc91082c --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpDataBlockAction.java @@ -0,0 +1,65 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * May 5, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpDataBlockAction extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent arg0) throws ExecutionException { + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(""); + + try { + + if (vpart == null) { + vpart = wpage.showView(RTKpUtil.DATABLOCK_VIEW_ID); + } else { + + if (!wpage.isPartVisible(vpart)) + vpart = wpage.showView(RTKpUtil.DATABLOCK_VIEW_ID); + + } + } catch (Exception e) { + + e.printStackTrace(); + + } + + return null; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpRecentKpEstAction.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpRecentKpEstAction.java new file mode 100644 index 0000000000..f00b0653f7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/actions/GeoMagRTKpRecentKpEstAction.java @@ -0,0 +1,65 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ + +package gov.noaa.nws.ncep.viz.rtkp.actions; + +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * May 5, 2014   1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpRecentKpEstAction extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent arg0) throws ExecutionException { + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(""); + + try { + + if (vpart == null) { + vpart = wpage.showView(RTKpUtil.RECENTKP_VIEW_ID); + } else { + if (!wpage.isPartVisible(vpart)) + vpart = wpage.showView(RTKpUtil.RECENTKP_VIEW_ID); + + } + } catch (Exception e) { + + e.printStackTrace(); + + } + + return null; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKpPlotAttributesDialog.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKpPlotAttributesDialog.java new file mode 100644 index 0000000000..198f243c97 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKpPlotAttributesDialog.java @@ -0,0 +1,305 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.controls; + +import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; +import gov.noaa.nws.ncep.viz.rtkp.KpPlotCapability; + +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +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.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Provides an interface to modify the Kp plot attributes. + * + *
+ * SOFTWARE HISTORY
+ * Date          Ticket#     Engineer    Description
+ * ------------  ----------  ----------- --------------------------
+ * June 06, 2014 1122        S. Gurung     Initial creation
+ * 
+ * @author sgurung
+ * @version 1.0
+ */
+
+public class EditKpPlotAttributesDialog extends Dialog {
+
+    private String dlgTitle = "Edit Kp Plot Colors";
+
+    private static EditKpPlotAttributesDialog INSTANCE = null;
+
+    private Shell shell;
+
+    private ColorButtonSelector plotColorCms = null;
+
+    private Combo textSizeCombo = null;
+
+    private Combo textFontCombo = null;
+
+    private ColorButtonSelector textColorCms = null;
+
+    private Combo pointStyleCombo = null;
+
+    private Combo pointSizeCombo = null;
+
+    private KpPlotCapability kpCap = null;
+
+    private final String[] textSizeOptions = { "10", "12", "14", "16", "18",
+            "20", "22", "24", "32" };
+
+    private final String[] textFontOptions = { "Courier", "Helvetica", "Times" };
+
+    private final String[] pointSizeOptions = { "0.5", "0.75", "1.0", "1.25",
+            "1.5", "1.75", "2.0", "2.25", "2.5", "2.75", "3.0" };
+
+    private final String[] pointStyleOptions = { "POINT", "CROSS", "X", "STAR",
+            "CIRCLE", "DISC", "DASH", "BOX", "SQUARE" };
+
+    public EditKpPlotAttributesDialog(Shell parentShell, String dialogTitle,
+            KpPlotCapability kpCap) {
+        super(parentShell);
+        this.dlgTitle = dialogTitle;
+
+        shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE);
+        shell.setText(dialogTitle);
+        shell.setSize(600, 800); // pack later
+
+        this.kpCap = kpCap;
+    }
+
+    public void initWidgets() {
+
+        textSizeCombo.setItems(textSizeOptions);
+
+        for (int i = 0; i < textSizeOptions.length; i++) {
+            String sz = kpCap.getTextSize();
+            if (textSizeOptions[i] == sz) {
+                textSizeCombo.select(i);
+            }
+        }
+
+        textFontCombo.setItems(textFontOptions);
+        for (int i = 0; i < textFontOptions.length; i++) {
+            String fnt = kpCap.getTextFont();
+            if (textFontOptions[i] == fnt) {
+                textFontCombo.select(i);
+            }
+        }
+
+        pointSizeCombo.setItems(pointSizeOptions);
+
+        for (int i = 0; i < pointSizeOptions.length; i++) {
+            String sz = kpCap.getPointSize();
+            if (pointSizeOptions[i] == sz) {
+                pointSizeCombo.select(i);
+            }
+        }
+
+        pointStyleCombo.setItems(pointStyleOptions);
+
+        for (int i = 0; i < pointStyleOptions.length; i++) {
+            String ps = kpCap.getPointStyle();
+            if (pointStyleOptions[i] == ps) {
+                pointStyleCombo.select(i);
+            }
+        }
+    }
+
+    /**
+     * Creates the dialog if the dialog does not exist and returns the instance.
+     * If the dialog exists, return the instance.
+     * 
+     * @param parShell
+     * @return
+     */
+    public static EditKpPlotAttributesDialog getInstance(Shell parShell,
+            String dialogTitle, KpPlotCapability ksCap) {
+
+        if (INSTANCE == null) {
+            INSTANCE = new EditKpPlotAttributesDialog(parShell, dialogTitle,
+                    ksCap);
+        }
+        return INSTANCE;
+
+    }
+
+    public Composite createDialog(Composite composite) {
+        Composite top = composite;
+
+        // Create the main layout for the shell.
+        GridLayout mainLayout = new GridLayout(1, true);
+        mainLayout.marginHeight = 1;
+        mainLayout.marginWidth = 1;
+        top.setLayout(mainLayout);
+
+        // Initialize all of the controls, and layouts
+
+        // Plot, Text and Point attribute options
+        Group optionsGroup = new Group(top, SWT.SHADOW_NONE);
+        optionsGroup.setText("Options");
+        GridData gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        optionsGroup.setLayoutData(gd);
+
+        createAttrControls(optionsGroup);
+
+        initWidgets();
+
+        createCloseButton();
+
+        return top;
+    }
+
+    /*
+     * Create plot attribute -- color, text attributes -- size, font and style
+     * and point attributes -- size and style.
+     */
+    private void createAttrControls(Group group) {
+
+        group.setLayout(new GridLayout(4, true));
+
+        GridLayout gl = new GridLayout(4, false);
+        gl.marginTop = 0;
+        gl.marginBottom = 3;
+        gl.marginRight = 0;
+        group.setLayout(gl);
+        group.setText("Options");
+
+        // Text size attribute
+        new Label(group, SWT.NONE).setText("Text Size: ");
+        textSizeCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        textSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                kpCap.setTextSize(textSizeCombo.getText());
+            }
+        });
+
+        // Point size attribute
+        new Label(group, SWT.NONE).setText("             Point Size: ");
+        pointSizeCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                kpCap.setPointSize(pointSizeCombo.getText());
+            }
+        });
+
+        // Text font attribute
+        new Label(group, SWT.NONE).setText("Text Font: ");
+        textFontCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
+        textFontCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                kpCap.setTextFont(textFontCombo.getText());
+            }
+        });
+
+        // Point size attribute
+        new Label(group, SWT.NONE).setText("             Point Style: ");
+        pointStyleCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointStyleCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                kpCap.setPointStyle(pointStyleCombo.getText());
+            }
+        });
+
+        // Text color
+        Label color_lbl = new Label(group, SWT.NONE);
+        color_lbl.setText("Text Color:");
+
+        textColorCms = new ColorButtonSelector(group, 85, 25);
+        textColorCms.setColorValue(kpCap.getTextColor());
+        textColorCms.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kpCap.setTextColor(textColorCms.getColorValue());
+            }
+        });
+
+        // Plot color
+        Label plotcolor_lbl = new Label(group, SWT.NONE);
+        plotcolor_lbl.setText("             Plot Color:");
+
+        plotColorCms = new ColorButtonSelector(group, 85, 25);
+        plotColorCms.setColorValue(kpCap.getPlotColor());
+        plotColorCms.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kpCap.setPlotColor(plotColorCms.getColorValue());
+            }
+        });
+
+    }
+
+    private void createCloseButton() {
+        Composite centeredComp = new Composite(shell, SWT.NONE);
+        GridLayout gl = new GridLayout(2, true);
+        centeredComp.setLayout(gl);
+        GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
+        gd.horizontalAlignment = SWT.CENTER;
+        centeredComp.setLayoutData(gd);
+
+        Button ok_btn = new Button(centeredComp, SWT.NONE);
+        ok_btn.setText("   OK    ");
+        ok_btn.setLayoutData(gd);
+        ok_btn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+
+        Button closeBtn = new Button(centeredComp, SWT.NONE);
+        closeBtn.setText("   Close   ");
+        closeBtn.setLayoutData(gd);
+        closeBtn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+    }
+
+    public KpPlotCapability open() {
+        Shell parent = getParent();
+        Display display = parent.getDisplay();
+
+        if (shell == null || shell.isDisposed()) {
+            shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE);
+            shell.setText(dlgTitle);
+            shell.setSize(600, 800);
+        }
+
+        createDialog(shell);
+
+        shell.pack();
+        shell.open();
+
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch()) {
+                display.sleep();
+            }
+        }
+
+        return kpCap;
+    }
+
+}
diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKsPlotAttributesDialog.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKsPlotAttributesDialog.java
new file mode 100644
index 0000000000..9c388d9ec4
--- /dev/null
+++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditKsPlotAttributesDialog.java
@@ -0,0 +1,476 @@
+/**
+ * This code has unlimited rights, and is provided "as is" by the National Centers 
+ * for Environmental Prediction, without warranty of any kind, either expressed or implied, 
+ * including but not limited to the implied warranties of merchantability and/or fitness 
+ * for a particular purpose.
+ * 
+ * This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
+ * 
+ **/
+package gov.noaa.nws.ncep.viz.rtkp.controls;
+
+import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector;
+import gov.noaa.nws.ncep.viz.rtkp.KsPlotCapability;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil.GeoMagStationType;
+
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+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.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Provides an interface to modify the Ks plot attributes.
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * Date          Ticket#     Engineer    Description
+ * ------------  ----------  ----------- --------------------------
+ * June 06, 2014 1122        S. Gurung     Initial creation
+ * 
+ * @author sgurung
+ * @version 1.0
+ */
+
+public class EditKsPlotAttributesDialog extends Dialog {
+
+    private String dlgTitle = "Edit Ks Plot Colors";
+
+    private static EditKsPlotAttributesDialog INSTANCE = null;
+
+    private Shell shell;
+
+    private RGB[] rgbs;
+
+    private ColorButtonSelector cms0 = null;
+
+    private ColorButtonSelector cms1 = null;
+
+    private ColorButtonSelector cms2 = null;
+
+    private ColorButtonSelector cms3 = null;
+
+    private ColorButtonSelector cms4 = null;
+
+    private ColorButtonSelector cms5 = null;
+
+    private ColorButtonSelector cms6 = null;
+
+    private ColorButtonSelector cms7 = null;
+
+    private ColorButtonSelector cms8 = null;
+
+    private Combo textSizeCombo = null;
+
+    private Combo textFontCombo = null;
+
+    private ColorButtonSelector textColorCms = null;
+
+    private Combo pointStyleCombo = null;
+
+    private Combo pointSizeCombo = null;
+
+    private KsPlotCapability ksCap = null;
+
+    private final String[] textSizeOptions = { "10", "12", "14", "16", "18",
+            "20", "22", "24", "32" };
+
+    private final String[] textFontOptions = { "Courier", "Helvetica", "Times" };
+
+    private final String[] pointSizeOptions = { "0.5", "0.75", "1.0", "1.25",
+            "1.5", "1.75", "2.0", "2.25", "2.5", "2.75", "3.0" };
+
+    private final String[] pointStyleOptions = { "POINT", "CROSS", "X", "STAR",
+            "CIRCLE", "DISC", "DASH", "BOX", "SQUARE" };
+
+    public EditKsPlotAttributesDialog(Shell parentShell, String dialogTitle,
+            KsPlotCapability ksCap) {
+        super(parentShell);
+        this.dlgTitle = dialogTitle;
+
+        shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE);
+        shell.setText(dialogTitle);
+        shell.setSize(600, 800); // pack later
+
+        this.ksCap = ksCap;
+        rgbs = ksCap.getPlotColors();
+    }
+
+    public void initWidgets() {
+
+        textSizeCombo.setItems(textSizeOptions);
+
+        for (int i = 0; i < textSizeOptions.length; i++) {
+            String sz = ksCap.getTextSize();
+            if (textSizeOptions[i] == sz) {
+                textSizeCombo.select(i);
+            }
+        }
+
+        textFontCombo.setItems(textFontOptions);
+        for (int i = 0; i < textFontOptions.length; i++) {
+            String fnt = ksCap.getTextFont();
+            if (textFontOptions[i] == fnt) {
+                textFontCombo.select(i);
+            }
+        }
+
+        pointSizeCombo.setItems(pointSizeOptions);
+
+        for (int i = 0; i < pointSizeOptions.length; i++) {
+            String sz = ksCap.getPointSize();
+            if (pointSizeOptions[i] == sz) {
+                pointSizeCombo.select(i);
+            }
+        }
+
+        pointStyleCombo.setItems(pointStyleOptions);
+
+        for (int i = 0; i < pointStyleOptions.length; i++) {
+            String ps = ksCap.getPointStyle();
+            if (pointStyleOptions[i] == ps) {
+                pointStyleCombo.select(i);
+            }
+        }
+    }
+
+    /**
+     * Creates the dialog if the dialog does not exist and returns the instance.
+     * If the dialog exists, return the instance.
+     * 
+     * @param parShell
+     * @return
+     */
+    public static EditKsPlotAttributesDialog getInstance(Shell parShell,
+            String dialogTitle, KsPlotCapability ksCap) {
+
+        if (INSTANCE == null) {
+            INSTANCE = new EditKsPlotAttributesDialog(parShell, dialogTitle,
+                    ksCap);
+        }
+        return INSTANCE;
+
+    }
+
+    public Composite createDialog(Composite composite) {
+        Composite top = composite;
+
+        // Create the main layout for the shell.
+        GridLayout mainLayout = new GridLayout(1, true);
+        mainLayout.marginHeight = 1;
+        mainLayout.marginWidth = 1;
+        top.setLayout(mainLayout);
+
+        // Initialize all of the controls, and layouts
+
+        // Ks plot colors
+        Group colorsGroup = new Group(top, SWT.SHADOW_NONE);
+        colorsGroup.setText("Station Count Colors");
+        GridData gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        colorsGroup.setLayoutData(gd);
+
+        createColorsControls(colorsGroup);
+
+        // Text options
+        Group textPointOptionsGroup = new Group(top, SWT.SHADOW_NONE);
+        textPointOptionsGroup.setText("Text Options");
+        gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        textPointOptionsGroup.setLayoutData(gd);
+
+        createTextPointAttrControls(textPointOptionsGroup);
+
+        initWidgets();
+
+        createCloseButton();
+
+        return top;
+    }
+
+    public void createColorsControls(final Group colorsGroup) {
+
+        colorsGroup.setLayout(new GridLayout(4, true));
+
+        int numStations = RTKpUtil.getGeoMagStationCodes(GeoMagStationType.KP)
+                .size();
+
+        Label color8_lbl = new Label(colorsGroup, SWT.NONE);
+        color8_lbl.setText("StationCount=" + numStations + ":");
+
+        cms8 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms8.setColorValue((RGB) rgbs[8]);
+        cms8.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[8] = cms8.getColorValue();
+            }
+        });
+
+        Label color1_lbl = new Label(colorsGroup, SWT.NONE);
+        color1_lbl.setText("StationCount=" + (numStations - 1) + ":");
+
+        cms1 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms1.setColorValue((RGB) rgbs[1]);
+        cms1.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[1] = cms1.getColorValue();
+            }
+        });
+
+        Label color2_lbl = new Label(colorsGroup, SWT.NONE);
+        color2_lbl.setText("StationCount=" + (numStations - 2) + ":");
+
+        cms2 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms2.setColorValue((RGB) rgbs[2]);
+        cms2.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[2] = cms2.getColorValue();
+            }
+        });
+
+        Label color3_lbl = new Label(colorsGroup, SWT.NONE);
+        color3_lbl.setText("StationCount=" + (numStations - 3) + ":");
+
+        cms3 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms3.setColorValue((RGB) rgbs[3]);
+        cms3.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[3] = cms3.getColorValue();
+            }
+        });
+
+        Label color4_lbl = new Label(colorsGroup, SWT.NONE);
+        color4_lbl.setText("StationCount=" + (numStations - 4) + ":");
+
+        cms4 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms4.setColorValue((RGB) rgbs[4]);
+        cms4.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[4] = cms4.getColorValue();
+            }
+        });
+
+        Label color5_lbl = new Label(colorsGroup, SWT.NONE);
+        color5_lbl.setText("StationCount=" + (numStations - 5) + ":");
+
+        cms5 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms5.setColorValue((RGB) rgbs[5]);
+        cms5.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[5] = cms5.getColorValue();
+            }
+        });
+
+        Label color6_lbl = new Label(colorsGroup, SWT.NONE);
+        color6_lbl.setText("StationCount=" + (numStations - 6) + ":");
+
+        cms6 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms6.setColorValue((RGB) rgbs[6]);
+        cms6.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[6] = cms6.getColorValue();
+            }
+        });
+
+        Label color7_lbl = new Label(colorsGroup, SWT.NONE);
+        String color7_lbl_str = (numStations - 7) + "";
+        if ((numStations - 7) > 1) {
+            for (int i = numStations - 7; i > 0; i--) {
+                color7_lbl_str += ", " + i;
+            }
+        }
+        color7_lbl.setText("StationCount=" + color7_lbl_str + ":");
+
+        cms7 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms7.setColorValue((RGB) rgbs[7]);
+        cms7.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[7] = cms7.getColorValue();
+            }
+        });
+
+        Label color0_lbl = new Label(colorsGroup, SWT.NONE);
+        color0_lbl.setText("StationCount=0:");
+
+        cms0 = new ColorButtonSelector(colorsGroup, 85, 25);
+        cms0.setColorValue((RGB) rgbs[0]);
+        cms0.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                rgbs[0] = cms0.getColorValue();
+            }
+        });
+
+    }
+
+    /*
+     * Create text attributes -- size, font and style
+     */
+    private void createTextPointAttrControls(Group txtPtGroup) {
+
+        txtPtGroup.setLayout(new GridLayout(4, true));
+
+        GridLayout gl = new GridLayout(4, false);
+        gl.marginTop = 0;
+        gl.marginBottom = 3;
+        gl.marginRight = 0;
+        txtPtGroup.setLayout(gl);
+        txtPtGroup.setText("Text and Point Options");
+
+        // Text size attribute
+        new Label(txtPtGroup, SWT.NONE).setText("Text Size: ");
+        textSizeCombo = new Combo(txtPtGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        textSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setTextSize(textSizeCombo.getText());
+            }
+        });
+
+        // Point size attribute
+        new Label(txtPtGroup, SWT.NONE).setText("              Point Size: ");
+        pointSizeCombo = new Combo(txtPtGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setPointSize(pointSizeCombo.getText());
+            }
+        });
+
+        // Text font attribute
+        new Label(txtPtGroup, SWT.NONE).setText("Text Font: ");
+        textFontCombo = new Combo(txtPtGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+        textFontCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setTextFont(textFontCombo.getText());
+            }
+        });
+
+        // Point size attribute
+        new Label(txtPtGroup, SWT.NONE).setText("              Point Style: ");
+        pointStyleCombo = new Combo(txtPtGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointStyleCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setPointStyle(pointStyleCombo.getText());
+            }
+        });
+
+        // Text color
+        Label color_lbl = new Label(txtPtGroup, SWT.NONE);
+        color_lbl.setText("Text Color:");
+
+        textColorCms = new ColorButtonSelector(txtPtGroup, 85, 25);
+        textColorCms.setColorValue(ksCap.getTextColor());
+        textColorCms.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                ksCap.setTextColor(textColorCms.getColorValue());
+            }
+        });
+
+    }
+
+    /*
+     * Create point attributes -- style and size
+     */
+    private void createPointAttrControls(Group pointGroup) {
+
+        pointGroup.setLayout(new GridLayout(2, true));
+
+        GridLayout gl = new GridLayout(2, false);
+        gl.marginTop = 0;
+        gl.marginBottom = 3;
+        gl.marginRight = 0;
+        pointGroup.setLayout(gl);
+        pointGroup.setText("Point");
+
+        // Point size attribute
+        new Label(pointGroup, SWT.NONE).setText("Style: ");
+        pointStyleCombo = new Combo(pointGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointStyleCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setPointStyle(pointStyleCombo.getText());
+            }
+        });
+
+        // Point size attribute
+        new Label(pointGroup, SWT.NONE).setText("Size: ");
+        pointSizeCombo = new Combo(pointGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+        pointSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                ksCap.setPointSize(pointSizeCombo.getText());
+            }
+        });
+    }
+
+    private void createCloseButton() {
+        Composite centeredComp = new Composite(shell, SWT.NONE);
+        GridLayout gl = new GridLayout(2, true);
+        centeredComp.setLayout(gl);
+        GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
+        gd.horizontalAlignment = SWT.CENTER;
+        centeredComp.setLayoutData(gd);
+
+        Button ok_btn = new Button(centeredComp, SWT.NONE);
+        ok_btn.setText("   OK    ");
+        ok_btn.setLayoutData(gd);
+        ok_btn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+
+        Button closeBtn = new Button(centeredComp, SWT.NONE);
+        closeBtn.setText("   Close   ");
+        closeBtn.setLayoutData(gd);
+        closeBtn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+    }
+
+    public KsPlotCapability open() {
+        Shell parent = getParent();
+        Display display = parent.getDisplay();
+
+        if (shell == null || shell.isDisposed()) {
+            shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE);
+            shell.setText(dlgTitle);
+            shell.setSize(600, 800);
+        }
+
+        createDialog(shell);
+
+        shell.pack();
+        shell.open();
+
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch()) {
+                display.sleep();
+            }
+        }
+
+        ksCap.setPlotColors(rgbs);
+
+        return ksCap;
+    }
+
+}
diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditMagActivityAttributesDialog.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditMagActivityAttributesDialog.java
new file mode 100644
index 0000000000..5500cf26a9
--- /dev/null
+++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditMagActivityAttributesDialog.java
@@ -0,0 +1,504 @@
+/**
+ * This code has unlimited rights, and is provided "as is" by the National Centers 
+ * for Environmental Prediction, without warranty of any kind, either expressed or implied, 
+ * including but not limited to the implied warranties of merchantability and/or fitness 
+ * for a particular purpose.
+ * 
+ * This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
+ * 
+ **/
+package gov.noaa.nws.ncep.viz.rtkp.controls;
+
+import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerTextSize;
+import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector;
+import gov.noaa.nws.ncep.viz.rtkp.MagActivityCapability;
+
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+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.FormLayout;
+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.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Slider;
+
+/**
+ * Provides an interface to modify the Mag activity map related capability
+ * (k-indices circle colors, marker color, marker size, text size etc.)
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * Date           Ticket#     Engineer    Description
+ * ------------   ----------  ----------- --------------------------
+ * June 2, 2014   1122        S. Gurung     Initial creation
+ * 
+ * @author sgurung
+ * @version 1.0
+ */
+
+public class EditMagActivityAttributesDialog extends Dialog {
+
+    private String dlgTitle = "Edit Mag Activity Attributes";
+
+    private static EditMagActivityAttributesDialog INSTANCE = null;
+
+    private Shell shell;
+
+    private RGB[] kIndicesColors;
+
+    private ColorButtonSelector cms0 = null;
+
+    private ColorButtonSelector cms1 = null;
+
+    private ColorButtonSelector cms2 = null;
+
+    private ColorButtonSelector cms3 = null;
+
+    private ColorButtonSelector cms4 = null;
+
+    private ColorButtonSelector cms5 = null;
+
+    private ColorButtonSelector cms6 = null;
+
+    private ColorButtonSelector cms7 = null;
+
+    private RGB nonNetwrkStnColor = null;
+
+    private ColorButtonSelector nnStnCms = null;
+
+    private ColorButtonSelector[] kTextColorsCms = new ColorButtonSelector[8];
+
+    private RGB[] kIndicesTextColors;
+
+    private Float markerSize = null;
+
+    private MarkerTextSize markerTextSize = null;
+
+    public EditMagActivityAttributesDialog(Shell parentShell,
+            String dialogTitle, RGB[] colors, RGB[] kIndicesTextColors,
+            RGB nonNetwrkStnColor, Float markerSize,
+            MarkerTextSize markerTextSize) {
+        super(parentShell);
+        this.dlgTitle = dialogTitle;
+
+        shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE);
+        shell.setText(dialogTitle);
+        shell.setSize(300, 500); // pack later
+
+        this.kIndicesColors = colors;
+        this.kIndicesTextColors = kIndicesTextColors;
+        this.nonNetwrkStnColor = nonNetwrkStnColor;
+        this.markerSize = markerSize;
+        this.markerTextSize = markerTextSize;
+    }
+
+    /**
+     * Creates the dialog if the dialog does not exist and returns the instance.
+     * If the dialog exists, return the instance.
+     * 
+     * @param parShell
+     * @return
+     */
+    public static EditMagActivityAttributesDialog getInstance(Shell parShell,
+            String dialogTitle, RGB[] colors, RGB[] kIndicesTextColors,
+            RGB nonNetwrkStnColor, Float markerSize,
+            MarkerTextSize markerTextSize) {
+
+        if (INSTANCE == null) {
+            INSTANCE = new EditMagActivityAttributesDialog(parShell,
+                    dialogTitle, colors, kIndicesTextColors, nonNetwrkStnColor,
+                    markerSize, markerTextSize);
+        }
+        return INSTANCE;
+
+    }
+
+    public Composite createDialog(Composite composite) {
+        Composite top = composite;
+
+        // Create the main layout for the shell.
+        GridLayout mainLayout = new GridLayout(1, true);
+        mainLayout.marginHeight = 1;
+        mainLayout.marginWidth = 1;
+        top.setLayout(mainLayout);
+
+        // Initialize all of the controls, and layouts
+        initializeComponents(top);
+        createCloseButton();
+
+        return top;
+    }
+
+    public void initializeComponents(final Composite composite) {
+
+        Composite top_form = composite;
+
+        composite.setLayout(new GridLayout(1, true));
+        GridData gd = new GridData();
+
+        // K-indices colors
+
+        Group kiColors = new Group(top_form, SWT.SHADOW_NONE);
+        kiColors.setText("K-indices Colors");
+        gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        kiColors.setLayoutData(gd);
+        kiColors.setLayout(new FormLayout());
+
+        createkIndicesColorsControls(kiColors);
+
+        // K-indices text colors
+
+        Group kiTextColors = new Group(top_form, SWT.SHADOW_NONE);
+        kiTextColors.setText("K-indices Text Colors");
+        gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        kiTextColors.setLayoutData(gd);
+        kiTextColors.setLayout(new FormLayout());
+
+        createkIndicesTextColorsControls(kiTextColors);
+
+        // Marker attributes
+
+        Group markerGroup = new Group(composite, SWT.SHADOW_NONE);
+        markerGroup.setText("Marker");
+
+        gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.grabExcessVerticalSpace = true;
+        gd.horizontalAlignment = SWT.FILL;
+        markerGroup.setLayoutData(gd);
+        markerGroup.setLayout(new FormLayout());
+
+        createMarkerControls(markerGroup);
+
+    }
+
+    public void createkIndicesColorsControls(Group kiGroup) {
+        kiGroup.setLayout(new GridLayout(4, true));
+
+        Label color0_lbl = new Label(kiGroup, SWT.NONE);
+        color0_lbl.setText("Quiet:");
+
+        cms0 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms0.setColorValue((RGB) kIndicesColors[0]);
+        cms0.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[0] = cms0.getColorValue();
+            }
+        });
+
+        Label color1_lbl = new Label(kiGroup, SWT.NONE);
+        color1_lbl.setText("Unsettled:");
+
+        cms1 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms1.setColorValue((RGB) kIndicesColors[1]);
+        cms1.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[1] = cms1.getColorValue();
+            }
+        });
+
+        Label color2_lbl = new Label(kiGroup, SWT.NONE);
+        color2_lbl.setText("Active:");
+
+        cms2 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms2.setColorValue((RGB) kIndicesColors[2]);
+        cms2.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[2] = cms2.getColorValue();
+            }
+        });
+
+        Label color3_lbl = new Label(kiGroup, SWT.NONE);
+        color3_lbl.setText("Minorstorm:");
+
+        cms3 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms3.setColorValue((RGB) kIndicesColors[3]);
+        cms3.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[3] = cms3.getColorValue();
+            }
+        });
+
+        Label color4_lbl = new Label(kiGroup, SWT.NONE);
+        color4_lbl.setText("Moderatestorm:");
+
+        cms4 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms4.setColorValue((RGB) kIndicesColors[4]);
+        cms4.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[4] = cms4.getColorValue();
+            }
+        });
+
+        Label color5_lbl = new Label(kiGroup, SWT.NONE);
+        color5_lbl.setText("Strongstorm:");
+
+        cms5 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms5.setColorValue((RGB) kIndicesColors[5]);
+        cms5.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[5] = cms5.getColorValue();
+            }
+        });
+
+        Label color6_lbl = new Label(kiGroup, SWT.NONE);
+        color6_lbl.setText("Severestorm:");
+
+        cms6 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms6.setColorValue((RGB) kIndicesColors[6]);
+        cms6.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[6] = cms6.getColorValue();
+            }
+        });
+
+        Label color7_lbl = new Label(kiGroup, SWT.NONE);
+        color7_lbl.setText("Extremestorm:");
+
+        cms7 = new ColorButtonSelector(kiGroup, 85, 25);
+        cms7.setColorValue((RGB) kIndicesColors[7]);
+        cms7.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesColors[7] = cms7.getColorValue();
+            }
+        });
+
+    }
+
+    public void createkIndicesTextColorsControls(Group kiTextGroup) {
+        kiTextGroup.setLayout(new GridLayout(4, true));
+
+        Label color0_lbl = new Label(kiTextGroup, SWT.NONE);
+        color0_lbl.setText("Quiet:");
+
+        kTextColorsCms[0] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[0].setColorValue((RGB) kIndicesTextColors[0]);
+        kTextColorsCms[0].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[0] = kTextColorsCms[0].getColorValue();
+                kIndicesTextColors[1] = kTextColorsCms[0].getColorValue();
+                kIndicesTextColors[2] = kTextColorsCms[0].getColorValue();
+            }
+        });
+
+        Label color1_lbl = new Label(kiTextGroup, SWT.NONE);
+        color1_lbl.setText("Unsettled:");
+
+        kTextColorsCms[1] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[1].setColorValue((RGB) kIndicesTextColors[3]);
+        kTextColorsCms[1].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[3] = kTextColorsCms[1].getColorValue();
+            }
+        });
+
+        Label color2_lbl = new Label(kiTextGroup, SWT.NONE);
+        color2_lbl.setText("Active:");
+
+        kTextColorsCms[2] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[2].setColorValue((RGB) kIndicesTextColors[4]);
+        kTextColorsCms[2].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[4] = kTextColorsCms[2].getColorValue();
+            }
+        });
+
+        Label color3_lbl = new Label(kiTextGroup, SWT.NONE);
+        color3_lbl.setText("Minorstorm:");
+
+        kTextColorsCms[3] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[3].setColorValue((RGB) kIndicesTextColors[5]);
+        kTextColorsCms[3].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[5] = kTextColorsCms[3].getColorValue();
+            }
+        });
+
+        Label color4_lbl = new Label(kiTextGroup, SWT.NONE);
+        color4_lbl.setText("Moderatestorm:");
+
+        kTextColorsCms[4] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[4].setColorValue((RGB) kIndicesTextColors[6]);
+        kTextColorsCms[4].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[6] = kTextColorsCms[4].getColorValue();
+            }
+        });
+
+        Label color5_lbl = new Label(kiTextGroup, SWT.NONE);
+        color5_lbl.setText("Strongstorm:");
+
+        kTextColorsCms[5] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[5].setColorValue((RGB) kIndicesTextColors[7]);
+        kTextColorsCms[5].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[7] = kTextColorsCms[5].getColorValue();
+            }
+        });
+
+        Label color6_lbl = new Label(kiTextGroup, SWT.NONE);
+        color6_lbl.setText("Severestorm:");
+
+        kTextColorsCms[6] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[6].setColorValue((RGB) kIndicesTextColors[8]);
+        kTextColorsCms[6].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[8] = kTextColorsCms[6].getColorValue();
+            }
+        });
+
+        Label color7_lbl = new Label(kiTextGroup, SWT.NONE);
+        color7_lbl.setText("Extremestorm:");
+
+        kTextColorsCms[7] = new ColorButtonSelector(kiTextGroup, 85, 25);
+        kTextColorsCms[7].setColorValue((RGB) kIndicesTextColors[9]);
+        kTextColorsCms[7].addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                kIndicesTextColors[9] = kTextColorsCms[7].getColorValue();
+            }
+        });
+
+    }
+
+    public void createMarkerControls(Group markerGroup) {
+        markerGroup.setLayout(new GridLayout(2, true));
+
+        // Marker Size
+
+        Label markerSize_lbl = new Label(markerGroup, SWT.NONE);
+        markerSize_lbl.setText("Marker Size:");
+
+        Group markerSizeGroup = new Group(markerGroup, SWT.SHADOW_NONE);
+        markerSizeGroup.setLayout(new GridLayout(1, true));
+
+        final Label selectMarkerSizeSliderText = new Label(markerSizeGroup,
+                SWT.NONE);
+        GridData gridData1 = new GridData();
+        gridData1.horizontalIndent = 50;
+        gridData1.verticalIndent = 0;
+        selectMarkerSizeSliderText.setLayoutData(gridData1);
+        final Slider selectMarkerSizeSlider = new Slider(markerSizeGroup,
+                SWT.HORIZONTAL);
+        selectMarkerSizeSlider.setMinimum(5);
+        selectMarkerSizeSlider.setMaximum(31);
+        selectMarkerSizeSlider.setIncrement(1);
+        selectMarkerSizeSlider.setThumb(1);
+        selectMarkerSizeSlider.setSelection(10);
+        float mSize = markerSize;
+        selectMarkerSizeSlider.setSelection((int) (mSize * 10f + 0.5));
+        selectMarkerSizeSlider.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                markerSize = (Float) ((float) selectMarkerSizeSlider
+                        .getSelection() / 10);
+                selectMarkerSizeSliderText.setText(markerSize.toString());
+                selectMarkerSizeSliderText.redraw();
+                selectMarkerSizeSliderText.update();
+            }
+        });
+        selectMarkerSizeSliderText.setText(markerSize.toString());
+
+        // Marker Text Size
+
+        Label markerTextSize_lbl = new Label(markerGroup, SWT.NONE);
+        markerTextSize_lbl.setText("MarkerText Size:");
+
+        final Combo selectMarkerTextSizeCombo = new Combo(markerGroup,
+                SWT.DROP_DOWN | SWT.READ_ONLY);
+        for (MarkerTextSize mts : MarkerTextSize.values()) {
+            selectMarkerTextSizeCombo.add(mts.getDisplayName());
+        }
+        String markerTextSizeMenuEntry = markerTextSize.getDisplayName();
+        selectMarkerTextSizeCombo.setText(markerTextSizeMenuEntry);
+        selectMarkerTextSizeCombo.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                markerTextSize = MarkerTextSize.values()[selectMarkerTextSizeCombo
+                        .getSelectionIndex()];
+            }
+        });
+
+        Label nonNetwrkStnMkr_lbl = new Label(markerGroup, SWT.NONE);
+        nonNetwrkStnMkr_lbl.setText("Non-network Station Marker Color:");
+
+        nnStnCms = new ColorButtonSelector(markerGroup, 85, 25);
+        nnStnCms.setColorValue((RGB) nonNetwrkStnColor);
+        nnStnCms.addListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                nonNetwrkStnColor = nnStnCms.getColorValue();
+            }
+        });
+
+    }
+
+    private void createCloseButton() {
+        Composite centeredComp = new Composite(shell, SWT.NONE);
+        GridLayout gl = new GridLayout(2, true);
+        centeredComp.setLayout(gl);
+        GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
+        gd.horizontalAlignment = SWT.CENTER;
+        centeredComp.setLayoutData(gd);
+
+        Button ok_btn = new Button(centeredComp, SWT.NONE);
+        ok_btn.setText("   OK    ");
+        ok_btn.setLayoutData(gd);
+        ok_btn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+
+        Button closeBtn = new Button(centeredComp, SWT.NONE);
+        closeBtn.setText("   Close   ");
+        closeBtn.setLayoutData(gd);
+        closeBtn.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent event) {
+                shell.dispose();
+            }
+        });
+
+    }
+
+    public MagActivityCapability open() {
+        Shell parent = getParent();
+        Display display = parent.getDisplay();
+
+        if (shell == null || shell.isDisposed()) {
+            shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE);
+            shell.setText(dlgTitle);
+            shell.setSize(300, 500);
+        }
+
+        createDialog(shell);
+
+        shell.pack();
+        shell.open();
+
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch()) {
+                display.sleep();
+            }
+        }
+
+        MagActivityCapability mac = new MagActivityCapability(kIndicesColors,
+                kIndicesTextColors, nonNetwrkStnColor, markerSize,
+                markerTextSize);
+
+        return mac;
+    }
+
+}
diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditNetworkDialog.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditNetworkDialog.java
new file mode 100644
index 0000000000..480847dda1
--- /dev/null
+++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/EditNetworkDialog.java
@@ -0,0 +1,398 @@
+/**
+ * This code has unlimited rights, and is provided "as is" by the National Centers 
+ * for Environmental Prediction, without warranty of any kind, either expressed or implied, 
+ * including but not limited to the implied warranties of merchantability and/or fitness 
+ * for a particular purpose.
+ * 
+ * This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
+ * 
+ **/
+package gov.noaa.nws.ncep.viz.rtkp.controls;
+
+import gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpDataBlockWindow;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil.GeoMagStationType;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+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.exception.VizException;
+import com.raytheon.viz.ui.dialogs.CaveJFACEDialog;
+
+/**
+ * A dialog to Retrieve PGEN activities from EDEX.
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * Date       	 Ticket#		Engineer	Description
+ * ------------	 ----------	-----------	-----------------------------------
+ * April 4, 2014 1122		sgurung  	Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class EditNetworkDialog extends CaveJFACEDialog { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(EditNetworkDialog.class); + + private String title = null; + + private Shell shell; + + private Button saveBtn = null; + + private Button cancelBtn = null; + + private Button begCurSynPeriodBtn; + + private Button begPrevSynPeriodBtn; + + private Button prevSynPeriodOnlyBtn; + + private List kpStations = null; + + private HashMap> curKpStationsStates = null; + + private GeoMagRTKpDataBlockWindow dbWindow = null; + + private int kpState = 0; + + private static final int SAVE_ID = IDialogConstants.CLIENT_ID + 7687; + + private static final String SAVE_LABEL = "Save"; + + private static final int CANCEL_ID = IDialogConstants.CLIENT_ID + 7688; + + private static final String CANCEL_LABEL = "Exit"; + + /** Table control. */ + private Table table; + + /* + * Constructor + */ + public EditNetworkDialog(Shell parShell, String btnName, + GeoMagRTKpDataBlockWindow dbWindow) throws VizException { + + super(parShell); + + setTitle(btnName); + + this.kpStations = RTKpUtil.getGeoMagStationCodes(GeoMagStationType.KP); + this.curKpStationsStates = RTKpUtil.getStationsStatesMap( + GeoMagStationType.KP, 0); + this.dbWindow = dbWindow; + + } + + /* + * Set up the file mode. + */ + private void setTitle(String btnName) { + title = "Edit Network"; + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets + * .Shell) + */ + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + this.setShellStyle(SWT.RESIZE | SWT.PRIMARY_MODAL); + + this.shell = shell; + if (title != null) { + shell.setText(title); + } + } + + /** + * (non-Javadoc) Create all of the widgets on the Dialog + * + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + @Override + public Control createDialogArea(Composite parent) { + + Composite dlgAreaForm = (Composite) super.createDialogArea(parent); + + // Create the main layout for the dialog. + GridLayout mainLayout = new GridLayout(2, false); + mainLayout.marginHeight = 3; + mainLayout.marginWidth = 3; + dlgAreaForm.setLayout(mainLayout); + + Group stnsGroup = new Group(dlgAreaForm, SWT.NONE); + stnsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + stnsGroup.setText(" Select Stations to use for Kp Est "); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + gd.verticalAlignment = SWT.FILL; + stnsGroup.setLayoutData(gd); + stnsGroup.setLayout(new GridLayout(1, true)); + + /* + * stations + */ + table = new Table(stnsGroup, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI + | SWT.CHECK | SWT.FULL_SELECTION); + table.setHeaderVisible(false); + table.setLinesVisible(false); + + int kpStationsSize = (kpStations != null) ? kpStations.size() : 0; + for (int i = 0; i < kpStationsSize; i++) { + String stnCode = kpStations.get(i); + + TableItem item = new TableItem(table, SWT.NONE); + item.setText(stnCode); + // item.setData(stnCode); + + if (curKpStationsStates.containsKey(stnCode)) { + Map stnMap = curKpStationsStates.get(stnCode); + item.setChecked((Integer) stnMap.get("kp_active") == 1 ? true + : false); + } else { + item.setChecked(false); + } + + } + + /** + * Draw settings buttons + */ + Group applySettingsButtonGroup = new Group(dlgAreaForm, SWT.NONE); + applySettingsButtonGroup.setText("Apply these settings"); + gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + gd.verticalAlignment = SWT.FILL; + applySettingsButtonGroup.setLayoutData(gd); + applySettingsButtonGroup.setLayout(new GridLayout(1, false)); + + begCurSynPeriodBtn = new Button(applySettingsButtonGroup, SWT.RADIO); + begCurSynPeriodBtn + .setText("beginning with the current synoptic period"); + begCurSynPeriodBtn.setSelection(true); + + begPrevSynPeriodBtn = new Button(applySettingsButtonGroup, SWT.RADIO); + begPrevSynPeriodBtn + .setText("beginning with the previous synoptic period"); + + prevSynPeriodOnlyBtn = new Button(applySettingsButtonGroup, SWT.RADIO); + prevSynPeriodOnlyBtn.setText("for the previous synoptic period only"); + + begCurSynPeriodBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (begCurSynPeriodBtn.getSelection()) { + kpState = 0; + } + } + }); + + begPrevSynPeriodBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (begPrevSynPeriodBtn.getSelection()) { + kpState = 1; + } + } + }); + + prevSynPeriodOnlyBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (prevSynPeriodOnlyBtn.getSelection()) { + kpState = 2; + } + } + }); + + return dlgAreaForm; + } + + /** + * Create Replace/Append/Cancel button for "Open" a product file or + * Save/Cancel button for "Save" a product file. + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + + saveBtn = createButton(parent, SAVE_ID, SAVE_LABEL, true); + cancelBtn = createButton(parent, CANCEL_ID, CANCEL_LABEL, true); + + saveBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + + MessageDialog confirmDlg = new MessageDialog(shell, "Confirm", + null, "Do you want to save the changes?", + MessageDialog.QUESTION, new String[] { "Yes", "No" }, 0); + confirmDlg.open(); + + if (confirmDlg.getReturnCode() == MessageDialog.CANCEL) { + return; + } + save(); + } + }); + + cancelBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + close(); + } + }); + + } + + public void save() { + + try { + + int save = 0; + HashMap> prevKpStationsStates = RTKpUtil + .getStationsStatesMap(GeoMagStationType.KP, 1); + + TableItem[] items = table.getItems(); + + if (items != null) { + for (int i = 0; i < items.length; i += 1) { + TableItem item = items[i]; + + String stnCode = item.getText(); + + if (curKpStationsStates.containsKey(stnCode)) { + Map stnMap = curKpStationsStates + .get(stnCode); + + if (stnMap != null) { + // Apply changes beginning with current synoptic + // period + boolean curStateActive = ((Integer) stnMap + .get("kp_active") == 1) ? true : false; + if (kpState != 2 + && curStateActive != item.getChecked()) { + stnMap.put("kp_active", (item.getChecked() ? 1 + : 0)); + boolean ret = RTKpUtil.changeStationState( + stnCode, 0); + if (!ret) { + MessageDialog confirmDlg = new MessageDialog( + shell, + "Error", + null, + "Encountered error in ChangeStationState...", + MessageDialog.ERROR, + new String[] { "OK" }, 0); + confirmDlg.open(); + } + } + } + } + + if (prevKpStationsStates.containsKey(stnCode)) { + Map stnMap = curKpStationsStates + .get(stnCode); + + if (stnMap != null) { + // Apply changes to previous synoptic period + boolean prevStateActive = ((Integer) stnMap + .get("kp_active") == 1) ? true : false; + if (kpState != 0) { + if (prevStateActive != item.getChecked()) { + + boolean ret = RTKpUtil.changeStationState( + stnCode, 1); + if (!ret) { + MessageDialog confirmDlg = new MessageDialog( + shell, + "Error", + null, + "Encountered error in ChangeStationState...", + MessageDialog.ERROR, + new String[] { "OK" }, 0); + confirmDlg.open(); + } + save = 2; + } + } + } + } + + } + if (kpState == 2) { + int maxDiff = 0; + for (int i = 0; i < items.length; i += 1) { + TableItem item = items[i]; + int butnVal = (item.getChecked() == true ? 1 : 0); + + String stnCode = item.getText(); + int curStnStateVal = 0; + + if (curKpStationsStates.containsKey(stnCode)) { + Map stnMap = curKpStationsStates + .get(stnCode); + curStnStateVal = (Integer) stnMap.get("kp_active"); + } + + int diff = Math.abs(curStnStateVal - butnVal); + + if (diff > maxDiff) + maxDiff = diff; + + } + if (save == 2 && maxDiff != 0) { + MessageDialog confirmDlg = new MessageDialog( + shell, + "Information", + null, + "Done. Reverting check boxes to show active stations for current synoptic period.", + MessageDialog.INFORMATION, + new String[] { "OK" }, 0); + confirmDlg.open(); + } + } + + } + + dbWindow.setDataBlockContent(); + dbWindow.displayDataBlock(); + + System.out.println("Done. "); + super.close(); + } catch (Exception e) { + statusHandler.handle(Priority.WARN, + "Encountered error in ChangeStationState.", e); + } + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagAnalysisPlotDlg.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagAnalysisPlotDlg.java new file mode 100644 index 0000000000..d7ba568a25 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagAnalysisPlotDlg.java @@ -0,0 +1,569 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.controls; + +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; +import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; +import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResourceData; +import gov.noaa.nws.ncep.viz.ui.display.NCPaneManager; + +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener; +import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener.DisplayChangeType; +import com.raytheon.uf.viz.core.datastructure.LoopProperties; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; +import com.raytheon.uf.viz.core.rsc.IInputHandler; +import com.raytheon.uf.viz.core.rsc.IInputHandler.InputPriority; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +import com.raytheon.viz.ui.editor.IMultiPaneEditor; +import com.raytheon.viz.ui.editor.ISelectedPanesChangedListener; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Display Magnetometer analysis plot (h, hqdc, d and dqdc) Dialog. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 05/14/2014              sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagAnalysisPlotDlg extends CaveSWTDialog implements + IMultiPaneEditor { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagAnalysisPlotDlg.class); + + private int height = 750; + + private int width = 850; + + private LoopProperties loopProps = new LoopProperties(); + + private NCPaneManager paneManager = null; + + private AbstractRBD rbdBndl = null; + + private String stationCode = null; + + private String sourceId = null; + + public NCPaneManager getPaneManager() { + return paneManager; + } + + public void setPaneManager(NCPaneManager paneManager) { + this.paneManager = paneManager; + } + + /** + * Constructor. + * + * @param parentShell + * The parent shell + * @param height + * The height of the dialog + * @param width + * The width of the dialog + * @param rbdBndl + * The resource bundle file to load + * @param stationCode + * The stationCode + * @param height + * The sourceId + */ + public GeoMagAnalysisPlotDlg(Shell parentShell, int height, int width, + AbstractRBD rbdBndl, String stationCode, String sourceId) { + super(parentShell); + setText("Magnetometer H & D Plot for " + stationCode); + this.height = height; + this.width = width; + this.rbdBndl = rbdBndl; + this.stationCode = stationCode; + this.sourceId = sourceId; + + paneManager = new NCPaneManager(rbdBndl.getPaneLayout(), + rbdBndl.getDisplayType()); + paneManager.setContextualMenusEnabled(false); + } + + @Override + protected Layout constructShellLayout() { + // Create the main layout for the shell. + GridLayout mainLayout = new GridLayout(1, true); + mainLayout.marginHeight = 1; + mainLayout.marginWidth = 1; + mainLayout.horizontalSpacing = 1; + mainLayout.verticalSpacing = 1; + return mainLayout; + } + + @Override + protected void initializeComponents(Shell shell) { + setReturnValue(false); + + // Initialize all of the controls and layout + initializeComponents(); + } + + /** + * Initialize the gui widgets + */ + private void initializeComponents() { + + Composite comp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, true); + comp.setLayout(gl); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, true); + gd.widthHint = width; + gd.heightHint = height; + comp.setLayoutData(gd); + + paneManager.initializeComponents(this, comp); + + AbstractRenderableDisplay[] bundleDisplays = rbdBndl.getDisplays(); + int numDisplays = bundleDisplays.length; + + for (int i = 0; i < numDisplays; ++i) { + addPane(bundleDisplays[i]); + ((INatlCntrsRenderableDisplay) bundleDisplays[i]) + .setPaneManager(getPaneManager()); + loadResourceBundleDefn(getDisplayPanes()[i], + (INatlCntrsRenderableDisplay) bundleDisplays[i], + (NCTimeMatcher) bundleDisplays[i].getDescriptor() + .getTimeMatcher()); + } + } + + public boolean loadResourceBundleDefn(IDisplayPane pane, + INatlCntrsRenderableDisplay rendDisplay, NCTimeMatcher timeMatcher) { + + if (timeMatcher == null) { + System.out.println("Error Loading Timeline???"); + return false; + } + + INatlCntrsDescriptor descr = (INatlCntrsDescriptor) rendDisplay + .getDescriptor(); + + ResourceList rscList = descr.getResourceList(); + + for (int r = 0; r < rscList.size(); r++) { + if (rscList.get(r).getResourceData() instanceof GeoMagResourceData) { + GeoMagResourceData rscData = (GeoMagResourceData) rscList + .get(r).getResourceData(); + // ResourceName rscName = rscData.getResourceName(); + alterResource(rscData, stationCode, "stationCode"); + alterResource(rscData, sourceId, "sourceId"); + } + } + + rbdBndl.getTimeMatcher().setLatestRefTime(); + rbdBndl.initTimeline(); + descr.setTimeMatcher(timeMatcher); + descr.setNumberOfFrames(timeMatcher.getNumFrames()); + DataTime[] dataTimes = timeMatcher.getFrameTimes().toArray( + new DataTime[0]); + + if (dataTimes == null || dataTimes.length == 0) { + // descr.setDataTimes( null ); + } else { + descr.setDataTimes(dataTimes); + + if (timeMatcher.isForecast()) { + descr.setFrame(0); + } else { + descr.setFrame(dataTimes.length - 1); + } + } + + descr.setSuspendZoom(true); + rscList.instantiateResources(descr, true); + + pane.setRenderableDisplay(rendDisplay); + pane.zoom(15, 0, 0); + pane.getTarget().setNeedsRefresh(true); + pane.refresh(); + + return true; + } + + private void alterResource(AbstractRequestableResourceData data, + String selectedString, String key) { + Map reqMap = data.getMetadataMap(); + RequestConstraint rc = reqMap.get(key); + if (rc != null) { + rc.setConstraintValue(selectedString); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#registerMouseHandler(com + * .raytheon.uf.viz.core.rsc.IInputHandler) + */ + @Override + public void registerMouseHandler(IInputHandler handler) { + paneManager.registerMouseHandler(handler); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#unregisterMouseHandler + * (com.raytheon.uf.viz.core.rsc.IInputHandler) + */ + @Override + public void unregisterMouseHandler(IInputHandler handler) { + paneManager.unregisterMouseHandler(handler); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer#getLoopProperties() + */ + @Override + public LoopProperties getLoopProperties() { + return loopProps; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#setLoopProperties(com. + * raytheon.uf.viz.core.datastructure.LoopProperties) + */ + @Override + public void setLoopProperties(LoopProperties loopProperties) { + loopProps = loopProperties; + } + + @Override + public IDisplayPane addPane(IRenderableDisplay renderableDisplay) { + return paneManager.addPane(renderableDisplay); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#translateClick(double, + * double) + */ + // @Override + public Coordinate translateClick2(double x, double y) { + IDisplayPane pane = getActiveDisplayPane(); + // Convert the screen coordinates to grid space + double[] world = pane.screenToGrid(x, y, 0); + IExtent extent = pane.getRenderableDisplay().getExtent(); + // Verify grid space is within the extent, otherwiser return null + if (world == null || extent.contains(world) == false) { + return null; + } + // use descriptor to convert pixel world to CRS world space + world = pane.getDescriptor().pixelToWorld(world); + // Check for null + if (world == null) { + return null; + } + return new Coordinate(world[0], world[1], world[2]); + } + + @Override + public Coordinate translateClick(double x, double y) { + return getPaneManager().translateClick(x, y); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#translateInverseClick( + * com.vividsolutions.jts.geom.Coordinate) + */ + @Override + public double[] translateInverseClick(Coordinate c) { + if (c == null) { + return null; + } + IDisplayPane pane = getActiveDisplayPane(); + double[] grid = pane.getDescriptor().worldToPixel( + new double[] { c.x, c.y, c.z }); + if (grid == null) { + return null; + } + return pane.gridToScreen(grid); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer#getDisplayPanes() + */ + @Override + public IDisplayPane[] getDisplayPanes() { + return paneManager.getDisplayPanes(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer#refresh() + */ + @Override + public void refresh() { + paneManager.refresh(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IDisplayPaneContainer#getActiveDisplayPane() + */ + @Override + public IDisplayPane getActiveDisplayPane() { + return paneManager.getActiveDisplayPane(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.editor.IMultiPaneEditor#getNumberofPanes() + */ + @Override + public int getNumberofPanes() { + return paneManager.getNumberofPanes(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#setSelectedPane(java.lang + * .String, com.raytheon.uf.viz.core.IDisplayPane) + */ + @Override + public void setSelectedPane(String action, IDisplayPane pane) { + paneManager.setSelectedPane(action, pane); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#getSelectedPane(java.lang + * .String) + */ + @Override + public IDisplayPane getSelectedPane(String action) { + return paneManager.getSelectedPane(action); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#getSelectedPanes(java.lang + * .String) + */ + @Override + public IDisplayPane[] getSelectedPanes(String action) { + return paneManager.getSelectedPanes(action); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#isSelectedPane(java.lang. + * String, com.raytheon.uf.viz.core.IDisplayPane) + */ + @Override + public boolean isSelectedPane(String action, IDisplayPane pane) { + return paneManager.isSelectedPane(action, pane); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#addSelectedPaneChangedListener + * (com.raytheon.viz.ui.editor.ISelectedPanesChangedListener) + */ + @Override + public void addSelectedPaneChangedListener( + ISelectedPanesChangedListener listener) { + paneManager.addSelectedPaneChangedListener(listener); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#removeSelectedPaneChangedListener + * (com.raytheon.viz.ui.editor.ISelectedPanesChangedListener) + */ + @Override + public void removeSelectedPaneChangedListener( + ISelectedPanesChangedListener listener) { + paneManager.removeSelectedPaneChangedListener(listener); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#removePane(com.raytheon.uf + * .viz.core.IDisplayPane) + */ + @Override + public void removePane(IDisplayPane pane) { + paneManager.removePane(pane); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#hidePane(com.raytheon.uf. + * viz.core.IDisplayPane) + */ + @Override + public void hidePane(IDisplayPane pane) { + paneManager.hidePane(pane); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.editor.IMultiPaneEditor#showPane(com.raytheon.uf. + * viz.core.IDisplayPane) + */ + @Override + public void showPane(IDisplayPane pane) { + paneManager.showPane(pane); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.editor.IMultiPaneEditor#displayedPaneCount() + */ + @Override + public int displayedPaneCount() { + return paneManager.displayedPaneCount(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.editor.IMultiPaneEditor#clear() + */ + @Override + public void clear() { + paneManager.clear(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer# + * addRenderableDisplayChangedListener + * (com.raytheon.uf.viz.core.IRenderableDisplayChangedListener) + */ + @Override + public void addRenderableDisplayChangedListener( + IRenderableDisplayChangedListener displayChangedListener) { + + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer# + * removeRenderableDisplayChangedListener + * (com.raytheon.uf.viz.core.IRenderableDisplayChangedListener) + */ + @Override + public void removeRenderableDisplayChangedListener( + IRenderableDisplayChangedListener displayChangedListener) { + + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IDisplayPaneContainer# + * notifyRenderableDisplayChangedListeners + * (com.raytheon.uf.viz.core.IDisplayPane, + * com.raytheon.uf.viz.core.drawables.IRenderableDisplay, + * com.raytheon.uf.viz + * .core.IRenderableDisplayChangedListener.DisplayChangeType) + */ + @Override + public void notifyRenderableDisplayChangedListeners(IDisplayPane pane, + IRenderableDisplay display, DisplayChangeType type) { + + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + @Override + public void registerMouseHandler(IInputHandler handler, + InputPriority priority) { + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagRTKpPlotDialog.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagRTKpPlotDialog.java new file mode 100644 index 0000000000..f579d5c609 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/controls/GeoMagRTKpPlotDialog.java @@ -0,0 +1,329 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.controls; + +import gov.noaa.nws.ncep.viz.localization.NcPathManager; +import gov.noaa.nws.ncep.viz.rtkp.GeoMagRTKpDescriptor; +import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagRTKpResourceData; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import java.io.File; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +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.DateTime; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +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.common.time.DataTime; +import com.raytheon.uf.viz.core.DescriptorMap; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.viz.ui.BundleLoader; +import com.raytheon.viz.ui.UiUtil; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Provides an interface to select RTKP Plot. + * + *
+ * SOFTWARE HISTORY
+ * Date           Ticket#     Engineer    Description
+ * ------------   ----------  ----------- --------------------------
+ * 04/06/2014     1122        S. Gurung   Initial creation
+ * 
+ * @author sgurung
+ * @version 1.0
+ */
+
+public class GeoMagRTKpPlotDialog extends CaveJFACEDialog {
+    private static final transient IUFStatusHandler statusHandler = UFStatus
+            .getHandler(GeoMagRTKpPlotDialog.class);
+
+    private static final int LOAD_NEW_ID = IDialogConstants.CLIENT_ID + 3841;
+
+    private Composite comp;
+
+    private Button durations[] = new Button[6];
+
+    private Button fixedButton, updatingButton;
+
+    private DateTime startDate;
+
+    private Combo startHour;
+
+    /**
+     * Constructor.
+     * 
+     * @param parent
+     */
+    public GeoMagRTKpPlotDialog(Shell parent) {
+        super(parent);
+    }
+
+    /**
+     * Sets the title for the dialog.
+     * 
+     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
+     *      .Shell)
+     */
+    @Override
+    protected void configureShell(Shell shell) {
+        super.configureShell(shell);
+        shell.setText("Kp Time Series Plot");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * com.raytheon.viz.ui.dialogs.CaveJFACEDialog#createDialogArea(org.eclipse
+     * .swt.widgets.Composite)
+     */
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        comp = (Composite) super.createDialogArea(parent);
+
+        // GridLayout layout = new GridLayout(1, false);
+        // comp.setLayout(layout);
+        GridLayout mainLayout = new GridLayout(1, true);
+        // mainLayout.marginHeight = 1;
+        // mainLayout.marginWidth = 1;
+        comp.setLayout(mainLayout);
+
+        // Label label0 = new Label(comp, SWT.NONE);
+        // label0.setText("Real-Time Ground-based Magnetometers");
+        // label0.getFont().getFontData()[0].setStyle(SWT.BOLD);
+        GridData data = new GridData(SWT.CENTER, SWT.CENTER, true, false);
+        // label0.setLayoutData(data);
+
+        Composite row2 = new Composite(comp, SWT.NONE);
+        RowLayout rowLayout2 = new RowLayout();
+        rowLayout2.center = true;
+        row2.setLayout(rowLayout2);
+
+        Label durationLabel = new Label(row2, SWT.NONE);
+        durationLabel.setText("Duration: ");
+
+        durations[0] = new Button(row2, SWT.RADIO);
+        durations[0].setText("3 hr");
+        durations[0].setData(new Integer(3));
+
+        durations[1] = new Button(row2, SWT.RADIO);
+        durations[1].setText("6 hr");
+        durations[1].setData(new Integer(6));
+
+        durations[2] = new Button(row2, SWT.RADIO);
+        durations[2].setText("12 hr");
+        durations[2].setData(new Integer(12));
+        durations[2].setSelection(true);
+
+        durations[3] = new Button(row2, SWT.RADIO);
+        durations[3].setText("24 hr");
+        durations[3].setData(new Integer(24));
+
+        durations[4] = new Button(row2, SWT.RADIO);
+        durations[4].setText("2 day");
+        durations[4].setData(new Integer(48));
+
+        durations[5] = new Button(row2, SWT.RADIO);
+        durations[5].setText("3 day");
+        durations[5].setData(new Integer(72));
+
+        Composite row3 = new Composite(comp, SWT.NONE);
+        RowLayout rowLayout3 = new RowLayout();
+        rowLayout3.center = true;
+        row3.setLayout(rowLayout3);
+
+        updatingButton = new Button(row3, SWT.RADIO);
+        updatingButton.setText("Updating Display");
+        updatingButton.setSelection(true);
+        updatingButton.addSelectionListener(new SelectionListener() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                startDate.setEnabled(false);
+                startHour.setEnabled(false);
+            }
+
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+            }
+        });
+
+        fixedButton = new Button(row3, SWT.RADIO);
+        fixedButton.setText("Fixed display beginning");
+        fixedButton.addSelectionListener(new SelectionListener() {
+
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                startDate.setEnabled(true);
+                startHour.setEnabled(true);
+            }
+
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+            }
+        });
+
+        startDate = new DateTime(row3, SWT.DATE | SWT.LONG | SWT.DROP_DOWN
+                | SWT.BORDER);
+        startDate.setEnabled(false);
+
+        Label hourLabel = new Label(row3, SWT.NONE);
+        hourLabel.setText("Hour");
+
+        startHour = new Combo(row3, SWT.NONE);
+        startHour.setItems(new String[] { "00", "03", "06", "09", "12", "15",
+                "18", "21" });
+        startHour.select(0);
+        startHour.setEnabled(false);
+
+        return comp;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+     */
+    @Override
+    protected void buttonPressed(int buttonId) {
+        if (buttonId == LOAD_NEW_ID) {
+            loadPlot();
+        } else
+            super.buttonPressed(buttonId);
+    }
+
+    private void loadPlot() {
+        File bundleFile = NcPathManager.getInstance().getStaticFile(
+                "ncep/Bundles/GeoMagRTKpMonitorPlots.xml");
+
+        DataTime startTime = null;
+        Map vars = new HashMap();
+        // vars.put("stationCode", "BOU");
+        int duration = getDuration();
+        boolean setDate = fixedButton.getSelection();
+        if (setDate) {
+            startTime = getStartTime();
+        }
+
+        Bundle b;
+        try {
+            b = Bundle.unmarshalBundle(bundleFile, vars);
+
+            IRenderableDisplay renderableDisplay = b.getDisplays()[0];
+            IDescriptor bundleDescriptor = renderableDisplay.getDescriptor();
+            if (bundleDescriptor instanceof GeoMagRTKpDescriptor) {
+                GeoMagRTKpDescriptor geo = (GeoMagRTKpDescriptor) bundleDescriptor;
+                for (ResourcePair pair : geo.getSerializableResources()) {
+                    if (pair.getResourceData() instanceof GeoMagRTKpResourceData) {
+                        GeoMagRTKpResourceData rscData = (GeoMagRTKpResourceData) pair
+                                .getResourceData();
+                        rscData.setPlotLengthInHours(duration);
+                        if (setDate) {
+                            rscData.setStartTime(startTime);
+                            rscData.setUpdating(false);
+                        }
+                    }
+                }
+            }
+            String bundleEditorId = DescriptorMap.getEditorId(bundleDescriptor
+                    .getClass().getName());
+
+            AbstractEditor editor = UiUtil.createOrOpenEditor(bundleEditorId,
+                    renderableDisplay);
+            BundleLoader.loadTo(editor, b);
+
+            // show the "Data Block" and "Recent Kp Estimates Block" view/window
+            RTKpUtil.showDataBlock(
+                    getDataBlockStartTime(getEndTime(startTime).getRefTime())
+                            .getRefTime(), getEndTime(startTime).getRefTime());
+
+        } catch (VizException e) {
+            statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
+        }
+    }
+
+    private DataTime getStartTime() {
+        Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+        time.set(Calendar.YEAR, startDate.getYear());
+        time.set(Calendar.MONTH, startDate.getMonth());
+        time.set(Calendar.DAY_OF_MONTH, startDate.getDay());
+        time.set(Calendar.HOUR_OF_DAY, Integer.parseInt(startHour.getText()));
+        time.set(Calendar.MINUTE, 0);
+        time.set(Calendar.SECOND, 0);
+        time.set(Calendar.MILLISECOND, 0);
+        return new DataTime(time);
+    }
+
+    private DataTime getDataBlockStartTime(Date endTime) {
+        Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+        time.setTime(endTime);
+        time.add(Calendar.MINUTE, -20);
+        return new DataTime(time);
+    }
+
+    public DataTime getEndTime(DataTime startTime) {
+        DataTime endTime = null;
+        if (startTime != null) {
+            long stime = startTime.getRefTime().getTime();
+            // add in milliseconds
+            stime += getDuration() * 60 * 60 * 1000;
+            endTime = new DataTime(new Date(stime));
+        } else {
+            endTime = new DataTime(new Date());
+        }
+        return endTime;
+    }
+
+    private int getDuration() {
+        int value = 0;
+        for (Button opt : durations) {
+            if (opt.getSelection()) {
+                value = (Integer) opt.getData();
+                break;
+            }
+        }
+        return value;
+    }
+
+    /**
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+     */
+    @Override
+    protected void createButtonsForButtonBar(Composite parent) {
+        createButton(parent, LOAD_NEW_ID, "Create Plot", true);
+        createButton(parent, IDialogConstants.CANCEL_ID, "Cancel", false);
+    }
+
+}
diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpDataBlockWindow.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpDataBlockWindow.java
new file mode 100644
index 0000000000..d60987a494
--- /dev/null
+++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpDataBlockWindow.java
@@ -0,0 +1,861 @@
+/**
+ * This code has unlimited rights, and is provided "as is" by the National Centers 
+ * for Environmental Prediction, without warranty of any kind, either expressed or implied, 
+ * including but not limited to the implied warranties of merchantability and/or fitness 
+ * for a particular purpose.
+ * 
+ * This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
+ * 
+ **/
+package gov.noaa.nws.ncep.viz.rtkp.palette;
+
+import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min;
+import gov.noaa.nws.ncep.viz.rtkp.controls.EditNetworkDialog;
+import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagWorldActivityResource;
+import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagWorldActivityTitleDateResource;
+import gov.noaa.nws.ncep.viz.rtkp.util.GeoMagTimeSeriesDataException;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil;
+import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil.GeoMagStationType;
+import gov.noaa.nws.ncep.viz.ui.display.NatlCntrsEditor;
+import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr;
+
+import java.awt.Color;
+import java.math.BigInteger;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+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.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+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.VizApp;
+import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
+import com.raytheon.uf.viz.core.drawables.ResourcePair;
+import com.raytheon.uf.viz.core.exception.VizException;
+import com.raytheon.viz.ui.UiUtil;
+
+/**
+ * 
+ * This java class performs the RTKp Data Block GUI construction.
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- -----------------------------------
+ * April 4, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpDataBlockWindow extends ViewPart implements + IGeoMagRTKpDataBlockListener, SelectionListener, DisposeListener, + IPartListener { + + private static IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagRTKpDataBlockWindow.class); + + private IWorkbenchPage page; + + private Shell shell; + + private boolean isState = false; + + private Group textGp; + + private Text text; + + private StringBuffer textStr = new StringBuffer(""); + + private Button editNwBtn; + + private Date startTime = null; + + private boolean isEditorVisible = true; + + private int btnGapX = 5; + + private int staBtnWidth = 150; + + private int btnHeight = 20; + + private int pushbtnHeight = 20; + + private int labelGap = 15; + + private boolean showKpOnly = true; + + private String kType = "K"; + + static final SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MMM-dd HH:mm:ss"); + + static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); + + private List kp_last10_text = new ArrayList(); + + private List kp_last10_values = new ArrayList(); + + private List kp_last10_color = new ArrayList(); + + private RGB[] kindicesColors = { new RGB(0, 128, 0), new RGB(0, 128, 0), + new RGB(0, 128, 0), new RGB(100, 228, 100), new RGB(9, 135, 205), + new RGB(142, 53, 239), new RGB(205, 0, 205), new RGB(255, 255, 0), + new RGB(215, 125, 0), new RGB(255, 0, 0) }; + + private Color recentKpEstTitleColor = Color.decode("0xFFFFFF"); + + protected Timer timer; + + protected TimerTask timerTask; + + protected boolean loadDone = false; + + protected Date curSynPerEndTime = null; + + // create this singleton object + private static GeoMagRTKpDataBlockWindow instance = null; + + /** + * Constructor + * + */ + public GeoMagRTKpDataBlockWindow() { + + super(); + + shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + + if (instance == null) { + instance = this; + } else { + GeoMagRTKpDataBlockWindow tmp = instance; + instance = this; + instance.setState(tmp.isState()); + } + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + public static GeoMagRTKpDataBlockWindow getAccess() { + return instance; + } + + /** + * Invoked by the workbench to initialize this View. + */ + public void init(IViewSite site) { + try { + super.init(site); + } catch (PartInitException pie) { + pie.printStackTrace(); + } + + page = site.getPage(); + page.addPartListener(this); + + constructDataTimer(); + } + + protected void constructDataTimer() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + + timer = new Timer("rtkpDataBlockDataRetrieve"); + timerTask = new TimerTask() { + @Override + public void run() { + setDataBlockContent(); + loadDone = true; + + fireUpdateEvent(); + } + }; + // update data every 10 seconds + timer.schedule(timerTask, 0, 10000); + } + }); + } + + /** + * Disposes resource. invoked by the workbench + */ + public void dispose() { + if (!isEditorVisible) { + instance = null; + return; + } else { + GeoMagWorldActivityResource geomagMapResource = GeoMagWorldActivityResource + .getGeoMagWorldActivityResource(); + geomagMapResource.dispose(); + + super.dispose(); + isEditorVisible = false; + + NatlCntrsEditor editor = GeoMagWorldActivityResource.getMapEditor(); + + if (editor != null) { + for (IRenderableDisplay display : UiUtil + .getDisplaysFromContainer(editor)) { + for (ResourcePair rp : display.getDescriptor() + .getResourceList()) { + if (rp.getResource() instanceof GeoMagWorldActivityResource) { + GeoMagWorldActivityResource rsc = (GeoMagWorldActivityResource) rp + .getResource(); + rsc.unload(); + } + if (rp.getResource() instanceof GeoMagWorldActivityTitleDateResource) { + GeoMagWorldActivityTitleDateResource rsc = (GeoMagWorldActivityTitleDateResource) rp + .getResource(); + rsc.unload(); + } + } + } + } + + /* + * remove the workbench part listener + */ + page.removePartListener(this); + + if (timerTask != null) { + timerTask.cancel(); + } + + if (timer != null) { + timer.cancel(); + } + + instance = null; + } + } + + private void close() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + if (wpage != null) { + IViewPart vpart = wpage.findView(RTKpUtil.DATABLOCK_VIEW_ID); + wpage.hideView(vpart); + } + NcDisplayMngr.setPanningMode(); + } + + /** + * Invoked by the workbench, this method sets up the SWT controls for the + * rtkp datablock palette + */ + @Override + public void createPartControl(Composite parent) { + + parent.setLayout(new GridLayout(1, false)); + // create textGp group. It contains text and textMode group + textGp = new Group(parent, SWT.SHADOW_OUT); + textGp.setLayout(new GridLayout()); + if ("Ks".equals(kType)) { + textGp.setText("Recent Station Ks/Gamma Values"); + } else { + textGp.setText("Recent Station K/Gamma Values"); + } + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + textGp.setLayoutData(data); + + createTextArea(textGp); + createOptionsGp(parent); + } + + public void createTextArea(Composite parent) { + + // Text display area + text = new Text(parent, SWT.V_SCROLL | SWT.H_SCROLL); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + text.setLayoutData(data); + Font font = text.getFont(); + FontData[] fontData = font.getFontData(); + for (int i = 0; i < fontData.length; i++) { + // fontData[i].setHeight(9); + fontData[i].setName("courier"); + // fontData[i].setStyle(1); + fontData[i].setStyle(SWT.BOLD); + } + Font newFont = new Font(font.getDevice(), fontData); + text.setFont(newFont); + text.setEditable(false); + } + + public void createOptionsGp(Composite parent) { + + Group optionsGrp = new Group(parent, SWT.SHADOW_OUT); + optionsGrp.setLayout(new GridLayout(3, false)); + + Group kKsGp = new Group(optionsGrp, SWT.SHADOW_OUT); + + Button showStationKBtn = new Button(kKsGp, SWT.RADIO); + showStationKBtn.setText("Show Station K"); + showStationKBtn.setEnabled(true); + showStationKBtn.setBounds(kKsGp.getBounds().x + btnGapX, + kKsGp.getBounds().y - 5 + labelGap, staBtnWidth, btnHeight); + showStationKBtn.setSelection(true); + + showStationKBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + setkType("K"); + setDataBlockContent(); + displayDataBlock(); + } + }); + Button showStationKsBtn = new Button(kKsGp, SWT.RADIO); + showStationKsBtn.setText("Show Station Ks"); + showStationKsBtn.setEnabled(true); + showStationKsBtn.setBounds(showStationKBtn.getBounds().x + + showStationKBtn.getBounds().width + btnGapX, + kKsGp.getBounds().y - 7 + labelGap, staBtnWidth, btnHeight); + + showStationKsBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + setkType("Ks"); + setDataBlockContent(); + displayDataBlock(); + } + }); + + Group kpKGp = new Group(optionsGrp, SWT.SHADOW_OUT); + + Button showKpStationsBtn = new Button(kpKGp, SWT.RADIO); + showKpStationsBtn.setText("Kp Stations Only"); + showKpStationsBtn.setEnabled(true); + showKpStationsBtn.setBounds(kpKGp.getBounds().x + btnGapX, + kpKGp.getBounds().y - 5 + labelGap, staBtnWidth, btnHeight); + showKpStationsBtn.setSelection(true); + + showKpStationsBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + showKpOnly = true; + setDataBlockContent(); + displayDataBlock(); + } + }); + Button showAllKStationsBtn = new Button(kpKGp, SWT.RADIO); + showAllKStationsBtn.setText("Show All K Stations"); + showAllKStationsBtn.setEnabled(true); + showAllKStationsBtn + .setBounds( + showKpStationsBtn.getBounds().x + + showKpStationsBtn.getBounds().width + btnGapX, + kpKGp.getBounds().y - 7 + labelGap, staBtnWidth + 25, + btnHeight); + + showAllKStationsBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + showKpOnly = false; + setDataBlockContent(); + displayDataBlock(); + } + }); + + // Push buttons for Previous text info + editNwBtn = new Button(optionsGrp, SWT.PUSH); + editNwBtn.setText("Edit Network"); + editNwBtn.setEnabled(true); + editNwBtn.setBounds(showAllKStationsBtn.getBounds().x + + showAllKStationsBtn.getBounds().width + btnGapX, + kpKGp.getBounds().y + labelGap, staBtnWidth, pushbtnHeight); + + editNwBtn.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + openEditNetworkDialog(); + } + }); + } + + public void setDataBlockContent() { + + endTime = RTKpUtil.calcCurTime(); + startTime = RTKpUtil.calcDataBlockStartTime(endTime); + + String filler = " "; + textStr = new StringBuffer(""); + kp_last10_text = new ArrayList(); + kp_last10_values = new ArrayList(); + + try { + + List kStations = RTKpUtil + .getGeoMagStationCodes(GeoMagStationType.KP); + if (!showKpOnly) { + kStations = RTKpUtil.getGeoMagStationCodes(GeoMagStationType.K); + } + int kStationsSize = (kStations != null) ? kStations.size() : 0; + + HashMap> curKpStationsStates = RTKpUtil + .getStationsStatesMap(GeoMagStationType.KP, 0); + + // get list of kp stations based on state for current synoptic + // period + + Date dbStartTime = RTKpUtil.calcDataBlockStartTime(endTime); + + List> kpDataList = RTKpUtil.getEstKpIndex1min( + dbStartTime, endTime); + + List kDataList = RTKpUtil.getEstKIndex1min(kStations, + dbStartTime, endTime); + + float maxGamma = getMaxGamma(kDataList); + double gammaSize = Math.floor(Math.log10(maxGamma)) + 1; + + String gammaFiller = ""; + String gammaFillerHeader = ""; + + for (int i = 0; i < (int) gammaSize; i++) { + gammaFiller += "."; + gammaFillerHeader += " "; + } + + // display header with list of station abbreviations + // (stations not being used in kp average get [ and ] around the + // names) + textStr.append(" Time " + filler); + for (int i = 0; i < kStationsSize; i++) { + if (curKpStationsStates.containsKey(kStations.get(i))) { + Map stnMap = curKpStationsStates + .get(kStations.get(i)); + + if (stnMap != null) { + // Apply changes beginning with current synoptic + // period + boolean curStateActive = ((Integer) stnMap + .get("kp_active") == 1) ? true : false; + if (curStateActive) { + textStr.append(" " + kStations.get(i) + "*" + + gammaFillerHeader + filler); + } else { + textStr.append(" " + kStations.get(i) + + gammaFillerHeader + filler); + } + } + } else { + textStr.append(" " + kStations.get(i) + gammaFillerHeader + + filler); + } + } + textStr.append(" Kp" + filler + "" + filler + "N\n"); + + // minute lines with data + int min = 0; + do { + + // increment minute by 1 + Calendar startTimeCal = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + startTimeCal.setTime(dbStartTime); + startTimeCal.add(Calendar.MINUTE, 1); + dbStartTime = startTimeCal.getTime(); + + // add time + String time = timeFormat.format(startTimeCal.getTime()); + textStr.append(" " + String.format("%-5s", time)); + + textStr.append(filler); + String kStr = " "; + + for (int i = 0; i < kStationsSize; i++) { + GeoMagK1min rec = getMatch1minRecord(kDataList, + dbStartTime, kStations.get(i)); + if (rec == null) { + kStr += ".... " + gammaFiller + filler; + continue; + } + + String k_disp = String.format("%.2f", rec.getKestReal()); + if ("Ks".equals(kType)) { + k_disp = String.format("%.2f", rec.getKs()); + } + String gamma = "" + (int) rec.getKestGamma(); + + if (gamma.length() < gammaSize) { + for (int j = gamma.length(); j < gammaSize; j++) { + gamma += " "; + } + } + + if (("99999.00".equals(k_disp) || "33333.00".equals(k_disp)) + && "99999".equals(gamma)) { + kStr += "" + ".... " + gammaFiller + filler; + } else { + kStr += "" + k_disp + "/" + gamma + filler; + } + } + + // display kp data + String kpStr = " "; + + Integer kpValue = 0; + Map ksMap = getMatchKsRecord(kpDataList, + dbStartTime); + if (ksMap != null) { + Date refTime = (Date) ksMap.get("reftime"); + Double Kp_est = (Double) ksMap.get("Kp_est"); + Double ks_avg = (Double) ksMap.get("ks_avg"); + BigInteger station_count = (BigInteger) ksMap + .get("station_count"); + + kpValue = (int) Math.round(Kp_est); + + double curKp = (double) (Math.round(3 * Kp_est)); + kpStr += RTKpUtil.KpLu[(int) curKp] + filler; + + kpStr += String.format("%.2f", ks_avg) + filler; + kpStr += station_count.toString(); + + double lbdry = 0d; + double ubdry = 0d; + + recentKpEstTitleColor = Color.decode("0xFFFFFF"); + + if (Kp_est * 3d >= 11d) { // greater than or equal to 4M + lbdry = Math.round(Kp_est) - 0.5; // lower boundary + ubdry = lbdry + 1d / 6d; + // when in the 1/2 to 2/3 below, shade as dark + // orange + // (otherwise red) + if (lbdry <= ks_avg && ks_avg < ubdry) { + recentKpEstTitleColor = Color.decode("0xE56717"); // dark + // orange + } else { + recentKpEstTitleColor = Color.decode("0xFF0000"); // red + } + } + + } else { + kpStr = " .." + filler + "(....)"; + } + + textStr.append(kStr + kpStr + "\n"); + + if (!kpStr.equals(" .." + filler + "(....)") && min++ >= 10) { + kp_last10_text.add(String.format("%-5s", time) + " " + + kpStr); + kp_last10_values.add(kpValue); + } + + } while (dbStartTime.compareTo(endTime) != 0); + + setKp_last10_colors(); + + loadDone = true; + } catch (GeoMagTimeSeriesDataException e) { + statusHandler.handle(Priority.PROBLEM, + "Error retrieving ks_avg from geomag_k1min table.", e); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error retrieving ks_avg from geomag_k1min table.", e); + } + + } + + public void displayDataBlock() { + + if (!loadDone) { + setDataBlockContent(); + } + + text.setText(textStr.toString()); + RTKpUtil.showGeoMagWorldActivity(this); + RTKpUtil.showRecentKpEstBlock(this); + + } + + private float getMaxGamma(List kDataList) { + + int kDataListSize = (kDataList != null) ? kDataList.size() : 0; + + float maxGamma = 0f; + for (int i = 0; i < kDataListSize; i++) { + GeoMagK1min k1minRec = kDataList.get(i); + if (k1minRec.getKestGamma() > maxGamma + && k1minRec.getKestGamma() != 99999.99f) { + maxGamma = k1minRec.getKestGamma(); + } + } + return maxGamma; + } + + private GeoMagK1min getMatch1minRecord(List kDataList, + Date refTime, String stationCode) { + + int kDataListSize = (kDataList != null) ? kDataList.size() : 0; + + for (int i = 0; i < kDataListSize; i++) { + GeoMagK1min k1minRec = kDataList.get(i); + if (k1minRec.match(refTime, stationCode)) { + return k1minRec; + } + } + + return null; + } + + public void openEditNetworkDialog() { + + EditNetworkDialog dialog; + try { + dialog = new EditNetworkDialog(shell, "Edit Network", this); + dialog.open(); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error while opening EditNetwork dialog.", e); + } + + } + + private Map getMatchKsRecord( + List> kpDataList, Date refTime) { + + int kpDataListSize = (kpDataList != null) ? kpDataList.size() : 0; + + for (int i = 0; i < kpDataListSize; i++) { + Map map = kpDataList.get(i); + if (map != null && map.get("reftime") != null) { + if (((Date) map.get("reftime")).compareTo(refTime) == 0) { + return map; + } + } + } + + return null; + } + + private Date getDBStartTime() { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTime(endTime); + cal.add(Calendar.MINUTE, -20); + return cal.getTime(); + } + + public Text getText() { + return text; + } + + public void setText(Text text) { + this.text = text; + } + + public StringBuffer getTextStr() { + return textStr; + } + + public void setTextStr(StringBuffer textStr) { + this.textStr = textStr; + } + + public void widgetDefaultSelected(SelectionEvent se) { + + } + + /* + * invoked when widget is disposed + * + * @see + * org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt + * .events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent event) { + + } + + @Override + public void partActivated(IWorkbenchPart part) { + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + partActivated(part); + } + + @Override + public void partClosed(IWorkbenchPart part) { + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + } + + @Override + public void partOpened(IWorkbenchPart part) { + } + + @Override + public void setFocus() { + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell() + .setFocus(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + } + + public boolean isState() { + return isState; + } + + public void setState(boolean isState) { + this.isState = isState; + } + + public void setEditorVisible(boolean isVisible) { + this.isEditorVisible = isVisible; + } + + public boolean getEditorVisible() { + return this.isEditorVisible; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + private Date endTime = null; + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public List getKp_last10_text() { + return kp_last10_text; + } + + public void setKp_last10_text(List kp_last10_text) { + this.kp_last10_text = kp_last10_text; + } + + public List getKp_last10_values() { + return kp_last10_values; + } + + public void setKp_last10_values(List kp_last10_values) { + this.kp_last10_values = kp_last10_values; + } + + public List getKp_last10_color() { + return kp_last10_color; + } + + public void setKp_last10_color(List kp_last10_color) { + this.kp_last10_color = kp_last10_color; + } + + public void setKp_last10_colors() { + + if (this.kindicesColors != null && kp_last10_values != null) { + kp_last10_color = new ArrayList(); + // set kp last10 text colors + for (int i = 0; i < kp_last10_values.size(); i++) { + Integer kp = kp_last10_values.get(i); + kp_last10_color.add(kindicesColors[kp]); + } + } + } + + public RGB[] getKindicesColors() { + return kindicesColors; + } + + public void setKindicesColors(RGB[] kindicesColors) { + if (kindicesColors != null && kindicesColors.length == 10) { + this.kindicesColors = kindicesColors; + } + } + + public Color getRecentKpEstTitleColor() { + return recentKpEstTitleColor; + } + + public void setRecentKpEstTitleColor(Color recentKpEstTitleColor) { + this.recentKpEstTitleColor = recentKpEstTitleColor; + } + + public boolean isShowKpOnly() { + return showKpOnly; + } + + public void setShowKpOnly(boolean showKpOnly) { + this.showKpOnly = showKpOnly; + } + + public String getkType() { + return kType; + } + + public void setkType(String kType) { + this.kType = kType; + + if ("Ks".equals(kType)) { + textGp.setText("Recent Station Ks/Gamma Values"); + } else { + textGp.setText("Recent Station K/Gamma Values"); + } + } + + @Override + public void update() { + displayDataBlock(); + } + + public void fireUpdateEvent() { + final GeoMagRTKpDataBlockWindow gmDBWin = GeoMagRTKpDataBlockWindow + .getAccess(); + + VizApp.runAsync(new Runnable() { + public void run() { + if (gmDBWin != null) { + gmDBWin.update(); + } + } + }); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpRecentKpWindow.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpRecentKpWindow.java new file mode 100644 index 0000000000..07e90fac67 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/GeoMagRTKpRecentKpWindow.java @@ -0,0 +1,334 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.palette; + +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +/** + * + * This java class performs the RTKP Recent Kp Estimates GUI construction. + * + *
+ * SOFTWARE HISTORY
+ * Date          Ticket#        Engineer    Description
+ * ------------  ---------- ----------- -----------------------------------
+ * April 4, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpRecentKpWindow extends ViewPart implements + SelectionListener, DisposeListener, IPartListener { + + private IWorkbenchPage page; + + private boolean isState = false; + + private Group textGp; + + private StyledText text; + + private Date startTime = null; + + private boolean isEditorVisible = true; + + static final SimpleDateFormat f = new SimpleDateFormat( + "yyyy-MMM-dd HH:mm:ss"); + + /** + * Constructor + * + */ + public GeoMagRTKpRecentKpWindow() { + + super(); + if (geomagrtkpRecentKpWindow == null) + geomagrtkpRecentKpWindow = this; + else { + GeoMagRTKpRecentKpWindow tmp = geomagrtkpRecentKpWindow; + geomagrtkpRecentKpWindow = this; + geomagrtkpRecentKpWindow.setState(tmp.isState()); + } + f.setTimeZone(TimeZone.getTimeZone("GMT")); + + } + + // create this singleton object + private static GeoMagRTKpRecentKpWindow geomagrtkpRecentKpWindow = null; + + public static GeoMagRTKpRecentKpWindow getAccess() { + return geomagrtkpRecentKpWindow; + } + + /** + * Invoked by the workbench to initialize this View. + */ + public void init(IViewSite site) { + try { + super.init(site); + } catch (PartInitException pie) { + pie.printStackTrace(); + } + + page = site.getPage(); + page.addPartListener(this); + + } + + /** + * Disposes resource. invoked by the workbench + */ + public void dispose() { + if (!isEditorVisible) { + return; + } else { + super.dispose(); + close(); + geomagrtkpRecentKpWindow = null; + + /* + * remove the workbench part listener + */ + page.removePartListener(this); + } + + } + + private void close() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + if (wpage != null) { + IViewPart vpart = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + wpage.hideView(vpart); + } + + NcDisplayMngr.setPanningMode(); + } + + /** + * Invoked by the workbench, this method sets up the SWT controls for the + * nctext palette + */ + @Override + public void createPartControl(Composite parent) { + + parent.setLayout(new GridLayout(1, false)); + // create textGp group. It contains text and textMode group + textGp = new Group(parent, SWT.SHADOW_OUT); + textGp.setLayout(new GridLayout()); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + textGp.setLayoutData(data); + + createTextArea(textGp); + } + + public void createTextArea(Composite parent) { + + // Text display area + text = new StyledText(parent, SWT.NONE); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + text.setLayoutData(data); + Font font = text.getFont(); + FontData[] fontData = font.getFontData(); + for (int i = 0; i < fontData.length; i++) { + fontData[i].setHeight(12); + fontData[i].setName("courier"); + fontData[i].setStyle(SWT.BOLD); + } + Font newFont = new Font(font.getDevice(), fontData); + text.setFont(newFont); + text.setEditable(false); + } + + public void displayRecentKpEstimates(List kp_last10_text, + List kp_last10_color, java.awt.Color titleColor) { + + text.setBackground(new Color(text.getFont().getDevice(), 0, 0, 0)); + text.setText(""); + + StyleRange[] styleRanges = new StyleRange[kp_last10_text.size() + 1]; + + // set title and title string color + String title = "Recent Kp Estimates\n"; + text.append(title); + Color titleStringColor = new Color(text.getFont().getDevice(), + titleColor.getRed(), titleColor.getGreen(), + titleColor.getBlue()); + styleRanges[0] = new StyleRange(0, title.length(), titleStringColor, + null); + + // add recent kp estimates to text display + if (kp_last10_text != null && kp_last10_color != null) { + + // add kp lines + for (int i = 0; i < kp_last10_text.size(); i++) { + String kpStr = kp_last10_text.get(i); + text.append(kpStr + "\n"); + } + + // add colors + int strIndex = title.length(); + for (int i = 0; i < kp_last10_text.size(); i++) { + String kpStr = kp_last10_text.get(i); + RGB color = kp_last10_color.get(i); + Color textColor = new Color(text.getFont().getDevice(), + color.red, color.green, color.blue); + + int kpStrLength = kpStr.length(); + + styleRanges[i + 1] = new StyleRange(strIndex, kpStrLength, + textColor, null); + + strIndex += kpStr.length() + 1; + + } + text.setStyleRanges(styleRanges); + + } + } + + public StyledText getText() { + return text; + } + + public void setText(StyledText text) { + this.text = text; + } + + public void widgetDefaultSelected(SelectionEvent se) { + + } + + /* + * invoked when widget is disposed + * + * @see + * org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt + * .events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent event) { + + } + + @Override + public void partActivated(IWorkbenchPart part) { + if (part instanceof GeoMagRTKpRecentKpWindow) { + // GeoMagWorldActivityResource rsc = + // GeoMagWorldActivityResource.getNctextuiResource(); + // if (rsc != null) + // rsc.setEditable(true); + } + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + partActivated(part); + } + + @Override + public void partClosed(IWorkbenchPart part) { + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + } + + @Override + public void partOpened(IWorkbenchPart part) { + } + + /** + * + * @return the currently selected category on the palette + */ + public String getCurrentCategory() { + return null; + } + + @Override + public void setFocus() { + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell() + .setFocus(); + } + + @Override + public void widgetSelected(SelectionEvent e) { + } + + public boolean isState() { + return isState; + } + + public void setState(boolean isState) { + this.isState = isState; + } + + public void setEditorVisible(boolean isVisible) { + this.isEditorVisible = isVisible; + } + + public boolean getEditorVisible() { + return this.isEditorVisible; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + private Date endTime = null; + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/IGeoMagRTKpDataBlockListener.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/IGeoMagRTKpDataBlockListener.java new file mode 100644 index 0000000000..4083f5b5e9 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/palette/IGeoMagRTKpDataBlockListener.java @@ -0,0 +1,31 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.palette; + +/** + * + * IGeoMagRTKpDataBlockListener + * + *
+ * SOFTWARE HISTORY
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- -----------------------------------
+ * June 12, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public interface IGeoMagRTKpDataBlockListener { + + public void update(); +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResource.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResource.java new file mode 100644 index 0000000000..bac6109204 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResource.java @@ -0,0 +1,523 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.viz.rtkp.KpPlotCapability; +import gov.noaa.nws.ncep.viz.rtkp.KsPlotCapability; +import gov.noaa.nws.ncep.viz.rtkp.util.GeoMagTimeSeriesDataException; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpTimeSeriesZoomHandler; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import java.math.BigInteger; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; +import java.util.TreeSet; + +import javax.measure.unit.SI; +import javax.measure.unit.Unit; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +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.common.style.StyleException; +import com.raytheon.uf.common.style.level.SingleLevel; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle; +import com.raytheon.uf.viz.core.RGBColors; +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.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.xy.timeseries.TimeSeriesEditor; +import com.raytheon.uf.viz.xy.timeseries.adapter.AbstractTimeSeriesAdapter; +import com.raytheon.uf.viz.xy.timeseries.rsc.TimeSeriesResource; +import com.raytheon.viz.core.graphing.util.GraphPrefsFactory; +import com.raytheon.viz.core.graphing.xy.XYData; +import com.raytheon.viz.core.graphing.xy.XYDataList; +import com.raytheon.viz.core.rsc.ICombinedResourceData.CombineOperation; +import com.raytheon.viz.ui.EditorUtil; + +/** + * Provides a resource for displaying RTKP time series plot. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * March 3, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagRTKpResource extends TimeSeriesResource { + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagRTKpResource.class); + + public static SimpleDateFormat sdf = new SimpleDateFormat( + "HHmm 'UTC' dd MMM yyyy"); + + private static Unit unit = SI.NANO(SI.TESLA); + + static final long ONE_MINUTE_IN_MILLIS = 60000;// millisecs + + private Set dataTimes = new TreeSet(); + + protected Timer timer; + + protected TimerTask timerTask; + + protected boolean loadDone = false; + + protected Date prevSynPerStartTime = null; + + protected Date updatedDate = null; + + /** + * @param data + * @param props + * @param adapter + */ + public GeoMagRTKpResource(GeoMagRTKpResourceData data, + LoadProperties props, AbstractTimeSeriesAdapter adapter) { + super(data, props, adapter); + + data.addChangeListener(new IResourceDataChanged() { + + @Override + public void resourceChanged(ChangeType type, Object object) { + // do nothing + } + + }); + + if (RTKpUtil.KS_PLOT.equals(resourceData.getSource())) { + getCapabilities().addCapability(KsPlotCapability.class); + getCapabilities().removeCapability(KpPlotCapability.class); + } else if (RTKpUtil.KP_PLOT.equals(resourceData.getSource())) { + getCapabilities().addCapability(KpPlotCapability.class); + getCapabilities().removeCapability(KsPlotCapability.class); + } + + loadData(); + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + + if (secondaryResource != null) { + secondaryResource.setDescriptor(this.descriptor); + secondaryResource.init(target); + } + + constructDataTimer(); + + // Load the Graph Preferences + if (prefs == null) { + try { + + SingleLevel level = new SingleLevel("SURFACE"); + level.setValue(0.0); + + prefs = GraphPrefsFactory.buildPreferences( + resourceData.getYParameter().code, level); + } catch (StyleException e) { + throw new VizException(e.getLocalizedMessage(), e); + } + } + + if (prefs != null && prefs.getDisplayUnits() != null) { + units = prefs.getDisplayUnitLabel(); + } + + prevSynPerStartTime = ((GeoMagRTKpResourceData) resourceData) + .getStartTime().getRefTime(); + + updatedDate = RTKpUtil.getCurrentTime(); + + if (EditorUtil.getActiveEditor() != null) { + if (EditorUtil.getActiveEditor() instanceof TimeSeriesEditor) { + TimeSeriesEditor editor = (TimeSeriesEditor) EditorUtil + .getActiveEditor(); + + // Register RTKpTimeSeriesZoomHandler mouse handler that does + // nothing when mouse wheel moves + RTKpTimeSeriesZoomHandler zoomHandler = new RTKpTimeSeriesZoomHandler( + this.descriptor.getRenderableDisplay()); + editor.registerMouseHandler(zoomHandler); + } + } + } + + protected void constructDataTimer() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + timer = new Timer("rtkpDataRetrieve"); + timerTask = new TimerTask() { + @Override + public void run() { + // try { + + if (prevSynPerStartTime != null) { + Date newSynPerStartTime = RTKpUtil + .calcPrevSynPerStartTime(); + + if (!prevSynPerStartTime.equals(newSynPerStartTime)) { + ((GeoMagRTKpResourceData) resourceData) + .setStartTime(new DataTime( + newSynPerStartTime)); + prevSynPerStartTime = newSynPerStartTime; + } + } + + updatedDate = RTKpUtil.getCurrentTime(); + loadData(); + loadDone = true; + + // updatedDate = RTKpUtil.getCurrentTime(); + // issueRefresh(); + } + }; + // update data every 10 seconds + timer.schedule(timerTask, 0, 10000); + } + }); + } + + protected void loadData() { + + XYDataList oldData = data; + try { + data = getXYDataList(); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, "Error loading data.", e); + } + sortData(); + + dataTimes = new TreeSet(); + for (XYData d : data.getData()) { + dataTimes.add((DataTime) d.getX()); + } + dataTimes = new TreeSet(); + for (XYData d : data.getData()) { + dataTimes.add((DataTime) d.getX()); + } + + if (graph != null) { + graph.reconstruct(); + } + if (oldData != null) { + oldData.dispose(); + } + + issueRefresh(); + } + + public XYDataList getXYDataList() throws VizException { + ArrayList xyData = new ArrayList(); + + if ((GeoMagRTKpResourceData) resourceData != null + && ((GeoMagRTKpResourceData) resourceData).getStartTime() != null) { + try { + + Date startTime = ((GeoMagRTKpResourceData) resourceData) + .getStartTime().getRefTime(); + + Date endTime = ((GeoMagRTKpResourceData) resourceData) + .getEndTime().getRefTime(); + + if (endTime == null) { + Calendar cal = ((GeoMagRTKpResourceData) resourceData) + .getStartTime().getRefTimeAsCalendar(); + cal.add(Calendar.HOUR, 6); + endTime = cal.getTime(); + } + SimpleDateFormat f = new SimpleDateFormat( + "yyyy-MMM-dd HH:mm:ss"); + f.setTimeZone(TimeZone.getTimeZone("GMT")); + + List> rsltsList = RTKpUtil + .getEstKpIndex1min(startTime, endTime); + + int rsltsListSize = (rsltsList != null) ? rsltsList.size() : 0; + + ArrayList stationCountsList = new ArrayList(); + + for (int i = 0; i < rsltsListSize; i++) { + Map map = rsltsList.get(i); + Date refTime = (Date) map.get("reftime"); + Double ks_avg = (Double) map.get("ks_avg"); + Double Kp_est = (Double) map.get("Kp_est"); + BigInteger station_count = (BigInteger) map + .get("station_count"); + stationCountsList.add(station_count); + + DataTime x = new DataTime(refTime); + + if (RTKpUtil.KP_PLOT.equals(resourceData.getSource())) { + xyData.add(new XYData(x, Kp_est)); + } else { + xyData.add(new XYData(x, ks_avg)); + } + } + + ((GeoMagRTKpResourceData) resourceData) + .setStationCountsList(stationCountsList); + + } catch (GeoMagTimeSeriesDataException e) { + statusHandler.handle(Priority.PROBLEM, + "Error retrieving data from geomag_k1min table.", e); + } + } + + XYDataList list = new XYDataList(); + list.setData(xyData); + + return list; + } + + /** + * + */ + private void sortData() { + Collections.sort(data.getData(), new Comparator() { + + @Override + public int compare(XYData xy1, XYData xy2) { + DataTime t1 = (DataTime) xy1.getX(); + DataTime t2 = (DataTime) xy2.getX(); + return t1.compareTo(t2); + } + + }); + + } + + public DataTime[] getDataTimes() { + return dataTimes.toArray(new DataTime[0]); + } + + @Override + public void addRecord(PluginDataObject record) { + // do nothing + } + + @Override + public Object getGraphKey() { + return resourceData.getSource(); + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + if (RTKpUtil.KS_PLOT.equals(resourceData.getSource())) { + getCapabilities().removeCapability(KpPlotCapability.class); + } else if (RTKpUtil.KP_PLOT.equals(resourceData.getSource())) { + getCapabilities().removeCapability(KsPlotCapability.class); + } + + if (data == null) { + return; + } + + if (secondaryResource != null) { + secondaryResource.paint(target, paintProps); + } + + if (combineOperation == CombineOperation.NONE) { + return; + } + + if (graph == null) { + graph = descriptor.getGraph(this); + } + + if (graph == null) { + return; + } + + // Wait for graph to initialize before plotting to it, TODO: do better + if (graph.isReady() == false) { + return; + } + + ArrayList stationCountsList = ((GeoMagRTKpResourceData) resourceData) + .getStationCountsList(); + + target.setupClippingPlane(graph.getExtent()); + double[] prevScreen = null; + for (int i = 0; i < data.getData().size(); i++) { + + XYData point = data.getData().get(i); + + if (point.getY() != null) { + // double newY = toDeltanT.convert(((Number) point.getY()) + // .doubleValue()); + + double[] screen = getScreenPosition(point.getX(), point.getY()); + + RGB color = RGBColors.getRGBColor("white"); + float pointSize = 1.75f; + PointStyle pointStyle = PointStyle.POINT; + + // Connects adjacent data points with a line + if (prevScreen != null) { + + if (RTKpUtil.KS_PLOT.equals(resourceData.getSource())) { + if (stationCountsList != null + && stationCountsList.size() > 0) { + int colIndex = stationCountsList.get(i).intValue(); + color = RTKpUtil.getStationCountColor( + colIndex, + getCapabilities().getCapability( + resourceData, + KsPlotCapability.class) + .getPlotColors()); + } + pointSize = (float) Float.parseFloat(getCapability( + KsPlotCapability.class).getPointSize()); + pointStyle = PointStyle.valueOf(getCapability( + KsPlotCapability.class).getPointStyle()); + } else { + color = getCapability(KpPlotCapability.class) + .getPlotColor(); + pointSize = (float) Float.parseFloat(getCapability( + KpPlotCapability.class).getPointSize()); + pointStyle = PointStyle.valueOf(getCapability( + KpPlotCapability.class).getPointStyle()); + } + + target.drawPoint(screen[0], screen[1], 0.0, color, + pointStyle, pointSize); + + } + + prevScreen = screen; + } + } + target.clearClippingPlane(); + } + + @Override + public void paintInsetMap(IGraphicsTarget target, + PaintProperties paintProps, MapDescriptor insetMapDescriptor) + throws VizException { + + // Paint the border (in black to override the previous border painted in + // grey) + IExtent extent = paintProps.getView().getExtent(); + + target.drawRect(extent, new RGB(0, 0, 0), 2.0f, 0.0); + paintProps.setAlpha(0.0f); + } + + private double[] getScreenPosition(Object x, Object y) { + double valY = ((Number) y).doubleValue(); + double valX = ((DataTime) x).getValidTime().getTimeInMillis(); + return graph.getGridLocation(valX, valY); + } + + public DataTime getStartTime() { + return ((GeoMagRTKpResourceData) resourceData).getStartTime(); + } + + public DataTime getEndTime() { + return ((GeoMagRTKpResourceData) resourceData).getEndTime(); + } + + public Timer getTimer() { + return timer; + } + + public void setTimer(Timer timer) { + this.timer = timer; + } + + public TimerTask getTimerTask() { + return timerTask; + } + + public void setTimerTask(TimerTask timerTask) { + this.timerTask = timerTask; + } + + public boolean isLoadDone() { + return loadDone; + } + + public void setLoadDone(boolean loadDone) { + this.loadDone = loadDone; + } + + public Date getPrevSynPerStartTime() { + return prevSynPerStartTime; + } + + public void setPrevSynPerStartTime(Date prevSynPerStartTime) { + this.prevSynPerStartTime = prevSynPerStartTime; + } + + public Date getUpdatedDate() { + return updatedDate; + } + + public void setUpdatedDate(Date updatedDate) { + this.updatedDate = updatedDate; + } + + @Override + public String getName() { + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + StringBuilder sb = new StringBuilder(resourceData.getSource()); + if (data.getData().size() == 0) + sb.append(" - NO DATA"); + return sb.toString(); + } + + @Override + public String[] getTitles() { + return new String[] { "NOAA estimated real-time Kp index" }; + } + + /** + * Called when resource is disposed + * + * @see com.raytheon.viz.core.rsc.IVizResource#dispose() + */ + @Override + public void disposeInternal() { + resourceData = null; + timerTask.cancel(); + timer.cancel(); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResourceData.java new file mode 100644 index 0000000000..e88dbf87c0 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagRTKpResourceData.java @@ -0,0 +1,264 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; + +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 com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.RecordFactory; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.xy.timeseries.adapter.AbstractTimeSeriesAdapter; +import com.raytheon.uf.viz.xy.timeseries.rsc.TimeSeriesResourceData; + +/** + * Resource Data for RTKP resource. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * April 4, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class GeoMagRTKpResourceData extends TimeSeriesResourceData { + + private static final int MILLISECONDS_PER_HOUR = 60 * 60 * 1000; + + @XmlAttribute + private boolean updating = true; + + /** + * length of plot in hours + */ + @XmlAttribute + private int plotLengthInHours = 6; + + private DataTime startTime = null; + + private ArrayList stationCountsList = new ArrayList(); + + public GeoMagRTKpResourceData() { + super(); + } + + @Override + protected AbstractVizResource constructResource( + LoadProperties loadProperties, PluginDataObject[] objects) + throws VizException { + if (objects.length > 0) { + AbstractTimeSeriesAdapter adapter = getAdapter(objects[0]); + adapter.setResourceData(this); + GeoMagRTKpResource resource = new GeoMagRTKpResource(this, + loadProperties, adapter); + // for (PluginDataObject object : objects) { + // resource.addRecord(object); + // } + return resource; + } + throw new VizException( + "No Data Available: unable to determine resource type"); + + } + + /* + * Copied here from TimeSeriesResourceData since it is declared private. Can + * remove this if changed to protected. + */ + private static final String TIME_SERIES_ADAPTER_EXTENSION = "com.raytheon.uf.viz.xy.timeseries.timeseriesadapter"; + + /* + * Copied here from TimeSeriesResourceData.getAdapter() since it is private. + * Can remove this if overridden method changed to protected. + */ + private AbstractTimeSeriesAdapter getAdapter(PluginDataObject object) + throws VizException { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + if (registry == null) { + throw new VizException("Error loading ExtensionRegistry"); + } + IExtensionPoint point = registry + .getExtensionPoint(TIME_SERIES_ADAPTER_EXTENSION); + if (point == null) { + throw new VizException( + "Error loading Extension points for Time Series Adapters"); + } + Map uriFields = RecordFactory.getInstance() + .loadMapFromUri(object.getDataURI()); + IExtension[] extensions = point.getExtensions(); + + for (IExtension ext : extensions) { + IConfigurationElement[] config = ext.getConfigurationElements(); + + for (IConfigurationElement cfg : config) { + boolean useAdapter = false; + String targetClass = cfg.getAttribute("class"); + for (Class clazz : object.getClass().getInterfaces()) { + if (clazz.getName().equals(targetClass)) { + useAdapter = true; + break; + } + } + if (!useAdapter) { + for (Class clazz = object.getClass(); clazz != PluginDataObject.class; clazz = clazz + .getSuperclass()) { + if (clazz.getName().equals(targetClass)) { + useAdapter = true; + break; + } + } + } + + IConfigurationElement[] constraints = cfg + .getChildren("constraint"); + for (IConfigurationElement constraint : constraints) { + Object value = uriFields + .get(constraint.getAttribute("key")); + if (value == null) { + value = "null"; + } + if (!value.toString().equals( + constraint.getAttribute("value"))) { + useAdapter = false; + break; + } + } + if (useAdapter) { + try { + return (AbstractTimeSeriesAdapter) cfg + .createExecutableExtension("adapter"); + } catch (CoreException e) { + throw new VizException( + "Error constructing Time Series adapter", e); + } + } + + } + } + + throw new VizException("No Time Series adapter registered for: " + + object.getClass().getSimpleName()); + } + + @Override + public DataTime[] getAvailableTimes() throws VizException { + DataTime[] times = super.getAvailableTimes(); + times = filterTimes(times, startTime, getEndTime()); + return times; + } + + /** + * Given the times, filter them to only return times between given times + * + * @param times + * @param start + * @param end + * @return + */ + public DataTime[] filterTimes(DataTime[] times, DataTime startTime, + DataTime endTime) { + List validTimes = new ArrayList(); + for (DataTime time : times) { + if (time.compareTo(startTime) >= 0 && time.compareTo(endTime) <= 0) { + validTimes.add(time); + } + } + return validTimes.toArray(new DataTime[validTimes.size()]); + } + + private DataTime calculateStartTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + ttime.set(Calendar.MINUTE, 0); + ttime.set(Calendar.SECOND, 0); + ttime.set(Calendar.MILLISECOND, 0); + int currentHour = ttime.get(Calendar.HOUR_OF_DAY); + // Find next synoptic time as endtime + int hoursToAdd = 3 - (currentHour % 3); + ttime.add(Calendar.HOUR_OF_DAY, hoursToAdd); + // subtract plot length time to get starttime + ttime.add(Calendar.HOUR_OF_DAY, -plotLengthInHours); + + return new DataTime(ttime.getTime()); + } + + public int getPlotLengthInHours() { + return plotLengthInHours; + } + + public void setPlotLengthInHours(int duration) { + this.plotLengthInHours = duration; + } + + public DataTime getStartTime() { + return startTime; + } + + public void setStartTime(DataTime startTime) { + this.startTime = startTime; + } + + public DataTime getEndTime() { + DataTime endTime = null; + if (startTime != null) { + long stime = startTime.getRefTime().getTime(); + // add in milliseconds + stime += plotLengthInHours * MILLISECONDS_PER_HOUR; + endTime = new DataTime(new Date(stime)); + } + return endTime; + } + + public boolean isUpdating() { + return updating; + } + + @Override + public void update(Object updateData) { + // do nothing + } + + public void setUpdating(boolean updating) { + this.updating = updating; + } + + public ArrayList getStationCountsList() { + return stationCountsList; + } + + public void setStationCountsList(ArrayList stationCountsList) { + this.stationCountsList = stationCountsList; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagSampling.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagSampling.java new file mode 100644 index 0000000000..791ad77747 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagSampling.java @@ -0,0 +1,466 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +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.DrawableString; +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.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IFont.Style; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +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.AbstractVizResource.ResourceStatus; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * GeoMagSampling resource, draws sample text to the screen. Also picks up mouse + * events. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date           Ticket#    Engineer         Description
+ * ------------   ---------- -----------      --------------------------
+ * April 16, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagSampling { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagSampling.class); + + /** + * The result of a hover operation: a set of strings and corresponding + * colors + * + */ + protected static class SampleResult { + + public SampleResult() { + + } + + public String[] labels; + + public RGB[] colors; + } + + private IFont hoverFont = null; + + private boolean errorInHovering = false; + + private VerticalAlignment verticalAlignment = VerticalAlignment.TOP; + + public GeoMagSampling() { + + } + + protected SampleResult doHover(ReferencedCoordinate coord, + ResourceList resources) throws VizException { + SampleResult result = new SampleResult(); + List labelList = new ArrayList(); + List colorList = new ArrayList(); + try { + int size = resources.size(); + + for (int i = size - 1; i >= 0; --i) { + ResourcePair rp = resources.get(i); + String retVal = recursiveHoverSearch(rp, coord); + + if (retVal != null && retVal.length() > 0) { + + RGB color = null; + if (rp.getResource().hasCapability( + ColorableCapability.class)) { + color = rp.getResource() + .getCapability(ColorableCapability.class) + .getColor(); + } + int p1, p2; + p1 = 0; + while ((p2 = retVal.indexOf('\n', p1)) >= 0) { + colorList.add(color); + labelList.add(retVal.substring(p1, p2)); + p1 = p2 + 1; + } + String s = retVal.substring(p1); + if (s.length() > 0) { + colorList.add(color); + labelList.add(retVal.substring(p1)); + } + + break; + } + } + } catch (Throwable t) { + statusHandler.handle(Priority.PROBLEM, "Error sampling resources: " + + t.getLocalizedMessage(), t); + + } + + result.labels = labelList.toArray(new String[labelList.size()]); + result.colors = colorList.toArray(new RGB[colorList.size()]); + return result; + } + + private String recursiveHoverSearch(ResourcePair rp, + ReferencedCoordinate coordinate) throws VizException { + ResourceProperties props = rp.getProperties(); + AbstractVizResource rsc = rp.getResource(); + + if (rsc != null && rsc.getStatus() == ResourceStatus.INITIALIZED + && props.isVisible()) { + String curVal = rsc.inspect(coordinate); + + if (curVal != null && curVal.length() > 0) { + return curVal; + } + } + + return null; + } + + protected void paintResult(IGraphicsTarget target, IDescriptor descriptor, + PaintProperties paintProps, ReferencedCoordinate coord) + throws VizException { + if (hoverFont == null) { + hoverFont = target.initializeFont(target.getDefaultFont() + .getFontName(), 12, new Style[] { Style.BOLD }); + hoverFont.setSmoothing(false); + hoverFont.setScaleFont(false); + } + + SampleResult result = doHover(coord, descriptor.getResourceList()); + + verticalAlignment = VerticalAlignment.TOP; + target.clearClippingPlane(); + try { + if (result != null) { + double[] world = new double[] { coord.getObject().x, + coord.getObject().y }; + double[] pixel = descriptor.worldToPixel(world); + Coordinate c = new Coordinate(pixel[0], pixel[1]); + int canvasWidth = paintProps.getCanvasBounds().width; + double extentWidth = paintProps.getView().getExtent() + .getWidth(); + double ratioX = canvasWidth / extentWidth; + + if (result.labels.length > 0) { + List strsToUse = new ArrayList(); + HorizontalAlignment[] alignments = new HorizontalAlignment[result.labels.length]; + boolean[] modified = new boolean[result.labels.length]; + for (int i = 0; i < modified.length; ++i) { + modified[i] = false; + alignments[i] = HorizontalAlignment.LEFT; + String[] tmp = new String[] { result.labels[i], + result.labels[i] }; + strsToUse.add(tmp); + } + + adjustStrings(target, paintProps, strsToUse, modified, + alignments, c, ratioX, null); + + HorizontalAlignment horizontalAlignment = alignments[0]; + boolean good = true; + for (int i = 1; i < alignments.length && good; ++i) { + if (horizontalAlignment != alignments[i]) { + good = false; + } + } + + if (!good) { + // not all the same, figure out alignments!!! + int maxLen = 0; + int i = 0; + for (String[] s : strsToUse) { + if (s[0].length() > maxLen) { + maxLen = s[0].length(); + horizontalAlignment = alignments[i]; + } + ++i; + } + + adjustStrings(target, paintProps, strsToUse, modified, + alignments, c, ratioX, horizontalAlignment); + } + + List actualStrs = new ArrayList(); + for (int i = 0; i < strsToUse.size(); ++i) { + String[] strs = strsToUse.get(i); + for (int j = 1; j < strs.length; ++j) { + actualStrs.add(strs[j]); + // colorsToUse.add(result.colors[i]); + } + } + + String[] newStrs = actualStrs.toArray(new String[actualStrs + .size()]); + + double referencePtY = adjustLabelWrapY( + target, + newStrs, + c.y + + ((AbstractRenderableDisplay.CURSOR_HEIGHT) / ratioX), + paintProps.getView().getExtent(), ratioX); + + if (horizontalAlignment == HorizontalAlignment.RIGHT) { + c.x -= (target.getStringBounds(hoverFont, newStrs, + TextStyle.BOXED).getWidth() / ratioX); + } + + DrawableString hoverString = new DrawableString(newStrs, + new RGB(0, 0, 0)); + hoverString.font = hoverFont; + hoverString.textStyle = TextStyle.BOXED; + hoverString.horizontalAlignment = HorizontalAlignment.LEFT; + hoverString.verticallAlignment = verticalAlignment; + hoverString.boxColor = new RGB(255, 255, 255); + hoverString.setCoordinates(c.x, referencePtY); + + target.drawStrings(hoverString); + } + } + errorInHovering = false; + } catch (Exception e) { + if (errorInHovering) { + // Keep down the number of error messages + + statusHandler.handle( + Priority.PROBLEM, + "Error painting sample text: " + + e.getLocalizedMessage(), e); + + } + errorInHovering = true; + } + } + + private void adjustStrings(IGraphicsTarget target, + PaintProperties paintProps, List strsToUse, + boolean[] modified, HorizontalAlignment[] alignments, Coordinate c, + double ratio, HorizontalAlignment targetAlignment) { + List strsToUseInternal = new ArrayList(); + for (int i = 0; i < strsToUse.size(); ++i) { + String str = strsToUse.get(i)[0]; + String[] split = str.split("[ ]"); + boolean done = false; + int divideBy = strsToUse.get(i).length - 1; + int maxDivisions = 0; + for (int j = 0; j < split.length; ++j) { + if (split[j].isEmpty() == false) { + ++maxDivisions; + } + } + + if (alignments[i] == targetAlignment) { + strsToUseInternal.add(strsToUse.get(i)); + } else { + String[] test = new String[] { str }; + while (!done) { + if (divideBy > maxDivisions + || alignments[i] == targetAlignment) { + done = true; + continue; + } + + int approxLenPerStr = str.length() / divideBy; + List strs = new ArrayList(); + + for (int j = 0; j < split.length;) { + String line = split[j++]; + while (j < split.length) { + String s = split[j]; + if (s.length() + line.length() <= approxLenPerStr) { + if (!s.isEmpty()) { + if (j == split.length - 1 + && split[1].equalsIgnoreCase("=")) { + line = split[split.length - 1]; + } else { + line += " " + s; + } + } else { + line += " "; + } + ++j; + } else { + break; + } + } + strs.add(line); + } + + test = strs.toArray(new String[strs.size()]); + + HorizontalAlignment alignment = adjustLabelWrapX(target, + test, c.x, paintProps.getView().getExtent(), ratio, + alignments[i]); + if (alignment == alignments[i] + && (targetAlignment == null || alignment == targetAlignment)) { + // the alignment was not changed and we are the target + // alignment, we are done + done = true; + } else { + if (targetAlignment == null) { + // alignment changed, check to see if it changes + // back + HorizontalAlignment tmpAlignment = alignment; + alignment = adjustLabelWrapX(target, test, c.x, + paintProps.getView().getExtent(), ratio, + alignment); + if (alignment != tmpAlignment) { + // we moved back, we need to divide and + // conquer + alignments[i] = HorizontalAlignment.LEFT; + modified[i] = true; + divideBy++; + } else { + // we are good at this alignment + alignments[i] = alignment; + done = true; + } + } else { + // we need to be the targetAlignment + alignment = adjustLabelWrapX(target, test, c.x, + paintProps.getView().getExtent(), ratio, + targetAlignment); + if (alignment == targetAlignment) { + // we are fine at other alignment also, use it: + alignments[i] = alignment; + done = true; + } else { + alignments[i] = targetAlignment; + modified[i] = true; + divideBy++; + } + } + } + } + + String[] addTo = new String[test.length + 1]; + addTo[0] = str; + for (int j = 0; j < test.length; ++j) { + addTo[j + 1] = test[j]; + } + + strsToUseInternal.add(addTo); + } + } + strsToUse.clear(); + strsToUse.addAll(strsToUseInternal); + } + + /** + * Adjusts the x label if the width of the longest label extends the extent + * + * @param target + * @param labels + * @param x + * @param extent + * @param ratio + * @return + */ + private HorizontalAlignment adjustLabelWrapX(IGraphicsTarget target, + String[] labels, double x, IExtent extent, double ratio, + HorizontalAlignment horizontalAlignment) { + double referencePoint = x; + + // Find the max width of the label in pixels + double maxWidth = 0; + IFont font = hoverFont; + for (String label : labels) { + Rectangle2D bounds = target.getStringBounds(font, label); + if (bounds.getWidth() > maxWidth) { + maxWidth = bounds.getWidth(); + } + } + + // Get the width in gl space + double widthInGl = maxWidth / ratio; + + if (horizontalAlignment == HorizontalAlignment.LEFT) { + // Check to see if text extends screen extent + if (referencePoint + widthInGl > extent.getMaxX()) { + horizontalAlignment = HorizontalAlignment.RIGHT; + } + } else { + // Check to see if text extends screen extent + if (referencePoint - widthInGl < extent.getMinX()) { + horizontalAlignment = HorizontalAlignment.LEFT; + } + } + + return horizontalAlignment; + } + + /** + * Adjusts the y label position if the stacked labels exceeds the screen + * extent height + * + * @param target + * @param labels + * @param y + * @param extent + * @param ratio + * @return + */ + private double adjustLabelWrapY(IGraphicsTarget target, String[] labels, + double y, IExtent extent, double ratio) { + double referencePoint = y; + + double totalHeight = target.getStringBounds(hoverFont, labels, + TextStyle.BLANKED).getHeight(); + + // convert to gl space + double maxHeightInGl = (totalHeight) / ratio; + + // check to see if height extends map height + if (referencePoint + maxHeightInGl > extent.getMaxY()) { + verticalAlignment = VerticalAlignment.BOTTOM; + referencePoint -= (AbstractRenderableDisplay.CURSOR_HEIGHT + 2) + / ratio; + } + + // return adjusted point + return referencePoint; + } + + public void dispose() { + if (hoverFont != null) { + hoverFont.dispose(); + } + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityMouseHandler.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityMouseHandler.java new file mode 100644 index 0000000000..4d6a88d310 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityMouseHandler.java @@ -0,0 +1,263 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation; +import gov.noaa.nws.ncep.ui.pgen.tools.InputHandlerDefaultImpl; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil.GeoMagStationType; +import gov.noaa.nws.ncep.viz.ui.display.NatlCntrsEditor; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import org.geotools.referencing.GeodeticCalculator; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +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.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapDescriptor; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Mouse handler for Geomag World Activity Map. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * May 5, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagWorldActivityMouseHandler extends InputHandlerDefaultImpl { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagWorldActivityMouseHandler.class); + + private static final double geomagStnPointMinDistance = 75000; + + static int textDispIndex = 0; + + private List allStations = null; + + private GeoMagWorldActivityResource resource; + + /** + * Index of the selected point. + */ + protected int ptIndex = 0; + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.IInputHandler#handleMouseDown(int, int, + * int) + */ + @Override + public boolean handleMouseDown(int x, int y, int button) { + return false; + } + + public GeoMagWorldActivityMouseHandler(GeoMagWorldActivityResource resource) { + this.resource = resource; + this.allStations = RTKpUtil.getGeoMagStations(GeoMagStationType.ALL); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.IInputHandler#handleMouseUp(int, int, int) + * handle left button, so user be able to pick stn and print text report + */ + @Override + public boolean handleMouseUp(int x, int y, int button) { + + // button 1 is left mouse button + if (button == 1) { + NatlCntrsEditor mapEditor = GeoMagWorldActivityResource + .getMapEditor(); + if (mapEditor != null) { + // Check if mouse is in geographic extent + Coordinate loc = mapEditor.translateClick(x, y); + if (loc == null) + return false; + + if (resource != null) { + // get the stn (point) list + List points = allStations;// resource.getPoints(); + + if (points.isEmpty() == false) { + + // get the stn close to loc "enough" and retrieve text + // report for it + GeoMagStation stnPt = getPtWithinMinDist(points, loc); + + if (stnPt != null) { + + Date endTime = new Date(); + + List stnCodes = new ArrayList(); + stnCodes.add(stnPt.getStationCode()); + try { + List> latestStnKLst = RTKpUtil + .getLatestEstKIndex(stnCodes, null, + null); + if (latestStnKLst != null + && latestStnKLst.size() == 1) { + endTime = (Date) latestStnKLst.get(0).get( + "reftime"); + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error while retrieving latest est k index: " + + e.getLocalizedMessage(), e); + } + + Calendar endTimeCal = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + endTimeCal.setTime(endTime); + endTimeCal.set(Calendar.MINUTE, 0); + endTimeCal.set(Calendar.SECOND, 0); + endTimeCal.set(Calendar.MILLISECOND, 0); + int currentHour = endTimeCal + .get(Calendar.HOUR_OF_DAY); + // find current synoptic end time + int hoursToAdd = 3 - (currentHour % 3); + endTimeCal.add(Calendar.HOUR_OF_DAY, hoursToAdd); + // subtract -12 to get start time + + Calendar startTimeCal = Calendar + .getInstance(TimeZone.getTimeZone("GMT")); + startTimeCal.setTime(endTimeCal.getTime()); + startTimeCal.add(Calendar.HOUR_OF_DAY, -12); + + try { + RTKpUtil.loadHDWithQdcPlots(stnPt + .getStationCode(), RTKpUtil + .getMostAvailableDataBasedOnSourceId( + stnPt.getStationCode(), + startTimeCal.getTime(), + endTimeCal.getTime())); + } catch (Exception e) { + statusHandler.handle( + Priority.PROBLEM, + "Error while loading H & D plot for " + + stnPt.getStationCode() + + " in a new window: " + + e.getLocalizedMessage(), e); + } + return true; + } + + } + } + + } + } + return false; + } + + @Override + public boolean handleMouseMove(int x, int y) { + NatlCntrsEditor mapEditor = GeoMagWorldActivityResource.getMapEditor(); + if (mapEditor != null) { + // Check if mouse is in geographic extent + Coordinate loc = mapEditor.translateClick(x, y); + if (loc == null) + return false; + + if (resource != null) { + // get the stn (point) list + List points = allStations; + + if (points.isEmpty() == false) { + + // get the stn close to loc "enough" and retrieve text + // report for it + GeoMagStation stnPt = getPtWithinMinDist(points, loc); + + if (stnPt != null) { + resource.sampleCoord = new ReferencedCoordinate(loc); + resource.sampleString = stnPt.getStationCode(); + } else { + resource.sampleCoord = null; + resource.sampleString = null; + } + + } + } + } + + resource.issueRefresh(); + + return false; + } + + /** + * Gets the nearest point of an selected element to the input point + * + * @param el + * element + * @param pt + * input point + * @return + */ + protected GeoMagStation getPtWithinMinDist(List points, + Coordinate pt) { + + GeoMagStation thePoint = null; + double minDistance = geomagStnPointMinDistance; + GeodeticCalculator gc; + NatlCntrsEditor mapEditor = GeoMagWorldActivityResource.getMapEditor(); + if (mapEditor != null) { + IMapDescriptor desc; + desc = (IMapDescriptor) mapEditor.getActiveDisplayPane() + .getRenderableDisplay().getDescriptor(); + + gc = new GeodeticCalculator(desc.getCRS()); + gc.setStartingGeographicPoint(pt.x, pt.y); + + for (GeoMagStation point : points) { + + gc.setDestinationGeographicPoint(point.getLocation() + .getLongitude(), point.getLocation().getLatitude()); + double dist; + try { + dist = gc.getOrthodromicDistance(); + + if (dist < minDistance) { + + minDistance = dist; + thePoint = point; + } + } catch (Exception e) { + // statusHandler.handle(Priority.PROBLEM, + // e.getLocalizedMessage(), e); + } + + } + } + return thePoint; + + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResource.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResource.java new file mode 100644 index 0000000000..e03381e32a --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResource.java @@ -0,0 +1,822 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.Location; +import gov.noaa.nws.ncep.ui.pgen.display.DisplayElementFactory; +import gov.noaa.nws.ncep.ui.pgen.display.IDisplayable; +import gov.noaa.nws.ncep.ui.pgen.elements.Symbol; +import gov.noaa.nws.ncep.ui.pgen.elements.SymbolLocationSet; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.common.staticPointDataSource.LabeledPoint; +import gov.noaa.nws.ncep.viz.resources.manager.ResourceBndlLoader; +import gov.noaa.nws.ncep.viz.rtkp.MagActivityCapability; +import gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpDataBlockWindow; +import gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpRecentKpWindow; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil.GeoMagStationType; +import gov.noaa.nws.ncep.viz.ui.display.NatlCntrsEditor; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; +import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; + +import java.awt.Color; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +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.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +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.VizApp; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapDescriptor; +import com.raytheon.uf.viz.core.map.MapDescriptor; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IInputHandler; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.raytheon.viz.ui.input.EditableManager; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Provides a resource for displaying RTKP world wide mag activity map with + * recent k values. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * May 5, 2014   1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagWorldActivityResource extends + AbstractVizResource { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagWorldActivityResource.class); + + private SimpleDateFormat topLabelSdf = new SimpleDateFormat( + "dd-MMM-yy HH:mm:ss 'UTC'"); + + private static GeoMagWorldActivityResourceData geoMagWorldActResourceData; + + private static GeoMagWorldActivityResource geoMagWorldActResource = null; + + protected GeoMagWorldActivityTitleDateResource topLabelResource = null; + + protected ResourcePair topLabelRscPair = null; + + private List symbolList = null; + + private SymbolLocationSet otherStnSymbolSet = null; + + private List latestKIndexPoints; + + private List labelStrings = null; + + private static NatlCntrsEditor mapEditor = null; + + private IFont font = null; + + private List> latestStnKLst = null; + + private List points = new ArrayList(); + + private List otherStnPt = new ArrayList(); + + private GeoMagRTKpDataBlockWindow dataBlock = null; + + private final GeoMagSampling samplingRsc; + + protected ReferencedCoordinate sampleCoord; + + protected String sampleString; + + private static GeoMagWorldActivityMouseHandler mouseHandler; + + public static NatlCntrsEditor getMapEditor() { + return mapEditor; + } + + public List getOtherStnPt() { + return otherStnPt; + } + + public void setOtherStnPt(List otherStnPt) { + if (otherStnPt == null) + this.otherStnPt.clear(); + else + this.otherStnPt = otherStnPt; + } + + public List getPoints() { + return points; + } + + public void setPoints(List points) { + if (points == null) + this.points.clear(); + else + this.points = points; + } + + public List getLatestKIndexPoints() { + return latestKIndexPoints; + } + + public void setLatestKIndexPoints(List latestKIndexPoints) { + + this.latestKIndexPoints = latestKIndexPoints; + } + + private static void createMapEditor() { + // create an editor MapEditor + if (mapEditor != null) + return; + + try { + + // TODO: what if the active editor is not a Map Editor ? + // should we find one, create one or prompt + // + AbstractEditor ed = NcDisplayMngr.getActiveNatlCntrsEditor(); + + if (NcEditorUtil.getNcDisplayType(ed) == NcDisplayType.NMAP_DISPLAY) { + mapEditor = (NatlCntrsEditor) ed; + } else { + mapEditor = (NatlCntrsEditor) NcDisplayMngr + .createNatlCntrsEditor(NcDisplayType.NMAP_DISPLAY, + "Worldwide Mag Activity Map"); + + // get this to set the editor to 'Worldwide Mag Activity Map' + ResourceBndlLoader rbdLoader = new ResourceBndlLoader( + "Worldwide Mag Activity Map"); + rbdLoader.addDefaultRBD(NcDisplayType.NMAP_RTKP_WORLD_DISPLAY, + mapEditor); + VizApp.runSync(rbdLoader); + } + + } catch (Exception ve) { + statusHandler.handle( + Priority.PROBLEM, + "Could not load initial editor: " + + ve.getLocalizedMessage(), ve); + } + } + + public static GeoMagWorldActivityResource getGeoMagWorldActivityResource() { + if (geoMagWorldActResource == null) { + if (mapEditor == null) + createMapEditor(); + if (mapEditor != null) { + IMapDescriptor desc = (IMapDescriptor) mapEditor + .getActiveDisplayPane().getRenderableDisplay() + .getDescriptor(); + try { + if (geoMagWorldActResourceData == null) + geoMagWorldActResourceData = new GeoMagWorldActivityResourceData(); + geoMagWorldActResource = geoMagWorldActResourceData + .construct(new LoadProperties(), desc); + desc.getResourceList().add(geoMagWorldActResource); + geoMagWorldActResource.init(mapEditor + .getActiveDisplayPane().getTarget()); + + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + return geoMagWorldActResource; + } + + /** + * Default constructor + */ + protected GeoMagWorldActivityResource( + GeoMagWorldActivityResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + getCapability(EditableCapability.class).setEditable(true); + samplingRsc = new GeoMagSampling(); + topLabelSdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + getCapabilities().addCapability(MagActivityCapability.class); + } + + /** + * Called when resource is disposed + * + * @see com.raytheon.viz.core.rsc.IVizResource#dispose() + */ + @Override + public void disposeInternal() { + if (mapEditor != null) { + mapEditor.unregisterMouseHandler(mouseHandler); + mouseHandler = null; + mapEditor = null; + } + if (font != null) { + font.dispose(); + font = null; + } + if (samplingRsc != null) { + samplingRsc.dispose(); + } + + getDescriptor().getResourceList().remove(topLabelRscPair); + + closeAssociatedViews(); + geoMagWorldActResource = null; + geoMagWorldActResourceData = null; + + if (topLabelResource != null) { + topLabelResource.dispose(); + } + super.dispose(); + this.dispose(); + } + + public void registerMouseHandler() { + mouseHandler = getMouseHandler(); + if (mapEditor != null && mouseHandler != null) + mapEditor.registerMouseHandler((IInputHandler) mouseHandler); + } + + public void unregisterMouseHandler() { + mouseHandler = getMouseHandler(); + if (mapEditor != null && mouseHandler != null) + mapEditor.unregisterMouseHandler((IInputHandler) mouseHandler); + } + + @Override + public void propertiesChanged(ResourceProperties updatedProps) { + if (updatedProps.isVisible()) { + reopenAssociatedViews(); + } else { + hideAssociatedViews(); + } + } + + private void hideAssociatedViews() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(RTKpUtil.DATABLOCK_VIEW_ID); + if (wpage.isPartVisible(vpart)) { + GeoMagRTKpDataBlockWindow paletteWin = GeoMagRTKpDataBlockWindow + .getAccess(); + paletteWin.setEditorVisible(false); + wpage.hideView(vpart); + } + vpart = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + if (wpage.isPartVisible(vpart)) { + GeoMagRTKpRecentKpWindow paletteWin = GeoMagRTKpRecentKpWindow + .getAccess(); + paletteWin.setEditorVisible(false); + wpage.hideView(vpart); + } + } + + private void closeAssociatedViews() { + + IWorkbenchWindow win = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (win == null) + return; + IWorkbenchPage wpage = win.getActivePage(); + if (wpage != null) { + IViewPart vpart1 = wpage.findView(RTKpUtil.DATABLOCK_VIEW_ID); + wpage.hideView(vpart1); + + IViewPart vpart2 = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + wpage.hideView(vpart2); + } + + NcDisplayMngr.setPanningMode(); + } + + private void reopenAssociatedViews() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(RTKpUtil.DATABLOCK_VIEW_ID); + if (!wpage.isPartVisible(vpart)) { + GeoMagRTKpDataBlockWindow paletteWin = GeoMagRTKpDataBlockWindow + .getAccess(); + paletteWin.setEditorVisible(true); + try { + vpart = wpage.showView(RTKpUtil.DATABLOCK_VIEW_ID); + } catch (Exception e) { + e.printStackTrace(); + } + } + + vpart = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + if (!wpage.isPartVisible(vpart)) { + GeoMagRTKpRecentKpWindow paletteWin = GeoMagRTKpRecentKpWindow + .getAccess(); + paletteWin.setEditorVisible(true); + try { + vpart = wpage.showView(RTKpUtil.DATABLOCK_VIEW_ID); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.core.rsc.IVizResource#getCoordinateReferenceSystem() + */ + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + + if (descriptor == null) + return null; + + return descriptor.getCRS(); + + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.core.rsc.IVizResource#getName() + */ + @Override + public String getName() { + + return "Worldwide Mag Activity Map"; + + } + + public void init(GeoMagRTKpDataBlockWindow dataBlock) { + + this.dataBlock = dataBlock; + + if (topLabelRscPair == null && topLabelResource == null) { + topLabelRscPair = ResourcePair + .constructSystemResourcePair(new GeoMagWorldActivityTitleDateResourceData()); + + getDescriptor().getResourceList().add(topLabelRscPair); + getDescriptor().getResourceList().instantiateResources( + getDescriptor(), true); + + topLabelResource = (GeoMagWorldActivityTitleDateResource) topLabelRscPair + .getResource(); + } + + // register mouse handler + registerMouseHandler(); + + if (dataBlock.isShowKpOnly() + || dataBlock.getkType().equals(RTKpUtil.KS_PLOT)) { + points = RTKpUtil.getGeoMagStations(GeoMagStationType.KP); + otherStnPt = RTKpUtil.getGeoMagStations(GeoMagStationType.NON_KP); + } else { + points = RTKpUtil.getGeoMagStations(GeoMagStationType.K); + otherStnPt = RTKpUtil.getGeoMagStations(GeoMagStationType.NON_K); + } + + List stnCodes = RTKpUtil + .getGeoMagStationCodes(GeoMagStationType.ALL); + try { + latestStnKLst = RTKpUtil.getLatestEstKIndex(stnCodes, null, null); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + " Error while retrieving latest est k index. Exception: " + + e.getLocalizedMessage(), e); + } + + try { + latestKIndexPoints = createKIndexLabelPointData(points); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.core.rsc.IVizResource#init(com.raytheon.viz.core. + * IGraphicsTarget) + */ + @Override + public void initInternal(IGraphicsTarget target) throws VizException { + // EditableManager.makeEditable(this, + // getCapability(EditableCapability.class).isEditable()); + + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.core.rsc.IVizResource#isApplicable(com.raytheon.viz. + * core.PixelExtent) + */ + public boolean isApplicable(PixelExtent extent) { + + return true; + + } + + private void generateSymbolForDrawing() { + String type; + float lineWidth = resourceData.getMarkerWidth(); + + Boolean clear = false; + + String category = new String("Marker"); + double sizeScale = getCapabilities().getCapability(resourceData, + MagActivityCapability.class).getMarkerSize(); + + if (RTKpUtil.KS_PLOT.equals(dataBlock.getkType())) { + sizeScale += 0.7; + } + + if (points.isEmpty() == true) { + symbolList = null; + } else { + + symbolList = new ArrayList(points.size()); + + Coordinate[] locations = new Coordinate[points.size()]; + Color[] colors = new Color[points.size()]; + + HashMap> latestStnsKMap = new HashMap>(); + for (int i = 0; i < latestStnKLst.size(); i++) { + latestStnsKMap.put( + (String) latestStnKLst.get(i).get("stationcode"), + latestStnKLst.get(i)); + } + + int i = 0; + + for (GeoMagStation p : points) { + Location loc = p.getLocation(); + double lon, lat; + lon = loc.getLongitude(); + lat = loc.getLatitude(); + + Map stnKMap = latestStnsKMap.get(p + .getStationCode()); + if (stnKMap != null) { + Integer k = (Integer) stnKMap.get("kestindex"); + Float ks = (Float) stnKMap.get("ks"); + + if (RTKpUtil.KS_PLOT.equals(dataBlock.getkType())) { + k = ks.intValue(); + } + colors[i] = getCapabilities().getCapability(resourceData, + MagActivityCapability.class).getNOAAScaleColors()[k]; + + } else { + colors[i] = getCapabilities().getCapability(resourceData, + MagActivityCapability.class).getNOAAScaleColors()[0]; + } + + locations[i] = new Coordinate(lon, lat); + + symbolList.add(new Symbol(null, new Color[] { colors[i] }, + lineWidth, sizeScale, clear, locations[i], category, + "FILLED_CIRCLE")); + i++; + + } + + } + if (otherStnPt.isEmpty() == true) { + otherStnSymbolSet = null; + } else { + // SymbolLocationSet constructor requires a positive-length array of + // Coordinate + Coordinate[] locations = new Coordinate[otherStnPt.size()]; + + int i = 0; + for (GeoMagStation p : otherStnPt) { + Location loc = p.getLocation(); + double lon, lat; + lon = loc.getLongitude(); + lat = loc.getLatitude(); + locations[i++] = new Coordinate(lon, lat); + } + + RGB nonNwMarkerColor = getCapabilities().getCapability( + resourceData, MagActivityCapability.class) + .getNonNetwrkStnColor(); + Color[] colors = new Color[] { new Color(nonNwMarkerColor.red, + nonNwMarkerColor.green, nonNwMarkerColor.blue) }; + type = resourceData.getOtherStnMarkerType().toString(); + + otherStnSymbolSet = new SymbolLocationSet(null, colors, lineWidth, + sizeScale + 0.5, clear, locations, category, type); + + } + + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.core.drawables.IRenderable#paint(com.raytheon.viz.core + * .IGraphicsTarget, com.raytheon.viz.core.drawables.PaintProperties) + */ + @Override + public void paintInternal(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + // if the Kindices colors are changed, redraw the text in the + // "Recent Kp Estimates" block + if (!Arrays.equals( + this.dataBlock.getKindicesColors(), + getCapabilities().getCapability(resourceData, + MagActivityCapability.class).getNOAAScaleRGBColors())) { + this.dataBlock.setKindicesColors(getCapabilities().getCapability( + resourceData, MagActivityCapability.class) + .getNOAAScaleRGBColors()); + this.dataBlock.setKp_last10_colors(); + RTKpUtil.showRecentKpEstBlock(this.dataBlock); + } + + if (font == null + || resourceData.getMarkerTextSize() != getCapabilities() + .getCapability(resourceData, + MagActivityCapability.class) + .getMarkerTextSize()) { + + font = target.initializeFont( + "Monospace", + (float) (12 * getCapabilities() + .getCapability(resourceData, + MagActivityCapability.class) + .getMarkerTextSize().getSoftwareSize()), null); + + font.setSmoothing(false); + font.setScaleFont(false); + resourceData.setMarkerTextSize(getCapabilities().getCapability( + resourceData, MagActivityCapability.class) + .getMarkerTextSize()); + } + + // paintTopLabels(target, paintProps); + + generateSymbolForDrawing(); + + if (symbolList != null) { + + DisplayElementFactory df = new DisplayElementFactory(target, + this.descriptor); + + for (Symbol symbol : symbolList) { + ArrayList elements = df.createDisplayElements( + symbol, paintProps); + for (IDisplayable each : elements) { + try { + each.draw(target, paintProps); + each.dispose(); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + if (otherStnSymbolSet != null) { + + DisplayElementFactory df = new DisplayElementFactory(target, + this.descriptor); + ArrayList elements = df.createDisplayElements( + otherStnSymbolSet, paintProps); + for (IDisplayable each : elements) { + try { + each.draw(target, paintProps); + each.dispose(); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + double offsetX = 0.0;// charWidth / 2.0 / screenToWorldRatio; + double offsetY = 0.0;// charHeight / screenToWorldRatio; + + labelStrings = new ArrayList(); + + if (latestKIndexPoints != null) { + + for (LabeledPoint lp : latestKIndexPoints) { + double[] latlon = new double[] { lp.getLongitude(), + lp.getLatitude() }; + double[] pix = this.descriptor.worldToPixel(latlon); + if (pix == null) { + continue; + } + if (paintProps.getView().isVisible(pix)) { + + String lpStr = lp.getName(); + double k_val = Double.parseDouble(lpStr); + + int k_val_int = (int) k_val; + if (k_val_int > 9) { + k_val_int = 0; + } + + RGB color = getCapabilities().getCapability(resourceData, + MagActivityCapability.class) + .getkIndicesTextColors()[k_val_int]; + + DrawableString drawStr = new DrawableString(lp.getName(), + color); + drawStr.font = font; + drawStr.setCoordinates(pix[0] + offsetX, pix[1] + offsetY); + drawStr.horizontalAlignment = HorizontalAlignment.CENTER; + drawStr.verticallAlignment = VerticalAlignment.MIDDLE; + drawStr.textStyle = TextStyle.NORMAL; + labelStrings.add(drawStr); + } + } + + // } + + if (labelStrings != null) { + target.drawStrings(labelStrings); + } + + } + if (sampleCoord != null) { + + samplingRsc + .paintResult(target, descriptor, paintProps, sampleCoord); + } + + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#inspect(com.raytheon + * .uf.common.geospatial.ReferencedCoordinate) + */ + @Override + public String inspect(ReferencedCoordinate coord) throws VizException { + + if (coord == null) + return "No Data"; + if (sampleString == null) + return ""; + + StringBuilder sb = new StringBuilder(); + + sb.append(sampleString); + + for (int i = 0; i < latestStnKLst.size(); i++) { + + Map map = latestStnKLst.get(i); + + String stnCode = (String) map.get("stationcode"); + + if (stnCode.equals(sampleString)) { + Date reftime = (Date) map.get("reftime"); + + sb.append(" (Latest Data " + reftime + ")"); + } + } + + return sb.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.core.rsc.capabilities.IProjectableResource#isProjectable + * (org.opengis.referencing.crs.CoordinateReferenceSystem) + */ + public boolean isProjectable(CoordinateReferenceSystem mapData) { + + return true; + + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.core.rsc.capabilities.IProjectableResource#project(org + * .opengis.referencing.crs.CoordinateReferenceSystem) + */ + @Override + public void project(CoordinateReferenceSystem mapData) throws VizException { + + } + + private GeoMagWorldActivityMouseHandler getMouseHandler() { + + if (mouseHandler == null) { + mouseHandler = new GeoMagWorldActivityMouseHandler(this); + } + + return mouseHandler; + } + + /** + * Check if the resource is currently editable + * + * @return editable + */ + public boolean isEditable() { + return getCapability(EditableCapability.class).isEditable(); + } + + public void setEditable(boolean enable) { + getCapability(EditableCapability.class).setEditable(enable); + EditableManager.makeEditable(this, + getCapability(EditableCapability.class).isEditable()); + } + + public GeoMagRTKpDataBlockWindow getDataBlock() { + return dataBlock; + } + + public void setDataBlock(GeoMagRTKpDataBlockWindow dataBlock) { + this.dataBlock = dataBlock; + } + + public List createKIndexLabelPointData( + List stns) { + + List stnPoints = new ArrayList(); + HashMap kStnMap = new HashMap(); + for (int i = 0; i < points.size(); i++) { + kStnMap.put(points.get(i).getStationCode(), points.get(i)); + } + + for (int i = 0; i < latestStnKLst.size(); i++) { + Map map = latestStnKLst.get(i); + GeoMagStation stn = kStnMap.get(map.get("stationcode")); + + if (stn != null) { + Integer k = (Integer) map.get("kestindex"); + Float ks = (Float) map.get("ks"); + Date reftime = (Date) map.get("reftime"); + + String displayStr = k.toString(); + if (RTKpUtil.KS_PLOT.equals(dataBlock.getkType())) { + displayStr = String.format("%.1f", ks); + } + LabeledPoint lp = new LabeledPoint(displayStr, stn + .getLocation().getLatitude(), stn.getLocation() + .getLongitude()); + lp.addLabel("k_est", "k"); + stnPoints.add(lp); + } + } + + return stnPoints; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResourceData.java new file mode 100644 index 0000000000..a39b54a030 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityResourceData.java @@ -0,0 +1,209 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerState; +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerTextSize; +import gov.noaa.nws.ncep.viz.common.ui.Markers.MarkerType; + +import org.eclipse.swt.graphics.RGB; + +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; + +/** + * Resource data for RTKP world wide mag activity map. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#    Engineer    Description
+ * ------------  ---------- ----------- --------------------------
+ * May 5, 2014   1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagWorldActivityResourceData extends AbstractResourceData { + + private RGB color = new RGB(0, 255, 0); + + private MarkerState markerState = MarkerState.MARKER_PLUS_TEXT; + + private MarkerType markerType = MarkerType.BOX; + + private RGB otherStncolor = new RGB(157, 114, 50); + + private MarkerState otherStnMarkerState = MarkerState.MARKER_PLUS_TEXT; + + private MarkerType otherStnMarkerType = MarkerType.FILLED_TRIANGLE; + + private Float markerSize = 1.3f; + + private Integer markerWidth = 2; + + private MarkerTextSize markerTextSize = MarkerTextSize.MEDIUM; + + private String mapName = "GEOMAGWORLDACTIVITY"; + + public GeoMagWorldActivityResourceData() { + super(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.comm.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public GeoMagWorldActivityResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new GeoMagWorldActivityResource(this, loadProperties); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + // do nothing + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof GeoMagWorldActivityResourceData)) + return false; + GeoMagWorldActivityResourceData rdata = (GeoMagWorldActivityResourceData) obj; + if (this.markerState.equals(rdata.getMarkerState()) + && this.markerType.equals(rdata.getMarkerType()) + && this.markerSize.equals(rdata.getMarkerSize()) + && this.markerWidth.equals(rdata.getMarkerWidth()) + && this.markerTextSize.equals(rdata.getMarkerTextSize()) + && this.markerWidth.equals(rdata.getMarkerWidth()) + && this.otherStnMarkerState.equals(rdata + .getOtherStnMarkerState()) + && this.otherStnMarkerType + .equals(rdata.getOtherStnMarkerType()) + && this.otherStncolor.equals(rdata.getOtherStncolor()) + && this.color.equals(rdata.getColor())) + return true; + return false; + } + + public RGB getColor() { + return color; + } + + public void setColor(RGB kStnColor) { + this.color = kStnColor; + } + + public MarkerState getMarkerState() { + return markerState; + } + + public void setMarkerState(MarkerState markerState) { + this.markerState = markerState; + } + + public MarkerType getMarkerType() { + return markerType; + } + + public void setMarkerType(MarkerType markerType) { + this.markerType = markerType; + } + + public Float getMarkerSize() { + return markerSize; + } + + public void setMarkerSize(Float markerSize) { + this.markerSize = markerSize; + } + + public Integer getMarkerWidth() { + return markerWidth; + } + + public void setMarkerWidth(Integer markerWidth) { + this.markerWidth = markerWidth; + } + + public MarkerTextSize getMarkerTextSize() { + return markerTextSize; + } + + public void setMarkerTextSize(MarkerTextSize markerTextSize) { + this.markerTextSize = markerTextSize; + } + + public String getMapName() { + return mapName; + } + + public void setMapName(String mapName) { + this.mapName = mapName; + } + + public MarkerState getkStnMarkerState() { + return markerState; + } + + public void setkStnMarkerState(MarkerState kStnMarkerState) { + this.markerState = kStnMarkerState; + } + + public MarkerType getkStnMarkerType() { + return markerType; + } + + public void setkStnMarkerType(MarkerType kStnMarkerType) { + this.markerType = kStnMarkerType; + } + + public RGB getOtherStncolor() { + return otherStncolor; + } + + public void setOtherStncolor(RGB otherStncolor) { + this.otherStncolor = otherStncolor; + } + + public MarkerState getOtherStnMarkerState() { + return otherStnMarkerState; + } + + public void setOtherStnMarkerState(MarkerState otherStnMarkerState) { + this.otherStnMarkerState = otherStnMarkerState; + } + + public MarkerType getOtherStnMarkerType() { + return otherStnMarkerType; + } + + public void setOtherStnMarkerType(MarkerType otherStnMarkerType) { + this.otherStnMarkerType = otherStnMarkerType; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResource.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResource.java new file mode 100644 index 0000000000..0b816cd2f6 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResource.java @@ -0,0 +1,152 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource; +import gov.noaa.nws.ncep.viz.rtkp.util.RTKpUtil; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +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.RGBColors; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapDescriptor; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer     Description
+ * ------------ ----------  -----------  --------------------------
+ * 08/26/14     #4078       Shova Gurung Initial Creation.
+ * 
+ * 
+ * 
+ * + * @author sgurung + * @version 1 + */ +public class GeoMagWorldActivityTitleDateResource + extends + AbstractVizResource + implements INatlCntrsResource, PropertyChangeListener { + + private SimpleDateFormat topLabelSdf = new SimpleDateFormat( + "dd-MMM-yy HH:mm:ss 'UTC'"); + + private IFont font = null; + + private IGraphicsTarget currTarget = null; + + private PaintProperties currPaintProps = null; + + public GeoMagWorldActivityTitleDateResource( + GeoMagWorldActivityTitleDateResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + rscData = resourceData; + } + + GeoMagWorldActivityTitleDateResourceData rscData; + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + topLabelSdf.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + currTarget = target; + currPaintProps = paintProps; + + if (font == null) { + font = target.initializeFont(rscData.getFontName(), + 1.5f * rscData.getFontSize(), null); + if (font == null) { + font = target.initializeFont(target.getDefaultFont() + .getFontName(), 1.5f * rscData.getFontSize(), null); + } + font.setScaleFont(false); + font.setSmoothing(false); + } + + currTarget.clearClippingPlane(); + + IExtent pixExtents = paintProps.getView().getExtent(); + double pixExtentsMinX = pixExtents.getMinX(); + double pixExtentsMaxX = pixExtents.getMaxX(); + double pixExtentsMinY = pixExtents.getMinY(); + double pixExtentsMaxY = pixExtents.getMaxY(); + double pixExtentsWidth = pixExtents.getWidth(); + double pixExtentsHeight = pixExtents.getHeight(); + + double minX = 0, maxX = 0; + double minY = 0, maxY = 0; + + double xScaleFactor = pixExtentsWidth + / (double) paintProps.getCanvasBounds().width; + double yScaleFactor = pixExtentsHeight + / (double) paintProps.getCanvasBounds().height; + + minX = pixExtentsMinX + pixExtentsWidth * 0.005; + minY = pixExtentsMinY + pixExtentsHeight * 0.05; + + double yMargin = 2 * yScaleFactor; + + double textX = minX; + double textY = minY - yMargin * 3; + + currTarget.drawString(font, rscData.getTitle(), textX, textY, 0, + IGraphicsTarget.TextStyle.NORMAL, + RGBColors.getRGBColor("white"), HorizontalAlignment.LEFT, 0.0); + + maxX = pixExtentsMaxX - pixExtentsWidth * 0.005; + minY = pixExtentsMinY + pixExtentsHeight * 0.05; + + textX = maxX; + textY = minY - yMargin * 3; + + currTarget.drawString(font, + topLabelSdf.format(RTKpUtil.getCurrentTime()), textX, textY, 0, + IGraphicsTarget.TextStyle.NORMAL, + RGBColors.getRGBColor("white"), HorizontalAlignment.RIGHT, 0.0); + + currTarget.setupClippingPlane(currPaintProps.getClippingPane()); + } + + @Override + protected void disposeInternal() { + if (font != null) { + font.dispose(); + font = null; + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + } + + @Override + public void resourceAttrsModified() { + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResourceData.java new file mode 100644 index 0000000000..3ce72dbe38 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/rsc/GeoMagWorldActivityTitleDateResourceData.java @@ -0,0 +1,140 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.rsc; + +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResourceData; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 08/26/14     #4078       Shova Gurung Initial Creation.
+ * 
+ * 
+ * 
+ * + * @author sgurung + * @version 1 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "geoMagWorldActivityTitleDateResourceData") +public class GeoMagWorldActivityTitleDateResourceData extends + AbstractNatlCntrsResourceData { + + @XmlElement + private Integer fontSize; + + @XmlElement + private String fontName; + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + private RGB color = null; + + private RGB dfltColor = new RGB(255, 255, 255); + + private String title = null; + + @Override + public AbstractVizResource constructResource( + LoadProperties loadProperties, IDescriptor descriptor) + throws VizException { + return new GeoMagWorldActivityTitleDateResource(this, loadProperties); + } + + public RGB getColor() { + return (color == null ? dfltColor : color); + } + + public void setColor(RGB _color) { + color = _color; + } + + public String getFontName() { + return fontName; + } + + public void setFontName(String fontName) { + this.fontName = fontName; + } + + public Integer getFontSize() { + return (fontSize == null ? 12 : fontSize); + } + + public void setFontSize(Integer fs) { + this.fontSize = fs; + } + + // default no-arg required to serialize + public GeoMagWorldActivityTitleDateResourceData() { + title = "Geomagnetic Activity Map"; + } + + public GeoMagWorldActivityTitleDateResourceData(String title) { + this.title = title; + } + + @Override + public AbstractVizResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new GeoMagWorldActivityTitleDateResource(this, loadProperties); + } + + @Override + public void update(Object updateData) { + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object obj) { + if (!super.equals(obj)) { + return false; + } + + if (obj instanceof GeoMagWorldActivityTitleDateResourceData == false) { + return false; + } + + GeoMagWorldActivityTitleDateResourceData other = (GeoMagWorldActivityTitleDateResourceData) obj; + if (this.title == other.getTitle() + && this.getFontName() == other.getFontName() + && this.getFontSize() == other.getFontSize() + && this.getColor() == other.getColor()) { + return true; + + } + + return false; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/GeoMagTimeSeriesDataException.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/GeoMagTimeSeriesDataException.java new file mode 100644 index 0000000000..592c7df370 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/GeoMagTimeSeriesDataException.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 gov.noaa.nws.ncep.viz.rtkp.util; + +/** + * Exception used for problems retrieving RTKP data from EDEX datastores. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2014 1122           sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class GeoMagTimeSeriesDataException extends Exception { + + private static final long serialVersionUID = 1L; + + public GeoMagTimeSeriesDataException() { + } + + /** + * @param message + */ + public GeoMagTimeSeriesDataException(String message) { + super(message); + } + + /** + * @param cause + */ + public GeoMagTimeSeriesDataException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public GeoMagTimeSeriesDataException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpTimeSeriesZoomHandler.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpTimeSeriesZoomHandler.java new file mode 100644 index 0000000000..21971497a9 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpTimeSeriesZoomHandler.java @@ -0,0 +1,46 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.util; + +import org.eclipse.swt.widgets.Event; + +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.xy.timeseries.util.TimeSeriesZoomHandler; + +/** + * This class has been extended from raytheon's TimeSeriesZoomHandler class in + * order to override the handleMouseWheel() behavior so that zooming is disabled + * for RTKp graphs. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 09/02/14     #4078       Shova Gurung Initial Creation.
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ + +public class RTKpTimeSeriesZoomHandler extends TimeSeriesZoomHandler { + + public RTKpTimeSeriesZoomHandler(IRenderableDisplay display) { + super(display); + } + + @Override + public boolean handleMouseWheel(Event event, int x, int y) { + return false; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpUtil.java b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpUtil.java new file mode 100644 index 0000000000..2b5c1a3319 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rtkp/src/gov/noaa/nws/ncep/viz/rtkp/util/RTKpUtil.java @@ -0,0 +1,1136 @@ +/** + * This code has unlimited rights, and is provided "as is" by the National Centers + * for Environmental Prediction, without warranty of any kind, either expressed or implied, + * including but not limited to the implied warranties of merchantability and/or fitness + * for a particular purpose. + * + * This code has been developed by the NCEP-SIB for use in the AWIPS2 system. + * + **/ +package gov.noaa.nws.ncep.viz.rtkp.util; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.ChangeStationStateRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveGeoMagDataRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveGeoMagDataRequest.RetrieveGeoMagDataRequestType; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveK1minRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveK1minRequest.RetrieveK1minRequestType; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveStationStateRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStation; +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.GeoMagStationList; +import gov.noaa.nws.ncep.common.dataplugin.geomag.util.GeoMagStationLookup; +import gov.noaa.nws.ncep.viz.localization.NcPathManager; +import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; +import gov.noaa.nws.ncep.viz.rtkp.Activator; +import gov.noaa.nws.ncep.viz.rtkp.controls.GeoMagAnalysisPlotDlg; +import gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpDataBlockWindow; +import gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpRecentKpWindow; +import gov.noaa.nws.ncep.viz.rtkp.rsc.GeoMagWorldActivityResource; + +import java.awt.Color; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; + +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; +import com.raytheon.uf.common.geospatial.MapUtil; +import com.raytheon.uf.common.serialization.comm.RequestRouter; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; +import com.raytheon.viz.ui.VizWorkbenchManager; +//import gov.noaa.nws.ncep.viz.resources.manager.NcBundleLoader; +//import gov.noaa.nws.ncep.viz.resources.manager.ResourceBndlLoader2; + +/** + * + * Utility class for RTKP. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 22, 2014 1122       sgurung     Initial creation
+ * 
+ * 
+ * + * @author sgurung + * @version 1.0 + */ +public class RTKpUtil { + + private static final String GEOMAGDATA_ERROR = "GeoMag Time Series Data Util Exception"; + + /* + * Geomag Data Block view ID is also defined in plugin.xml. + */ + public static final String DATABLOCK_VIEW_ID = "gov.noaa.nws.ncep.viz.rtkp.GEOMAGRTKPDATABLOCK"; + + /* + * Geomag Recent Kp view ID is also defined in plugin.xml. + */ + public static final String RECENTKP_VIEW_ID = "gov.noaa.nws.ncep.viz.rtkp.GEOMAGRTKPRECENTKP"; + + /** Path to geoMagStations.xml file. */ + public static final String GEOMAGSTATIONS_FILE_NAME = "ncep" + + File.separator + "geomag" + File.separator + "geoMagStations.xml"; + + /* + * Lookup table to convert floating point to easy read format + */ + public static String[] KpLu = { "0o", "0+", "1-", "1o", "1+", "2-", "2o", + "2+", "3-", "3o", "3+", "4-", "4o", "4+", "5-", "5o", "5+", "6-", + "6o", "6+", "7-", "7o", "7+", "8-", "8o", "8+", "9-", "9o" }; + + public static enum GeoMagStationType { + ALL, K, NON_K, KP, NON_KP + } + + public static final String KS_PLOT = "Ks"; + + public static final String KP_PLOT = "Kp"; + + /** + * Returns color for a given station count index from the list of colors + * provided
+ * + * @param index + * @param colors + * @return RGB object + */ + public static RGB getStationCountColor(int index, RGB[] colors) { + + int numStations = RTKpUtil.getGeoMagStationCodes(GeoMagStationType.KP) + .size(); + + // color table - keyed to the number of stations + RGB colorTable[] = new RGB[numStations + 1]; + colorTable[numStations] = colors[8]; + if (numStations > 1) { + colorTable[numStations - 1] = colors[1]; + } + if (numStations > 2) { + colorTable[numStations - 2] = colors[2]; + } + if (numStations > 3) { + colorTable[numStations - 3] = colors[3]; + } + if (numStations > 4) { + colorTable[numStations - 4] = colors[4]; + } + if (numStations > 5) { + colorTable[numStations - 5] = colors[5]; + } + if (numStations > 6) { + colorTable[numStations - 6] = colors[6]; + } + if (numStations > 7) { + for (int i = numStations - 7; i > 0; i--) { + colorTable[i] = colors[7]; + } + } + + colorTable[0] = colors[0]; + + return colorTable[index]; + } + + /** + * Retrieves a GeoMagK1min record for a given station code and reftime.
+ * + * @param stationCode + * Station Code + * @param refTime + * Reference time + * @return GeoMagK1min object + * @throws GeoMagTimeSeriesDataException + */ + public static GeoMagK1min retrieveK1minRecord(String stationCode, + Date refTime) throws GeoMagTimeSeriesDataException { + + RetrieveK1minRequest req = new RetrieveK1minRequest(stationCode, + refTime, null); + GeoMagK1min record = null; + try { + Object rslts = ThriftClient.sendRequest(req); + + if (rslts != null && rslts instanceof List) { + ArrayList rsltsList = (ArrayList) rslts; + if (rsltsList != null && rsltsList.size() > 0) + record = rsltsList.get(0); + } + } catch (Exception e) { + throw new GeoMagTimeSeriesDataException( + "Error during retrieval request.", e); + } + + return record; + } + + /** + * Retrieves list of GeoMagK1min records for a given stationcode, start date + * and end date.
+ * + * @param stationCode + * A station code + * @param startTime + * start date + * @param endTime + * end date + * @return List of GeoMagK1min records + * @throws GeoMagTimeSeriesDataException + */ + public static List retrieveStationK1minRecords( + String stationCode, Date startTime, Date endTime) + throws GeoMagTimeSeriesDataException { + + RetrieveK1minRequest req = new RetrieveK1minRequest(stationCode, + startTime, endTime); + List rsltsList = new ArrayList(); + try { + Object rslts = ThriftClient.sendRequest(req); + + if (rslts != null && rslts instanceof List) { + rsltsList = (ArrayList) rslts; + } + } catch (Exception e) { + throw new GeoMagTimeSeriesDataException( + "Error during retrieval request.", e); + } + + return rsltsList; + } + + /** + * Retrieves list of GeoMagK1min records for a list of station codes, start + * date and end date.
+ * + * @param stationCodes + * A list of station codes + * @param startTime + * start date + * @param endTime + * end date + * @return List of GeoMagK1min records + * @throws GeoMagTimeSeriesDataException + */ + public static List getEstKIndex1min(List stationCodes, + Date startTime, Date endTime) throws GeoMagTimeSeriesDataException { + + RetrieveK1minRequest req = new RetrieveK1minRequest(stationCodes, + startTime, endTime, RetrieveK1minRequestType.K); + List rsltsList = new ArrayList(); + try { + Object rslts = ThriftClient.sendRequest(req); + + if (rslts != null && rslts instanceof List) { + rsltsList = (ArrayList) rslts; + } + } catch (Exception e) { + throw new GeoMagTimeSeriesDataException( + "Error during retrieval request.", e); + } + + return rsltsList; + } + + /** + * Retrieves list of maps containing kp estimates data for a a given start + * date and end date.
+ * + * @param startTime + * start date + * @param endTime + * end date + * @return List of maps containing data + * @throws GeoMagTimeSeriesDataException + */ + public static List> getEstKpIndex1min(Date startTime, + Date endTime) throws GeoMagTimeSeriesDataException { + + SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss"); + f.setTimeZone(TimeZone.getTimeZone("GMT")); + + RetrieveK1minRequest request = new RetrieveK1minRequest(null, + startTime, endTime, RetrieveK1minRequestType.KP); + List> rsltsList = new ArrayList>(); + + DbQueryResponse response = null; + try { + response = (DbQueryResponse) RequestRouter.route(request); + } catch (Exception e) { + throw new GeoMagTimeSeriesDataException( + "Error during geomag data retrieval request." + + e.getLocalizedMessage(), e); + } + + if (response != null) { + rsltsList = response.getResults(); + int rsltsListSize = (rsltsList != null) ? rsltsList.size() : 0; + + List> newRsltsList = new ArrayList>(); + + for (int i = 0; i < rsltsListSize; i++) { + Map map = rsltsList.get(i); + Double ks_avg = (Double) map.get("ks_avg"); + Double Kp_est = (double) Math.round(3 * ks_avg) / 3.0; + + map.put("Kp_est", Kp_est); + newRsltsList.add(map); + } + + rsltsList = newRsltsList; + } + + return rsltsList; + } + + /** + * Retrieves the last data date among data from kp stations
+ * + * @param startTime + * start date + * @param endTime + * end date + * @return lastDataDate + * @throws GeoMagTimeSeriesDataException + */ + public static Date getKpStationsLastDataDate(Date startTime, Date endTime) + throws VizException { + + RetrieveK1minRequest request = new RetrieveK1minRequest( + getGeoMagStationCodes(GeoMagStationType.KP), startTime, + endTime, RetrieveK1minRequestType.LAST_DATA_DATE); + Date lastDataDate = new Date(); + + try { + Object rslt = ThriftClient.sendRequest(request); + + if (rslt != null && rslt instanceof Date) { + lastDataDate = (Date) rslt; + } + } catch (Exception e) { + throw new VizException("Error while retrieving last data date." + + e.getLocalizedMessage(), e); + } + + return lastDataDate; + } + + /** + * Save GeoMagStationList to xml file.
+ * + * @param sfstnlist + * GeoMagStationList containing list of stations + */ + public static void saveGeoMagStationList(GeoMagStationList sfstnlist) + throws VizException { + + try { + GeoMagStationLookup.getInstance().saveGeoMagStationList(sfstnlist); + } catch (Exception e) { + throw new VizException( + " Exception while saving geoMagStations.xml file: " + + e.getMessage()); + } + + } + + /** + * Save a list of GeoMagStations to xml file.
+ * + * @param stns + * List of GeoMagStations + */ + public static void saveGeoMagStations(List stns) + throws VizException { + + List allStations = RTKpUtil + .getGeoMagStations(GeoMagStationType.ALL); + List stnsToSave = new ArrayList(); + + HashMap stnMap = new HashMap(); + + if (stns != null) { + for (int i = 0; i < stns.size(); i++) { + stnMap.put(stns.get(i).getStationCode(), stns.get(i)); + } + } + if (allStations != null && !allStations.isEmpty()) { + for (int i = 0; i < allStations.size(); i++) { + GeoMagStation stn = (GeoMagStation) allStations.get(i); + if (stnMap.containsKey(stn.getStationCode())) { + // stn.setKpState(stnMap.get(stn.getStationCode()) + // .getKpState()); + stnsToSave.add(stn); + } else { + stnsToSave.add(stn); + } + } + } else { + stnsToSave = stns; + } + + GeoMagStationList stnlist = new GeoMagStationList( + (ArrayList) stnsToSave); + + try { + saveGeoMagStationList(stnlist); + } catch (Exception e) { + throw new VizException( + " Exception while saving geoMagStations.xml file: " + + e.getMessage()); + } + + } + + /** + * Sets up an eclipse Command and ExecuteEvent for a registered commandId, + * and then executes it. + * + * @param commandId + * Command id + */ + public static void exeCommand(String commandId) { + + IEditorPart part = VizWorkbenchManager.getInstance().getActiveEditor(); + + if (part != null) { + ICommandService service = (ICommandService) part.getSite() + .getService(ICommandService.class); + Command cmd = service.getCommand(commandId); + + if (cmd != null) { + + try { + + ExecutionEvent exec = new ExecutionEvent(cmd, + new HashMap(), null, null); + + // Execute the handler + cmd.executeWithChecks(exec); + + } catch (Exception e) { + // Error executing Handler + + e.printStackTrace(); + String msg = "Could not draw the window"; + ErrorDialog.openError( + Display.getCurrent().getActiveShell(), + "Error Activating one of RTKp's Window" + " Tool", + msg, new Status(Status.ERROR, Activator.PLUGIN_ID, + msg, e)); + } + } + } + } + + /** + * Displays the data block for RTKP. + * + * @param startTime + * start date + * @param endTime + * end date + */ + public static void showDataBlock(Date startTime, Date endTime) { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + IViewPart vpart = wpage.findView(RTKpUtil.DATABLOCK_VIEW_ID); + if (vpart == null) { + exeCommand("gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpDataBlockAction"); + } + + GeoMagRTKpDataBlockWindow rtkpDataBlockWindow = GeoMagRTKpDataBlockWindow + .getAccess(); + if (rtkpDataBlockWindow != null) { + rtkpDataBlockWindow.setEndTime(endTime); + rtkpDataBlockWindow.setStartTime(startTime); + rtkpDataBlockWindow.displayDataBlock(); + // showRecentKpEstBlock(rtkpDataBlockWindow); + } + } + + /** + * Displays the recent Kp estimates block for RTKP. + * + * @param rtkpDataBlockWindow + * GeoMagRTKpDataBlockWindow + */ + public static void showRecentKpEstBlock( + GeoMagRTKpDataBlockWindow rtkpDataBlockWindow) { + + String perspective = getPerspective(); + + // display the recent kp estimates view only in NCP + if (perspective != null && perspective.contains("NCP")) { + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + IViewPart vpart = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + if (vpart == null) { + exeCommand("gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpRecentKpAction"); + } + + GeoMagRTKpRecentKpWindow rtkpRecentKpWindow = GeoMagRTKpRecentKpWindow + .getAccess(); + if (rtkpRecentKpWindow != null && rtkpDataBlockWindow != null) { + rtkpRecentKpWindow.displayRecentKpEstimates( + rtkpDataBlockWindow.getKp_last10_text(), + rtkpDataBlockWindow.getKp_last10_color(), + rtkpDataBlockWindow.getRecentKpEstTitleColor()); + } + } + } + + public static String getPerspective() { + IWorkbenchWindow window = VizWorkbenchManager.getInstance() + .getCurrentWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + IPerspectiveDescriptor desc = page.getPerspective(); + if (desc != null) { + return desc.getId(); + } + } + } + return null; + } + + /** + * Displays the recent Kp estimates block for RTKP. + * + * @param kp_last10_text + * kp_last10_text + * @param kp_last10_color + * kp_last10_color + * @param titleColor + * titleColor + */ + public static void showRecentKpEstBlock(List kp_last10_text, + List kp_last10_color, Color titleColor) { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + IViewPart vpart = wpage.findView(RTKpUtil.RECENTKP_VIEW_ID); + if (vpart == null) { + exeCommand("gov.noaa.nws.ncep.viz.rtkp.palette.GeoMagRTKpRecentKpAction"); + } + + GeoMagRTKpRecentKpWindow rtkpRecentKpWindow = GeoMagRTKpRecentKpWindow + .getAccess(); + if (rtkpRecentKpWindow != null) { + rtkpRecentKpWindow.displayRecentKpEstimates(kp_last10_text, + kp_last10_color, titleColor); + } + } + + /** + * Displays the Geomag World-wide Mag Activity Map RTKP. + * + * @param dataBlock + * GeoMagRTKpDataBlockWindow + */ + public static void showGeoMagWorldActivity( + GeoMagRTKpDataBlockWindow dataBlock) { + GeoMagWorldActivityResource geomagMapResource = GeoMagWorldActivityResource + .getGeoMagWorldActivityResource(); + geomagMapResource.init(dataBlock); + geomagMapResource.issueRefresh(); + } + + /** + * Get a list of maps containing the latest estimate kindex and ks values + * for a given list of station codes, start and end dates. + * + * @param stationCodes + * A list of station codes + * @param startTime + * start date + * @param endTime + * end date + * @return List + */ + public static List> getLatestEstKIndex( + final List stationCodes, final Date startTime, + final Date endTime) throws VizException { + + RetrieveK1minRequest request = new RetrieveK1minRequest(stationCodes, + startTime, endTime, RetrieveK1minRequestType.LATEST_K); + List> rsltsList = new ArrayList>(); + + DbQueryResponse response = null; + try { + response = (DbQueryResponse) RequestRouter.route(request); + } catch (Exception e) { + throw new VizException( + "Error during latest k-index retrieval request." + + e.getLocalizedMessage(), e); + } + + if (response != null) { + rsltsList = response.getResults(); + int rsltsListSize = (rsltsList != null) ? rsltsList.size() : 0; + + List> newRsltsList = new ArrayList>(); + + for (int i = 0; i < rsltsListSize; i++) { + Map map = rsltsList.get(i); + Integer k = (Integer) map.get("kestindex"); + Float ks = (Float) map.get("ks"); + + if (k > 9) { + k = 0; + } + + if (ks > 9.0) { + ks = 0.0f; + } + map.put("kestindex", k); + map.put("ks", ks); + newRsltsList.add(map); + + } + + rsltsList = newRsltsList; + } + + return rsltsList; + } + + /** + * Get a list of all magnetometer stations and their current states. + * + * @param prevPeriod + * Obtain values for previous synoptic period? 1='yes' and 0='no' + * (default) + * @return List + */ + public static List> getStationsStates( + final GeoMagStationType type, final Integer prevPeriod) + throws VizException { + + Date refTime = null; + if (prevPeriod == 1) { + refTime = calcPrevSynPerStartTime(); + } else { + refTime = calcCurSynPerStartTime(); + } + + if (refTime == null) { + return new ArrayList>(); + } + + List stnCodes = RTKpUtil.getGeoMagStationCodes(type); + + RetrieveStationStateRequest request = new RetrieveStationStateRequest( + stnCodes, refTime); + + DbQueryResponse response = null; + try { + response = (DbQueryResponse) RequestRouter.route(request); + } catch (Exception e) { + throw new VizException("Error stations' states retrieval request." + + e.getLocalizedMessage(), e); + } + + List> rsltsList = new ArrayList>(); + if (response != null) { + rsltsList = response.getResults(); + int rsltsListSize = (rsltsList != null) ? rsltsList.size() : 0; + + List> newRsltsList = new ArrayList>(); + Map stnMap = new HashMap(); + int processk = 0, kpstation = 0, active = 0; + String prevStation = null; + + for (int i = 0; i < rsltsListSize; i++) { + Map map = rsltsList.get(i); + String stationCode = (String) map.get("stationcode"); + String state = (String) map.get("processingstate"); + + if (!stationCode.equals(prevStation)) { + processk = 0; + kpstation = 0; + active = 0; + stnMap = new HashMap(); + stnMap.put("stationcode", stationCode); + } + if ("Process".equals(state)) { + processk = 1; + } + if ("Algorithm".equals(state)) { + kpstation = 1; + } + if ("Active".equals(state)) { + active = 1; + } + + stnMap.put("k_station", processk); + stnMap.put("kp_station", kpstation); + stnMap.put("kp_active", active); + if (newRsltsList.contains(stnMap)) { + newRsltsList.remove(stnMap); + } + newRsltsList.add(stnMap); + + prevStation = stationCode; + } + + rsltsList = newRsltsList; + } + + return rsltsList; + + } + + /** + * Get a list of all magnetometer stations and their current states. + * + * @param type + * GeoMagStationType (ALL, K, NON_K, KP, NON_KP, KP_ACTIVE) + * @param prevPeriod + * Obtain values for previous synoptic period? 1='yes' and 0='no' + * (default) + * @return List + */ + public static HashMap> getStationsStatesMap( + final GeoMagStationType type, final Integer prevPeriod) + throws VizException { + + List> curKpStationsStates = RTKpUtil + .getStationsStates(type, prevPeriod); + int curKpStationsStatesSize = (curKpStationsStates != null) ? curKpStationsStates + .size() : 0; + + HashMap> statesMap = new HashMap>(); + + for (int i = 0; i < curKpStationsStatesSize; i++) { + Map stnMap = curKpStationsStates.get(i); + String stnCode = (String) stnMap.get("stationcode"); + statesMap.put(stnCode, stnMap); + } + + return statesMap; + } + + /** + * Get a list of all active kp magnetometer station codes + * + * @return List + */ + public static List getCurActiveKpStationCodes() throws VizException { + + List> curKpStationsStates = RTKpUtil + .getStationsStates(GeoMagStationType.KP, 0); + int curKpStationsStatesSize = (curKpStationsStates != null) ? curKpStationsStates + .size() : 0; + + List activeKpStations = new ArrayList(); + for (int i = 0; i < curKpStationsStatesSize; i++) { + Map stnMap = curKpStationsStates.get(i); + String stnCode = (String) stnMap.get("stationcode"); + activeKpStations.add(stnCode); + } + + // List> prevKpStationsStates = RTKpUtil + // .getStationsStates(GeoMagStationType.KP, 1); + // int prevKpStationsStatesSize = (prevKpStationsStates != null) ? + // prevKpStationsStates + // .size() : 0; + // for (int i = 0; i < prevKpStationsStatesSize; i++) { + // Map stnMap = prevKpStationsStates.get(i); + // String stnCode = (String) stnMap.get("stationcode"); + // if (!activeKpStations.contains(stnCode)) { + // activeKpStations.add(stnCode); + // } + // } + + return activeKpStations; + } + + /** + * Toggles whether or not a station is used in the Kp algorithm for the + * current or prior synoptic period. + * + * @param stationCode + * Station code + * @param prevPeriod + * Obtain values for previous synoptic period? 1='yes' and 0='no' + * (default) + * @return List + */ + public static boolean changeStationState(final String stationCode, + final Integer prevPeriod) throws VizException { + + Boolean rval = Boolean.FALSE; + Date synopticTime = null; + if (prevPeriod == 1) { + synopticTime = calcPrevSynPerStartTime(); + } else { + synopticTime = calcCurSynPerStartTime(); + } + + if (synopticTime != null) { + + ChangeStationStateRequest request = new ChangeStationStateRequest( + stationCode, prevPeriod, synopticTime); + try { + rval = (Boolean) RequestRouter.route(request); + } catch (Exception e) { + throw new VizException( + "Error stations' states retrieval request." + + e.getLocalizedMessage(), e); + } + } + return rval; + } + + /** + * Get a list of GeoMagStation Codes given a GeoMagStationType (ALL, K, + * NON_K, KP, NON_KP, KP_ACTIVE). + * + * @param type + * - GeoMagStationType (ALL, K, NON_K, KP, NON_KP, KP_ACTIVE) + * @return List + */ + public static List getGeoMagStationCodes(GeoMagStationType type) { + + List stations = new ArrayList(); + + Map> allStations = GeoMagStationLookup + .getInstance().getStationsByCodeMap(); + + if (allStations != null) { + Object[] stnCodes = allStations.keySet().toArray(); + int stnCodesSize = (stnCodes != null) ? stnCodes.length : 0; + + if (stnCodes != null && stnCodesSize > 0) { + + for (Object stnCode : stnCodes) { + ArrayList station = allStations.get(stnCode); + if (station != null && station.size() > 0) { + + boolean kStation = (station.get(0).getkStation() == 1 ? true + : false); + boolean kpStation = (station.get(0).getKpStation() == 1 ? true + : false); + switch (type) { + case K: + if (kStation) { + stations.add(station.get(0).getStationCode()); + } + break; + case NON_K: + if (!kStation) { + stations.add(station.get(0).getStationCode()); + } + break; + case KP: + if (kStation && kpStation) { + stations.add(station.get(0).getStationCode()); + } + break; + case NON_KP: + if (kStation && !kpStation) { + stations.add(station.get(0).getStationCode()); + } + break; + case ALL: + default: + stations.add(station.get(0).getStationCode()); + break; + } + } + } + } + } + java.util.Collections.sort(stations); + return stations; + } + + /** + * Get a list of GeoMagStations given a GeoMagStationType (ALL, K, NON_K, + * KP, NON_KP, KP_ACTIVE). + * + * @param type + * - GeoMagStationType (ALL, K, NON_K, KP, NON_KP) + * @return List + */ + public static List getGeoMagStations(GeoMagStationType type) { + + List stations = new ArrayList(); + + Map> allStations = GeoMagStationLookup + .getInstance().getStationsByCodeMap(); + + if (allStations != null) { + Object[] stnCodes = allStations.keySet().toArray(); + int stnCodesSize = (stnCodes != null) ? stnCodes.length : 0; + + if (stnCodes != null && stnCodesSize > 0) { + + for (Object stnCode : stnCodes) { + ArrayList station = allStations.get(stnCode); + if (station != null && station.size() > 0) { + + station.get(0) + .getLocation() + .setLongitude( + MapUtil.correctLon(station.get(0) + .getLocation().getLongitude())); + station.get(0) + .getLocation() + .setLatitude( + MapUtil.correctLat(station.get(0) + .getLocation().getLatitude())); + + boolean kStation = (station.get(0).getkStation() == 1 ? true + : false); + boolean kpStation = (station.get(0).getKpStation() == 1 ? true + : false); + + switch (type) { + case K: + if (kStation) { + stations.add(station.get(0)); + } + break; + case NON_K: + if (!kStation) { + stations.add(station.get(0)); + } + break; + case KP: + if (kStation && kpStation) { + stations.add(station.get(0)); + } + break; + case NON_KP: + if (kStation && !kpStation) { + stations.add(station.get(0)); + } + break; + case ALL: + default: + stations.add(station.get(0)); + break; + } + + } + } + } + } + java.util.Collections.sort(stations); + return stations; + } + + /** + * Returns start time of previous synoptic period + * + * @return startTime of previous synoptic period + */ + public static Date calcPrevSynPerStartTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + ttime.set(Calendar.MINUTE, 0); + ttime.set(Calendar.SECOND, 0); + ttime.set(Calendar.MILLISECOND, 0); + int currentHour = ttime.get(Calendar.HOUR_OF_DAY); + // find current synoptic period end time + int hoursToAdd = 3 - (currentHour % 3); + ttime.add(Calendar.HOUR_OF_DAY, hoursToAdd); + // subtract -6 to get start time of previous synoptic period + ttime.add(Calendar.HOUR_OF_DAY, -6); + + return ttime.getTime(); + } + + /** + * Returns start time of current synoptic period + * + * @return startTime of current synoptic period + */ + public static Date calcCurSynPerStartTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + ttime.set(Calendar.MINUTE, 0); + ttime.set(Calendar.SECOND, 0); + ttime.set(Calendar.MILLISECOND, 0); + int currentHour = ttime.get(Calendar.HOUR_OF_DAY); + // find current synoptic period end time + int hoursToAdd = 3 - (currentHour % 3); + ttime.add(Calendar.HOUR_OF_DAY, hoursToAdd); + // subtract -3 to get start time of current synoptic period + ttime.add(Calendar.HOUR_OF_DAY, -3); + + return ttime.getTime(); + } + + /** + * Returns end time of current synoptic period + * + * @return endTime of current synoptic period + */ + public static Date calcCurSynPerEndTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + ttime.set(Calendar.MINUTE, 0); + ttime.set(Calendar.SECOND, 0); + ttime.set(Calendar.MILLISECOND, 0); + int currentHour = ttime.get(Calendar.HOUR_OF_DAY); + // find current synoptic period end time + int hoursToAdd = 3 - (currentHour % 3); + ttime.add(Calendar.HOUR_OF_DAY, hoursToAdd); + + return ttime.getTime(); + } + + /** + * Returns the current date with second and millisecond set to 0 + * + * @return currentTime + */ + public static Date calcCurTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + ttime.set(Calendar.SECOND, 0); + ttime.set(Calendar.MILLISECOND, 0); + return ttime.getTime(); + } + + /** + * Returns the current time + * + * @return currentTime + */ + public static Date getCurrentTime() { + Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + return ttime.getTime(); + } + + /** + * Returns the start time for Data Block given an end time + * + * @param endTime + * @return startTime + */ + public static Date calcDataBlockStartTime(Date endTime) { + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + time.setTime(endTime); + time.add(Calendar.MINUTE, -20); + return time.getTime(); + } + + public static void loadHDWithQdcPlots(String stationCode, String sourceId) + throws VizException { + + File rbdFile = NcPathManager.getInstance().getStaticFile( + "ncep/Bundles/GeoMagHDQdcPlots.xml"); // GeoMagHDQdcPlots + // WNG_hdqdc_plot1_mp_test + AbstractRBD rbdBndl = AbstractRBD.getRbd(rbdFile); + + Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + GeoMagAnalysisPlotDlg dlg = new GeoMagAnalysisPlotDlg(parent, 850, 850, + rbdBndl, stationCode, sourceId); + dlg.open(); + } + + public static String getMostAvailableDataBasedOnSourceId( + String stationCode, Date startTime, Date endTime) + throws VizException { + + String sourceId = "101"; + try { + Integer count101 = getGeoMagRecordsCountForSource(stationCode, + startTime, endTime, 101); + Integer count102 = getGeoMagRecordsCountForSource(stationCode, + startTime, endTime, 102); + Integer count103 = getGeoMagRecordsCountForSource(stationCode, + startTime, endTime, 103); + + Integer max = count101; + if (count102 > max) { + max = count102; + sourceId = "102"; + } + if (count103 > max) { + max = count103; + sourceId = "103"; + } + + } catch (GeoMagTimeSeriesDataException e) { + throw new VizException( + "Error at getMostAvailableDataBasedOnSourceId().", e); + } + return sourceId; + + } + + public static Integer getGeoMagRecordsCountForSource(String stationCode, + Date startTime, Date endTime, int sourceId) + throws GeoMagTimeSeriesDataException { + + RetrieveGeoMagDataRequest request = new RetrieveGeoMagDataRequest( + stationCode, startTime, endTime, sourceId, + RetrieveGeoMagDataRequestType.DATA_LIST); + + List rsltsList = new ArrayList(); + try { + Object rslts = ThriftClient.sendRequest(request); + + if (rslts != null && rslts instanceof List) { + rsltsList = (ArrayList) rslts; + } + } catch (Exception e) { + throw new GeoMagTimeSeriesDataException( + "Error during retrieval request.", e); + } + + return (rsltsList != null) ? rsltsList.size() : 0; + } + + /** + * Displays an Exception in a Message Dialog + * + * @param e + */ + public static void showError(Exception e) { + + StringBuilder sb = new StringBuilder(e.getMessage()); + + Throwable temp = e; + while ((temp = temp.getCause()) != null) { + sb.append("\n"); + sb.append(temp.getMessage()); + } + + MessageDialog errorDlg = new MessageDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), GEOMAGDATA_ERROR, null, + sb.toString(), MessageDialog.ERROR, new String[] { "OK" }, 0); + + errorDlg.open(); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/AbstractNcPaneManager.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/AbstractNcPaneManager.java index 38814399e0..52c3af2d97 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/AbstractNcPaneManager.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/AbstractNcPaneManager.java @@ -70,6 +70,9 @@ import com.vividsolutions.jts.geom.Coordinate; * 01/28/12 #972 Greg Hull created from NCPaneManager minus remove PaneLayout code. * 12/16/13 #958 sgurung Do not set virtual cursor for NcNonMapRenderableDisplay * 05/16/2014 #1136 qzhou Add NCTimeseries for Graph. + * 09/09/2014 R4078 sgurung Added "contextualMenusEnabled" to specify whether to + * enable/disable contextual menus in panes. + * *
* * @author ghull @@ -104,6 +107,8 @@ public abstract class AbstractNcPaneManager extends PaneManager implements protected boolean timeSyncPanesEnabled = true; + protected boolean contextualMenusEnabled = true; + protected boolean isHide = false; // means loop rsc on, and Hide btn // displayed @@ -493,7 +498,7 @@ public abstract class AbstractNcPaneManager extends PaneManager implements VizDisplayPane pane = null; try { pane = new VizDisplayPane(paneContainer, canvasComp, - renderableDisplay, true); + renderableDisplay, contextualMenusEnabled); // register the inputManager and the mouse listener for pane // selection registerHandlers(pane); @@ -766,4 +771,12 @@ public abstract class AbstractNcPaneManager extends PaneManager implements public boolean arePanesTimeSynced() { return timeSyncPanesEnabled; } + + public boolean areContextualMenusEnabled() { + return contextualMenusEnabled; + } + + public void setContextualMenusEnabled(boolean val) { + this.contextualMenusEnabled = val; + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java index 50d9ebfefe..95bd3e2dae 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java @@ -51,6 +51,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 04/21/2014 #1136 qzhou Initial creation + * 07/28/2014 R4078 sgurung Added code changes to support loading TimeSeriesResource in a new window. + * * *
* @@ -148,9 +150,9 @@ public class NCTimeSeriesRenderableDisplay extends AbstractXyRenderableDisplay // TODO? if null then set to the descriptors gridGeom?? @Override public NCTimeSeriesDescriptor getDescriptor() { - if (super.getDescriptor() instanceof NCTimeSeriesDescriptor) { + if (super.getDescriptor() instanceof NCTimeSeriesDescriptor) { return (NCTimeSeriesDescriptor) super.getDescriptor(); - } else { + } else { super.getDescriptor(); } @@ -254,11 +256,20 @@ public class NCTimeSeriesRenderableDisplay extends AbstractXyRenderableDisplay @Override public void notifyAdd(ResourcePair rp) throws VizException { - // TODO : any checks on the type of resource here. - AbstractNcPaneManager pm = NcEditorUtil - .getNcPaneManager((AbstractEditor) container); - if (pm != null) { - pm.setDisplayAvailable(false); + if (container != null) { + if (container instanceof AbstractEditor) { + // TODO : any checks on the type of resource here. + AbstractNcPaneManager pm = NcEditorUtil + .getNcPaneManager((AbstractEditor) container); + if (pm != null) { + pm.setDisplayAvailable(false); + } + } else { + AbstractNcPaneManager pm = (AbstractNcPaneManager) getPaneManager(); + if (pm != null) { + pm.setDisplayAvailable(false); + } + } } } diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml index 4fbf382725..251e358e81 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml @@ -618,19 +618,19 @@ - + tooltip="Real-time Kp Monitor"> - + NC * 09/27/2009 169 G. Hull require NCMapEditor * 07/07/2014 R4079 Q. Zhou Add timeseries view + * 05/05/2014 R4078 S. Gurung Added place holder for RTKp related views *
* * @author @@ -71,6 +72,12 @@ public class NCPerspective implements IPerspectiveFactory { layout.addActionSet("gov.noaa.nws.ncep.viz.ui.personalities.NCActionSet"); + layout.addPlaceholder("gov.noaa.nws.ncep.viz.rtkp.GEOMAGRTKPDATABLOCK", + IPageLayout.BOTTOM, 0.60f, refId); + + layout.addPlaceholder("gov.noaa.nws.ncep.viz.rtkp.GEOMAGRTKPRECENTKP", + IPageLayout.RIGHT, 0.75f, refId); + long t5 = System.currentTimeMillis(); // System.out.println("Time to add Action set: " + (t5-t4) + " ms"); System.out.println("Time to Create NCP perspective layout: " From 09a6987e5859994aa90e3306a14e33d1dc620e1d Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Fri, 10 Oct 2014 10:05:46 -0400 Subject: [PATCH 08/19] VLab Issue #4230 - Fix wind barb/brbk menu option in plot model dialog Change-Id: I6c1c8a10385ab531bc4b00049a5e31c21f42ba2a Former-commit-id: 064288886f4fcc61993064e516edbb8c7c80a63f [formerly 064288886f4fcc61993064e516edbb8c7c80a63f [formerly 14a48cc8077d1c0b2302d53a01839d7adbb533a2]] Former-commit-id: 909a8d7342889d012d405bb7af937b0e28be5b4d Former-commit-id: 796e9e1901aee3918e53694210edac3b5b1b0bd1 --- .../plotModels/NcPlotImageCreator.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java index 80b24f5af7..09c26cf75c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java @@ -79,6 +79,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 06/17/2014 923 S. Russell altered method setUpSymbolMappingTables() * 06/17/2014 923 S. Russell altered method createRenderableData() * 07/08/2014 TTR1027 B. Hebbard Force createRenderableData to recreate wind vectors each time. + * 09/10/2014 Redmine 4230 S. Russell Fix wind barb/brbk menu option in plot model dialog box */ public class NcPlotImageCreator { @@ -249,7 +250,7 @@ public class NcPlotImageCreator { IFont prevFont; - public static enum Position { // TODO: Explain each? + public static enum Position { TC, UL, UC, UR, ML, MC, MR, LL, LC, LR, BC, SC, WD, INVALID } @@ -285,7 +286,6 @@ public class NcPlotImageCreator { setUpPlotPositionToPlotModelElementMapping(plotModel); setUpSymbolMappingTables(); - plotDensity = initialDensity; initializeFonts(); Tracer.print("< Exit"); @@ -513,6 +513,15 @@ public class NcPlotImageCreator { pme.setPosition("WD"); } + + // Redmine 4230 + // NcPlotImageCreator will not process BRBK unless it has + // the abstract ( not on thcae grid of plot model buttons ) + // position "WD" + if (pme.getParamName().equalsIgnoreCase("BRBK")) { + pme.setPosition("WD"); + } + Position position = getPositionFromPlotModelElementPosition(pme .getPosition()); plotModelPositionMap.put(position, pme); @@ -2265,10 +2274,15 @@ public class NcPlotImageCreator { if (symbolPatternName == null || symbolPatternName.isEmpty()) { continue; + } else { + // Redmine 4230 + symbolPatternName = symbolPatternName + .trim(); } Symbol symbol = symbolNameToSymbolMap .get(symbolPatternName); + RGB rgb = null; /* * Get the conditional color for the @@ -2557,7 +2571,6 @@ public class NcPlotImageCreator { DrawableString drawableString = null; String metParamName = plotParamDefn.getMetParamName(); Semaphore sm = new Semaphore(1); - String PTNDSign = null; synchronized (station.listOfParamsToPlot) { sm.acquireUninterruptibly(); @@ -2568,12 +2581,14 @@ public class NcPlotImageCreator { } for (AbstractMetParameter metParamToPlot : station.listOfParamsToPlot) { + if (metParamToPlot.getMetParamName().compareTo( metParamName) == 0) { try { String formattedString = getFormattedValueToPlot( plotParamDefn, metParamToPlot); + if (formattedString == null) { return null; } From 565321365172d46ad3fde8ac5d5390dd1928b02e Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Thu, 16 Oct 2014 14:58:03 -0400 Subject: [PATCH 09/19] VLab Issue #4318 - Add a new plot parameter SGHT Change-Id: Iaf51f6298b35b731193f89693d19043380906fea Former-commit-id: a77b62260555301be33cb09927c079368f5a21e8 [formerly a77b62260555301be33cb09927c079368f5a21e8 [formerly 9029d63f0a2d10f61780d94e3f83433ebdb113c9]] Former-commit-id: d4636d84e52797a569537244d20b7cad330cba66 Former-commit-id: 1fa4e7be5f0111affeeedda65347924234013a93 --- .../metparameters/MetParameterFactory.java | 789 ++++++++++++------ .../PressureChange3HrAndTendency.java | 7 +- .../metparameters/SignificantWaveHeight.java | 59 ++ .../parameterconversion/PRLibrary.java | 640 +++++++++----- .../PlotParameters/plotParameters_obs.xml | 5 +- .../PlotParameters/plotParameters_sfcobs.xml | 4 + 6 files changed, 1040 insertions(+), 464 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/SignificantWaveHeight.java diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/MetParameterFactory.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/MetParameterFactory.java index 9405bb66df..f63e99b7ca 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/MetParameterFactory.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/MetParameterFactory.java @@ -41,7 +41,7 @@ public class MetParameterFactory implements ISerializableObject { @DynamicSerializeElement private HashMap ncParamsAliasMap = new HashMap(); - // + // @DynamicSerializeElement private HashMap ncParamsMap = new HashMap(); @@ -57,290 +57,559 @@ public class MetParameterFactory implements ISerializableObject { private MetParameterFactory() { try { - ncParamsMap.put(AircraftType.class.getSimpleName(), new AircraftType()); - ncParamsMap.put(AircraftReportType.class.getSimpleName(), new AircraftReportType()); - ncParamsMap.put(AmountOfCondPrecipIn12Hrs.class.getSimpleName(), new AmountOfCondPrecipIn12Hrs()); - ncParamsMap.put(AmountOfCondPrecipIn24Hrs.class.getSimpleName(), new AmountOfCondPrecipIn24Hrs()); - ncParamsMap.put(Avg3HrShipSpeed.class.getSimpleName(), new Avg3HrShipSpeed()); - ncParamsMap.put(Avg1HrHeatFlux.class.getSimpleName(), new Avg1HrHeatFlux()); - ncParamsMap.put(Avg1HrSnowPhaseChangeHeatFlux.class.getSimpleName(), new Avg1HrSnowPhaseChangeHeatFlux()); - ncParamsMap.put(Avg1HrSubSurfaceHeatFlux.class.getSimpleName(), new Avg1HrSubSurfaceHeatFlux()); - ncParamsMap.put(BaseOfIcing.class.getSimpleName(), new BaseOfIcing()); - ncParamsMap.put(BaseOfTurbulence.class.getSimpleName(), new BaseOfTurbulence()); - ncParamsMap.put(BaseOfWeather.class.getSimpleName(), new BaseOfWeather()); - ncParamsMap.put(BruntVaisalaFreq.class.getSimpleName(), new BruntVaisalaFreq()); - ncParamsMap.put(BruntVaisalaPeriod.class.getSimpleName(), new BruntVaisalaPeriod()); - // ncParamsMap.put( BruntVaisalaFrequencySquared.class.getSimpleName(), new BruntVaisalaFrequencySquared() ); - ncParamsMap.put(CatFcstCeilingHeightCond.class.getSimpleName(), new CatFcstCeilingHeightCond()); - ncParamsMap.put(CatFcstObstructionsVision.class.getSimpleName(), new CatFcstObstructionsVision()); - ncParamsMap.put(CatFcstPrecipitation.class.getSimpleName(), new CatFcstPrecipitation()); + ncParamsMap.put(AircraftType.class.getSimpleName(), + new AircraftType()); + ncParamsMap.put(AircraftReportType.class.getSimpleName(), + new AircraftReportType()); + ncParamsMap.put(AmountOfCondPrecipIn12Hrs.class.getSimpleName(), + new AmountOfCondPrecipIn12Hrs()); + ncParamsMap.put(AmountOfCondPrecipIn24Hrs.class.getSimpleName(), + new AmountOfCondPrecipIn24Hrs()); + ncParamsMap.put(Avg3HrShipSpeed.class.getSimpleName(), + new Avg3HrShipSpeed()); + ncParamsMap.put(Avg1HrHeatFlux.class.getSimpleName(), + new Avg1HrHeatFlux()); + ncParamsMap.put( + Avg1HrSnowPhaseChangeHeatFlux.class.getSimpleName(), + new Avg1HrSnowPhaseChangeHeatFlux()); + ncParamsMap.put(Avg1HrSubSurfaceHeatFlux.class.getSimpleName(), + new Avg1HrSubSurfaceHeatFlux()); + ncParamsMap.put(BaseOfIcing.class.getSimpleName(), + new BaseOfIcing()); + ncParamsMap.put(BaseOfTurbulence.class.getSimpleName(), + new BaseOfTurbulence()); + ncParamsMap.put(BaseOfWeather.class.getSimpleName(), + new BaseOfWeather()); + ncParamsMap.put(BruntVaisalaFreq.class.getSimpleName(), + new BruntVaisalaFreq()); + ncParamsMap.put(BruntVaisalaPeriod.class.getSimpleName(), + new BruntVaisalaPeriod()); + // ncParamsMap.put( + // BruntVaisalaFrequencySquared.class.getSimpleName(), new + // BruntVaisalaFrequencySquared() ); + ncParamsMap.put(CatFcstCeilingHeightCond.class.getSimpleName(), + new CatFcstCeilingHeightCond()); + ncParamsMap.put(CatFcstObstructionsVision.class.getSimpleName(), + new CatFcstObstructionsVision()); + ncParamsMap.put(CatFcstPrecipitation.class.getSimpleName(), + new CatFcstPrecipitation()); - ncParamsMap.put(CatFcstSnowAmountFalling06hr.class.getSimpleName(), new CatFcstSnowAmountFalling06hr()); - ncParamsMap.put(CatFcstSnowAmountFalling12hr.class.getSimpleName(), new CatFcstSnowAmountFalling12hr()); - ncParamsMap.put(CatFcstSnowAmountFalling24hr.class.getSimpleName(), new CatFcstSnowAmountFalling24hr()); - ncParamsMap.put(CatFcstVisibilityCond.class.getSimpleName(), new CatFcstVisibilityCond()); - ncParamsMap.put(CeilingFromSurface.class.getSimpleName(), new CeilingFromSurface()); - ncParamsMap.put(CeilingFromSeaLevel.class.getSimpleName(), new CeilingFromSeaLevel()); + ncParamsMap.put(CatFcstSnowAmountFalling06hr.class.getSimpleName(), + new CatFcstSnowAmountFalling06hr()); + ncParamsMap.put(CatFcstSnowAmountFalling12hr.class.getSimpleName(), + new CatFcstSnowAmountFalling12hr()); + ncParamsMap.put(CatFcstSnowAmountFalling24hr.class.getSimpleName(), + new CatFcstSnowAmountFalling24hr()); + ncParamsMap.put(CatFcstVisibilityCond.class.getSimpleName(), + new CatFcstVisibilityCond()); + ncParamsMap.put(CeilingFromSurface.class.getSimpleName(), + new CeilingFromSurface()); + ncParamsMap.put(CeilingFromSeaLevel.class.getSimpleName(), + new CeilingFromSeaLevel()); ncParamsMap.put(CloudCover.class.getSimpleName(), new CloudCover()); - ncParamsMap.put(ClimDayTemp.class.getSimpleName(), new ClimDayTemp()); - ncParamsMap.put(ClimNightTemp.class.getSimpleName(), new ClimNightTemp()); - ncParamsMap.put(Clim12HrPOP.class.getSimpleName(), new Clim12HrPOP()); - ncParamsMap.put(Clim24HrPOP.class.getSimpleName(), new Clim24HrPOP()); + ncParamsMap.put(ClimDayTemp.class.getSimpleName(), + new ClimDayTemp()); + ncParamsMap.put(ClimNightTemp.class.getSimpleName(), + new ClimNightTemp()); + ncParamsMap.put(Clim12HrPOP.class.getSimpleName(), + new Clim12HrPOP()); + ncParamsMap.put(Clim24HrPOP.class.getSimpleName(), + new Clim24HrPOP()); ncParamsMap.put(CloudBase1.class.getSimpleName(), new CloudBase1()); ncParamsMap.put(CloudBase2.class.getSimpleName(), new CloudBase2()); - ncParamsMap.put(CloudFractionInLayer.class.getSimpleName(), new CloudFractionInLayer()); + ncParamsMap.put(CloudFractionInLayer.class.getSimpleName(), + new CloudFractionInLayer()); ncParamsMap.put(CloudWater.class.getSimpleName(), new CloudWater()); ncParamsMap.put(CloudTop1.class.getSimpleName(), new CloudTop1()); ncParamsMap.put(CloudTop2.class.getSimpleName(), new CloudTop2()); - ncParamsMap.put(CondProbOf6HrSevereWeather.class.getSimpleName(), new CondProbOf6HrSevereWeather()); - ncParamsMap.put(CondProbOf12HrSevereWeather.class.getSimpleName(), new CondProbOf12HrSevereWeather()); - ncParamsMap.put(CondProbOf12HrFreezingPrecip.class.getSimpleName(), new CondProbOf12HrFreezingPrecip()); - ncParamsMap.put(CondProbOf12HrRain.class.getSimpleName(), new CondProbOf12HrRain()); - ncParamsMap.put(CondFcstPrecip12HrType.class.getSimpleName(), new CondFcstPrecip12HrType()); - ncParamsMap.put(CondProbOf12HrSnow.class.getSimpleName(), new CondProbOf12HrSnow()); - ncParamsMap.put(CondProbOf24HrSevereWeather.class.getSimpleName(), new CondProbOf24HrSevereWeather()); - ncParamsMap.put(CondProbOfFreezingPrecip.class.getSimpleName(), new CondProbOfFreezingPrecip()); - ncParamsMap.put(CondProbOfLiquidPrecip.class.getSimpleName(), new CondProbOfLiquidPrecip()); - ncParamsMap.put(CondProbOfMixedPrecip.class.getSimpleName(), new CondProbOfMixedPrecip()); - ncParamsMap.put(CondProbOfContPrecip.class.getSimpleName(), new CondProbOfContPrecip()); - ncParamsMap.put(CondProbOfDrizzle.class.getSimpleName(), new CondProbOfDrizzle()); - ncParamsMap.put(CondProbOfShowers.class.getSimpleName(), new CondProbOfShowers()); - ncParamsMap.put(CondProbOfSnow.class.getSimpleName(), new CondProbOfSnow()); - ncParamsMap.put(ConvectivePrecip.class.getSimpleName(), new ConvectivePrecip()); + ncParamsMap.put(CondProbOf6HrSevereWeather.class.getSimpleName(), + new CondProbOf6HrSevereWeather()); + ncParamsMap.put(CondProbOf12HrSevereWeather.class.getSimpleName(), + new CondProbOf12HrSevereWeather()); + ncParamsMap.put(CondProbOf12HrFreezingPrecip.class.getSimpleName(), + new CondProbOf12HrFreezingPrecip()); + ncParamsMap.put(CondProbOf12HrRain.class.getSimpleName(), + new CondProbOf12HrRain()); + ncParamsMap.put(CondFcstPrecip12HrType.class.getSimpleName(), + new CondFcstPrecip12HrType()); + ncParamsMap.put(CondProbOf12HrSnow.class.getSimpleName(), + new CondProbOf12HrSnow()); + ncParamsMap.put(CondProbOf24HrSevereWeather.class.getSimpleName(), + new CondProbOf24HrSevereWeather()); + ncParamsMap.put(CondProbOfFreezingPrecip.class.getSimpleName(), + new CondProbOfFreezingPrecip()); + ncParamsMap.put(CondProbOfLiquidPrecip.class.getSimpleName(), + new CondProbOfLiquidPrecip()); + ncParamsMap.put(CondProbOfMixedPrecip.class.getSimpleName(), + new CondProbOfMixedPrecip()); + ncParamsMap.put(CondProbOfContPrecip.class.getSimpleName(), + new CondProbOfContPrecip()); + ncParamsMap.put(CondProbOfDrizzle.class.getSimpleName(), + new CondProbOfDrizzle()); + ncParamsMap.put(CondProbOfShowers.class.getSimpleName(), + new CondProbOfShowers()); + ncParamsMap.put(CondProbOfSnow.class.getSimpleName(), + new CondProbOfSnow()); + ncParamsMap.put(ConvectivePrecip.class.getSimpleName(), + new ConvectivePrecip()); ncParamsMap.put(ShipCourse.class.getSimpleName(), new ShipCourse()); - ncParamsMap.put(DayTempAnomaly.class.getSimpleName(), new DayTempAnomaly()); - ncParamsMap.put(DayTempFcst.class.getSimpleName(), new DayTempFcst()); - ncParamsMap.put(DewPointDepression.class.getSimpleName(), new DewPointDepression()); - ncParamsMap.put(DewPointTemp.class.getSimpleName(), new DewPointTemp()); - ncParamsMap.put(DryBulbTemp.class.getSimpleName(), new DryBulbTemp()); - ncParamsMap.put(FiveSecPeakWindDir.class.getSimpleName(), new FiveSecPeakWindDir()); - ncParamsMap.put(PredomSwellWaveDir.class.getSimpleName(), new PredomSwellWaveDir()); - ncParamsMap.put(SecondarySwellWaveDir.class.getSimpleName(), new SecondarySwellWaveDir()); + ncParamsMap.put(DayTempAnomaly.class.getSimpleName(), + new DayTempAnomaly()); + ncParamsMap.put(DayTempFcst.class.getSimpleName(), + new DayTempFcst()); + ncParamsMap.put(DewPointDepression.class.getSimpleName(), + new DewPointDepression()); + ncParamsMap.put(DewPointTemp.class.getSimpleName(), + new DewPointTemp()); + ncParamsMap.put(DryBulbTemp.class.getSimpleName(), + new DryBulbTemp()); + ncParamsMap.put(FiveSecPeakWindDir.class.getSimpleName(), + new FiveSecPeakWindDir()); + ncParamsMap.put(PredomSwellWaveDir.class.getSimpleName(), + new PredomSwellWaveDir()); + ncParamsMap.put(SecondarySwellWaveDir.class.getSimpleName(), + new SecondarySwellWaveDir()); ncParamsMap.put(DPRN.class.getSimpleName(), new DPRN()); - ncParamsMap.put(DryAirDensity.class.getSimpleName(), new DryAirDensity()); - ncParamsMap.put(DryHydrostaticHeight.class.getSimpleName(), new DryHydrostaticHeight()); - ncParamsMap.put(TimeOf5SecPeakWindInHrs.class.getSimpleName(), new TimeOf5SecPeakWindInHrs()); - ncParamsMap.put(TimeOf5SecPeakWindInMins.class.getSimpleName(), new TimeOf5SecPeakWindInMins()); - ncParamsMap.put(EquivPotentialTemp.class.getSimpleName(), new EquivPotentialTemp()); - ncParamsMap.put(EquivWindSpeed10min.class.getSimpleName(), new EquivWindSpeed10min()); - ncParamsMap.put(EquivWindSpeed20min.class.getSimpleName(), new EquivWindSpeed20min()); - ncParamsMap.put(FcstFZRainAccumulationIn12Hours.class.getSimpleName(), new FcstFZRainAccumulationIn12Hours()); - ncParamsMap.put(FcstFZRainAccumulationToWatchThresh.class.getSimpleName(), new FcstFZRainAccumulationToWatchThresh()); - ncParamsMap.put(FcstSnowIcePelletAccumulation12Hrs.class.getSimpleName(), new FcstSnowIcePelletAccumulation12Hrs()); - ncParamsMap.put(FcstSnowIcePelletAccumToWatchThresh.class.getSimpleName(), new FcstSnowIcePelletAccumToWatchThresh()); - ncParamsMap.put(FlashFloodGuid01Hr.class.getSimpleName(), new FlashFloodGuid01Hr()); - ncParamsMap.put(FlashFloodGuid03Hr.class.getSimpleName(), new FlashFloodGuid03Hr()); - ncParamsMap.put(FlashFloodGuid06Hr.class.getSimpleName(), new FlashFloodGuid06Hr()); - ncParamsMap.put(FlashFloodGuid12Hr.class.getSimpleName(), new FlashFloodGuid12Hr()); - ncParamsMap.put(FlashFloodGuid24Hr.class.getSimpleName(), new FlashFloodGuid24Hr()); - ncParamsMap.put(FlightRulesID.class.getSimpleName(), new FlightRulesID()); - ncParamsMap.put(FlightLevel.class.getSimpleName(), new FlightLevel()); - ncParamsMap.put(FosbergFireWxIndex.class.getSimpleName(), new FosbergFireWxIndex()); - ncParamsMap.put(FZRainWatchThresh.class.getSimpleName(), new FZRainWatchThresh()); - // ncParamsMap.put( GenericDimensionlessParameter.class.getSimpleName(), new GenericDimensionlessParameter() ); - // ncParamsMap.put( GustBarb.class.getSimpleName(), new GustBarb() ); + ncParamsMap.put(DryAirDensity.class.getSimpleName(), + new DryAirDensity()); + ncParamsMap.put(DryHydrostaticHeight.class.getSimpleName(), + new DryHydrostaticHeight()); + ncParamsMap.put(TimeOf5SecPeakWindInHrs.class.getSimpleName(), + new TimeOf5SecPeakWindInHrs()); + ncParamsMap.put(TimeOf5SecPeakWindInMins.class.getSimpleName(), + new TimeOf5SecPeakWindInMins()); + ncParamsMap.put(EquivPotentialTemp.class.getSimpleName(), + new EquivPotentialTemp()); + ncParamsMap.put(EquivWindSpeed10min.class.getSimpleName(), + new EquivWindSpeed10min()); + ncParamsMap.put(EquivWindSpeed20min.class.getSimpleName(), + new EquivWindSpeed20min()); + ncParamsMap.put( + FcstFZRainAccumulationIn12Hours.class.getSimpleName(), + new FcstFZRainAccumulationIn12Hours()); + ncParamsMap.put( + FcstFZRainAccumulationToWatchThresh.class.getSimpleName(), + new FcstFZRainAccumulationToWatchThresh()); + ncParamsMap.put( + FcstSnowIcePelletAccumulation12Hrs.class.getSimpleName(), + new FcstSnowIcePelletAccumulation12Hrs()); + ncParamsMap.put( + FcstSnowIcePelletAccumToWatchThresh.class.getSimpleName(), + new FcstSnowIcePelletAccumToWatchThresh()); + ncParamsMap.put(FlashFloodGuid01Hr.class.getSimpleName(), + new FlashFloodGuid01Hr()); + ncParamsMap.put(FlashFloodGuid03Hr.class.getSimpleName(), + new FlashFloodGuid03Hr()); + ncParamsMap.put(FlashFloodGuid06Hr.class.getSimpleName(), + new FlashFloodGuid06Hr()); + ncParamsMap.put(FlashFloodGuid12Hr.class.getSimpleName(), + new FlashFloodGuid12Hr()); + ncParamsMap.put(FlashFloodGuid24Hr.class.getSimpleName(), + new FlashFloodGuid24Hr()); + ncParamsMap.put(FlightRulesID.class.getSimpleName(), + new FlightRulesID()); + ncParamsMap.put(FlightLevel.class.getSimpleName(), + new FlightLevel()); + ncParamsMap.put(FosbergFireWxIndex.class.getSimpleName(), + new FosbergFireWxIndex()); + ncParamsMap.put(FZRainWatchThresh.class.getSimpleName(), + new FZRainWatchThresh()); + // ncParamsMap.put( + // GenericDimensionlessParameter.class.getSimpleName(), new + // GenericDimensionlessParameter() ); + // ncParamsMap.put( GustBarb.class.getSimpleName(), new GustBarb() + // ); ncParamsMap.put(HailSize.class.getSimpleName(), new HailSize()); ncParamsMap.put(HeatIndex.class.getSimpleName(), new HeatIndex()); - ncParamsMap.put(HeightAboveSeaLevel.class.getSimpleName(), new HeightAboveSeaLevel()); - ncParamsMap.put(InstrumentWaveHeight.class.getSimpleName(), new InstrumentWaveHeight()); - ncParamsMap.put(PredomSwellWaveHeight.class.getSimpleName(), new PredomSwellWaveHeight()); - ncParamsMap.put(SecondarySwellWaveHeight.class.getSimpleName(), new SecondarySwellWaveHeight()); + ncParamsMap.put(HeightAboveSeaLevel.class.getSimpleName(), + new HeightAboveSeaLevel()); + ncParamsMap.put(InstrumentWaveHeight.class.getSimpleName(), + new InstrumentWaveHeight()); + ncParamsMap.put(PredomSwellWaveHeight.class.getSimpleName(), + new PredomSwellWaveHeight()); + ncParamsMap.put(SecondarySwellWaveHeight.class.getSimpleName(), + new SecondarySwellWaveHeight()); ncParamsMap.put(WaveHeight.class.getSimpleName(), new WaveHeight()); - ncParamsMap.put(WindWaveHeight.class.getSimpleName(), new WindWaveHeight()); - ncParamsMap.put(Highest1MinMeanWindSpeedInPastHour.class.getSimpleName(), new Highest1MinMeanWindSpeedInPastHour()); - ncParamsMap.put(HighResWaveHeight.class.getSimpleName(), new HighResWaveHeight()); - ncParamsMap.put(HumitureIndex.class.getSimpleName(), new HumitureIndex()); + ncParamsMap.put(WindWaveHeight.class.getSimpleName(), + new WindWaveHeight()); + ncParamsMap.put( + Highest1MinMeanWindSpeedInPastHour.class.getSimpleName(), + new Highest1MinMeanWindSpeedInPastHour()); + ncParamsMap.put(HighResWaveHeight.class.getSimpleName(), + new HighResWaveHeight()); + ncParamsMap.put(HumitureIndex.class.getSimpleName(), + new HumitureIndex()); ncParamsMap.put(IceCode.class.getSimpleName(), new IceCode()); ncParamsMap.put(IceType.class.getSimpleName(), new IceType()); - ncParamsMap.put(IcingIntensitySymbol.class.getSimpleName(), new IcingIntensitySymbol()); - ncParamsMap.put(IcingTypeSymbol.class.getSimpleName(), new IcingTypeSymbol()); - ncParamsMap.put(InterWindDir.class.getSimpleName(), new InterWindDir()); - ncParamsMap.put(InterWindSpeed.class.getSimpleName(), new InterWindSpeed()); - ncParamsMap.put(InterWindTime.class.getSimpleName(), new InterWindTime()); + ncParamsMap.put(IcingIntensitySymbol.class.getSimpleName(), + new IcingIntensitySymbol()); + ncParamsMap.put(IcingTypeSymbol.class.getSimpleName(), + new IcingTypeSymbol()); + ncParamsMap.put(InterWindDir.class.getSimpleName(), + new InterWindDir()); + ncParamsMap.put(InterWindSpeed.class.getSimpleName(), + new InterWindSpeed()); + ncParamsMap.put(InterWindTime.class.getSimpleName(), + new InterWindTime()); ncParamsMap.put(LandSea.class.getSimpleName(), new LandSea()); - ncParamsMap.put(LatentHeatOfVapor.class.getSimpleName(), new LatentHeatOfVapor()); - ncParamsMap.put(LCLParcelPressure.class.getSimpleName(), new LCLParcelPressure()); - ncParamsMap.put(LCLParcelTemperature.class.getSimpleName(), new LCLParcelTemperature()); - ncParamsMap.put(LiftedIndex.class.getSimpleName(), new LiftedIndex()); - ncParamsMap.put(LiftedSurfaceAirTempAt500mb.class.getSimpleName(), new LiftedSurfaceAirTempAt500mb()); - ncParamsMap.put(Lowest01MinAvgPressInPastHour.class.getSimpleName(), new Lowest01MinAvgPressInPastHour()); - ncParamsMap.put(Max24HrTemp.class.getSimpleName(), new Max24HrTemp()); + ncParamsMap.put(LatentHeatOfVapor.class.getSimpleName(), + new LatentHeatOfVapor()); + ncParamsMap.put(LCLParcelPressure.class.getSimpleName(), + new LCLParcelPressure()); + ncParamsMap.put(LCLParcelTemperature.class.getSimpleName(), + new LCLParcelTemperature()); + ncParamsMap.put(LiftedIndex.class.getSimpleName(), + new LiftedIndex()); + ncParamsMap.put(LiftedSurfaceAirTempAt500mb.class.getSimpleName(), + new LiftedSurfaceAirTempAt500mb()); + ncParamsMap.put( + Lowest01MinAvgPressInPastHour.class.getSimpleName(), + new Lowest01MinAvgPressInPastHour()); + ncParamsMap.put(Max24HrTemp.class.getSimpleName(), + new Max24HrTemp()); ncParamsMap.put(Max6HrTemp.class.getSimpleName(), new Max6HrTemp()); - ncParamsMap.put(MaxDailyWeatherMapTemp.class.getSimpleName(), new MaxDailyWeatherMapTemp()); + ncParamsMap.put(MaxDailyWeatherMapTemp.class.getSimpleName(), + new MaxDailyWeatherMapTemp()); ncParamsMap.put(MaxDayTemp.class.getSimpleName(), new MaxDayTemp()); - ncParamsMap.put(MaxEditedTemp.class.getSimpleName(), new MaxEditedTemp()); - ncParamsMap.put(MaxCloudCover.class.getSimpleName(), new MaxCloudCover()); - ncParamsMap.put(MaxPrecipPR6X.class.getSimpleName(), new MaxPrecipPR6X()); //remove?? - ncParamsMap.put(MaxMidnightTemp.class.getSimpleName(), new MaxMidnightTemp()); - ncParamsMap.put(MaxOrMinTemp.class.getSimpleName(), new MaxOrMinTemp()); - ncParamsMap.put(Max12HrPrecipFcst.class.getSimpleName(), new Max12HrPrecipFcst()); - ncParamsMap.put(MaxWindSpeed.class.getSimpleName(), new MaxWindSpeed()); - ncParamsMap.put(MeanSeaLevelPres.class.getSimpleName(), new MeanSeaLevelPres()); - ncParamsMap.put(Min24HrTemp.class.getSimpleName(), new Min24HrTemp()); + ncParamsMap.put(MaxEditedTemp.class.getSimpleName(), + new MaxEditedTemp()); + ncParamsMap.put(MaxCloudCover.class.getSimpleName(), + new MaxCloudCover()); + ncParamsMap.put(MaxPrecipPR6X.class.getSimpleName(), + new MaxPrecipPR6X()); // remove?? + ncParamsMap.put(MaxMidnightTemp.class.getSimpleName(), + new MaxMidnightTemp()); + ncParamsMap.put(MaxOrMinTemp.class.getSimpleName(), + new MaxOrMinTemp()); + ncParamsMap.put(Max12HrPrecipFcst.class.getSimpleName(), + new Max12HrPrecipFcst()); + ncParamsMap.put(MaxWindSpeed.class.getSimpleName(), + new MaxWindSpeed()); + ncParamsMap.put(MeanSeaLevelPres.class.getSimpleName(), + new MeanSeaLevelPres()); + ncParamsMap.put(Min24HrTemp.class.getSimpleName(), + new Min24HrTemp()); ncParamsMap.put(Min6HrTemp.class.getSimpleName(), new Min6HrTemp()); - ncParamsMap.put(MinDailyWeatherMapTemp.class.getSimpleName(), new MinDailyWeatherMapTemp()); - ncParamsMap.put(MinNightTemp.class.getSimpleName(), new MinNightTemp()); - ncParamsMap.put(MixingRatio.class.getSimpleName(), new MixingRatio()); - ncParamsMap.put(MoistHydrostaticHeight.class.getSimpleName(), new MoistHydrostaticHeight()); - ncParamsMap.put(MontgomeryStreamFnct.class.getSimpleName(), new MontgomeryStreamFnct()); - ncParamsMap.put(MountainObscThreshMetIndicator.class.getSimpleName(), new MountainObscThreshMetIndicator()); - ncParamsMap.put(MountainObscThresh.class.getSimpleName(), new MountainObscThresh()); - ncParamsMap.put(NightTempAnomaly.class.getSimpleName(), new NightTempAnomaly()); - ncParamsMap.put(NewSnowAmount.class.getSimpleName(), new NewSnowAmount()); - ncParamsMap.put(NightTempFcst.class.getSimpleName(), new NightTempFcst()); - ncParamsMap.put(NumInterWinds.class.getSimpleName(), new NumInterWinds()); - ncParamsMap.put(AirParcelTemp.class.getSimpleName(), new AirParcelTemp()); + ncParamsMap.put(MinDailyWeatherMapTemp.class.getSimpleName(), + new MinDailyWeatherMapTemp()); + ncParamsMap.put(MinNightTemp.class.getSimpleName(), + new MinNightTemp()); + ncParamsMap.put(MixingRatio.class.getSimpleName(), + new MixingRatio()); + ncParamsMap.put(MoistHydrostaticHeight.class.getSimpleName(), + new MoistHydrostaticHeight()); + ncParamsMap.put(MontgomeryStreamFnct.class.getSimpleName(), + new MontgomeryStreamFnct()); + ncParamsMap.put( + MountainObscThreshMetIndicator.class.getSimpleName(), + new MountainObscThreshMetIndicator()); + ncParamsMap.put(MountainObscThresh.class.getSimpleName(), + new MountainObscThresh()); + ncParamsMap.put(NightTempAnomaly.class.getSimpleName(), + new NightTempAnomaly()); + ncParamsMap.put(NewSnowAmount.class.getSimpleName(), + new NewSnowAmount()); + ncParamsMap.put(NightTempFcst.class.getSimpleName(), + new NightTempFcst()); + ncParamsMap.put(NumInterWinds.class.getSimpleName(), + new NumInterWinds()); + ncParamsMap.put(AirParcelTemp.class.getSimpleName(), + new AirParcelTemp()); ncParamsMap.put(Omega.class.getSimpleName(), new Omega()); - ncParamsMap.put(PeakWindDir.class.getSimpleName(), new PeakWindDir()); - ncParamsMap.put(PeakWindSpeed.class.getSimpleName(), new PeakWindSpeed()); - ncParamsMap.put(PeakWindSpeedTime.class.getSimpleName(), new PeakWindSpeedTime()); - ncParamsMap.put(InstrumentWavePeriod.class.getSimpleName(), new InstrumentWavePeriod()); - ncParamsMap.put(PredomSwellWavePeriod.class.getSimpleName(), new PredomSwellWavePeriod()); - ncParamsMap.put(SecondarySwellWavePeriod.class.getSimpleName(), new SecondarySwellWavePeriod()); + ncParamsMap.put(PeakWindDir.class.getSimpleName(), + new PeakWindDir()); + ncParamsMap.put(PeakWindSpeed.class.getSimpleName(), + new PeakWindSpeed()); + ncParamsMap.put(PeakWindSpeedTime.class.getSimpleName(), + new PeakWindSpeedTime()); + ncParamsMap.put(InstrumentWavePeriod.class.getSimpleName(), + new InstrumentWavePeriod()); + ncParamsMap.put(PredomSwellWavePeriod.class.getSimpleName(), + new PredomSwellWavePeriod()); + ncParamsMap.put(SecondarySwellWavePeriod.class.getSimpleName(), + new SecondarySwellWavePeriod()); ncParamsMap.put(WavePeriod.class.getSimpleName(), new WavePeriod()); - ncParamsMap.put(WindWavePeriod.class.getSimpleName(), new WindWavePeriod()); - ncParamsMap.put(PerpendicularWindComp.class.getSimpleName(), new PerpendicularWindComp()); - ncParamsMap.put(PotentialTemp.class.getSimpleName(), new PotentialTemp()); - ncParamsMap.put(PotentialTempAt10Meters.class.getSimpleName(), new PotentialTempAt10Meters()); - ncParamsMap.put(PlatformTrueDirection.class.getSimpleName(), new PlatformTrueDirection()); - ncParamsMap.put(PlatformTrueSpeed.class.getSimpleName(), new PlatformTrueSpeed()); - ncParamsMap.put(PotentialTempLapseRate.class.getSimpleName(), new PotentialTempLapseRate()); - ncParamsMap.put(PrecipitableWaterForEntireSounding.class.getSimpleName(), new PrecipitableWaterForEntireSounding()); - ncParamsMap.put(PrecipitableWaterUptoSpecifiedLevel.class.getSimpleName(), new PrecipitableWaterUptoSpecifiedLevel()); - ncParamsMap.put(Precipitation.class.getSimpleName(), new Precipitation()); + ncParamsMap.put(WindWavePeriod.class.getSimpleName(), + new WindWavePeriod()); + ncParamsMap.put(PerpendicularWindComp.class.getSimpleName(), + new PerpendicularWindComp()); + ncParamsMap.put(PotentialTemp.class.getSimpleName(), + new PotentialTemp()); + ncParamsMap.put(PotentialTempAt10Meters.class.getSimpleName(), + new PotentialTempAt10Meters()); + ncParamsMap.put(PlatformTrueDirection.class.getSimpleName(), + new PlatformTrueDirection()); + ncParamsMap.put(PlatformTrueSpeed.class.getSimpleName(), + new PlatformTrueSpeed()); + ncParamsMap.put(PotentialTempLapseRate.class.getSimpleName(), + new PotentialTempLapseRate()); + ncParamsMap.put( + PrecipitableWaterForEntireSounding.class.getSimpleName(), + new PrecipitableWaterForEntireSounding()); + ncParamsMap.put( + PrecipitableWaterUptoSpecifiedLevel.class.getSimpleName(), + new PrecipitableWaterUptoSpecifiedLevel()); + ncParamsMap.put(Precipitation.class.getSimpleName(), + new Precipitation()); ncParamsMap.put(Precip01Hr.class.getSimpleName(), new Precip01Hr()); ncParamsMap.put(Precip03Hr.class.getSimpleName(), new Precip03Hr()); ncParamsMap.put(Precip06Hr.class.getSimpleName(), new Precip06Hr()); - // ncParamsMap.put( PrecipitationIn09Hours.class.getSimpleName(), new PrecipitationIn09Hours() ); + // ncParamsMap.put( PrecipitationIn09Hours.class.getSimpleName(), + // new PrecipitationIn09Hours() ); ncParamsMap.put(Precip12Hr.class.getSimpleName(), new Precip12Hr()); ncParamsMap.put(Precip18Hr.class.getSimpleName(), new Precip18Hr()); ncParamsMap.put(Precip24Hr.class.getSimpleName(), new Precip24Hr()); - ncParamsMap.put(PresentWeather.class.getSimpleName(), new PresentWeather()); - ncParamsMap.put(PressureLevel.class.getSimpleName(), new PressureLevel()); - ncParamsMap.put(PressChange3Hr.class.getSimpleName(), new PressChange3Hr()); + ncParamsMap.put(PresentWeather.class.getSimpleName(), + new PresentWeather()); + ncParamsMap.put(PressureLevel.class.getSimpleName(), + new PressureLevel()); + ncParamsMap.put(PressChange3Hr.class.getSimpleName(), + new PressChange3Hr()); // TTR 923 - ncParamsMap.put(PressChange3HrAbsVal.class.getSimpleName(), new PressChange3HrAbsVal()); - ncParamsMap.put(PressureChange3HrAndTendency.class.getSimpleName(), new PressureChange3HrAndTendency()); + ncParamsMap.put(PressChange3HrAbsVal.class.getSimpleName(), + new PressChange3HrAbsVal()); + ncParamsMap.put(PressureChange3HrAndTendency.class.getSimpleName(), + new PressureChange3HrAndTendency()); - ncParamsMap.put(PressChange24Hr.class.getSimpleName(), new PressChange24Hr()); - ncParamsMap.put(PressureTendencySymbol.class.getSimpleName(), new PressureTendencySymbol()); - ncParamsMap.put(POPFcst06Hrs.class.getSimpleName(), new POPFcst06Hrs()); - ncParamsMap.put(POPFcst12Hrs.class.getSimpleName(), new POPFcst12Hrs()); - ncParamsMap.put(POPFcst24Hrs.class.getSimpleName(), new POPFcst24Hrs()); - ncParamsMap.put(POPAnomalyIn12hrs.class.getSimpleName(), new POPAnomalyIn12hrs()); - ncParamsMap.put(POPAnomalyIn12hrs.class.getSimpleName(), new POPAnomalyIn12hrs()); + ncParamsMap.put(PressChange24Hr.class.getSimpleName(), + new PressChange24Hr()); + ncParamsMap.put(PressureTendencySymbol.class.getSimpleName(), + new PressureTendencySymbol()); + ncParamsMap.put(POPFcst06Hrs.class.getSimpleName(), + new POPFcst06Hrs()); + ncParamsMap.put(POPFcst12Hrs.class.getSimpleName(), + new POPFcst12Hrs()); + ncParamsMap.put(POPFcst24Hrs.class.getSimpleName(), + new POPFcst24Hrs()); + ncParamsMap.put(POPAnomalyIn12hrs.class.getSimpleName(), + new POPAnomalyIn12hrs()); + ncParamsMap.put(POPAnomalyIn12hrs.class.getSimpleName(), + new POPAnomalyIn12hrs()); ncParamsMap.put(POP01Hr.class.getSimpleName(), new POP01Hr()); ncParamsMap.put(POP03Hrs.class.getSimpleName(), new POP03Hrs()); ncParamsMap.put(POP06Hrs.class.getSimpleName(), new POP06Hrs()); ncParamsMap.put(POP12Hrs.class.getSimpleName(), new POP12Hrs()); ncParamsMap.put(POP24Hrs.class.getSimpleName(), new POP24Hrs()); - ncParamsMap.put(POPAnomalyIn24hrs.class.getSimpleName(), new POPAnomalyIn24hrs()); - ncParamsMap.put(QuantPrecipFcstBestCat06Hr.class.getSimpleName(), new QuantPrecipFcstBestCat06Hr()); - ncParamsMap.put(QuantPrecipFcstBestCat12Hr.class.getSimpleName(), new QuantPrecipFcstBestCat12Hr()); - ncParamsMap.put(QuantPrecipFcstBestCat24Hr.class.getSimpleName(), new QuantPrecipFcstBestCat24Hr()); - ncParamsMap.put(RateOfIceAccretionOnVesselInSaltWater.class.getSimpleName(), new RateOfIceAccretionOnVesselInSaltWater()); - ncParamsMap.put(RelativeHumidity.class.getSimpleName(), new RelativeHumidity()); - ncParamsMap.put(RelFreqPrecip24HrsClim.class.getSimpleName(), new RelFreqPrecip24HrsClim()); - ncParamsMap.put(RichardsonNumber.class.getSimpleName(), new RichardsonNumber()); - ncParamsMap.put(SatEquivPotentialTemp.class.getSimpleName(), new SatEquivPotentialTemp()); - ncParamsMap.put(SatMixingRatio.class.getSimpleName(), new SatMixingRatio()); - ncParamsMap.put(SatVaporPressure.class.getSimpleName(), new SatVaporPressure()); - ncParamsMap.put(SeaIceDriftDist.class.getSimpleName(), new SeaIceDriftDist()); - ncParamsMap.put(SeaLevelPressure.class.getSimpleName(), new SeaLevelPressure()); - ncParamsMap.put(SeaSurfaceTemp.class.getSimpleName(), new SeaSurfaceTemp()); - ncParamsMap.put(ShowalterIndex.class.getSimpleName(), new ShowalterIndex()); - ncParamsMap.put(SkinTemperature.class.getSimpleName(), new SkinTemperature()); - ncParamsMap.put(SkyCoverage.class.getSimpleName(), new SkyCoverage()); - ncParamsMap.put(SnowDepth.class.getSimpleName(), new SnowDepth()); - ncParamsMap.put(SnowIcePelletWatchThresh.class.getSimpleName(), new SnowIcePelletWatchThresh()); - ncParamsMap.put(SpeedOf05SecPeakWind.class.getSimpleName(), new SpeedOf05SecPeakWind()); - ncParamsMap.put(SpecificHumidity.class.getSimpleName(), new SpecificHumidity()); - ncParamsMap.put(SpecificHumidityAt02Meters.class.getSimpleName(), new SpecificHumidityAt02Meters()); - ncParamsMap.put(SpecificHumidityAt10Meters.class.getSimpleName(), new SpecificHumidityAt10Meters()); - ncParamsMap.put(StabilityWithRespectToPressure.class.getSimpleName(), new StabilityWithRespectToPressure()); - ncParamsMap.put(StationElevation.class.getSimpleName(), new StationElevation()); - ncParamsMap.put(StationID.class.getSimpleName(), new StationID()); - ncParamsMap.put(StationLatitude.class.getSimpleName(), new StationLatitude()); - ncParamsMap.put(StationLongitude.class.getSimpleName(), new StationLongitude()); - ncParamsMap.put(StationName.class.getSimpleName(), new StationName()); - ncParamsMap.put(SurfacePressure.class.getSimpleName(), new SurfacePressure()); - ncParamsMap.put(StormMotionSpeed.class.getSimpleName(), new StormMotionSpeed()); - ncParamsMap.put(StormMotionDirection.class.getSimpleName(), new StormMotionDirection()); - // ncParamsMap.put( SumOfFour6HrPrecipitation.class.getSimpleName(), new SumOfFour6HrPrecipitation() ); - ncParamsMap.put(SunshineDuration.class.getSimpleName(), new SunshineDuration()); - ncParamsMap.put(SurfaceEquivPotentialTemp.class.getSimpleName(), new SurfaceEquivPotentialTemp()); - ncParamsMap.put(SurfaceMixingRatio.class.getSimpleName(), new SurfaceMixingRatio()); - ncParamsMap.put(SurfacePotentialTemp.class.getSimpleName(), new SurfacePotentialTemp()); - ncParamsMap.put(SurfacePressure.class.getSimpleName(), new SurfacePressure()); - ncParamsMap.put(SurfaceSatEquivPotentialTemp.class.getSimpleName(), new SurfaceSatEquivPotentialTemp()); - ncParamsMap.put(SurfaceSatMixingRatio.class.getSimpleName(), new SurfaceSatMixingRatio()); - ncParamsMap.put(AirTemperature.class.getSimpleName(), new AirTemperature()); - ncParamsMap.put(TempLapseRate.class.getSimpleName(), new TempLapseRate()); - ncParamsMap.put(ProbableCeiling.class.getSimpleName(), new ProbableCeiling()); - ncParamsMap.put(ProbableCeilingAsMeanSeaLevel.class.getSimpleName(), new ProbableCeilingAsMeanSeaLevel()); - ncParamsMap.put(ProbableFlightRuleIdentifier.class.getSimpleName(), new ProbableFlightRuleIdentifier()); - ncParamsMap.put(ProbableMountainObscThreshMetIndicator.class.getSimpleName(), new ProbableMountainObscThreshMetIndicator()); - ncParamsMap.put(ProbableVisibility.class.getSimpleName(), new ProbableVisibility()); - ncParamsMap.put(ProbableWindDirection.class.getSimpleName(), new ProbableWindDirection()); - ncParamsMap.put(ProbableWindGust.class.getSimpleName(), new ProbableWindGust()); - ncParamsMap.put(ProbableWindSpeed.class.getSimpleName(), new ProbableWindSpeed()); - // ncParamsMap.put( ThunderstormOccurring2hr.class.getSimpleName(), new ThunderstormOccurring2hr() ); - // ncParamsMap.put( ThunderstormOccurring6hr.class.getSimpleName(), new ThunderstormOccurring6hr() ); - // ncParamsMap.put( ThunderstormOccurring12hr.class.getSimpleName(), new ThunderstormOccurring12hr() ); - // ncParamsMap.put( ThunderstormOccurring24hr.class.getSimpleName(), new ThunderstormOccurring24hr() ); - ncParamsMap.put(ShipIceThickness.class.getSimpleName(), new ShipIceThickness()); - ncParamsMap.put(StationNumber.class.getSimpleName(), new StationNumber()); - ncParamsMap.put(TopOfIcing.class.getSimpleName(), new TopOfIcing()); - ncParamsMap.put(TopOfTurbulence.class.getSimpleName(), new TopOfTurbulence()); - ncParamsMap.put(TopOfWeather.class.getSimpleName(), new TopOfWeather()); - ncParamsMap.put(TotalSkyCoverFcst12hr.class.getSimpleName(), new TotalSkyCoverFcst12hr()); - ncParamsMap.put(TotalPrecip.class.getSimpleName(), new TotalPrecip()); - ncParamsMap.put(TotalSkyCoverFcst12hr.class.getSimpleName(), new TotalSkyCoverFcst12hr()); - ncParamsMap.put(TurbulenceFrequencySymbol.class.getSimpleName(), new TurbulenceFrequencySymbol()); - ncParamsMap.put(TurbulenceIntensitySymbol.class.getSimpleName(), new TurbulenceIntensitySymbol()); - ncParamsMap.put(TurbulenceTypeSymbol.class.getSimpleName(), new TurbulenceTypeSymbol()); - ncParamsMap.put(TurbulentKineticEnergy.class.getSimpleName(), new TurbulentKineticEnergy()); - ncParamsMap.put(EstStormDirectionUComp.class.getSimpleName(), new EstStormDirectionUComp()); - ncParamsMap.put(UCompAt10Meters.class.getSimpleName(), new UCompAt10Meters()); - ncParamsMap.put(UncondProbOf06HrSevereWeather.class.getSimpleName(), new UncondProbOf06HrSevereWeather()); - ncParamsMap.put(UncondProbOf12HrSevereWeather.class.getSimpleName(), new UncondProbOf12HrSevereWeather()); - ncParamsMap.put(UncondProbOf24HrSevereWeather.class.getSimpleName(), new UncondProbOf24HrSevereWeather()); + ncParamsMap.put(POPAnomalyIn24hrs.class.getSimpleName(), + new POPAnomalyIn24hrs()); + ncParamsMap.put(QuantPrecipFcstBestCat06Hr.class.getSimpleName(), + new QuantPrecipFcstBestCat06Hr()); + ncParamsMap.put(QuantPrecipFcstBestCat12Hr.class.getSimpleName(), + new QuantPrecipFcstBestCat12Hr()); + ncParamsMap.put(QuantPrecipFcstBestCat24Hr.class.getSimpleName(), + new QuantPrecipFcstBestCat24Hr()); + ncParamsMap + .put(RateOfIceAccretionOnVesselInSaltWater.class + .getSimpleName(), + new RateOfIceAccretionOnVesselInSaltWater()); + ncParamsMap.put(RelativeHumidity.class.getSimpleName(), + new RelativeHumidity()); + ncParamsMap.put(RelFreqPrecip24HrsClim.class.getSimpleName(), + new RelFreqPrecip24HrsClim()); + ncParamsMap.put(RichardsonNumber.class.getSimpleName(), + new RichardsonNumber()); + ncParamsMap.put(SatEquivPotentialTemp.class.getSimpleName(), + new SatEquivPotentialTemp()); + ncParamsMap.put(SatMixingRatio.class.getSimpleName(), + new SatMixingRatio()); + ncParamsMap.put(SatVaporPressure.class.getSimpleName(), + new SatVaporPressure()); + ncParamsMap.put(SeaIceDriftDist.class.getSimpleName(), + new SeaIceDriftDist()); + ncParamsMap.put(SeaLevelPressure.class.getSimpleName(), + new SeaLevelPressure()); + ncParamsMap.put(SeaSurfaceTemp.class.getSimpleName(), + new SeaSurfaceTemp()); + ncParamsMap.put(ShowalterIndex.class.getSimpleName(), + new ShowalterIndex()); - ncParamsMap.put(UncondProbOfTstorms2hr.class.getSimpleName(), new UncondProbOfTstorms2hr()); - ncParamsMap.put(UncondProbOfTstorms6hr.class.getSimpleName(), new UncondProbOfTstorms6hr()); - ncParamsMap.put(UncondProbOfTstorms12hr.class.getSimpleName(), new UncondProbOfTstorms12hr()); - ncParamsMap.put(UncondProbOfTstorms24hr.class.getSimpleName(), new UncondProbOfTstorms24hr()); - ncParamsMap.put(VCompAt10Meters.class.getSimpleName(), new VCompAt10Meters()); - ncParamsMap.put(WindDirectionUComp.class.getSimpleName(), new WindDirectionUComp()); - ncParamsMap.put(VaporPressure.class.getSimpleName(), new VaporPressure()); - ncParamsMap.put(EstStormDirectionVComp.class.getSimpleName(), new EstStormDirectionVComp()); - ncParamsMap.put(IsentropesVerticalSeparation.class.getSimpleName(), new IsentropesVerticalSeparation()); - ncParamsMap.put(VerticalVelocity.class.getSimpleName(), new VerticalVelocity()); - ncParamsMap.put(VirtualPotentialTemp.class.getSimpleName(), new VirtualPotentialTemp()); - ncParamsMap.put(VirtualTemp.class.getSimpleName(), new VirtualTemp()); + // Redmine 4318 + ncParamsMap.put(SignificantWaveHeight.class.getSimpleName(), + new SignificantWaveHeight()); + + ncParamsMap.put(SkinTemperature.class.getSimpleName(), + new SkinTemperature()); + ncParamsMap.put(SkyCoverage.class.getSimpleName(), + new SkyCoverage()); + ncParamsMap.put(SnowDepth.class.getSimpleName(), new SnowDepth()); + ncParamsMap.put(SnowIcePelletWatchThresh.class.getSimpleName(), + new SnowIcePelletWatchThresh()); + ncParamsMap.put(SpeedOf05SecPeakWind.class.getSimpleName(), + new SpeedOf05SecPeakWind()); + ncParamsMap.put(SpecificHumidity.class.getSimpleName(), + new SpecificHumidity()); + ncParamsMap.put(SpecificHumidityAt02Meters.class.getSimpleName(), + new SpecificHumidityAt02Meters()); + ncParamsMap.put(SpecificHumidityAt10Meters.class.getSimpleName(), + new SpecificHumidityAt10Meters()); + ncParamsMap.put( + StabilityWithRespectToPressure.class.getSimpleName(), + new StabilityWithRespectToPressure()); + ncParamsMap.put(StationElevation.class.getSimpleName(), + new StationElevation()); + ncParamsMap.put(StationID.class.getSimpleName(), new StationID()); + ncParamsMap.put(StationLatitude.class.getSimpleName(), + new StationLatitude()); + ncParamsMap.put(StationLongitude.class.getSimpleName(), + new StationLongitude()); + ncParamsMap.put(StationName.class.getSimpleName(), + new StationName()); + ncParamsMap.put(SurfacePressure.class.getSimpleName(), + new SurfacePressure()); + ncParamsMap.put(StormMotionSpeed.class.getSimpleName(), + new StormMotionSpeed()); + ncParamsMap.put(StormMotionDirection.class.getSimpleName(), + new StormMotionDirection()); + // ncParamsMap.put( SumOfFour6HrPrecipitation.class.getSimpleName(), + // new SumOfFour6HrPrecipitation() ); + ncParamsMap.put(SunshineDuration.class.getSimpleName(), + new SunshineDuration()); + ncParamsMap.put(SurfaceEquivPotentialTemp.class.getSimpleName(), + new SurfaceEquivPotentialTemp()); + ncParamsMap.put(SurfaceMixingRatio.class.getSimpleName(), + new SurfaceMixingRatio()); + ncParamsMap.put(SurfacePotentialTemp.class.getSimpleName(), + new SurfacePotentialTemp()); + ncParamsMap.put(SurfacePressure.class.getSimpleName(), + new SurfacePressure()); + ncParamsMap.put(SurfaceSatEquivPotentialTemp.class.getSimpleName(), + new SurfaceSatEquivPotentialTemp()); + ncParamsMap.put(SurfaceSatMixingRatio.class.getSimpleName(), + new SurfaceSatMixingRatio()); + ncParamsMap.put(AirTemperature.class.getSimpleName(), + new AirTemperature()); + ncParamsMap.put(TempLapseRate.class.getSimpleName(), + new TempLapseRate()); + ncParamsMap.put(ProbableCeiling.class.getSimpleName(), + new ProbableCeiling()); + ncParamsMap.put( + ProbableCeilingAsMeanSeaLevel.class.getSimpleName(), + new ProbableCeilingAsMeanSeaLevel()); + ncParamsMap.put(ProbableFlightRuleIdentifier.class.getSimpleName(), + new ProbableFlightRuleIdentifier()); + ncParamsMap.put(ProbableMountainObscThreshMetIndicator.class + .getSimpleName(), + new ProbableMountainObscThreshMetIndicator()); + ncParamsMap.put(ProbableVisibility.class.getSimpleName(), + new ProbableVisibility()); + ncParamsMap.put(ProbableWindDirection.class.getSimpleName(), + new ProbableWindDirection()); + ncParamsMap.put(ProbableWindGust.class.getSimpleName(), + new ProbableWindGust()); + ncParamsMap.put(ProbableWindSpeed.class.getSimpleName(), + new ProbableWindSpeed()); + // ncParamsMap.put( ThunderstormOccurring2hr.class.getSimpleName(), + // new ThunderstormOccurring2hr() ); + // ncParamsMap.put( ThunderstormOccurring6hr.class.getSimpleName(), + // new ThunderstormOccurring6hr() ); + // ncParamsMap.put( ThunderstormOccurring12hr.class.getSimpleName(), + // new ThunderstormOccurring12hr() ); + // ncParamsMap.put( ThunderstormOccurring24hr.class.getSimpleName(), + // new ThunderstormOccurring24hr() ); + ncParamsMap.put(ShipIceThickness.class.getSimpleName(), + new ShipIceThickness()); + ncParamsMap.put(StationNumber.class.getSimpleName(), + new StationNumber()); + ncParamsMap.put(TopOfIcing.class.getSimpleName(), new TopOfIcing()); + ncParamsMap.put(TopOfTurbulence.class.getSimpleName(), + new TopOfTurbulence()); + ncParamsMap.put(TopOfWeather.class.getSimpleName(), + new TopOfWeather()); + ncParamsMap.put(TotalSkyCoverFcst12hr.class.getSimpleName(), + new TotalSkyCoverFcst12hr()); + ncParamsMap.put(TotalPrecip.class.getSimpleName(), + new TotalPrecip()); + ncParamsMap.put(TotalSkyCoverFcst12hr.class.getSimpleName(), + new TotalSkyCoverFcst12hr()); + ncParamsMap.put(TurbulenceFrequencySymbol.class.getSimpleName(), + new TurbulenceFrequencySymbol()); + ncParamsMap.put(TurbulenceIntensitySymbol.class.getSimpleName(), + new TurbulenceIntensitySymbol()); + ncParamsMap.put(TurbulenceTypeSymbol.class.getSimpleName(), + new TurbulenceTypeSymbol()); + ncParamsMap.put(TurbulentKineticEnergy.class.getSimpleName(), + new TurbulentKineticEnergy()); + ncParamsMap.put(EstStormDirectionUComp.class.getSimpleName(), + new EstStormDirectionUComp()); + ncParamsMap.put(UCompAt10Meters.class.getSimpleName(), + new UCompAt10Meters()); + ncParamsMap.put( + UncondProbOf06HrSevereWeather.class.getSimpleName(), + new UncondProbOf06HrSevereWeather()); + ncParamsMap.put( + UncondProbOf12HrSevereWeather.class.getSimpleName(), + new UncondProbOf12HrSevereWeather()); + ncParamsMap.put( + UncondProbOf24HrSevereWeather.class.getSimpleName(), + new UncondProbOf24HrSevereWeather()); + + ncParamsMap.put(UncondProbOfTstorms2hr.class.getSimpleName(), + new UncondProbOfTstorms2hr()); + ncParamsMap.put(UncondProbOfTstorms6hr.class.getSimpleName(), + new UncondProbOfTstorms6hr()); + ncParamsMap.put(UncondProbOfTstorms12hr.class.getSimpleName(), + new UncondProbOfTstorms12hr()); + ncParamsMap.put(UncondProbOfTstorms24hr.class.getSimpleName(), + new UncondProbOfTstorms24hr()); + ncParamsMap.put(VCompAt10Meters.class.getSimpleName(), + new VCompAt10Meters()); + ncParamsMap.put(WindDirectionUComp.class.getSimpleName(), + new WindDirectionUComp()); + ncParamsMap.put(VaporPressure.class.getSimpleName(), + new VaporPressure()); + ncParamsMap.put(EstStormDirectionVComp.class.getSimpleName(), + new EstStormDirectionVComp()); + ncParamsMap.put(IsentropesVerticalSeparation.class.getSimpleName(), + new IsentropesVerticalSeparation()); + ncParamsMap.put(VerticalVelocity.class.getSimpleName(), + new VerticalVelocity()); + ncParamsMap.put(VirtualPotentialTemp.class.getSimpleName(), + new VirtualPotentialTemp()); + ncParamsMap.put(VirtualTemp.class.getSimpleName(), + new VirtualTemp()); ncParamsMap.put(Visibility.class.getSimpleName(), new Visibility()); - ncParamsMap.put(WindDirectionVComp.class.getSimpleName(), new WindDirectionVComp()); - ncParamsMap.put(WaterEquivOfNewSnow.class.getSimpleName(), new WaterEquivOfNewSnow()); - ncParamsMap.put(WaveSteepness.class.getSimpleName(), new WaveSteepness()); - ncParamsMap.put(WetBulbPotentialTemp.class.getSimpleName(), new WetBulbPotentialTemp()); - ncParamsMap.put(WetBulbTemp.class.getSimpleName(), new WetBulbTemp()); - // ncParamsMap.put( WindBarb.class.getSimpleName(), new WindBarb() ); - ncParamsMap.put(WindChillEquivalentTemp.class.getSimpleName(), new WindChillEquivalentTemp()); - ncParamsMap.put(WindChillTemperature.class.getSimpleName(), new WindChillTemperature()); - ncParamsMap.put(WindSpeedComp.class.getSimpleName(), new WindSpeedComp()); - ncParamsMap.put(WindCompDirection.class.getSimpleName(), new WindCompDirection()); - ncParamsMap.put(WindDirection.class.getSimpleName(), new WindDirection()); + ncParamsMap.put(WindDirectionVComp.class.getSimpleName(), + new WindDirectionVComp()); + ncParamsMap.put(WaterEquivOfNewSnow.class.getSimpleName(), + new WaterEquivOfNewSnow()); + ncParamsMap.put(WaveSteepness.class.getSimpleName(), + new WaveSteepness()); + ncParamsMap.put(WetBulbPotentialTemp.class.getSimpleName(), + new WetBulbPotentialTemp()); + ncParamsMap.put(WetBulbTemp.class.getSimpleName(), + new WetBulbTemp()); + // ncParamsMap.put( WindBarb.class.getSimpleName(), new WindBarb() + // ); + ncParamsMap.put(WindChillEquivalentTemp.class.getSimpleName(), + new WindChillEquivalentTemp()); + ncParamsMap.put(WindChillTemperature.class.getSimpleName(), + new WindChillTemperature()); + ncParamsMap.put(WindSpeedComp.class.getSimpleName(), + new WindSpeedComp()); + ncParamsMap.put(WindCompDirection.class.getSimpleName(), + new WindCompDirection()); + ncParamsMap.put(WindDirection.class.getSimpleName(), + new WindDirection()); ncParamsMap.put(WindGust.class.getSimpleName(), new WindGust()); ncParamsMap.put(WindSpeed.class.getSimpleName(), new WindSpeed()); - ncParamsMap.put(CeilingFromSeaLevelWorstCase.class.getSimpleName(), new CeilingFromSeaLevelWorstCase()); - ncParamsMap.put(FlightRulesIdWorstCase.class.getSimpleName(), new FlightRulesIdWorstCase()); - ncParamsMap.put(MountainObscThreshMetIndicatorWorstCase.class.getSimpleName(), new MountainObscThreshMetIndicatorWorstCase()); - ncParamsMap.put(Probability.class.getSimpleName(), new Probability()); - ncParamsMap.put(ProbableSkyCoverage.class.getSimpleName(), new ProbableSkyCoverage()); - ncParamsMap.put(ReportTimeInHourMins.class.getSimpleName(), new ReportTimeInHourMins()); - ncParamsMap.put(ProbablePresentWeather.class.getSimpleName(), new ProbablePresentWeather()); - ncParamsMap.put(LowLevelWindShear.class.getSimpleName(), new LowLevelWindShear()); + ncParamsMap.put(CeilingFromSeaLevelWorstCase.class.getSimpleName(), + new CeilingFromSeaLevelWorstCase()); + ncParamsMap.put(FlightRulesIdWorstCase.class.getSimpleName(), + new FlightRulesIdWorstCase()); + ncParamsMap.put(MountainObscThreshMetIndicatorWorstCase.class + .getSimpleName(), + new MountainObscThreshMetIndicatorWorstCase()); + ncParamsMap.put(Probability.class.getSimpleName(), + new Probability()); + ncParamsMap.put(ProbableSkyCoverage.class.getSimpleName(), + new ProbableSkyCoverage()); + ncParamsMap.put(ReportTimeInHourMins.class.getSimpleName(), + new ReportTimeInHourMins()); + ncParamsMap.put(ProbablePresentWeather.class.getSimpleName(), + new ProbablePresentWeather()); + ncParamsMap.put(LowLevelWindShear.class.getSimpleName(), + new LowLevelWindShear()); ncParamsMap.put(WxPresent.class.getSimpleName(), new WxPresent()); } catch (Exception e) { e.printStackTrace(); @@ -369,16 +638,19 @@ public class MetParameterFactory implements ISerializableObject { AbstractMetParameter ncParam = ncParamsMap.get(ncParamName); try { - AbstractMetParameter newParam = (AbstractMetParameter) ncParam.getClass().getConstructor().newInstance(); + AbstractMetParameter newParam = (AbstractMetParameter) ncParam + .getClass().getConstructor().newInstance(); return newParam; } catch (Exception e) { - System.out.println("error getting newInstance for metParam " + ncParam.getClass().getSimpleName()); + System.out.println("error getting newInstance for metParam " + + ncParam.getClass().getSimpleName()); } return null; } - // u is the expected units and must be compatible with the units for the implemented + // u is the expected units and must be compatible with the units for the + // implemented // Quantity. public AbstractMetParameter createParameter(String prmName, String unitName) { Unit units; @@ -387,7 +659,8 @@ public class MetParameterFactory implements ISerializableObject { units = Unit.ONE; } else { try { - units = UnitFormat.getUCUMInstance().parseProductUnit(unitName, new ParsePosition(0)); + units = UnitFormat.getUCUMInstance().parseProductUnit(unitName, + new ParsePosition(0)); } catch (ParseException e) { System.out.println("unable to determine units for " + unitName); return null; @@ -399,7 +672,7 @@ public class MetParameterFactory implements ISerializableObject { // create a parameter value with MISSING value. // name may be an alias, or the name of the parameter - // + // public AbstractMetParameter createParameter(String prmName, Unit u) { AbstractMetParameter newParam = createParameter(prmName); newParam.setUnitPair(u); @@ -412,7 +685,8 @@ public class MetParameterFactory implements ISerializableObject { return newParam; } - public AbstractMetParameter createParameter(String prmName, Unit u, DataTime dt) { + public AbstractMetParameter createParameter(String prmName, Unit u, + DataTime dt) { AbstractMetParameter newParam = createParameter(prmName); newParam.setValidTime(dt); newParam.setUnitPair(u); @@ -421,9 +695,12 @@ public class MetParameterFactory implements ISerializableObject { public boolean alias(String prmName, String alias) { - if (ncParamsAliasMap.containsKey(alias) && !ncParamsAliasMap.get(alias).equals(prmName)) { - System.out.println("Error aliasing ncParam " + prmName + " : " + alias + " is already aliased to " + ncParamsAliasMap.get(alias)); - // return false; + if (ncParamsAliasMap.containsKey(alias) + && !ncParamsAliasMap.get(alias).equals(prmName)) { + System.out.println("Error aliasing ncParam " + prmName + " : " + + alias + " is already aliased to " + + ncParamsAliasMap.get(alias)); + // return false; } ncParamsAliasMap.put(alias, prmName); diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/PressureChange3HrAndTendency.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/PressureChange3HrAndTendency.java index 08f66d1ffa..37a0af0164 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/PressureChange3HrAndTendency.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/PressureChange3HrAndTendency.java @@ -21,7 +21,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize -public class PressureChange3HrAndTendency extends AbstractMetParameter implements Dimensionless, ISerializableObject { +public class PressureChange3HrAndTendency extends AbstractMetParameter + implements Dimensionless, ISerializableObject { @DynamicSerializeElement private static final long serialVersionUID = -6602297437762954327L; @@ -32,7 +33,9 @@ public class PressureChange3HrAndTendency extends AbstractMetParameter implement } @DeriveMethod - public PressureChange3HrAndTendency derive(PressChange3HrAbsVal p, PressureTendencySymbol ptsy) throws InvalidValueException, NullPointerException { + public PressureChange3HrAndTendency derive(PressChange3HrAbsVal p, + PressureTendencySymbol ptsy) throws InvalidValueException, + NullPointerException { if (p.hasValidValue() && ptsy.hasValidValue()) { Number n = (Number) new Integer(ptsy.getStringValue()); diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/SignificantWaveHeight.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/SignificantWaveHeight.java new file mode 100644 index 0000000000..52a252c51e --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/SignificantWaveHeight.java @@ -0,0 +1,59 @@ +package gov.noaa.nws.ncep.edex.common.metparameters; + +import gov.noaa.nws.ncep.edex.common.metparameters.MetParameterFactory.DeriveMethod; +import gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion.PRLibrary; +import gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion.PRLibrary.InvalidValueException; + +import javax.measure.quantity.Dimensionless; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#      Engineer    Description
+ * ------------ ----------   ----------- --------------------------
+ * Sep 26, 2014 Redmine 4318 srussell    Initial creation
+ * 
+ * 
+ * + * @author srussell + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class SignificantWaveHeight extends AbstractMetParameter implements + Dimensionless, ISerializableObject { + + @DynamicSerializeElement + private static final long serialVersionUID = 1L; + + public SignificantWaveHeight() { + super(UNIT); + } + + @DeriveMethod + public SignificantWaveHeight derive(WindWaveHeight w, + PredomSwellWaveHeight p) throws InvalidValueException, + NullPointerException { + + if (w.hasValidValue() && p.hasValidValue()) { + Amount swh = PRLibrary.prSGHT(w, p); + this.setValue(swh); + } else { + this.setValueToMissing(); + } + + return this; + } + +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/parameterconversion/PRLibrary.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/parameterconversion/PRLibrary.java index a841044b5a..7251dfca5d 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/parameterconversion/PRLibrary.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/metparameters/parameterconversion/PRLibrary.java @@ -42,7 +42,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prAltp(Amount pres, Amount selv) throws InvalidValueException, NullPointerException { + public static final Amount prAltp(Amount pres, Amount selv) + throws InvalidValueException, NullPointerException { // System.out.println("From prAltp:"); // System.out.println(" pres = " + pres.doubleValue()); // System.out.println(" selv = " + selv.doubleValue()); @@ -53,8 +54,10 @@ public final class PRLibrary { selv = checkAndConvertInputAmountToExpectedUnits(selv, SI.METER); pres = checkAndConvertInputAmountToExpectedUnits(pres, NcUnits.MILLIBAR); double seaLevelTempInKelvin = GempakConstants.TMCK + 15; - double hgtk = selv.getUnit().getConverterTo(SI.KILOMETER).convert(selv.doubleValue()); - double exponent = -(GempakConstants.GRAVTY / (GempakConstants.GAMUSD * GempakConstants.RDGAS) * 1000); + double hgtk = selv.getUnit().getConverterTo(SI.KILOMETER) + .convert(selv.doubleValue()); + double exponent = -(GempakConstants.GRAVTY + / (GempakConstants.GAMUSD * GempakConstants.RDGAS) * 1000); // double base = pres * ( 1.0f - ( hgtk * GempakConstants.GAMUSD / // seaLevelTempInKelvin ) ); // float altm = (float) Math.pow( base, Math.exp( exponent ) ); @@ -76,7 +79,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prCmsl(Amount ceil, Amount selv) throws InvalidValueException, NullPointerException { + public static final Amount prCmsl(Amount ceil, Amount selv) + throws InvalidValueException, NullPointerException { // System.out.println("From prCmsl:"); // System.out.println(" ceil = " + ceil.doubleValue()); // System.out.println(" selv = " + selv.doubleValue()); @@ -86,9 +90,12 @@ public final class PRLibrary { if (!checkNullOrInvalidValue(ceil) || !checkNullOrInvalidValue(selv)) return new Amount(NcUnits.HUNDREDS_OF_FEET); - selv = checkAndConvertInputAmountToExpectedUnits(selv, NcUnits.HUNDREDS_OF_FEET); - ceil = checkAndConvertInputAmountToExpectedUnits(ceil, NcUnits.HUNDREDS_OF_FEET); - return (new Amount(selv.doubleValue() + ceil.doubleValue(), NcUnits.HUNDREDS_OF_FEET)); + selv = checkAndConvertInputAmountToExpectedUnits(selv, + NcUnits.HUNDREDS_OF_FEET); + ceil = checkAndConvertInputAmountToExpectedUnits(ceil, + NcUnits.HUNDREDS_OF_FEET); + return (new Amount(selv.doubleValue() + ceil.doubleValue(), + NcUnits.HUNDREDS_OF_FEET)); } /** @@ -104,7 +111,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDrct(Amount uX, Amount vX) throws InvalidValueException, NullPointerException { + public static final Amount prDrct(Amount uX, Amount vX) + throws InvalidValueException, NullPointerException { // System.out.println("From prDrct:"); // System.out.println(" uX = " + uX.doubleValue()); // System.out.println(" vX = " + vX.doubleValue()); @@ -116,8 +124,10 @@ public final class PRLibrary { double vXVal = Double.NaN; double uXVal = Double.NaN; - if (uX.getUnit() != vX.getUnit() && uX.getUnit().isCompatible(vX.getUnit())) { - vXVal = vX.getUnit().getConverterTo(uX.getUnit()).convert(vX.doubleValue()); + if (uX.getUnit() != vX.getUnit() + && uX.getUnit().isCompatible(vX.getUnit())) { + vXVal = vX.getUnit().getConverterTo(uX.getUnit()) + .convert(vX.doubleValue()); vX = new Amount(vXVal, uX.getUnit()); } uXVal = uX.doubleValue(); @@ -145,7 +155,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDden(Amount pres, Amount tmpc) throws InvalidValueException, NullPointerException { + public static final Amount prDden(Amount pres, Amount tmpc) + throws InvalidValueException, NullPointerException { // System.out.println("From prDden:"); // System.out.println(" pres = " + pres.doubleValue()); // System.out.println(" tmpc = " + tmpc.doubleValue()); @@ -163,7 +174,8 @@ public final class PRLibrary { double tmpcVal = tmpc.doubleValue(); if (tmpcVal < -GempakConstants.TMCK) { - System.out.println("From prDden: temperature must be greater than or equal to -273.15 "); + System.out + .println("From prDden: temperature must be greater than or equal to -273.15 "); return new Amount(VolumetricDensity.UNIT); // throw new // InvalidRangeException("From prDden: temperature must be greater than or equal to -273.15 "); @@ -187,7 +199,8 @@ public final class PRLibrary { * both tmpx and dwpx are valid values */ - public static final Amount prDdep(Amount tmpx, Amount dwpx) throws InvalidValueException, NullPointerException { + public static final Amount prDdep(Amount tmpx, Amount dwpx) + throws InvalidValueException, NullPointerException { // System.out.println("From prDdep:"); // System.out.println(" tmpx = " + tmpx.doubleValue()); // System.out.println(" dwpx = " + dwpx.doubleValue()); @@ -221,7 +234,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDmax(Amount t00x, Amount t06x, Amount tdxc) throws InvalidValueException, NullPointerException { + public static final Amount prDmax(Amount t00x, Amount t06x, Amount tdxc) + throws InvalidValueException, NullPointerException { // System.out.println("From prDmax:"); // System.out.println(" t00x = " + t00x.doubleValue()); // System.out.println(" t06x = " + t06x.doubleValue()); @@ -238,16 +252,20 @@ public final class PRLibrary { if (tdxc != null && tdxc.doubleValue() > -9999) { tdxc = checkAndConvertInputAmountToExpectedUnits(tdxc, SI.CELSIUS); - double[] tempArray = { t00x.doubleValue(), t06x.doubleValue(), tdxc.doubleValue() }; + double[] tempArray = { t00x.doubleValue(), t06x.doubleValue(), + tdxc.doubleValue() }; Arrays.sort(tempArray); - double newTemp = SI.CELSIUS.getConverterTo(NonSI.FAHRENHEIT).convert(tempArray[2]); + double newTemp = SI.CELSIUS.getConverterTo(NonSI.FAHRENHEIT) + .convert(tempArray[2]); return (new Amount(newTemp, NonSI.FAHRENHEIT)); } else { double t00xVal = t00x.doubleValue(); double t06xVal = t06x.doubleValue(); - Amount dmax = (t00xVal > t06xVal ? checkAndConvertInputAmountToExpectedUnits(t00x, NonSI.FAHRENHEIT) - : checkAndConvertInputAmountToExpectedUnits(t06x, NonSI.FAHRENHEIT)); + Amount dmax = (t00xVal > t06xVal ? checkAndConvertInputAmountToExpectedUnits( + t00x, NonSI.FAHRENHEIT) + : checkAndConvertInputAmountToExpectedUnits(t06x, + NonSI.FAHRENHEIT)); return dmax; } @@ -270,7 +288,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDmin(Amount t12n, Amount t18n) throws InvalidValueException, NullPointerException { + public static final Amount prDmin(Amount t12n, Amount t18n) + throws InvalidValueException, NullPointerException { // System.out.println("From prDmin:"); // System.out.println(" t12n = " + t12n.doubleValue()); // System.out.println(" t18n = " + t18n.doubleValue()); @@ -281,8 +300,10 @@ public final class PRLibrary { t12n = checkAndConvertInputAmountToExpectedUnits(t12n, SI.CELSIUS); t18n = checkAndConvertInputAmountToExpectedUnits(t18n, SI.CELSIUS); - Amount minValue = (t12n.doubleValue() < t18n.doubleValue() ? t12n : t18n); - return (checkAndConvertInputAmountToExpectedUnits(minValue, NonSI.FAHRENHEIT)); + Amount minValue = (t12n.doubleValue() < t18n.doubleValue() ? t12n + : t18n); + return (checkAndConvertInputAmountToExpectedUnits(minValue, + NonSI.FAHRENHEIT)); } @@ -300,7 +321,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDwdp(Amount tmpx, Amount dpdx) throws InvalidValueException, NullPointerException { + public static final Amount prDwdp(Amount tmpx, Amount dpdx) + throws InvalidValueException, NullPointerException { // System.out.println("From prDwdp:"); // System.out.println(" tmpx = " + tmpx.doubleValue()); // System.out.println(" dpdx = " + dpdx.doubleValue()); @@ -313,12 +335,15 @@ public final class PRLibrary { Unit tempUnits = (Unit) tmpx.getUnit(); Unit dewpointDepUnits = (Unit) dpdx.getUnit(); - if (!tempUnits.equals(dewpointDepUnits) && tempUnits.isCompatible(dewpointDepUnits)) { - double dewpointDepValue = (double) dewpointDepUnits.getConverterTo(tempUnits).convert(dpdx.doubleValue()); + if (!tempUnits.equals(dewpointDepUnits) + && tempUnits.isCompatible(dewpointDepUnits)) { + double dewpointDepValue = (double) dewpointDepUnits.getConverterTo( + tempUnits).convert(dpdx.doubleValue()); dpdx = new Amount(dewpointDepValue, tempUnits); } - Amount dewpointTemperature = new Amount(tmpx.doubleValue() - dpdx.doubleValue(), tempUnits); + Amount dewpointTemperature = new Amount(tmpx.doubleValue() + - dpdx.doubleValue(), tempUnits); return dewpointTemperature; } @@ -335,7 +360,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prDwpt(Amount rmix, Amount pres) throws InvalidValueException, NullPointerException { + public static final Amount prDwpt(Amount rmix, Amount pres) + throws InvalidValueException, NullPointerException { // System.out.println("From prDwpt:"); // System.out.println(" rmix = " + rmix.doubleValue()); // System.out.println(" pres = " + pres.doubleValue()); @@ -350,7 +376,8 @@ public final class PRLibrary { double mixingRatioValue = rmix.doubleValue(); double pressureValue = pres.doubleValue(); if (mixingRatioValue <= 0) { - System.out.println("From prDwpt() - mixing ratio must be greater than 0"); + System.out + .println("From prDwpt() - mixing ratio must be greater than 0"); return new Amount(SI.CELSIUS); // throw new // InvalidRangeException("From prDwpt() - mixing ratio must be greater than 0"); @@ -368,10 +395,12 @@ public final class PRLibrary { double vaporPressure = (pressureValue * ratio) / (0.62197 + ratio); /* Correct vapor pressure */ - vaporPressure = vaporPressure / (1.001 + ((pressureValue - 100.0) / 900) * .0034); + vaporPressure = vaporPressure + / (1.001 + ((pressureValue - 100.0) / 900) * .0034); /* Calculate dewpoint */ - double dewPointValue = (double) (Math.log(vaporPressure / 6.112) * 243.5 / (17.67 - Math.log(vaporPressure / 6.112))); + double dewPointValue = (double) (Math.log(vaporPressure / 6.112) * 243.5 / (17.67 - Math + .log(vaporPressure / 6.112))); prDwpt = new Amount(dewPointValue, SI.CELSIUS); return prDwpt; } @@ -390,7 +419,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prFosb(Amount tmpc, Amount relh, Amount sped) throws InvalidValueException, NullPointerException { + public static final Amount prFosb(Amount tmpc, Amount relh, Amount sped) + throws InvalidValueException, NullPointerException { // System.out.println("From prFosb:"); // System.out.println("Temperature ( in K ) is: " + tmpc.doubleValue()); // System.out.println("Relative Humidity is: " + relh.doubleValue()); @@ -398,18 +428,22 @@ public final class PRLibrary { // checkNullOrInvalidValue( tmpc ); // checkNullOrInvalidValue( relh ); // checkNullOrInvalidValue( sped ); - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(relh) || !checkNullOrInvalidValue(sped)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(relh) + || !checkNullOrInvalidValue(sped)) return new Amount(Unit.ONE); tmpc = checkAndConvertInputAmountToExpectedUnits(tmpc, SI.CELSIUS); relh = checkAndConvertInputAmountToExpectedUnits(relh, NonSI.PERCENT); - sped = checkAndConvertInputAmountToExpectedUnits(sped, SI.METERS_PER_SECOND); + sped = checkAndConvertInputAmountToExpectedUnits(sped, + SI.METERS_PER_SECOND); /* Change temperature to degrees Fahrenheit */ - double tf = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT).convert(tmpc.doubleValue()); + double tf = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT) + .convert(tmpc.doubleValue()); /* Convert wind speed from meters/second to knots */ - double smph = sped.getUnit().getConverterTo(NonSI.MILES_PER_HOUR).convert(sped.doubleValue()); + double smph = sped.getUnit().getConverterTo(NonSI.MILES_PER_HOUR) + .convert(sped.doubleValue()); double A = 0.03229; double B = 0.281073; @@ -476,7 +510,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prHeat(Amount tmpf, Amount relh) throws InvalidValueException, NullPointerException { + public static final Amount prHeat(Amount tmpf, Amount relh) + throws InvalidValueException, NullPointerException { // System.out.println("From prHeat:"); // System.out.println(" tmpf = " + tmpf.doubleValue()); // System.out.println(" relh = " + relh.doubleValue()); @@ -491,32 +526,45 @@ public final class PRLibrary { relh = checkAndConvertInputAmountToExpectedUnits(relh, NonSI.PERCENT); double tmpfVal = tmpf.doubleValue(); double relhVal = relh.doubleValue(); - /* If the temperature is less than 40 degrees, set the heat index to the - * temperature */ + /* + * If the temperature is less than 40 degrees, set the heat index to the + * temperature + */ if (tmpfVal <= 40) prheat = tmpfVal; else { - /* Compute a simple heat index. If the value is less than 80 deg F - * use it */ + /* + * Compute a simple heat index. If the value is less than 80 deg F + * use it + */ prheat = (float) (61 + (tmpfVal - 68) * 1.2 + relhVal * 0.094); prheat = (float) ((tmpfVal + prheat) * 0.5); /* Else compute the full regression value */ if (prheat >= 80.0) { double t2 = tmpfVal * tmpfVal; double r2 = relhVal * relhVal; - prheat = (float) (-42.379 + 2.04901523 * tmpfVal + 10.14333127 * relhVal - 0.22475541 * tmpfVal * relhVal - 0.00683783 * t2 - 0.05481717 * r2 + 0.00122874 * t2 - * relhVal + 0.00085282 * tmpfVal * r2 - 0.00000199 * t2 * r2); - /* Adjust for high regression at low relative humidity for - * temperatures above 80 degrees F. */ - if ((relhVal <= 13.0) && ((tmpfVal >= 80.0) && (tmpfVal <= 112.0))) { + prheat = (float) (-42.379 + 2.04901523 * tmpfVal + 10.14333127 + * relhVal - 0.22475541 * tmpfVal * relhVal - 0.00683783 + * t2 - 0.05481717 * r2 + 0.00122874 * t2 * relhVal + + 0.00085282 * tmpfVal * r2 - 0.00000199 * t2 * r2); + /* + * Adjust for high regression at low relative humidity for + * temperatures above 80 degrees F. + */ + if ((relhVal <= 13.0) + && ((tmpfVal >= 80.0) && (tmpfVal <= 112.0))) { float adj1 = (float) ((13. - relhVal) / 4); - float adj2 = (float) (Math.sqrt((17 - Math.abs(tmpfVal - 95)) / 17)); + float adj2 = (float) (Math.sqrt((17 - Math + .abs(tmpfVal - 95)) / 17)); float adj = adj1 * adj2; prheat -= adj; } - /* Adjust for low regression at high relative humidity and - * temperatures in the mid-80s */ - else if ((relhVal > 85) && ((tmpfVal >= 80.0) && (tmpfVal <= 87.0))) { + /* + * Adjust for low regression at high relative humidity and + * temperatures in the mid-80s + */ + else if ((relhVal > 85) + && ((tmpfVal >= 80.0) && (tmpfVal <= 87.0))) { float adj1 = (float) ((relhVal - 85.0) / 10.0); float adj2 = (float) ((87.0 - tmpfVal) / 5); float adj = adj1 * adj2; @@ -542,7 +590,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prHmtr(Amount tmpf, Amount dwpf) throws InvalidValueException, NullPointerException { + public static final Amount prHmtr(Amount tmpf, Amount dwpf) + throws InvalidValueException, NullPointerException { // System.out.println("From prHmtr:"); // System.out.println(" tmpf = " + tmpf.doubleValue()); // System.out.println(" dwpf = " + dwpf.doubleValue()); @@ -554,7 +603,8 @@ public final class PRLibrary { tmpf = checkAndConvertInputAmountToExpectedUnits(tmpf, NonSI.FAHRENHEIT); dwpf = checkAndConvertInputAmountToExpectedUnits(dwpf, NonSI.FAHRENHEIT); - Amount dwpc = checkAndConvertInputAmountToExpectedUnits(dwpf, SI.CELSIUS); + Amount dwpc = checkAndConvertInputAmountToExpectedUnits(dwpf, + SI.CELSIUS); Amount vapr = prVapr(dwpc); if (!checkNullOrInvalidValue(vapr)) return new Amount(Unit.ONE); @@ -585,7 +635,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prIgro(Amount tmpc, Amount sstc, Amount sped) throws InvalidValueException, NullPointerException { + public static final Amount prIgro(Amount tmpc, Amount sstc, Amount sped) + throws InvalidValueException, NullPointerException { // System.out.println("From prIgro:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); // System.out.println(" sstc = " + sstc.doubleValue()); @@ -596,7 +647,8 @@ public final class PRLibrary { // checkNullOrInvalidValue( sstc ) ; // checkNullOrInvalidValue( sped ) ; - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(sstc) || !checkNullOrInvalidValue(sped)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(sstc) + || !checkNullOrInvalidValue(sped)) return new Amount(NcUnits.INCHES_PER_THREE_HOURS); checkAndConvertInputAmountToExpectedUnits(tmpc, SI.CELSIUS); @@ -612,13 +664,15 @@ public final class PRLibrary { if (spedVal < 0 || spedVal > 50) { // throw new // InvalidRangeException("The wind speed must lie between 0 and 50. Both limits inclusive"); - System.out.println("The wind speed must lie between 0 and 50. Both limits inclusive"); + System.out + .println("The wind speed must lie between 0 and 50. Both limits inclusive"); return new Amount(NcUnits.INCHES_PER_THREE_HOURS); } if (tmpcVal < -20 || tmpcVal > 0) { // throw new // InvalidRangeException("The observed surface air temperature must lie between -20 and 0. Both limits inclusive"); - System.out.println("The observed surface air temperature must lie between -20 and 0. Both limits inclusive"); + System.out + .println("The observed surface air temperature must lie between -20 and 0. Both limits inclusive"); return new Amount(NcUnits.INCHES_PER_THREE_HOURS); } if (sstcVal < -1.7f || sstcVal > 12) { @@ -638,7 +692,8 @@ public final class PRLibrary { if (prigro < 0) { // throw new // InvalidRangeException("The rate of ice growth must be greater than or equal to 0"); - System.out.println("The rate of ice growth must be greater than or equal to 0"); + System.out + .println("The rate of ice growth must be greater than or equal to 0"); return new Amount(NcUnits.INCHES_PER_THREE_HOURS); } return (new Amount(prigro, NcUnits.INCHES_PER_THREE_HOURS)); @@ -656,7 +711,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prLhvp(Amount tmpc) throws InvalidValueException, NullPointerException { + public static final Amount prLhvp(Amount tmpc) + throws InvalidValueException, NullPointerException { // System.out.println("From prLhvp:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); @@ -666,7 +722,8 @@ public final class PRLibrary { return new Amount(NcUnits.JOULES_PER_KILOGRAM); tmpc = checkAndConvertInputAmountToExpectedUnits(tmpc, SI.CELSIUS); - double latentHeatOfVapr = (float) ((2.500 - 0.00237 * tmpc.doubleValue()) * 1000000); + double latentHeatOfVapr = (float) ((2.500 - 0.00237 * tmpc + .doubleValue()) * 1000000); return (new Amount(latentHeatOfVapr, NcUnits.JOULES_PER_KILOGRAM)); } @@ -686,7 +743,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prLtmp(Amount thta, Amount thte, Amount pres) throws InvalidValueException, NullPointerException { + public static final Amount prLtmp(Amount thta, Amount thte, Amount pres) + throws InvalidValueException, NullPointerException { // System.out.println("From prLtmp:"); // System.out.println(" thta = " + thta.doubleValue()); // System.out.println(" thte = " + thte.doubleValue()); @@ -697,7 +755,8 @@ public final class PRLibrary { // checkNullOrInvalidValue(thte); // checkNullOrInvalidValue(pres); - if (!checkNullOrInvalidValue(thta) || !checkNullOrInvalidValue(thte) || !checkNullOrInvalidValue(pres)) + if (!checkNullOrInvalidValue(thta) || !checkNullOrInvalidValue(thte) + || !checkNullOrInvalidValue(pres)) return new Amount(SI.CELSIUS); thta = checkAndConvertInputAmountToExpectedUnits(thta, SI.KELVIN); @@ -711,9 +770,11 @@ public final class PRLibrary { Amount tmpd = prTmpk(pres, thta); checkNullOrInvalidValue(tmpe); checkNullOrInvalidValue(tmpd); - /* ( Non-Javadoc ) The correct parcel temperature is the warmer of the + /* + * ( Non-Javadoc ) The correct parcel temperature is the warmer of the * temperature on the dry adiabat and the temperature on the moist - * adiabat. */ + * adiabat. + */ double tmpeVal = tmpe.doubleValue(); double tmpdVal = tmpd.doubleValue(); @@ -738,7 +799,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prMobs(Amount cmsl, Amount otval) throws InvalidValueException, NullPointerException { + public static final Amount prMobs(Amount cmsl, Amount otval) + throws InvalidValueException, NullPointerException { // System.out.println("From prMobs:"); // System.out.println(" cmsl = " + cmsl.doubleValue()); // System.out.println(" otval = " + otval.doubleValue()); @@ -749,9 +811,12 @@ public final class PRLibrary { if (!checkNullOrInvalidValue(cmsl) || !checkNullOrInvalidValue(otval)) return new Amount(Unit.ONE); - cmsl = checkAndConvertInputAmountToExpectedUnits(cmsl, NcUnits.HUNDREDS_OF_FEET); - otval = checkAndConvertInputAmountToExpectedUnits(otval, NcUnits.HUNDREDS_OF_FEET); - return (cmsl.doubleValue() < otval.doubleValue() ? new Amount(1, Unit.ONE) : new Amount(1, Unit.ONE)); + cmsl = checkAndConvertInputAmountToExpectedUnits(cmsl, + NcUnits.HUNDREDS_OF_FEET); + otval = checkAndConvertInputAmountToExpectedUnits(otval, + NcUnits.HUNDREDS_OF_FEET); + return (cmsl.doubleValue() < otval.doubleValue() ? new Amount(1, + Unit.ONE) : new Amount(1, Unit.ONE)); } /** @@ -795,15 +860,19 @@ public final class PRLibrary { vapr = checkAndConvertInputAmountToExpectedUnits(vapr, NcUnits.MILLIBAR); double pressureValue = pres.doubleValue(); double vaporPressureValue = vapr.doubleValue(); - /* (Non-Javadoc) corr is a correction to the vapor pressure since the - * atmosphere is not an ideal gas. */ + /* + * (Non-Javadoc) corr is a correction to the vapor pressure since the + * atmosphere is not an ideal gas. + */ double corr = (double) (1.001 + ((pressureValue - 100) / 900) * 0.0034); double e = corr * vaporPressureValue; /* Test for unphysical case of large E at low PRES */ if (e <= (0.5 * pressureValue)) { /* Calculate mixing ratio */ - prmixr = new Amount((double) (0.62197 * (e / (pressureValue - e)) * 1000), NcUnits.GRAMS_PER_KILOGRAM); + prmixr = new Amount( + (double) (0.62197 * (e / (pressureValue - e)) * 1000), + NcUnits.GRAMS_PER_KILOGRAM); } return prmixr; } @@ -819,7 +888,8 @@ public final class PRLibrary { * */ // TODO : remove it to make it a part of display options or let it stay? - public static final Amount prP03c(Amount p03d) throws InvalidValueException, NullPointerException { + public static final Amount prP03c(Amount p03d) + throws InvalidValueException, NullPointerException { // System.out.println("From prP03c:"); // System.out.println(" p03d = " + p03d.doubleValue()); @@ -853,7 +923,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prP03CAbsVal(Amount p03cav, Amount ptsy) throws InvalidValueException, NullPointerException { + public static final Amount prP03CAbsVal(Amount p03cav, Amount ptsy) + throws InvalidValueException, NullPointerException { double p03c = 0.0d; if (!checkNullOrInvalidValue(p03cav) || !checkNullOrInvalidValue(ptsy)) { @@ -888,6 +959,27 @@ public final class PRLibrary { } + /** + * Redmine 4318 + * + */ + public static final Amount prSGHT(Amount howw, Amount hosw) + throws InvalidValueException, NullPointerException { + + if (!checkNullOrInvalidValue(howw) || !checkNullOrInvalidValue(hosw)) { + return new Amount(SI.METER); + } + + double w = howw.doubleValue(); + double s = hosw.doubleValue(); + double sght = 0.0d; + + sght = Math.sqrt(((Math.pow(w, 2)) + (Math.pow(s, 2)))); + + return new Amount(sght, SI.METER); + + } + /** * Computes station pressure from altimeter and station elevation using the * equation PALT = ALTM * ( 1 - ( SELK * GAMUSD / To ) ) ** expo where SELK @@ -902,7 +994,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prPalt(Amount altm, Amount selv) throws InvalidValueException, NullPointerException { + public static final Amount prPalt(Amount altm, Amount selv) + throws InvalidValueException, NullPointerException { // System.out.println("From prPalt:"); // System.out.println(" altm = " + altm.doubleValue()); // System.out.println(" selv = " + selv.doubleValue()); @@ -915,13 +1008,16 @@ public final class PRLibrary { altm = checkAndConvertInputAmountToExpectedUnits(altm, NcUnits.MILLIBAR); selv = checkAndConvertInputAmountToExpectedUnits(selv, SI.METER); - double hgtk = selv.getUnit().getConverterTo(SI.KILOMETER).convert(selv.doubleValue()); + double hgtk = selv.getUnit().getConverterTo(SI.KILOMETER) + .convert(selv.doubleValue()); /* Calculate the exponent */ - double expo = (GempakConstants.GRAVTY / (GempakConstants.GAMUSD * GempakConstants.RDGAS) * 1000.0f); + double expo = (GempakConstants.GRAVTY + / (GempakConstants.GAMUSD * GempakConstants.RDGAS) * 1000.0f); /* Calculate pressure */ - double prpalt = (altm.doubleValue() * Math.pow((1 - (hgtk * GempakConstants.GAMUSD / (GempakConstants.TMCK + 15))), expo)); + double prpalt = (altm.doubleValue() * Math.pow((1 - (hgtk + * GempakConstants.GAMUSD / (GempakConstants.TMCK + 15))), expo)); return (new Amount(prpalt, NcUnits.MILLIBAR)); } @@ -943,7 +1039,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prPlcl(Amount tmpc, Amount pres, Amount tlcl) throws InvalidValueException, NullPointerException { + public static final Amount prPlcl(Amount tmpc, Amount pres, Amount tlcl) + throws InvalidValueException, NullPointerException { double prplcl = GempakConstants.RMISSD; // System.out.println("From prPlcl:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); @@ -953,7 +1050,8 @@ public final class PRLibrary { // checkNullOrInvalidValue(tmpc); // checkNullOrInvalidValue(pres); // checkNullOrInvalidValue(tlcl); - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(tlcl)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) + || !checkNullOrInvalidValue(tlcl)) return new Amount(NcUnits.MILLIBAR); tmpc = checkAndConvertInputAmountToExpectedUnits(tmpc, SI.CELSIUS); @@ -963,7 +1061,8 @@ public final class PRLibrary { double tclValue = tlcl.doubleValue(); double tmpkValue = tmpk.doubleValue(); double presValue = pres.doubleValue(); - prplcl = (double) (presValue * Math.pow((tclValue / tmpkValue), (1 / GempakConstants.RKAPPA))); + prplcl = (double) (presValue * Math.pow((tclValue / tmpkValue), + (1 / GempakConstants.RKAPPA))); return new Amount(prplcl, NcUnits.MILLIBAR); } @@ -989,7 +1088,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prPmsl(Amount pres, Amount tmpc, Amount dwpc, Amount selv) throws InvalidValueException, NullPointerException { + public static final Amount prPmsl(Amount pres, Amount tmpc, Amount dwpc, + Amount selv) throws InvalidValueException, NullPointerException { // System.out.println("From prPmsl:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); // System.out.println(" pres = " + pres.doubleValue()); @@ -999,7 +1099,9 @@ public final class PRLibrary { // checkNullOrInvalidValue( tmpc ); // checkNullOrInvalidValue( dwpc ); // checkNullOrInvalidValue( selv ); - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(dwpc) || !checkNullOrInvalidValue(selv)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) + || !checkNullOrInvalidValue(dwpc) + || !checkNullOrInvalidValue(selv)) return new Amount(NcUnits.MILLIBAR); pres = checkAndConvertInputAmountToExpectedUnits(pres, NcUnits.MILLIBAR); @@ -1014,7 +1116,8 @@ public final class PRLibrary { double selvVal = selv.doubleValue(); double deltaV = selvVal * GempakConstants.GAMUSD / 1000; double tVave = tv.doubleValue() + (deltaV / 2); - double mathFormula = (GempakConstants.GRAVTY * selvVal) / (GempakConstants.RDGAS * tVave); + double mathFormula = (GempakConstants.GRAVTY * selvVal) + / (GempakConstants.RDGAS * tVave); double prpmsl = (pres.doubleValue() * Math.exp(mathFormula)); return (new Amount(prpmsl, NcUnits.MILLIBAR)); @@ -1037,7 +1140,8 @@ public final class PRLibrary { * */ - public static final Amount prPr6x(Amount p01, Amount p02, Amount p03, Amount p04) throws InvalidValueException, NullPointerException { + public static final Amount prPr6x(Amount p01, Amount p02, Amount p03, + Amount p04) throws InvalidValueException, NullPointerException { // System.out.println("From prPr6x:"); // System.out.println(" p01 = " + p01.doubleValue()); // System.out.println(" p02 = " + p02.doubleValue()); @@ -1052,7 +1156,8 @@ public final class PRLibrary { } if (thisAmount.getUnit() != NonSI.INCH) { - thisAmount = checkAndConvertInputAmountToExpectedUnits(thisAmount, NonSI.INCH); + thisAmount = checkAndConvertInputAmountToExpectedUnits( + thisAmount, NonSI.INCH); tempArray[index] = thisAmount; } tempDblArray[index] = thisAmount.doubleValue(); @@ -1080,7 +1185,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prPr24(Amount p01, Amount p02, Amount p03, Amount p04) throws InvalidValueException, NullPointerException { + public static final Amount prPr24(Amount p01, Amount p02, Amount p03, + Amount p04) throws InvalidValueException, NullPointerException { // System.out.println("From prPr24:"); // System.out.println(" p01 = " + p01.doubleValue()); // System.out.println(" p02 = " + p02.doubleValue()); @@ -1092,7 +1198,9 @@ public final class PRLibrary { // checkNullOrInvalidValue( p03 ); // checkNullOrInvalidValue( p04 ); - if (!checkNullOrInvalidValue(p01) || !checkNullOrInvalidValue(p02) || !checkNullOrInvalidValue(p03) || !checkNullOrInvalidValue(p04)) + if (!checkNullOrInvalidValue(p01) || !checkNullOrInvalidValue(p02) + || !checkNullOrInvalidValue(p03) + || !checkNullOrInvalidValue(p04)) return new Amount(NonSI.INCH); Amount[] tempArray = { p01, p02, p03, p04 }; @@ -1124,7 +1232,8 @@ public final class PRLibrary { if (p24Val < 0) { // throw new // InvalidRangeException("From prPr24: the total 24 hour precipitation amount cannot be less than 0 inches"); - System.out.println("From prPr24: the total 24 hour precipitation amount cannot be less than 0 inches"); + System.out + .println("From prPr24: the total 24 hour precipitation amount cannot be less than 0 inches"); return new Amount(NonSI.INCH); } return (new Amount(p24Val, NonSI.INCH)); @@ -1144,7 +1253,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prPres(Amount tmpc, Amount thta) throws InvalidValueException, NullPointerException { + public static final Amount prPres(Amount tmpc, Amount thta) + throws InvalidValueException, NullPointerException { // System.out.println("From prPres:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); // System.out.println(" thta = " + thta.doubleValue()); @@ -1162,17 +1272,21 @@ public final class PRLibrary { if (tmpcVal <= -GempakConstants.TMCK) { // throw new // InvalidRangeException("From prPres: the temperature must be greater than -273.15"); - System.out.println("From prPres: the temperature must be greater than -273.15"); + System.out + .println("From prPres: the temperature must be greater than -273.15"); return new Amount(NcUnits.MILLIBAR); } if (thtaVal <= 0) { // throw new // InvalidRangeException("From prPres: the potential temperature must be greater than 0"); - System.out.println("From prPres: the potential temperature must be greater than 0"); + System.out + .println("From prPres: the potential temperature must be greater than 0"); return new Amount(NcUnits.MILLIBAR); } - double tmpkVal = tmpc.getUnit().getConverterTo(SI.KELVIN).convert(tmpcVal); - double prpres = (float) (1000 * Math.pow(tmpkVal / thtaVal, 1 / GempakConstants.RKAPPA)); + double tmpkVal = tmpc.getUnit().getConverterTo(SI.KELVIN) + .convert(tmpcVal); + double prpres = (float) (1000 * Math.pow(tmpkVal / thtaVal, + 1 / GempakConstants.RKAPPA)); return (new Amount(prpres, NcUnits.MILLIBAR)); } @@ -1189,7 +1303,8 @@ public final class PRLibrary { */ // TODO add it to the Met Parameters or remove it and make it part of the // display options instead? - public static final Amount prPtsy(Amount p03d) throws InvalidValueException, NullPointerException { + public static final Amount prPtsy(Amount p03d) + throws InvalidValueException, NullPointerException { // System.out.println("From prPtsy:"); // System.out.println(" p03d = " + p03d.doubleValue()); @@ -1219,7 +1334,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prRelh(Amount tmpc, Amount dwpc) throws InvalidValueException, NullPointerException { + public static final Amount prRelh(Amount tmpc, Amount dwpc) + throws InvalidValueException, NullPointerException { // System.out.println("From prRelh:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); // System.out.println(" dwpc = " + dwpc.doubleValue()); @@ -1268,7 +1384,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prRhdp(Amount tmpc, Amount relh) throws InvalidValueException, NullPointerException { + public static final Amount prRhdp(Amount tmpc, Amount relh) + throws InvalidValueException, NullPointerException { // System.out.println("From prRhdp:"); // System.out.println(" tmpc =" + tmpc.doubleValue()); // System.out.println(" relh = " + relh.doubleValue()); @@ -1297,14 +1414,18 @@ public final class PRLibrary { double prrhdp = -191; Amount dewpointAmount = null; if (vapr >= (Math.pow(Math.E, -30))) {// legacy checks for 1.E-30 - prrhdp = (double) (243.5 * (Math.log(6.112) - Math.log(vapr)) / (Math.log(vapr) - Math.log(6.112) - 17.67)); + prrhdp = (double) (243.5 * (Math.log(6.112) - Math.log(vapr)) / (Math + .log(vapr) - Math.log(6.112) - 17.67)); - /* If the dew-point is less than -190 degrees C, it is treated as + /* + * If the dew-point is less than -190 degrees C, it is treated as * missing data Note: Legacy documents it but does not implement it. - * However, in CAVE, it was decided to implement it. */ + * However, in CAVE, it was decided to implement it. + */ if (prrhdp < -190) { - System.out.println(" From prRhdp: dewpoint is less than -190 C"); + System.out + .println(" From prRhdp: dewpoint is less than -190 C"); return new Amount(SI.CELSIUS); } } @@ -1384,7 +1505,9 @@ public final class PRLibrary { * @throws NullPointerException * */ - public void prRzll(Amount instltdg, Amount instlndg, Amount inrange, Amount inazim, Amount inhght) throws InvalidValueException, NullPointerException { + public void prRzll(Amount instltdg, Amount instlndg, Amount inrange, + Amount inazim, Amount inhght) throws InvalidValueException, + NullPointerException { // System.out.println("From prRzll:"); // System.out.println(" instltdg = " + instltdg.doubleValue()); // System.out.println(" instlndg = " + instlndg.doubleValue()); @@ -1398,15 +1521,23 @@ public final class PRLibrary { // checkNullOrInvalidValue(inazim); // checkNullOrInvalidValue(inhght); - if (!checkNullOrInvalidValue(instltdg) || !checkNullOrInvalidValue(instlndg) || !checkNullOrInvalidValue(inrange) || !checkNullOrInvalidValue(inazim) + if (!checkNullOrInvalidValue(instltdg) + || !checkNullOrInvalidValue(instlndg) + || !checkNullOrInvalidValue(inrange) + || !checkNullOrInvalidValue(inazim) || !checkNullOrInvalidValue(inhght)) return; - instltdg = checkAndConvertInputAmountToExpectedUnits(instltdg, NonSI.DEGREE_ANGLE); - instlndg = checkAndConvertInputAmountToExpectedUnits(instlndg, NonSI.DEGREE_ANGLE); - inrange = checkAndConvertInputAmountToExpectedUnits(inrange, SI.KILOMETER); - inazim = checkAndConvertInputAmountToExpectedUnits(inazim, SI.RADIAN); - inhght = checkAndConvertInputAmountToExpectedUnits(inhght, SI.KILOMETER); + instltdg = checkAndConvertInputAmountToExpectedUnits(instltdg, + NonSI.DEGREE_ANGLE); + instlndg = checkAndConvertInputAmountToExpectedUnits(instlndg, + NonSI.DEGREE_ANGLE); + inrange = checkAndConvertInputAmountToExpectedUnits(inrange, + SI.KILOMETER); + inazim = checkAndConvertInputAmountToExpectedUnits(inazim, + SI.RADIAN); + inhght = checkAndConvertInputAmountToExpectedUnits(inhght, + SI.KILOMETER); this.stltdg = new Amount(instltdg.doubleValue(), NonSI.DEGREE_ANGLE); this.stlndg = new Amount(instlndg.doubleValue(), NonSI.DEGREE_ANGLE); @@ -1420,11 +1551,14 @@ public final class PRLibrary { double radp = GempakConstants.RMISSD; /* Convert the station lat/lon to radians */ - Amount stlat = checkAndConvertInputAmountToExpectedUnits(stltdg, NonSI.DEGREE_ANGLE); - Amount stlon = checkAndConvertInputAmountToExpectedUnits(stlndg, NonSI.DEGREE_ANGLE); + Amount stlat = checkAndConvertInputAmountToExpectedUnits(stltdg, + NonSI.DEGREE_ANGLE); + Amount stlon = checkAndConvertInputAmountToExpectedUnits(stlndg, + NonSI.DEGREE_ANGLE); /* Get the elevation angle */ - hdr = (range.doubleValue() == 0.0f ? 0.0f : hght.doubleValue() / range.doubleValue()); + hdr = (range.doubleValue() == 0.0f ? 0.0f : hght.doubleValue() + / range.doubleValue()); // elev = (float) ( Math.abs(hdr) < 1.0f ? Math.asin(hdr) : 0.0f ); elev = (Math.abs(hdr) <= 1.0f ? Math.asin(hdr) : 0.0f); @@ -1445,7 +1579,8 @@ public final class PRLibrary { if (elev > 0.2618f) dist = (double) (rangeVal * Math.cos(elev)); else { - mathFormula1 = (double) ((1 - (Math.pow(elev, 2) / 2)) - rangeVal * elev / radp); + mathFormula1 = (double) ((1 - (Math.pow(elev, 2) / 2)) - rangeVal + * elev / radp); dist = rangeVal * mathFormula1; } @@ -1459,13 +1594,17 @@ public final class PRLibrary { // xlat = ( float ) ( stlat + ( cy / rad ) - ( Math.pow(cx, 2) / // mathFormula2 ) ); double stlatVal = stlat.doubleValue(); - mathFormula2 = (double) ((Math.pow(cx, 2) / (2 * Math.pow(rad, 2)) * Math.tan(stlatVal))); + mathFormula2 = (double) ((Math.pow(cx, 2) / (2 * Math.pow(rad, 2)) * Math + .tan(stlatVal))); double xlatVal = (double) (stlatVal + (cy / rad) - mathFormula2); - double xlonVal = (double) (stlon.doubleValue() + (cx / (rad * Math.cos(xlat.doubleValue())))); + double xlonVal = (double) (stlon.doubleValue() + (cx / (rad * Math + .cos(xlat.doubleValue())))); /* Change lat/lon to degrees */ - xlatVal = SI.RADIAN.getConverterTo(NonSI.DEGREE_ANGLE).convert(xlatVal); - xlonVal = SI.RADIAN.getConverterTo(NonSI.DEGREE_ANGLE).convert(xlonVal); + xlatVal = SI.RADIAN.getConverterTo(NonSI.DEGREE_ANGLE).convert( + xlatVal); + xlonVal = SI.RADIAN.getConverterTo(NonSI.DEGREE_ANGLE).convert( + xlonVal); this.xlat = new Amount(xlatVal, NonSI.DEGREE_ANGLE); this.xlon = new Amount(xlonVal, NonSI.DEGREE_ANGLE); @@ -1484,7 +1623,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prSped(Amount uWnd, Amount vWnd) throws InvalidValueException, NullPointerException { + public static final Amount prSped(Amount uWnd, Amount vWnd) + throws InvalidValueException, NullPointerException { // System.out.println("From prSped:"); // System.out.println(" uWnd = " +uWnd.doubleValue()); // System.out.println(" vWnd = " + vWnd.doubleValue()); @@ -1497,10 +1637,12 @@ public final class PRLibrary { Unit uWndUnits = uWnd.getUnit(); Unit vWndUnits = vWnd.getUnit(); if (uWndUnits != vWndUnits && uWndUnits.isCompatible(vWndUnits)) { - double vWndVal = vWndUnits.getConverterTo(uWndUnits).convert(vWnd.doubleValue()); + double vWndVal = vWndUnits.getConverterTo(uWndUnits).convert( + vWnd.doubleValue()); vWnd = new Amount(vWndVal, uWndUnits); } - double prsped = (Math.sqrt((Math.pow(uWnd.doubleValue(), 2) + Math.pow(vWnd.doubleValue(), 2)))); + double prsped = (Math.sqrt((Math.pow(uWnd.doubleValue(), 2) + Math.pow( + vWnd.doubleValue(), 2)))); return new Amount(prsped, uWndUnits); } @@ -1518,7 +1660,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static Amount prThta(Amount tmpc, Amount pres) throws InvalidValueException, NullPointerException { + public static Amount prThta(Amount tmpc, Amount pres) + throws InvalidValueException, NullPointerException { checkNullOrInvalidValue(tmpc); checkNullOrInvalidValue(pres); @@ -1536,10 +1679,12 @@ public final class PRLibrary { } /* Change temperature in degrees Celsius to Kelvin. */ - double temperatureInKelvin = (double) tmpc.getUnit().getConverterTo(SI.KELVIN).convert(tmpc.doubleValue()); + double temperatureInKelvin = (double) tmpc.getUnit() + .getConverterTo(SI.KELVIN).convert(tmpc.doubleValue()); /* Calculate theta using Poisson's equation */ - double prthta = (double) (temperatureInKelvin * Math.pow((1000 / pres.doubleValue()), GempakConstants.RKAPPA)); + double prthta = (double) (temperatureInKelvin * Math.pow( + (1000 / pres.doubleValue()), GempakConstants.RKAPPA)); return new Amount(prthta, SI.KELVIN); } @@ -1572,11 +1717,13 @@ public final class PRLibrary { // checkNullOrInvalidValue(pres); // checkNullOrInvalidValue(tmpc); // checkNullOrInvalidValue(dwpc); - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(dwpc)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) + || !checkNullOrInvalidValue(dwpc)) return new Amount(SI.KELVIN); if (pres.doubleValue() <= 0) { - System.out.println("From prThte() - Input pressure must be greater than 0 "); + System.out + .println("From prThte() - Input pressure must be greater than 0 "); return new Amount(SI.KELVIN); // throw new // InvalidRangeException("From prThte() - Input pressure must be greater than 0 "); @@ -1608,7 +1755,8 @@ public final class PRLibrary { return new Amount(SI.KELVIN); double lclTemp = tlcl.doubleValue(); - e = ((3.376f / lclTemp) - 0.00254f) * (mixingRatioVal * (1 + 0.81f * 0.001f * mixingRatioVal)); + e = ((3.376f / lclTemp) - 0.00254f) + * (mixingRatioVal * (1 + 0.81f * 0.001f * mixingRatioVal)); double prthte = (double) (thtam * Math.exp(e)); Amount equivPotentialTempAmount = new Amount(prthte, SI.KELVIN); return equivPotentialTempAmount; @@ -1633,7 +1781,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prThwc(Amount pres, Amount tmpc, Amount dwpc) throws InvalidValueException, NullPointerException { + public static final Amount prThwc(Amount pres, Amount tmpc, Amount dwpc) + throws InvalidValueException, NullPointerException { // System.out.println(" PRLibrary/prThwc:"); // System.out.println(" PRLibrary/prThwc. press = " + // pres.doubleValue()); @@ -1645,7 +1794,8 @@ public final class PRLibrary { // checkNullOrInvalidValue( tmpc ); // checkNullOrInvalidValue( dwpc ); - if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(dwpc)) + if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(pres) + || !checkNullOrInvalidValue(dwpc)) return new Amount(SI.CELSIUS); pres = checkAndConvertInputAmountToExpectedUnits(pres, NcUnits.MILLIBAR); @@ -1664,7 +1814,8 @@ public final class PRLibrary { // .println(" PRLibrary/prThwc. press 3 = " + pres.doubleValue()); if (presVal <= 0) { - System.out.println("From prThwc: Pressure must be greater than 0 mb"); + System.out + .println("From prThwc: Pressure must be greater than 0 mb"); return new Amount(SI.CELSIUS); // throw new // InvalidRangeException("From prThwc: Pressure must be greater than 0 mb"); @@ -1679,7 +1830,8 @@ public final class PRLibrary { return new Amount(SI.CELSIUS); /* Compute the parcel temperature (in Kelvin) */ - Amount prthwc = prTmst(thte, new Amount(1000, NcUnits.MILLIBAR), new Amount(0, SI.KELVIN)); + Amount prthwc = prTmst(thte, new Amount(1000, NcUnits.MILLIBAR), + new Amount(0, SI.KELVIN)); // System.out.println(" PRLibrary/prThwc. prthwc (K) 5 = " // + prthwc.doubleValue()); @@ -1719,15 +1871,18 @@ public final class PRLibrary { if (!checkNullOrInvalidValue(tmpc) || !checkNullOrInvalidValue(dwpc)) return new Amount(SI.KELVIN); - if (tmpc.doubleValue() < -GempakConstants.TMCK || dwpc.doubleValue() < -GempakConstants.TMCK) { - System.out.println("From prTlcl: Input temperature cannot be less than -273.15"); + if (tmpc.doubleValue() < -GempakConstants.TMCK + || dwpc.doubleValue() < -GempakConstants.TMCK) { + System.out + .println("From prTlcl: Input temperature cannot be less than -273.15"); return new Amount(SI.KELVIN); } Amount tmpk = checkAndConvertInputAmountToExpectedUnits(tmpc, SI.KELVIN); Amount dwpk = checkAndConvertInputAmountToExpectedUnits(dwpc, SI.KELVIN); double tempVal = tmpk.doubleValue(); double dewpointVal = dwpk.doubleValue(); - double lclTemp = (double) ((800 * (dewpointVal - 56) / (800 + (dewpointVal - 56) * Math.log(tempVal / dewpointVal))) + 56); + double lclTemp = (double) ((800 * (dewpointVal - 56) / (800 + (dewpointVal - 56) + * Math.log(tempVal / dewpointVal))) + 56); Amount prtlcl = new Amount(lclTemp, SI.KELVIN); return prtlcl; @@ -1747,7 +1902,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prTmpk(Amount pres, Amount thta) throws InvalidValueException, NullPointerException { + public static final Amount prTmpk(Amount pres, Amount thta) + throws InvalidValueException, NullPointerException { // System.out.println("From prTmpk:"); // System.out.println(" pres = " + pres.doubleValue()); // System.out.println("thta = " + thta.doubleValue()); @@ -1762,11 +1918,13 @@ public final class PRLibrary { double pressureValue = pres.doubleValue(); double thtaValue = thta.doubleValue(); if (pressureValue >= 0) { - double temperature = (double) (thtaValue * (Math.pow(pressureValue / 1000f, GempakConstants.RKAPPA))); + double temperature = (double) (thtaValue * (Math.pow( + pressureValue / 1000f, GempakConstants.RKAPPA))); prtmpk = new Amount(temperature, SI.KELVIN); return prtmpk; } else { - System.out.println("From prTmpk() - pressure cannot be less than 0 mb"); + System.out + .println("From prTmpk() - pressure cannot be less than 0 mb"); return new Amount(SI.KELVIN); // throw new // InvalidRangeException("From prTmpk() - pressure cannot be less than 0 mb"); @@ -1807,7 +1965,8 @@ public final class PRLibrary { // pres.doubleValue()); // System.out.println(" PRLibrary/prTmst. tguess = " // + tguess.doubleValue()); - if (!checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(thte) || !checkNullOrInvalidValue(tguess)) { + if (!checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(thte) + || !checkNullOrInvalidValue(tguess)) { return new Amount(SI.KELVIN); } // checkNullOrInvalidValue( thte ); @@ -1821,17 +1980,20 @@ public final class PRLibrary { double tguessVal = tguess.doubleValue(); if (thteVal <= 0) { - System.out.println(" From prTmst(): Potential temperature must be greater than 0"); + System.out + .println(" From prTmst(): Potential temperature must be greater than 0"); return new Amount(SI.KELVIN); // throw new // InvalidRangeException(" From prTmst(): Potential temperature must be greater than 0"); } else if (presVal <= 0) { - System.out.println(" From prTmst(): Pressure must be greater than 0"); + System.out + .println(" From prTmst(): Pressure must be greater than 0"); return new Amount(SI.KELVIN); // throw new // InvalidRangeException(" From prTmst(): Pressure must be greater than 0"); } else if (tguessVal < 0) { - System.out.println(" From prTmst(): First guess temperature must be greater than or equal to 0"); + System.out + .println(" From prTmst(): First guess temperature must be greater than or equal to 0"); return new Amount(SI.KELVIN); // throw new // InvalidRangeException(" From prTmst(): First guess temperature must be greater than 0"); @@ -1846,15 +2008,18 @@ public final class PRLibrary { if (tg == 0) { double diffVar = thte.doubleValue() - 270; double mathFormula1 = (double) (diffVar > 0 ? diffVar : 0.0); - tg = (double) ((thte.doubleValue() - .5f * (Math.pow(mathFormula1, 1.05f))) * (Math.pow(pres.doubleValue() / 1000.0f, 0.2f))); + tg = (double) ((thte.doubleValue() - .5f * (Math.pow(mathFormula1, + 1.05f))) * (Math.pow(pres.doubleValue() / 1000.0f, 0.2f))); } /* Set convergence and initial guess in degrees Celsius */ double epsi = 0.01f; double tgnu = SI.KELVIN.getConverterTo(SI.CELSIUS).convert(tg); - /* Set a limit of 100 iterations. Compute tenu,tenup, the thte's at one - * degree above the guess temperature. */ + /* + * Set a limit of 100 iterations. Compute tenu,tenup, the thte's at one + * degree above the guess temperature. + */ int index = 0; while (index < 100) { double tgnup = tgnu + 1; @@ -1893,7 +2058,8 @@ public final class PRLibrary { if ((cor < epsi) && (-cor < epsi)) { /* return on convergence */ - prtmst = tgnuAmount.getUnit().getConverterTo(SI.KELVIN).convert(tgnu); + prtmst = tgnuAmount.getUnit().getConverterTo(SI.KELVIN) + .convert(tgnu); // System.out.println(" PRLibrary/prTmst. prtmst 7 = " + // prtmst); @@ -1931,7 +2097,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prTmwb(Amount tmpk, Amount rmix, Amount pres) throws InvalidValueException, NullPointerException { + public static final Amount prTmwb(Amount tmpk, Amount rmix, Amount pres) + throws InvalidValueException, NullPointerException { // System.out.println("From prTmwb:"); // System.out.println(" tmpk = " + tmpk.doubleValue()); // System.out.println(" rmix = " + rmix.doubleValue()); @@ -1942,16 +2109,18 @@ public final class PRLibrary { // checkNullOrInvalidValue( tmpk ); // checkNullOrInvalidValue( rmix ); // checkNullOrInvalidValue( pres ); - if (!checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(tmpk) || !checkNullOrInvalidValue(rmix)) { + if (!checkNullOrInvalidValue(pres) || !checkNullOrInvalidValue(tmpk) + || !checkNullOrInvalidValue(rmix)) { return new Amount(SI.KELVIN); } tmpk = checkAndConvertInputAmountToExpectedUnits(tmpk, SI.KELVIN); - rmix = checkAndConvertInputAmountToExpectedUnits(rmix, NcUnits.GRAMS_PER_KILOGRAM); + rmix = checkAndConvertInputAmountToExpectedUnits(rmix, + NcUnits.GRAMS_PER_KILOGRAM); pres = checkAndConvertInputAmountToExpectedUnits(pres, NcUnits.MILLIBAR); double presVal = pres.doubleValue(); if (presVal <= 0) { // System.out - // .println("From prTmwb - pressure value must be greater than 0 "); + // .println("From prTmwb - pressure value must be greater than 0 "); return new Amount(SI.KELVIN); // throw new // InvalidRangeException("From prTmwb - pressure value must be greater than 0 "); @@ -2024,7 +2193,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prTvrk(Amount tmpc, Amount dwpc, Amount pres) throws InvalidValueException, NullPointerException { + public static final Amount prTvrk(Amount tmpc, Amount dwpc, Amount pres) + throws InvalidValueException, NullPointerException { // System.out.println("From prTvrk:"); // System.out.println(" tmpc = " + tmpc.doubleValue()); // System.out.println(" dwpc = " + dwpc.doubleValue()); @@ -2045,18 +2215,21 @@ public final class PRLibrary { else { /* Change temperature to Kelvin. */ - Amount tmpk = checkAndConvertInputAmountToExpectedUnits(tmpc, SI.KELVIN); + Amount tmpk = checkAndConvertInputAmountToExpectedUnits(tmpc, + SI.KELVIN); /* Find mixing ratio in g/kg; if missing, return temperature */ Amount rmix = prMixr(dwpc, pres); double virtualTemp; if (rmix.doubleValue() == GempakConstants.RMISSD) - virtualTemp = (double) tmpc.getUnit().getConverterTo(SI.KELVIN).convert(tmpc.doubleValue()); + virtualTemp = (double) tmpc.getUnit().getConverterTo(SI.KELVIN) + .convert(tmpc.doubleValue()); else { double mixingRatioVal = rmix.doubleValue(); double temp = tmpk.doubleValue(); - virtualTemp = (double) (temp * (1 + 0.001 * mixingRatioVal / 0.62197) / (1 + 0.001 * mixingRatioVal)); + virtualTemp = (double) (temp + * (1 + 0.001 * mixingRatioVal / 0.62197) / (1 + 0.001 * mixingRatioVal)); } prtvrk = new Amount(virtualTemp, SI.KELVIN); @@ -2075,15 +2248,18 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prUwnd(Amount sped, Amount drct) throws InvalidValueException, NullPointerException { + public static final Amount prUwnd(Amount sped, Amount drct) + throws InvalidValueException, NullPointerException { // System.out.println("From prUwnd:"); // System.out.println(" sped = " + sped.doubleValue()); // System.out.println(" drct = " + drct.doubleValue()); if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped)) { return new Amount(SI.METERS_PER_SECOND); } - drct = checkAndConvertInputAmountToExpectedUnits(drct, NonSI.DEGREE_ANGLE); - double pruwnd = ((-Math.sin(drct.doubleValue() * GempakConstants.DTR)) * sped.doubleValue()); + drct = checkAndConvertInputAmountToExpectedUnits(drct, + NonSI.DEGREE_ANGLE); + double pruwnd = ((-Math.sin(drct.doubleValue() * GempakConstants.DTR)) * sped + .doubleValue()); return new Amount(pruwnd, sped.getUnit()); // TODO :verify the units } @@ -2098,15 +2274,18 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prVwnd(Amount sped, Amount drct) throws InvalidValueException, NullPointerException { + public static final Amount prVwnd(Amount sped, Amount drct) + throws InvalidValueException, NullPointerException { // System.out.println("From prVwnd:"); // System.out.println(" sped = " + sped.doubleValue()); // System.out.println(" drct = " + drct.doubleValue()); if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped)) { return new Amount(SI.METERS_PER_SECOND); } - drct = checkAndConvertInputAmountToExpectedUnits(drct, NonSI.DEGREE_ANGLE); - double prvwnd = ((-Math.cos(drct.doubleValue() * GempakConstants.DTR)) * sped.doubleValue()); + drct = checkAndConvertInputAmountToExpectedUnits(drct, + NonSI.DEGREE_ANGLE); + double prvwnd = ((-Math.cos(drct.doubleValue() * GempakConstants.DTR)) * sped + .doubleValue()); return new Amount(prvwnd, sped.getUnit()); // TODO :verify the units } @@ -2131,11 +2310,13 @@ public final class PRLibrary { dwpc = checkAndConvertInputAmountToExpectedUnits(dwpc, SI.CELSIUS); double dewpointValue = dwpc.doubleValue(); if (dewpointValue >= -240.0f) - return (new Amount((6.112 * (Math.exp((17.67 * dewpointValue) / (dewpointValue + 243.5)))), NcUnits.MILLIBAR)); + return (new Amount((6.112 * (Math.exp((17.67 * dewpointValue) + / (dewpointValue + 243.5)))), NcUnits.MILLIBAR)); else { // throw new // InvalidRangeException("Exception from prVapr() - dewpoint cannot be less than -240 "); - System.out.println("From prVapr() - dewpoint cannot be less than -240 "); + System.out + .println("From prVapr() - dewpoint cannot be less than -240 "); return new Amount(NcUnits.MILLIBAR); } } @@ -2175,7 +2356,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prWceq(Amount tmpf, Amount sknt) throws InvalidValueException, NullPointerException { + public static final Amount prWceq(Amount tmpf, Amount sknt) + throws InvalidValueException, NullPointerException { // System.out.println("From prWceq:"); // System.out.println(" tmpf = " + tmpf.doubleValue()); // System.out.println(" sknt = " + sknt.doubleValue()); @@ -2186,23 +2368,32 @@ public final class PRLibrary { } /* Convert input variables to Celsius and meters/second. */ - Amount tmpc = checkAndConvertInputAmountToExpectedUnits(tmpf, SI.CELSIUS); - Amount sped = checkAndConvertInputAmountToExpectedUnits(sknt, SI.METERS_PER_SECOND); + Amount tmpc = checkAndConvertInputAmountToExpectedUnits(tmpf, + SI.CELSIUS); + Amount sped = checkAndConvertInputAmountToExpectedUnits(sknt, + SI.METERS_PER_SECOND); if (sped.doubleValue() <= 1.34) - /* If the wind speed does not exceed 1.34 m/s ( not much wind to + /* + * If the wind speed does not exceed 1.34 m/s ( not much wind to * contribute to the wind chill), return the input temperature as - * the wind chill temperature */ - prwceq = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT).convert(tmpc.doubleValue()); + * the wind chill temperature + */ + prwceq = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT) + .convert(tmpc.doubleValue()); else { - /* Compute the wind chill temp if the inputs are not missing and and + /* + * Compute the wind chill temp if the inputs are not missing and and * the wind speed is greater than 1.34 m/s. Equations for wind chill * computation from R. Falconer, * "Windchill, A Useful Wintertime Weather Variable", Weatherwise, - * Dec 1968. */ + * Dec 1968. + */ if (sped.getUnit() == SI.METERS_PER_SECOND) { - float windChill = (float) (33.0 - ((33.0 - tmpc.doubleValue()) * wci(sped.doubleValue()) / wci(1.34f))); - prwceq = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT).convert(windChill); + float windChill = (float) (33.0 - ((33.0 - tmpc.doubleValue()) + * wci(sped.doubleValue()) / wci(1.34f))); + prwceq = tmpc.getUnit().getConverterTo(NonSI.FAHRENHEIT) + .convert(windChill); } } @@ -2260,7 +2451,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prWcht(Amount tmpf, Amount sknt) throws InvalidValueException, NullPointerException { + public static final Amount prWcht(Amount tmpf, Amount sknt) + throws InvalidValueException, NullPointerException { // System.out.println("From prWcht:"); // System.out.println(" tmpf = " + tmpf.doubleValue()); // System.out.println(" sknt = " + sknt.doubleValue()); @@ -2270,19 +2462,26 @@ public final class PRLibrary { } /* Convert the speed to miles per hour */ - Amount smph = checkAndConvertInputAmountToExpectedUnits(sknt, NonSI.MILES_PER_HOUR); + Amount smph = checkAndConvertInputAmountToExpectedUnits(sknt, + NonSI.MILES_PER_HOUR); - /* If the inputs are not missing , check if the wind speed is <= 3 miles - * per hour */ + /* + * If the inputs are not missing , check if the wind speed is <= 3 miles + * per hour + */ double smphVal = smph.doubleValue(); double tmpfVal = tmpf.doubleValue(); if (smphVal <= 3) prwrcht = tmpfVal; else { - /* Compute the wind-chill temperature for wind speeds that exceed 3 - * miles per hour */ - float wcht = (float) (35.74 + 0.6215 * tmpfVal - 35.75 * Math.pow(smphVal, 0.16) + 0.4275 * tmpfVal * Math.pow(smphVal, 0.16)); + /* + * Compute the wind-chill temperature for wind speeds that exceed 3 + * miles per hour + */ + float wcht = (float) (35.74 + 0.6215 * tmpfVal - 35.75 + * Math.pow(smphVal, 0.16) + 0.4275 * tmpfVal + * Math.pow(smphVal, 0.16)); prwrcht = (wcht > tmpfVal ? tmpfVal : wcht); } return (new Amount(prwrcht, NonSI.FAHRENHEIT)); @@ -2303,7 +2502,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prWcmp(Amount drct, Amount sped, Amount dcmp) throws InvalidValueException, NullPointerException { + public static final Amount prWcmp(Amount drct, Amount sped, Amount dcmp) + throws InvalidValueException, NullPointerException { // System.out.println("From prWcmp:"); // System.out.println(" sped = " + sped.doubleValue()); // System.out.println(" drct = " + drct.doubleValue()); @@ -2312,16 +2512,22 @@ public final class PRLibrary { // checkNullOrInvalidValue( drct ); // checkNullOrInvalidValue( sped ); // checkNullOrInvalidValue( dcmp ); - if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped) || !checkNullOrInvalidValue(dcmp)) { + if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped) + || !checkNullOrInvalidValue(dcmp)) { return new Amount(SI.METERS_PER_SECOND); } - drct = checkAndConvertInputAmountToExpectedUnits(drct, NonSI.DEGREE_ANGLE); - dcmp = checkAndConvertInputAmountToExpectedUnits(dcmp, NonSI.DEGREE_ANGLE); - sped = checkAndConvertInputAmountToExpectedUnits(sped, SI.METERS_PER_SECOND); + drct = checkAndConvertInputAmountToExpectedUnits(drct, + NonSI.DEGREE_ANGLE); + dcmp = checkAndConvertInputAmountToExpectedUnits(dcmp, + NonSI.DEGREE_ANGLE); + sped = checkAndConvertInputAmountToExpectedUnits(sped, + SI.METERS_PER_SECOND); /* Calculate wind speed toward specified direction */ - double prwcmp = sped.doubleValue() * (-Math.cos((drct.doubleValue() - dcmp.doubleValue()) * GempakConstants.DTR)); + double prwcmp = sped.doubleValue() + * (-Math.cos((drct.doubleValue() - dcmp.doubleValue()) + * GempakConstants.DTR)); return new Amount(prwcmp, SI.METERS_PER_SECOND); } @@ -2344,7 +2550,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prWnml(Amount drct, Amount sped, Amount dcmp) throws InvalidValueException, NullPointerException { + public static final Amount prWnml(Amount drct, Amount sped, Amount dcmp) + throws InvalidValueException, NullPointerException { // System.out.println("From prWnml:"); // System.out.println(" sped = " + sped.doubleValue()); // System.out.println(" drct = " + drct.doubleValue()); @@ -2352,21 +2559,28 @@ public final class PRLibrary { // checkNullOrInvalidValue(sped); // checkNullOrInvalidValue(drct); // checkNullOrInvalidValue(dcmp); - if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped) || !checkNullOrInvalidValue(dcmp)) { + if (!checkNullOrInvalidValue(drct) || !checkNullOrInvalidValue(sped) + || !checkNullOrInvalidValue(dcmp)) { return new Amount(SI.METERS_PER_SECOND); } - drct = checkAndConvertInputAmountToExpectedUnits(drct, NonSI.DEGREE_ANGLE); - dcmp = checkAndConvertInputAmountToExpectedUnits(dcmp, NonSI.DEGREE_ANGLE); - sped = checkAndConvertInputAmountToExpectedUnits(sped, SI.METERS_PER_SECOND); + drct = checkAndConvertInputAmountToExpectedUnits(drct, + NonSI.DEGREE_ANGLE); + dcmp = checkAndConvertInputAmountToExpectedUnits(dcmp, + NonSI.DEGREE_ANGLE); + sped = checkAndConvertInputAmountToExpectedUnits(sped, + SI.METERS_PER_SECOND); if ((dcmp.doubleValue() < 0) && (dcmp.doubleValue() > 360)) { // throw new // InvalidRangeException("From prWnml - the wind direction 'dcmp' mus be greater than or equal to 0 and less than or equal to 360"); - System.out.println("From prWnml - the wind direction 'dcmp' mus be greater than or equal to 0 and less than or equal to 360"); + System.out + .println("From prWnml - the wind direction 'dcmp' mus be greater than or equal to 0 and less than or equal to 360"); return new Amount(SI.METERS_PER_SECOND); } /* Calculate wind speed 90 degrees to left of given direction. */ - double prwnml = (float) (sped.doubleValue() * (-Math.cos((drct.doubleValue() - dcmp.doubleValue() - 90) * GempakConstants.DTR))); + double prwnml = (float) (sped.doubleValue() * (-Math.cos((drct + .doubleValue() - dcmp.doubleValue() - 90) + * GempakConstants.DTR))); return (new Amount(prwnml, SI.METERS_PER_SECOND)); } @@ -2407,7 +2621,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prWxvf(Amount xvfr, Amount txvf) throws InvalidValueException, NullPointerException { + public static final Amount prWxvf(Amount xvfr, Amount txvf) + throws InvalidValueException, NullPointerException { // System.out.println("From prWxvf:"); // System.out.println(" xvfr = " + xvfr.doubleValue()); // System.out.println(" txvf = " + txvf.doubleValue()); @@ -2418,13 +2633,16 @@ public final class PRLibrary { double xvfrVal = xvfr.doubleValue(); double txvfVal = txvf.doubleValue(); - if (txvfVal != GempakConstants.RMISSD && xvfrVal != GempakConstants.RMISSD) + if (txvfVal != GempakConstants.RMISSD + && xvfrVal != GempakConstants.RMISSD) prwxvf = (xvfrVal < txvfVal ? xvfrVal : txvfVal); - else if (xvfrVal == GempakConstants.RMISSD && txvfVal != GempakConstants.RMISSD) + else if (xvfrVal == GempakConstants.RMISSD + && txvfVal != GempakConstants.RMISSD) prwxvf = xvfrVal; - else if (txvfVal != GempakConstants.RMISSD && xvfrVal != GempakConstants.RMISSD) + else if (txvfVal != GempakConstants.RMISSD + && xvfrVal != GempakConstants.RMISSD) prwxvf = txvfVal; } @@ -2446,7 +2664,8 @@ public final class PRLibrary { * @throws NullPointerException * */ - public static final Amount prXvfr(Amount ceil, Amount vsby) throws InvalidValueException, NullPointerException { + public static final Amount prXvfr(Amount ceil, Amount vsby) + throws InvalidValueException, NullPointerException { // System.out.println("From prXvfr:"); // System.out.println(" ceil = " + ceil.doubleValue()); // System.out.println(" vsby = " + vsby.doubleValue()); @@ -2459,7 +2678,8 @@ public final class PRLibrary { if (!checkNullOrInvalidValue(ceil)) return new Amount(Unit.ONE); - ceil = checkAndConvertInputAmountToExpectedUnits(ceil, NcUnits.HUNDREDS_OF_FEET); + ceil = checkAndConvertInputAmountToExpectedUnits(ceil, + NcUnits.HUNDREDS_OF_FEET); vsby = checkAndConvertInputAmountToExpectedUnits(vsby, NonSI.MILE); /* Compute categorical flight rules */ @@ -2477,7 +2697,8 @@ public final class PRLibrary { vc = 1; else if (ceilVal <= 30) vc = 2; - else if ((vsbyVal > 5) || (vsbyVal < 0) || (vsbyVal == GempakConstants.RMISSD)) { + else if ((vsbyVal > 5) || (vsbyVal < 0) + || (vsbyVal == GempakConstants.RMISSD)) { prxvfr = 3; } @@ -2524,7 +2745,8 @@ public final class PRLibrary { * * @throws InvalidRangeException */ - public static final Amount prZalt(Amount altm, Amount pres) throws InvalidValueException, NullPointerException { + public static final Amount prZalt(Amount altm, Amount pres) + throws InvalidValueException, NullPointerException { // System.out.println("From prZalt:"); // System.out.println(" altm = " + altm.doubleValue()); // System.out.println(" pres = " + pres.doubleValue()); @@ -2571,16 +2793,21 @@ public final class PRLibrary { */ private static double wci(double d) { - /* from R. Falconer, "Windchill, A Useful Wintertime Weather Variable", - * Weatherwise, Dec 1968. */ + /* + * from R. Falconer, "Windchill, A Useful Wintertime Weather Variable", + * Weatherwise, Dec 1968. + */ return ((double) (10 * Math.sqrt(d) + 10.45 - d)); } - public static final Amount checkAndConvertInputAmountToExpectedUnits(Amount amountIn, Unit expectedUnit) { + public static final Amount checkAndConvertInputAmountToExpectedUnits( + Amount amountIn, Unit expectedUnit) { Amount amountOut = null; - if (!amountIn.getUnit().equals(expectedUnit) && amountIn.getUnit().isCompatible(expectedUnit)) { - double newValue = amountIn.getUnit().getConverterTo(expectedUnit).convert(amountIn.doubleValue()); + if (!amountIn.getUnit().equals(expectedUnit) + && amountIn.getUnit().isCompatible(expectedUnit)) { + double newValue = amountIn.getUnit().getConverterTo(expectedUnit) + .convert(amountIn.doubleValue()); amountOut = new Amount(newValue, expectedUnit); } else // throw new ConversionException("Unable to convert " + @@ -2680,7 +2907,8 @@ public final class PRLibrary { * @throws InvalidRangeException */ - public static Amount prPmst(Amount thte, Amount tmpk) throws InvalidValueException, NullPointerException { + public static Amount prPmst(Amount thte, Amount tmpk) + throws InvalidValueException, NullPointerException { // checkNullOrInvalidValue(thte); // checkNullOrInvalidValue(tmpk); @@ -2693,7 +2921,7 @@ public final class PRLibrary { if (thte.getValue().doubleValue() <= 0) { // System.out - // .println("From prPmst(): The equivalent potential temperature must be greater than 0"); + // .println("From prPmst(): The equivalent potential temperature must be greater than 0"); return new Amount(SI.KELVIN); // throw new // InvalidRangeException("The equivalent potential temperature must be greater than 0"); @@ -2702,13 +2930,15 @@ public final class PRLibrary { /* Set convergence and initial guess of pressure. */ double epsi = 0.01; Amount tmpc = new Amount(tmpk.getValueAs(SI.CELSIUS), SI.CELSIUS); - double tempVal = 1000 * Math.pow(tmpk.getValue().doubleValue() / thte.getValue().doubleValue(), GempakConstants.AKAPPA); + double tempVal = 1000 * Math.pow(tmpk.getValue().doubleValue() + / thte.getValue().doubleValue(), GempakConstants.AKAPPA); Amount pgdn = new Amount(tempVal, NcUnits.MILLIBAR); boolean done = false; int i = 1; while (!done) { // Amount pgdn = new Amount ( tempVal, NcUnits.MILLIBAR ); - Amount pgup = new Amount(pgdn.getValueAs(NcUnits.MILLIBAR).doubleValue() + 1, NcUnits.MILLIBAR); + Amount pgup = new Amount(pgdn.getValueAs(NcUnits.MILLIBAR) + .doubleValue() + 1, NcUnits.MILLIBAR); Amount tedn = prThte(pgdn, tmpc, tmpc); Amount teup = prThte(pgup, tmpc, tmpc); @@ -2717,8 +2947,10 @@ public final class PRLibrary { return prpmst; /* Compute the correction; return on convergence. */ - double cor = (thte.getValueAs(SI.KELVIN).doubleValue() - tedn.getValueAs(SI.KELVIN).doubleValue()) - / (teup.getValueAs(SI.KELVIN).doubleValue() - tedn.getValueAs(SI.KELVIN).doubleValue()); + double cor = (thte.getValueAs(SI.KELVIN).doubleValue() - tedn + .getValueAs(SI.KELVIN).doubleValue()) + / (teup.getValueAs(SI.KELVIN).doubleValue() - tedn + .getValueAs(SI.KELVIN).doubleValue()); double pgdnVal = (pgdn.getValueAs(NcUnits.MILLIBAR).doubleValue() + cor); pgdn = new Amount(pgdnVal, NcUnits.MILLIBAR); diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/PlotParameters/plotParameters_obs.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/PlotParameters/plotParameters_obs.xml index cdb79ac79b..7c1c9d864c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/PlotParameters/plotParameters_obs.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/PlotModels/PlotParameters/plotParameters_obs.xml @@ -22,7 +22,7 @@ - + @@ -235,7 +235,8 @@ don't think this is needed here plotLookupTable="wx_symbol_trans.txt" There are 2 alternatives : First we can add/implement the arrayIndex="0" attribute to display other values and Second we can use the prioritySelectTable="wx_sym_select.txt". This is currently - only configured to rank all values the same so to prioritize it would need the ranking set --> + only configured to rank all values the same so to prioritize it would need the ranking set + RedMine 4230 --> + + + + From a00b252fff0f43d63431d66dbe8c3bb57edc6a41 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 17 Nov 2014 14:40:27 -0500 Subject: [PATCH 10/19] VLab Issue #4637 - Display label changes for WCN resource Change-Id: Ied1c62b307d9502a1fc2b4726e4bc3d39eb36758 Former-commit-id: 1e8f88310f8197e197dccbfe8808ae1b754ac8b1 [formerly 1e8f88310f8197e197dccbfe8808ae1b754ac8b1 [formerly d1e182b6701a567fcbb90a718d6c9f529c725edc]] Former-commit-id: 7b2af4a4fcd2a9846d116488ee83033ad846ea1a Former-commit-id: 19fd65f99d5410e8e0a2779d19df2fbf54d74007 --- .../nws/ncep/viz/rsc/aww/wcn/WcnResource.java | 646 +++++++++++++----- 1 file changed, 468 insertions(+), 178 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java index fcbf9b0470..4d8c5f0e5b 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.aww/src/gov/noaa/nws/ncep/viz/rsc/aww/wcn/WcnResource.java @@ -23,9 +23,12 @@ import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; import java.awt.Color; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.logging.Level; @@ -36,10 +39,15 @@ import org.eclipse.swt.graphics.RGB; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.edex.decodertools.core.LatLonPoint; +import com.raytheon.uf.viz.core.DrawableString; import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; @@ -48,12 +56,14 @@ import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.catalog.DirectDbQuery; import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage; +import com.raytheon.uf.viz.core.drawables.IDescriptor; 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.IMapDescriptor; +import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.viz.core.rsc.jts.JTSCompiler; import com.raytheon.viz.core.rsc.jts.JTSCompiler.PointStyle; @@ -90,6 +100,9 @@ import com.vividsolutions.jts.io.WKBReader; * parsing the ugc line where it started with a string that need to be re-parsed. Also * incorporating changes made by Dimitry for actually handling the > in UGC as well as * modifying times as appropriate. + * 10/16/2014 4637 J. Huber Fixed display label issue. Changed labeling mechanism from each WCN message to each county. + * Cleaned up deprecated methods as well. Changed gathering of reportType to read phenomena and + * significance from VTEC line. *
* * @author ujosyula @@ -107,9 +120,8 @@ public class WcnResource extends private List modifyList; - int timesThrough = 2; - - public class WcnRscDataObj implements IRscDataObject { + public class WcnRscDataObj implements IRscDataObject, + Comparable { String datauri; // used as a key string DataTime issueTime; // issue time from bulletin @@ -139,6 +151,12 @@ public class WcnResource extends DataTime evEndTime; + DataTime origEndTime; + + DataTime displayStart; + + DataTime displayEnd; + String evOfficeId; String evPhenomena; @@ -159,6 +177,12 @@ public class WcnResource extends public DataTime getDataTime() { return eventTime; } + + @Override + public int compareTo(WcnRscDataObj o) { + return (int) (this.issueTime.getRefTime().getTime() - o.issueTime + .getRefTime().getTime()); + } } protected class FrameData extends AbstractFrameData { @@ -203,7 +227,6 @@ public class WcnResource extends wcnDataMap.put(wcnRscDataObj.datauri, wcnRscDataObj); } } - return true; } } @@ -297,7 +320,6 @@ public class WcnResource extends countyFips = county.concat(inclusiveToken); outList.add(countyFips); - // UGC.addAwwFIPS(currentFips); } } else { outList.add(inUgcPart);// risky? @@ -317,24 +339,9 @@ public class WcnResource extends wcnStatusData = new WcnRscDataObj(); wcnStatusData.issueTime = new DataTime(awwRecord.getIssueTime()); - // WATCH COUNTY NOTIFICATION but we really need the referenced - // TORNADO or TSTRM (query the watch # ?) - wcnStatusData.reportType = AwwReportType - .getReportType(awwRecord.getReportType()); wcnStatusData.datauri = awwRecord.getDataURI(); + wcnStatusData.isCounty = isCountyUgs(awwugcs); - if (awwRecord.getBullMessage().contains("THUNDERSTORM")) { - wcnStatusData.reportType = AwwReportType.SEVERE_THUNDERSTORM_WATCH;// "THUNDERSTORM"; - } else if (awwRecord.getBullMessage().contains("TORNADO")) { - wcnStatusData.reportType = AwwReportType.TORNADO_WATCH;// "TORNADO"; - } - - if (!(wcnStatusData.isCounty = isCountyUgs(awwugcs))) { - // System.err.println("****** " - // + awwugcs.getEventTrackingNumber() + "-" - // + awwugcs.getProdPurgeTime() + " **************");// TODO - setMarineZonesFips(awwugcs.getAwwFIPS(), wcnStatusData);// T456 - } String ugcline = awwugcs.getUgc();// get the ugc line to find // the counties if (ugcline != null && ugcline != "") { @@ -358,8 +365,7 @@ public class WcnResource extends } if (temp != null && dontSkip) { - if (temp.startsWith("\r\r\n")) { // was - // .contains("\r\r\n") + if (temp.startsWith("\r\r\n")) { String temp1 = temp.substring(3); temp = temp1; } @@ -377,7 +383,6 @@ public class WcnResource extends .toCharArray()[5]))) { } else { (wcnStatusData.countyUgc).add(temp); - // awwugcs.setUgc(temp); } } else { fipsRangeReparse(temp, countyname, @@ -394,10 +399,7 @@ public class WcnResource extends countyname = temp.substring(0, 3); String temp2 = countyname.substring(0, 3) + temp.substring(3); - (wcnStatusData.countyUgc).add(temp2 - // countyname.concat(temp.substring(3)) - ); - // (wcnStatusData.countyUgc).add(temp); + (wcnStatusData.countyUgc).add(temp2); } String temp2 = countyname.substring(0, 3) @@ -407,8 +409,6 @@ public class WcnResource extends (wcnStatusData.countyUgc).add(temp2 .substring(3, 9)); } else { - // (wcnStatusData.countyUgc).add(temp2 - // .substring(0, 6)); fipsRangeReparse(temp2.substring(0, 6), countyname, (wcnStatusData.countyUgc)); @@ -449,12 +449,34 @@ public class WcnResource extends .getEventTrackingNumber(); wcnStatusData.evEndTime = new DataTime( awwVtech.getEventEndTime()); + wcnStatusData.origEndTime = wcnStatusData.evEndTime; + wcnStatusData.displayStart = wcnStatusData.issueTime; + wcnStatusData.displayEnd = wcnStatusData.origEndTime; wcnStatusData.evOfficeId = awwVtech.getOfficeID(); wcnStatusData.evPhenomena = awwVtech.getPhenomena(); wcnStatusData.evProductClass = awwVtech .getProductClass(); wcnStatusData.evSignificance = awwVtech .getSignificance(); + // RM4637 Create the report type from the VTEC phenomena + // and significance + String buildReportType = wcnStatusData.evPhenomena + + "." + wcnStatusData.evSignificance; + if (buildReportType.equalsIgnoreCase("TO.A")) { + wcnStatusData.reportType = AwwReportType.TORNADO_WATCH; + } else if (buildReportType.equalsIgnoreCase("SV.A")) { + wcnStatusData.reportType = AwwReportType.SEVERE_THUNDERSTORM_WATCH; + } else { + wcnStatusData.reportType = AwwReportType + .getReportType(awwRecord.getReportType()); + if (awwRecord.getBullMessage().contains( + "THUNDERSTORM")) { + wcnStatusData.reportType = AwwReportType.SEVERE_THUNDERSTORM_WATCH;// "THUNDERSTORM"; + } else if (awwRecord.getBullMessage().contains( + "TORNADO")) { + wcnStatusData.reportType = AwwReportType.TORNADO_WATCH;// "TORNADO"; + } + } if ((awwVtech.getAction().equalsIgnoreCase("COR")) || (awwVtech.getAction() @@ -468,7 +490,9 @@ public class WcnResource extends || (awwVtech.getAction() .equalsIgnoreCase("EXT")) || (awwVtech.getAction() - .equalsIgnoreCase("EXP"))) { + .equalsIgnoreCase("EXP")) + || (awwVtech.getAction() + .equalsIgnoreCase("CON"))) { modifyList.add(wcnStatusData); } @@ -521,20 +545,8 @@ public class WcnResource extends return (ArrayList) wcnDataList; } - // prior: - // "select AsBinary(the_geom), AsBinary(the_geom_0_001), wfo,name,id, lat, lon from mapdata.marinezones where "; private static String queryPrefixMZ_LatLons = "select wfo,name,id, lat, lon from mapdata.marinezones"; - // where ST_SetSrid('BOX3D(-180.0 -90.0, 180.0 90.0)'::box3d,4326)"; - - // private static final double ENV_MIN_X = -180.0; - // private static final double ENV_MAX_X = 180.0; - // private static final double ENV_MIN_Y = -90; - // private static final double ENV_MAX_Y = 90.0; - // private String geoConstraint = - // String.format("the_geom_0_001 && ST_SetSrid('BOX3D(%f %f, %f %f)'::box3d,4326)", - // ENV_MIN_X, ENV_MIN_Y, ENV_MAX_X, ENV_MAX_Y); - private WcnRscDataObj getCountyNameLatLon(WcnRscDataObj wdata) { wdata.countyPoints = new ArrayList(); wdata.countyNames = new ArrayList(); @@ -640,16 +652,7 @@ public class WcnResource extends && modify.evSignificance .equalsIgnoreCase(candidate.evSignificance)) { if (candidate.eventType.equalsIgnoreCase("CAN")) { - // System.err.print(modify.issueTime - // .getDisplayString() - // + "**" - // + modify.evEndTime.getDisplayString()); - candidate.evEndTime = modify.issueTime; - // (modify.issueTime.getValidTimeAsDate().getTime() - // <= modify.evEndTime - // .getValidTimeAsDate().getTime() ? - // modify.issueTime - // : modify.evEndTime); + candidate.evEndTime = candidate.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -665,7 +668,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar()));// ? } else if (candidate.eventType.equalsIgnoreCase("EXP")) { - candidate.evEndTime = modify.issueTime; + candidate.evEndTime = candidate.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -673,7 +676,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar())); } else if (candidate.eventType.equalsIgnoreCase("EXA")) { - candidate.evEndTime = modify.evEndTime; + candidate.evEndTime = candidate.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -681,7 +684,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar())); } else if (candidate.eventType.equalsIgnoreCase("EXT")) { - candidate.evEndTime = modify.evEndTime; + candidate.evEndTime = candidate.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -698,7 +701,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar())); } else if (candidate.eventType.equalsIgnoreCase("EXB")) { - candidate.evEndTime = modify.evEndTime; + candidate.evEndTime = candidate.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -706,7 +709,7 @@ public class WcnResource extends candidate.evEndTime .getRefTimeAsCalendar())); } else if (candidate.eventType.equalsIgnoreCase("CON")) { - candidate.evEndTime = modify.evEndTime; + candidate.evEndTime = modify.origEndTime; candidate.eventTime = new DataTime( candidate.eventTime.getRefTimeAsCalendar(), new TimeRange(candidate.eventTime @@ -726,7 +729,7 @@ public class WcnResource extends } } - }// end if !null + } } public void initResource(IGraphicsTarget grphTarget) throws VizException { @@ -767,11 +770,19 @@ public class WcnResource extends int symbolWidth = 2; int symbolSize = 2; - Collection wcnDataValues = currFrameData.wcnDataMap - .values(); + // RM 4637: Need to sort the WCNs by issue time prior to passing in to + // be chopped into individual counties. + List sortedWcns = new ArrayList(); - for (WcnRscDataObj wcnData : wcnDataValues) { + for (Map.Entry entry : currFrameData.wcnDataMap + .entrySet()) { + sortedWcns.add(entry.getValue()); + } + Collections.sort(sortedWcns); + List displayObjs = PreProcessDisplay(sortedWcns); + + for (PreProcessDisplayObj wcnData : displayObjs) { Boolean draw = false, drawLabel = true; if (wcnRscData.getColorCodeEnable()) { @@ -879,31 +890,29 @@ public class WcnResource extends draw = true; } - - if (getCurrentFrameTime().getValidTimeAsDate().getTime() <= wcnData - .getDataTime().getValidPeriod().getEnd().getTime() - || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wcnData - .getDataTime().getValidPeriod().getStart() + if (getCurrentFrameTime().getValidTimeAsDate().getTime() < wcnData.displayEnd + .getValidPeriod().getEnd().getTime() + || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wcnData.displayStart .getTime()) { - draw = true;// verify this rule; + draw = true; } - if (getCurrentFrameTime().getValidTimeAsDate().getTime() > wcnData - .getDataTime().getValidPeriod().getEnd().getTime()) { + if (getCurrentFrameTime().getValidTimeAsDate().getTime() > wcnData.displayEnd + .getValidPeriod().getEnd().getTime()) { draw = false; } - if (getCurrentFrameTime().getValidTimeAsDate().getTime() < wcnData - .getDataTime().getValidPeriod().getStart().getTime()) { + if (getCurrentFrameTime().getValidTimeAsDate().getTime() < wcnData.displayStart + .getTime()) { draw = false; } - if (getCurrentFrameTime().getValidTimeAsDate().getTime() == (wcnData - .getDataTime().getValidPeriod().getEnd().getTime())) { + if (getCurrentFrameTime().getValidTimeAsDate().getTime() == (wcnData.displayEnd + .getValidPeriod().getEnd().getTime())) { // do not draw endtime frame, that's what nmap2 does draw = false; } - + // } // draw the polygon if (true == draw) { @@ -912,23 +921,22 @@ public class WcnResource extends Color[] colors = new Color[] { new Color(color.red, color.green, color.blue) }; - for (int i = 0; i < wcnData.countyNumPoints; i++) { + // for (int i = 0; i < wcnData.countyNumPoints; i++) { - Coordinate coord = new Coordinate( - wcnData.countyLon[i], wcnData.countyLat[i]); - Symbol pointSymbol = new Symbol(null, colors, - symbolWidth, symbolSize * 0.4, false, - coord, "Symbol", "FILLED_DIAMOND"); - DisplayElementFactory df = new DisplayElementFactory( - target, getNcMapDescriptor()); - ArrayList displayEls = df - .createDisplayElements(pointSymbol, - paintProps); - for (IDisplayable each : displayEls) { - each.draw(target, paintProps); - each.dispose(); - } + Coordinate coord = new Coordinate(wcnData.countyLon, + wcnData.countyLat); + Symbol pointSymbol = new Symbol(null, colors, + symbolWidth, symbolSize * 0.4, false, coord, + "Symbol", "FILLED_DIAMOND"); + DisplayElementFactory df = new DisplayElementFactory( + target, getNcMapDescriptor()); + ArrayList displayEls = df + .createDisplayElements(pointSymbol, paintProps); + for (IDisplayable each : displayEls) { + each.draw(target, paintProps); + each.dispose(); } + // } } catch (Exception e) { logger.warning("In paintFrame(AbstractFrameData frameData, IGraphicsTarget target,PaintProperties paintProps)\n" + e.getClass().getCanonicalName() @@ -952,14 +960,13 @@ public class WcnResource extends if (wcnRscData.getWatchBoxUnionEnable()) { drawLabel = false; - double allX = wcnData.countyLon[0]; - double allY = wcnData.countyLat[0]; - for (int i = 1; i < wcnData.countyNumPoints; i++) { - allX += wcnData.countyLon[i]; - allY += wcnData.countyLat[i]; - } - double[] labelLatLon = { allX / wcnData.countyNumPoints, - allY / wcnData.countyNumPoints }; + double allX = wcnData.countyLon; + double allY = wcnData.countyLat; + /* + * for (int i = 1; i < wcnData.countyNumPoints; i++) { allX + * += wcnData.countyLon[i]; allY += wcnData.countyLat[i]; } + */ + double[] labelLatLon = { allX, allY }; // double[] labelLatLon = { // (wcnData.countyLon[0]+wcnData.countyLon[(wcnData.countyNumPoints)/2])/2, // (wcnData.countyLat[0]+wcnData.countyLat[(wcnData.countyNumPoints)/2])/2 @@ -978,7 +985,7 @@ public class WcnResource extends // box-time? DataTime startTime = new DataTime(wcnData.eventTime .getValidPeriod().getStart()); - DataTime endTime = new DataTime(wcnData.eventTime + DataTime endTime = new DataTime(wcnData.origEndTime .getValidPeriod().getEnd()); String temp = startTime.toString() .substring(11, 13) @@ -993,11 +1000,13 @@ public class WcnResource extends enabledText.add(""); text = enabledText.toArray(text); - - target.drawStrings(font, text, labelPix[0], - labelPix[1], 0.0, TextStyle.NORMAL, new RGB[] { - color, color }, - HorizontalAlignment.LEFT, VerticalAlignment.TOP); + DrawableString wcnTime = new DrawableString(text, color); + wcnTime.font = font; + wcnTime.setCoordinates(labelPix[0], labelPix[1], 0.0); + wcnTime.textStyle = TextStyle.NORMAL; + wcnTime.horizontalAlignment = HorizontalAlignment.LEFT; + wcnTime.verticallAlignment = VerticalAlignment.BOTTOM; + target.drawStrings(wcnTime); } drawCountyOutline2(wcnData, target, color, symbolWidth, @@ -1066,7 +1075,7 @@ public class WcnResource extends IWireframeShape newOutlineShape = target.createWireframeShape( false, descriptor, 0.0f); IShadedShape newShadedShape = target.createShadedShape(false, - descriptor, true); + descriptor.getGridGeometry(), true); JTSCompiler jtsCompiler = new JTSCompiler(newShadedShape, newOutlineShape, descriptor, PointStyle.CROSS); @@ -1131,55 +1140,295 @@ public class WcnResource extends } } - public void drawTimeLabelWatchNumber(WcnRscDataObj wcnData, + public void drawTimeLabelWatchNumber(PreProcessDisplayObj wcnData, IGraphicsTarget target, RGB color) { try { - for (int i = 0; i < wcnData.countyNumPoints; i++) { - double[] labelLatLon = { wcnData.countyLon[i], - wcnData.countyLat[i] }; - double[] labelPix = descriptor.worldToPixel(labelLatLon); + double[] labelLatLon = { wcnData.countyLon, wcnData.countyLat }; + double[] labelPix = descriptor.worldToPixel(labelLatLon); - if (labelPix != null) { - String[] text = new String[3]; - List enabledText = new ArrayList(); + if (labelPix != null) { + String[] text = new String[3]; + List enabledText = new ArrayList(); - if (wcnRscData.getWatchBoxNumberEnable()) { - enabledText.add(wcnData.watchNumber); - } - - if (wcnRscData.getWatchBoxLabelEnable()) { - enabledText.add(wcnData.countyNames.get(i)); - } - - if (wcnRscData.getWatchBoxTimeEnable()) { - DataTime startTime = new DataTime(wcnData.eventTime - .getValidPeriod().getStart()); - DataTime endTime = new DataTime(wcnData.eventTime - .getValidPeriod().getEnd()); - String temp = startTime.toString().substring(11, 13) - + startTime.toString().substring(14, 16) + "-" - + endTime.toString().substring(11, 13) - + endTime.toString().substring(14, 16); - enabledText.add(temp); - } - - for (int j = enabledText.size(); j < 3; j++) { - enabledText.add(""); - } - - text = enabledText.toArray(text); - - target.drawStrings(font, text, labelPix[0], labelPix[1], - 0.0, TextStyle.NORMAL, new RGB[] { color, color, - color }, HorizontalAlignment.LEFT, - VerticalAlignment.MIDDLE); + if (wcnRscData.getWatchBoxNumberEnable()) { + enabledText.add(wcnData.watchNumber); } + + if (wcnRscData.getWatchBoxLabelEnable()) { + enabledText.add(wcnData.countyNames); + } + + if (wcnRscData.getWatchBoxTimeEnable()) { + DataTime startTime = new DataTime(wcnData.eventTime + .getValidPeriod().getStart()); + DataTime endTime = new DataTime(wcnData.origEndTime + .getValidPeriod().getEnd()); + String temp = startTime.toString().substring(11, 13) + + startTime.toString().substring(14, 16) + "-" + + endTime.toString().substring(11, 13) + + endTime.toString().substring(14, 16); + enabledText.add(temp); + } + + for (int j = enabledText.size(); j < 3; j++) { + enabledText.add(""); + } + text = enabledText.toArray(text); + DrawableString wcnTime = new DrawableString(text, color); + wcnTime.font = font; + wcnTime.setCoordinates(labelPix[0], labelPix[1], 0.0); + wcnTime.textStyle = TextStyle.NORMAL; + wcnTime.horizontalAlignment = HorizontalAlignment.LEFT; + wcnTime.verticallAlignment = VerticalAlignment.BOTTOM; + target.drawStrings(wcnTime); } } catch (Exception e) { System.out.println("wcnResource.java at Line 427" + e);// TODO fix } } + // RM 4637 county by county display. Creates a subset of the master + // WcnRscDataObj and boils it down + // to only what is needed for display. + public class PreProcessDisplayObj implements + Comparable { + DataTime issueTime; // issue time from bulletin + + DataTime eventTime; + + AwwReportType reportType; + + float countyLat; + + float countyLon; + + String countyNames, stateNames; + + public String countyFips; + + String eventType; + + String watchNumber; // watch number to be displayed + + DataTime origEndTime; + + Date displayStart; + + DataTime displayEnd; + + String evTrack; + + String evPhenomena; + + String evSignificance; + + String evOfficeId; + + DataTime start; + + RGB color = new RGB(155, 155, 155); + + public String getKey() { + return getpreProcessDisplayObjKey(this); + } + + // Used to sort finished collection of single county objects. + @Override + public int compareTo(PreProcessDisplayObj o) { + + return (int) (this.issueTime.getRefTime().getTime() - o.issueTime + .getRefTime().getTime()); + } + } + + // RM 4637 time labels. The original implementation of this resource was to + // take each WCN message and + // use that as a basis for display. This had two flaws. One it caused + // multiple labels to be created for the + // same county. Two, if an EXT was issued it would cause a collision of + // labels. To fix this we pre-process + // all valid messages for the current frame data and make sure the county + // only has one label displayed at all + // times. For every message except EXT and EXB the first instance of the + // county in any WCN will set the time + // label. Since when the message is decoded if the VTEC start time is + // 000000T0000Z it will point back to NEW + // product, it does not matter which eventType we used to create the initial + // start time label. For EXT the + // display needs to be updated to reflect that. In those cases it resets the + // displayEnd variable time of the previous + // label so that there is only one label displayed at all times and the end + // time is correct based on the frame + // time. Once all the county labels are determined, the array is sorted and + // returned to have the labels drawn. + + private List PreProcessDisplay( + List wcnCollection) { + HashMap displayMap; + HashMap extMap; + HashMap splitWatch; + displayMap = new HashMap(); + extMap = new HashMap(); + splitWatch = new HashMap(); + List displayObj = new ArrayList(); + for (WcnRscDataObj processWCN : wcnCollection) { + for (int i = 0; i < processWCN.countyNumPoints; i++) { + PreProcessDisplayObj singleCounty = new PreProcessDisplayObj(); + singleCounty.countyFips = processWCN.countyFips.get(i); + singleCounty.countyLat = processWCN.countyLat[i]; + singleCounty.countyLon = processWCN.countyLon[i]; + singleCounty.countyNames = processWCN.countyNames.get(i); + if (!processWCN.eventType.equalsIgnoreCase("NEW") + || !processWCN.eventType.equalsIgnoreCase("CON")) { + singleCounty.displayStart = processWCN.issueTime + .getValidPeriod().getStart(); + } else { + singleCounty.displayStart = processWCN.eventTime + .getValidPeriod().getStart(); + } + singleCounty.displayEnd = processWCN.origEndTime; + singleCounty.eventTime = processWCN.eventTime; + singleCounty.eventType = processWCN.eventType; + singleCounty.issueTime = processWCN.issueTime; + singleCounty.origEndTime = processWCN.origEndTime; + singleCounty.reportType = processWCN.reportType; + singleCounty.stateNames = processWCN.stateNames.get(i); + singleCounty.watchNumber = processWCN.watchNumber; + // Some watches beginn when a previous is ending. The watch + // number in the WCN then is 001/002. + // Need to track this to avoid multiple labels being displayed. + if (singleCounty.watchNumber.contains("/")) { + splitWatch.put(singleCounty.countyFips, + singleCounty.watchNumber); + } + singleCounty.evTrack = processWCN.evTrack; + singleCounty.evPhenomena = processWCN.evPhenomena; + singleCounty.evSignificance = processWCN.evSignificance; + singleCounty.evOfficeId = processWCN.evOfficeId; + if (singleCounty.eventType.equalsIgnoreCase("EXT") + || singleCounty.eventType.equalsIgnoreCase("EXB") + || singleCounty.eventType.equalsIgnoreCase("EXA")) { + if (extMap.containsKey(singleCounty.countyFips + " " + + singleCounty.evTrack)) { + DataTime retrievePreviousEXTTime = extMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack); + PreProcessDisplayObj retrievePreviousEXT = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT" + + retrievePreviousEXTTime); + if (retrievePreviousEXT == null) { + retrievePreviousEXT = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + + "EXT"); + retrievePreviousEXT.displayEnd = singleCounty.issueTime; + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT", + retrievePreviousEXT); + extMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, + singleCounty.issueTime); + } else { + retrievePreviousEXT.displayEnd = singleCounty.issueTime; + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT" + " " + + retrievePreviousEXTTime, + retrievePreviousEXT); + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT" + " " + + singleCounty.issueTime, singleCounty); + extMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, + singleCounty.issueTime); + } + } else if (displayMap.containsKey(singleCounty.countyFips + + " " + singleCounty.evTrack)) { + PreProcessDisplayObj retrieveCurrent = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack); + retrieveCurrent.displayEnd = singleCounty.issueTime; + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, retrieveCurrent); + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT", + singleCounty); + extMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, singleCounty.issueTime); + } else { + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, singleCounty); + } + } else if (singleCounty.eventType.equalsIgnoreCase("CAN") + || singleCounty.eventType.equalsIgnoreCase("EXP")) { + if (extMap.containsKey(singleCounty.countyFips + " " + + singleCounty.evTrack)) { + DataTime retrievePreviousEXTTime = extMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack); + PreProcessDisplayObj retrievePreviousEXT = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT" + + retrievePreviousEXTTime); + if (retrievePreviousEXT == null) { + retrievePreviousEXT = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + + "EXT"); + if (singleCounty.eventType.equalsIgnoreCase("CAN")) { + retrievePreviousEXT.displayEnd = singleCounty.issueTime; + } else { + retrievePreviousEXT.displayEnd = singleCounty.origEndTime; + } + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT", + retrievePreviousEXT); + extMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, + singleCounty.origEndTime); + } else { + retrievePreviousEXT.displayEnd = singleCounty.origEndTime; + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack + " " + "EXT" + " " + + retrievePreviousEXTTime, + retrievePreviousEXT); + extMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, + singleCounty.origEndTime); + } + } else if (displayMap.containsKey(singleCounty.countyFips + + " " + singleCounty.evTrack)) { + PreProcessDisplayObj retrieveCurrent; + retrieveCurrent = displayMap + .get(singleCounty.countyFips + " " + + singleCounty.evTrack); + if (singleCounty.eventType.equalsIgnoreCase("CAN")) { + retrieveCurrent.displayEnd = singleCounty.issueTime; + } else { + retrieveCurrent.displayEnd = singleCounty.origEndTime; + } + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, retrieveCurrent); + } + } else { + if (!displayMap.containsKey(singleCounty.countyFips + " " + + singleCounty.evTrack)) { + displayMap.put(singleCounty.countyFips + " " + + singleCounty.evTrack, singleCounty); + } + } + } + } + + for (Map.Entry entry : displayMap + .entrySet()) { + displayObj.add(entry.getValue()); + } + Collections.sort(displayObj); + + return (displayObj); + } + // ---------------------------------------------------------------T456: // for pre-query the database @@ -1199,7 +1448,7 @@ public class WcnResource extends // if it is 1st round in the loop then draw outline since it pre-calculated // for all zones - private boolean isFirstRound = true; + // private boolean isFirstRound = true; // Area change flag private boolean areaChangeFlag = false; @@ -1221,7 +1470,7 @@ public class WcnResource extends private IMapDescriptor descriptor; - private RGB symbolColor = new RGB(155, 155, 155); + // private RGB symbolColor = new RGB(155, 155, 155); // private RGB color = new RGB (155, 155, 155); @@ -1326,7 +1575,7 @@ public class WcnResource extends IWireframeShape newUnionShape = target.createWireframeShape(false, descriptor, 0.0f); IShadedShape newShadedShape = target.createShadedShape(false, - descriptor, true); + descriptor.getGridGeometry(), true); JTSCompiler jtsCompiler = new JTSCompiler(newShadedShape, newOutlineShape, descriptor, PointStyle.CROSS); @@ -1365,7 +1614,7 @@ public class WcnResource extends } - private void drawCountyOutline2(WcnRscDataObj wData, + private void drawCountyOutline2(PreProcessDisplayObj wData, IGraphicsTarget target, RGB color, int outlineWidth, LineStyle lineStyle, PaintProperties paintProps, int drawOutlineOrShadedshapeorUnion) { @@ -1393,10 +1642,10 @@ public class WcnResource extends return; } - if (getCurrentFrameTime().getValidTimeAsDate().getTime() <= wData - .getDataTime().getValidPeriod().getEnd().getTime() - || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wData - .getDataTime().getValidPeriod().getStart().getTime()) { + if (getCurrentFrameTime().getValidTimeAsDate().getTime() <= wData.displayEnd + .getValidPeriod().getEnd().getTime() + || getCurrentFrameTime().getValidTimeAsDate().getTime() >= wData.displayStart + .getTime()) { // draw = true;// verify this rule; // // // // // // // // //TODO } @@ -1475,6 +1724,19 @@ public class WcnResource extends for (String s : w.countyFips) { sb.append(s);// TODO: is this necessary? } + sb.append(w.countyFips); + + return sb.toString(); + } + + public String getpreProcessDisplayObjKey(PreProcessDisplayObj w) { + + StringBuilder sb = new StringBuilder(w.evOfficeId); + + sb.append(w.evTrack).append(w.evPhenomena).append(w.evSignificance) + .append(w.eventType); + + sb.append(w.countyFips); return sb.toString(); } @@ -1496,27 +1758,65 @@ public class WcnResource extends // may need to be modified later to use the super class's version for // the common part - HashMap queryList = new HashMap( - resourceData.getMetadataMap()); + // RM4637: Changed query to use ThirftClient instead of uengine. Also, + // limit response to the last twelve hours from frame + // time requested. + DbQueryRequest request = new DbQueryRequest(); + DbQueryRequest requestWatchNumber = new DbQueryRequest(); + HashMap reqConstraints = new HashMap(); + RequestConstraint pluginName = new RequestConstraint( + wcnRscData.getPluginName()); + IDescriptor.FramesInfo frameTimes = this.descriptor.getFramesInfo(); + long watchcheck = frameTimes.getFrameTimes()[0].getRefTimeAsCalendar() + .getTimeInMillis(); + watchcheck = watchcheck - 43200000; + Date queryTime = new Date(watchcheck); + DataTime setQueryTime = new DataTime(queryTime); + reqConstraints.put("pluginName", pluginName); + reqConstraints.put("reportType", new RequestConstraint( + "WATCH COUNTY NOTIFICATION")); + reqConstraints.put("dataTime.refTime", new RequestConstraint( + setQueryTime.toString(), ConstraintType.GREATER_THAN)); + requestWatchNumber.setConstraints(reqConstraints); + requestWatchNumber.addRequestField("watchNumber"); + requestWatchNumber.setDistinct(true); + DbQueryResponse responseWatch = (DbQueryResponse) ThriftClient + .sendRequest(requestWatchNumber); - com.raytheon.uf.viz.core.catalog.LayerProperty prop = new com.raytheon.uf.viz.core.catalog.LayerProperty(); - prop.setDesiredProduct(com.raytheon.uf.viz.core.rsc.ResourceType.PLAN_VIEW); - prop.setEntryQueryParameters(queryList, false); - prop.setNumberOfImages(15000); // TODO: max # records ?? should we cap - // this? - - String script = null; - script = com.raytheon.uf.viz.core.catalog.ScriptCreator - .createScript(prop); - - if (script == null) { - return; + // reqConstraints.put("pluginName", pluginName); + // reqConstraints.put("reportType", new + // RequestConstraint("WATCH COUNTY NOTIFICATION")); + reqConstraints.remove("dataTime.refTime"); + List pdoList = new ArrayList(); + for (int i = 0; i < responseWatch.getResults().size(); i++) { + for (Map.Entry watchentry : responseWatch + .getResults().get(i).entrySet()) { + reqConstraints.put("watchNumber", new RequestConstraint( + watchentry.getValue().toString())); + request.setConstraints(reqConstraints); + DbQueryResponse response = (DbQueryResponse) ThriftClient + .sendRequest(request); + reqConstraints.remove("watchNumber"); + for (int j = 0; j < response.getResults().size(); j++) { + for (Map.Entry pdoentry : response + .getResults().get(j).entrySet()) { + pdoList.add(pdoentry.getValue()); + } + } + } } - Object[] pdoList = com.raytheon.uf.viz.core.comm.Connector - .getInstance().connect(script, null, 60000); - + // request.setConstraints(reqConstraints); + // request.setOrderByField("issueTime", OrderMode.ASC); + // response = (DbQueryResponse) ThriftClient.sendRequest(request); queryResult = new WcnCountyQueryResult(); + // List pdoList = new ArrayList(); + /* + * for (int i = 0;i < response.getResults().size();i++) { for + * (Map.Entry entry : + * response.getResults().get(i).entrySet()) { + * pdoList.add(entry.getValue()); } } + */ for (Object pdo : pdoList) { for (IRscDataObject dataObject : processRecord(pdo)) { @@ -1530,16 +1830,6 @@ public class WcnResource extends setAllFramesAsPopulated(); } - public void setMarineZonesFips(Set awwFipsSet, WcnRscDataObj wrdo) { - - if (awwFipsSet != null && wrdo != null) { - for (AwwFips eachAwwFips : awwFipsSet) { - wrdo.countyFips.add(eachAwwFips.getFips()); - } - } - - } - public boolean isCountyUgs(AwwUgc au) { Set awwFipsSet = au.getAwwFIPS(); boolean out = false; From 45cbb5c4613da5c1eacd4343fa0e010ab18685ff Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 17 Nov 2014 14:46:10 -0500 Subject: [PATCH 11/19] VLab Issue #4867 - UAIR display performance improvement Change-Id: I2065da34f46cf396bbc167822d79aef53092aaa4 Former-commit-id: 3714f234013d2cf46ceba96519a48d2c998c881c [formerly 3714f234013d2cf46ceba96519a48d2c998c881c [formerly 7b372387492fb00f91956d83ab03a702cbc407b7]] Former-commit-id: d0545c54c18d154e7ac9eed011b4cbe5cb922659 Former-commit-id: 490f2c7a418719d48b475aa82ae664495141ddc5 --- .../dataplugin/ncuair/dao/NcUairToRecord.java | 29 ++++++--- .../uengine/tasks/profile/MergeSounding2.java | 2 +- .../uengine/tasks/profile/NcSoundingDrv.java | 29 ++++++--- .../tasks/profile/ObservedSoundingQuery.java | 64 +++++++++++++++++-- 4 files changed, 96 insertions(+), 28 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/dao/NcUairToRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/dao/NcUairToRecord.java index ce5912856b..b061feb627 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/dao/NcUairToRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/src/gov/noaa/nws/ncep/common/dataplugin/ncuair/dao/NcUairToRecord.java @@ -15,6 +15,8 @@ * 10/2011 S. Gurung Added changes related to getting stid/lat/lon/elev * from database instead of snstns.xml file * 6/2014 T.Lee Added support XXAA, XXBB, XXCC, XXDD + * 10/2014 B. Hebbard Allow subsetting XXAA/TTAA params only for faster + * retrieval in cases where other params not needed * * * This code has been developed by the SIB for use in the AWIPS2 system. @@ -68,7 +70,7 @@ public class NcUairToRecord { HDR_PARAMS_LIST = sb.toString(); } - public static final String MAN_PARAMS_LIST; + public static final String AA_ONLY_PARAMS_LIST; static { StringBuffer sb = new StringBuffer(); sb.append(HDR_PARAMS_LIST); @@ -80,7 +82,22 @@ public class NcUairToRecord { sb.append("TTAA_SPED,"); sb.append("TTAA_HGHT,"); // ------------------------- - sb.append("numTTBB,"); + sb.append("numXXAA,"); + sb.append("XXAA_PRES,"); + sb.append("XXAA_TEMP,"); + sb.append("XXAA_DWPT,"); + sb.append("XXAA_DRCT,"); + sb.append("XXAA_SPED,"); + sb.append("XXAA_HGHT"); + AA_ONLY_PARAMS_LIST = sb.toString(); + } + + public static final String MAN_PARAMS_LIST; + static { + StringBuffer sb = new StringBuffer(); + sb.append(AA_ONLY_PARAMS_LIST); + // ------------------------- + sb.append(",numTTBB,"); sb.append("TTBB_PRES,"); sb.append("TTBB_TEMP,"); sb.append("TTBB_DWPT,"); @@ -152,14 +169,6 @@ public class NcUairToRecord { sb.append("TTBB_HI_MEAN_DRCT,"); sb.append("TTBB_HI_MEAN_SPED,"); // ------------------------- - sb.append("numXXAA,"); - sb.append("XXAA_PRES,"); - sb.append("XXAA_TEMP,"); - sb.append("XXAA_DWPT,"); - sb.append("XXAA_DRCT,"); - sb.append("XXAA_SPED,"); - sb.append("XXAA_HGHT,"); - // ------------------------- sb.append("numXXBB,"); sb.append("XXBB_PRES,"); sb.append("XXBB_TEMP,"); diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding2.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding2.java index 64a3d3f976..07ea0ad899 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding2.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding2.java @@ -238,7 +238,7 @@ public class MergeSounding2 implements ISerializableObject { sndata.clear(); sndata.add(sl); // System.out - // .println("return manatory level without merging!"); + // .println("return mandatory level without merging!"); // printOut(sndata); return sndata; } diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java index 19f5bcf8ae..ece9873e8c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java @@ -31,6 +31,9 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; * 06/25/2014 Chin Chen support dropsonde * 07/23/2014 Chin Chen Support PW * 08/26/2014 Chin Chen index out of bound bug + * 10/03/2014 B. Hebbard Performance improvement: Pass level and pwRequired params to + * ObservedSoundingQuery.getObservedSndNcUairDataGeneric( ) so + * it can decide whether it can economize on DB params it needs * * Python Script example to query multiple locations at one request: * The following 3 query examples, returns same results. @@ -1107,7 +1110,7 @@ public class NcSoundingDrv { long t003 = System.currentTimeMillis(); uairRecordArrList = ObservedSoundingQuery .getObservedSndNcUairDataGeneric(coordinateArray, stnIdArr, - rangeTimeStringLst, rangeTimeArr); + rangeTimeStringLst, rangeTimeArr, level, pwRequired); long t004 = System.currentTimeMillis(); System.out.println("getObservedSndNcUairDataGeneric query took " + (t004 - t003) + "ms"); @@ -1442,8 +1445,9 @@ public class NcSoundingDrv { // } returnedObject = cube; - // long t02 = System.currentTimeMillis(); - // System.out.println("getSoundingData2Generic query took "+(t02-t01)+" ms in total"); + long t02 = System.currentTimeMillis(); + System.out.println("getSoundingData2Generic query took " + (t02 - t01) + + " ms in total"); return returnedObject; } @@ -1470,18 +1474,23 @@ public class NcSoundingDrv { } List uairRecordArrList; - // long t003 = System.currentTimeMillis(); + long t003 = System.currentTimeMillis(); uairRecordArrList = ObservedSoundingQuery .getObservedSndNcUairDataGeneric(coordinateArray, stnIdArr, - rangeTimeStringLst, rangeTimeArr); - // long t004 = System.currentTimeMillis(); - // System.out.println("getObservedSndNcUairDataGeneric API call took "+(t004-t003)+"ms"); + rangeTimeStringLst, rangeTimeArr, level, pwRequired); + long t004 = System.currentTimeMillis(); + System.out.println("getObservedSndNcUairDataGeneric API call took " + + (t004 - t003) + "ms"); if (uairRecordArrList != null && uairRecordArrList.size() > 0) { - // long t005 = System.currentTimeMillis(); + long t005 = System.currentTimeMillis(); soundingProfileList = processQueryReturnedNcUairData( uairRecordArrList, useNcSoundingLayer2); - // long t006 = System.currentTimeMillis(); - // System.out.println("getSoundingDataGeneric total sounding time merging for "+uairRecordArrList.size()+" profiles took "+(t006-t005)+"ms"); + long t006 = System.currentTimeMillis(); + System.out + .println("getSoundingDataGeneric total sounding time merging for " + + uairRecordArrList.size() + + " profiles took " + + (t006 - t005) + "ms"); } } else if (sndType.equals(PfcSndType.NAMSND.toString()) diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java index 76975fc7e4..504708e735 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java @@ -67,6 +67,9 @@ import com.vividsolutions.jts.geom.Coordinate; * Jul 19, 2013 1992 bsteffen Remove redundant time columns from bufrua. * Aug 30, 2013 2298 rjpeter Make getPluginName abstract * June, 2014 Chin Chen Retrieved observed sounding with reftime + * Oct 03, 2014 B. Hebbard Performance improvement: getObservedSndNcUairDataGeneric( ) + * limits DB param set to retrieve, in cases where possible + * (mandatory level and no PW-for-full-sounding) * * * @author Chin Chen @@ -949,7 +952,8 @@ public class ObservedSoundingQuery { */ public static List getObservedSndNcUairDataGeneric( Coordinate[] coordArray, String[] stnIdArray, - List soundingTimeStrList, long[] soundTimeLongArr) { + List soundingTimeStrList, long[] soundTimeLongArr, + String level, int pwRequired) { // List soundingProfileList= new // ArrayList(); PointDataQuery request = null; @@ -963,8 +967,31 @@ public class ObservedSoundingQuery { boolean queryByStn; try { request = new PointDataQuery("ncuair"); - request.setParameters(NcUairToRecord.MAN_PARAMS_LIST); + // If a mandatory level is being requested, then we + // can speed things up significantly by getting only the + // TTAA/XXAA parameters from the datastore. Exceptions + // to this are made (a) if we need precipitable water for + // the entire sounding whose algorithm requires all data + // types, OR (b) we're only requesting data for a single + // station (as for Cloud Height) in which case performance + // isn't an issue. + boolean multipleStationsRequested = (coordArray != null && coordArray.length > 1) + || (stnIdArray != null && stnIdArray.length > 1); + if (isMandatoryLevel(level) && pwRequired == 0 + && multipleStationsRequested) { + request.setParameters(NcUairToRecord.AA_ONLY_PARAMS_LIST); + // ...otherwise, we'd better grab the whole set + } else { + request.setParameters(NcUairToRecord.MAN_PARAMS_LIST); + } request.addParameter("nil", String.valueOf(false), "="); + // The following may look wasteful if we only need one level, + // but requesting a specific level (1) requires spelling out + // parameters to which it applies, and more importantly + // (2) saves NO time on the resulting IDataStore request, + // because all levels are retrieved there anyway(!). See note + // in PointDataPluginDao.getPointData( ): "...for now, we + // will retrieve all levels and then post-process the result" request.requestAllLevels(); String d = ""; for (String timeStr : soundingTimeStrList) { @@ -1006,8 +1033,10 @@ public class ObservedSoundingQuery { long t001 = System.currentTimeMillis(); result = request.execute(); long t002 = System.currentTimeMillis(); - // totalRqTime=totalRqTime+(t002-t001); - // System.out.println("getObservedSndNcUairDataGeneric data query alone took "+(t002-t001)+"ms"); + // totalRqTime = totalRqTime + (t002 - t001); + System.out + .println("getObservedSndNcUairDataGeneric data query alone took " + + (t002 - t001) + "ms"); if (result != null) { long t003 = System.currentTimeMillis(); @@ -1181,7 +1210,8 @@ public class ObservedSoundingQuery { .add(pickedUairRecords .toArray(new NcUairRecord[pickedUairRecords .size()])); - // System.out.println("getObservedSndNcUairDataGeneric Number of records in PF=" + // System.out + // .println("getObservedSndNcUairDataGeneric Number of records in PF=" // + pickedUairRecords.size()); } } @@ -1189,16 +1219,36 @@ public class ObservedSoundingQuery { } long t004 = System.currentTimeMillis(); - // System.out.println(" sorting return records took "+(t004-t003)+"ms"); + System.out.println(" sorting return records took " + + (t004 - t003) + "ms"); } } catch (Exception e) { e.printStackTrace(); } - // System.out.println("getObservedSndNcUairDataGeneric Number profiles (record[]s) in finalRecordArrayList="+finalRecordArrayList.size()); + // System.out + // .println("getObservedSndNcUairDataGeneric Number profiles (record[]s) in finalRecordArrayList=" + // + finalRecordArrayList.size()); return finalRecordArrayList; } + private static boolean isMandatoryLevel(String level) { + if (level == null) { + return false; + } + // alternate: final String mandatoryLevels = + // ".surface.1000.925.850.700.500.400.300.250.200.150.100.mb"; + // return mandatoryLevels.contains/* IgnoreCase */("." + level + "."); + final String[] mandatoryLevels = { /* "surface", */"1000", "925", + "850", "700", "500", "400", "300", "250", "200", "150", "100" }; + for (String s : mandatoryLevels) { + if (s.equals/* IgnoreCase */(level)) { + return true; + } + } + return false; + } + /* * This method query ONE station's specific one dataType data only * From 63d586723bdd2cea950e20cc77c8f3c0a9741a92 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Wed, 19 Nov 2014 12:15:23 -0500 Subject: [PATCH 12/19] VLab Issue #4864 - Change ASCAT colorbar orientation; fixes #4864 Change-Id: I46aab7514c7fcccdbe77f5f0df0ad28402e7ab47 Former-commit-id: b2067ead8a07b8d8cbed235ee9b1d24e0cd47789 [formerly b2067ead8a07b8d8cbed235ee9b1d24e0cd47789 [formerly 2c48ff66fb6819af157046c4b39e5745bbe8f12b]] Former-commit-id: 6309e62c8f15d07ec4e5c33f3125475ae1e3ebec Former-commit-id: 0973fbc1e303561dedd0f4417657ef0c0c11a49b --- .../resources/colorBar/ColorBarResource.java | 1178 ++++++++--------- .../META-INF/MANIFEST.MF | 1 + .../viz/rsc/ncscat/rsc/NcscatResource.java | 29 +- 3 files changed, 607 insertions(+), 601 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/colorBar/ColorBarResource.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/colorBar/ColorBarResource.java index cc383151ac..0a298f1b79 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/colorBar/ColorBarResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/colorBar/ColorBarResource.java @@ -1,675 +1,665 @@ package gov.noaa.nws.ncep.viz.resources.colorBar; -import gov.noaa.nws.ncep.viz.ui.display.IColorBar; + import gov.noaa.nws.ncep.gempak.parameters.colorbar.ColorBarAnchorLocation; import gov.noaa.nws.ncep.gempak.parameters.colorbar.ColorBarOrientation; +import gov.noaa.nws.ncep.viz.ui.display.IColorBar; + +import org.eclipse.swt.graphics.RGB; + import com.raytheon.uf.viz.core.DrawableString; import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IGraphicsTarget; - -import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; - +import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.drawables.IDescriptor; - import com.raytheon.uf.viz.core.drawables.PaintProperties; import com.raytheon.uf.viz.core.exception.VizException; - import com.raytheon.uf.viz.core.rsc.AbstractVizResource; - import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability; - -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; - /** -* -*
-* SOFTWARE HISTORY
-* Date         Ticket#     Engineer    Description
-* ------------ ----------  ----------- --------------------------
-* 04/11/10      #259        Greg Hull    Initial Creation.
-* 07/11/11                  Greg Hull    changed to a Resource and create ColorBarResourceData.
-* 06/07/12      #717        Archana      Updated paintInternal() to label the colorbar and 
-*                                        display its unit 
-* 06/07/12      #794        Archana      Updated paintInternal() to reverse 
-*                                        the color order in the color-bar.
-* 07/10/12      #743        Archana      Updated paintInternal() to accommodate GEMPAK CLRBAR parameter
-*                                        Updated paintInternal() to fix label displacement while changing the 
-*                                        zoom or the underlying area.                                         
-*                                        
-* 
-* -* @author ghull -* @version 1 -*/ -public class ColorBarResource extends AbstractVizResource { + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 04/11/10      #259        Greg Hull    Initial Creation.
+ * 07/11/11                  Greg Hull    changed to a Resource and create ColorBarResourceData.
+ * 06/07/12      #717        Archana      Updated paintInternal() to label the colorbar and 
+ *                                        display its unit 
+ * 06/07/12      #794        Archana      Updated paintInternal() to reverse 
+ *                                        the color order in the color-bar.
+ * 07/10/12      #743        Archana      Updated paintInternal() to accommodate GEMPAK CLRBAR parameter
+ *                                        Updated paintInternal() to fix label displacement while changing the 
+ *                                        zoom or the underlying area.
+ * 10/10/14      R4864       B. Hebbard   (Secondary to TTR 986)  Fix off-by-one error in labeling
+ *                                        intervals with horizontal mode and reverseOrder=false;
+ *                                        adjust position of "last" (smallest) label in this case.
+ * 
+ * 
+ * + * @author ghull + * @version 1 + */ +public class ColorBarResource extends + AbstractVizResource { - public ColorBarResource( ColorBarResourceData resourceData, - LoadProperties loadProperties) { - super(resourceData, loadProperties); - cBarData = resourceData; - getCapabilities().addCapability(ColorMapCapability.class); - } + public ColorBarResource(ColorBarResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + cBarData = resourceData; + getCapabilities().addCapability(ColorMapCapability.class); + } - ColorBarResourceData cBarData; - - IExtent colorBarExtent=null; - - - public void setColorBar( IColorBar cbar ) { - cBarData.setColorBar( cbar ); - } - - @Override - protected void initInternal(IGraphicsTarget target) throws VizException { - //System.out.println("ColorBar initInternal"); - - } + ColorBarResourceData cBarData; - @Override - protected void paintInternal( IGraphicsTarget target, - PaintProperties paintProps) throws VizException { - IColorBar colorBar = cBarData.getColorbar(); - - if( colorBar == null || !colorBar.isDrawColorBar()) { - return; - } + IExtent colorBarExtent = null; - - RGB colorOfAllLabels = colorBar.getLabelColor(); + public void setColorBar(IColorBar cbar) { + cBarData.setColorBar(cbar); + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + // System.out.println("ColorBar initInternal"); + + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + IColorBar colorBar = cBarData.getColorbar(); + + if (colorBar == null || !colorBar.isDrawColorBar()) { + return; + } + + RGB colorOfAllLabels = colorBar.getLabelColor(); RGB colorOfThisLabel = colorOfAllLabels; String labelStr; - target.clearClippingPlane(); + target.clearClippingPlane(); - IExtent pixExtents = paintProps.getView().getExtent(); + IExtent pixExtents = paintProps.getView().getExtent(); double pixExtentsMinX = pixExtents.getMinX(); double pixExtentsMaxX = pixExtents.getMaxX(); double pixExtentsMinY = pixExtents.getMinY(); double pixExtentsMaxY = pixExtents.getMaxY(); double pixExtentsWidth = pixExtents.getWidth(); double pixExtentsHeight = pixExtents.getHeight(); - - int numIntrvls = colorBar.getNumIntervals(); - double minX=0, maxX=0; - double minY=0, maxY=0; - double intrvlXsize = 0; - double intrvlYsize = 0; - - double xScaleFactor= pixExtentsWidth/(double)paintProps.getCanvasBounds().width; - double yScaleFactor= pixExtentsHeight/(double)paintProps.getCanvasBounds().height; - double cbarPixLength; + int numIntrvls = colorBar.getNumIntervals(); + + double minX = 0, maxX = 0; + double minY = 0, maxY = 0; + double intrvlXsize = 0; + double intrvlYsize = 0; + + double xScaleFactor = pixExtentsWidth + / (double) paintProps.getCanvasBounds().width; + double yScaleFactor = pixExtentsHeight + / (double) paintProps.getCanvasBounds().height; + double cbarPixLength; double lengthRatio = colorBar.getLengthAsRatio(); double xViewCoord = colorBar.getXPixelCoordFraction(); double yViewCoord = colorBar.getYPixelCoordFraction(); ColorBarOrientation colorBarOrientation = colorBar.getOrientation(); - ColorBarAnchorLocation anchorLocation = colorBar.getAnchorLoc(); - - if(colorBarOrientation == null || anchorLocation == null ) - return; - - if(colorBarOrientation == ColorBarOrientation.Horizontal){ - if(lengthRatio == 1) - lengthRatio = 0.999; - cbarPixLength = lengthRatio* pixExtentsWidth*(1-xViewCoord); - } - else{ -// if(lengthRatio == 1) -// lengthRatio = 0.996; - cbarPixLength = lengthRatio* pixExtentsHeight*(1-yViewCoord); - } -// -// double cbarPixWidth = ( colorBarOrientation == ColorBarOrientation.Horizontal ? -// (double)colorBar.getWidthInPixels() * yScaleFactor : -// (double)colorBar.getWidthInPixels() * xScaleFactor ); + ColorBarAnchorLocation anchorLocation = colorBar.getAnchorLoc(); - double cbarPixWidth = ( colorBarOrientation == ColorBarOrientation.Horizontal ? - (double)colorBar.getWidthInPixels()/1000 * pixExtentsHeight : - (double)colorBar.getWidthInPixels()/1000 * pixExtentsWidth ); - - double yMargin = 2 * yScaleFactor; + if (colorBarOrientation == null || anchorLocation == null) + return; - double textX = 0; - double textY = 0; + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + if (lengthRatio == 1) + lengthRatio = 0.999; + cbarPixLength = lengthRatio * pixExtentsWidth * (1 - xViewCoord); + } else { + // if(lengthRatio == 1) + // lengthRatio = 0.996; + cbarPixLength = lengthRatio * pixExtentsHeight * (1 - yViewCoord); + } + // + // double cbarPixWidth = ( colorBarOrientation == + // ColorBarOrientation.Horizontal ? + // (double)colorBar.getWidthInPixels() * yScaleFactor : + // (double)colorBar.getWidthInPixels() * xScaleFactor ); - - String unitStr = colorBar.getDisplayUnitStr(); + double cbarPixWidth = (colorBarOrientation == ColorBarOrientation.Horizontal ? (double) colorBar + .getWidthInPixels() / 1000 * pixExtentsHeight + : (double) colorBar.getWidthInPixels() / 1000 * pixExtentsWidth); - /* - * Calculate the location of the 4 corners of the colorbar based on its - * orientation and anchor location. If the current length ratio causes the color bar to - * be partially rendered beyond the visible screen area, move it back in. - */ + double yMargin = 2 * yScaleFactor; - if( anchorLocation == ColorBarAnchorLocation.UpperLeft ) { - - minX = pixExtentsMinX + pixExtentsWidth*xViewCoord ; - minY = pixExtentsMinY + pixExtentsHeight*yViewCoord ; + double textX = 0; + double textY = 0; - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - maxX = minX + cbarPixLength ; - maxY = minY + cbarPixWidth ; - - if(maxX > pixExtentsMinX + pixExtentsWidth ){ + String unitStr = colorBar.getDisplayUnitStr(); + + /* + * Calculate the location of the 4 corners of the colorbar based on its + * orientation and anchor location. If the current length ratio causes + * the color bar to be partially rendered beyond the visible screen + * area, move it back in. + */ + + if (anchorLocation == ColorBarAnchorLocation.UpperLeft) { + + minX = pixExtentsMinX + pixExtentsWidth * xViewCoord; + minY = pixExtentsMinY + pixExtentsHeight * yViewCoord; + + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + maxX = minX + cbarPixLength; + maxY = minY + cbarPixWidth; + + if (maxX > pixExtentsMinX + pixExtentsWidth) { cbarPixLength = pixExtentsMaxX - minX; maxX = minX + cbarPixLength; - } - } - else { - maxX = minX + cbarPixWidth ; - maxY = minY + cbarPixLength ; - if(maxY > pixExtentsMinY + pixExtentsHeight ){ - cbarPixLength = pixExtentsMaxY - pixExtentsHeight*yViewCoord; - maxY = minY + cbarPixLength; - } - } + } + } else { + maxX = minX + cbarPixWidth; + maxY = minY + cbarPixLength; + if (maxY > pixExtentsMinY + pixExtentsHeight) { + cbarPixLength = pixExtentsMaxY - pixExtentsHeight + * yViewCoord; + maxY = minY + cbarPixLength; + } + } + } else if (anchorLocation == ColorBarAnchorLocation.UpperRight) { + maxX = pixExtentsMaxX - pixExtentsWidth * xViewCoord; + minY = pixExtentsMinY + pixExtentsHeight * yViewCoord; + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + minX = maxX - cbarPixLength; + maxY = minY + cbarPixWidth; - } - else if( anchorLocation == ColorBarAnchorLocation.UpperRight ) { - maxX = pixExtentsMaxX - pixExtentsWidth*xViewCoord; - minY = pixExtentsMinY + pixExtentsHeight*yViewCoord ; - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - minX = maxX - cbarPixLength; - maxY = minY + cbarPixWidth; - - if(minX < pixExtentsMinX ){ + if (minX < pixExtentsMinX) { cbarPixLength = maxX - pixExtentsMinX; minX = maxX - cbarPixLength; - } - } - else { - minX = maxX - cbarPixWidth; - maxY = minY + cbarPixLength; - if(maxY > pixExtentsMinY + pixExtentsHeight ){ - cbarPixLength = pixExtentsMaxY - pixExtentsHeight*yViewCoord; - maxY = minY + cbarPixLength; - } - } - - - } - else if( anchorLocation == ColorBarAnchorLocation.LowerLeft ) { - - minX = pixExtentsMinX + pixExtentsWidth*xViewCoord; - maxY = pixExtentsMaxY - pixExtentsHeight*yViewCoord; - - - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - maxX = minX + cbarPixLength; - minY = maxY - cbarPixWidth; - - if( maxX > pixExtentsMaxX ){ - cbarPixLength = pixExtentsMaxX - minX; - maxX = minX + cbarPixLength*0.999; - - } - } - else { - - maxX = minX + cbarPixWidth; - minY = maxY - cbarPixLength; - if( (minY -yMargin*3) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = maxY - minY; } - - } - - - } - else if( anchorLocation == ColorBarAnchorLocation.LowerRight ) { - - maxX = pixExtentsMaxX - pixExtentsWidth*xViewCoord; - maxY = pixExtentsMaxY - pixExtentsHeight*yViewCoord; - - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - minX = maxX - cbarPixLength; - minY = maxY - cbarPixWidth; - if(minX < pixExtentsMinX){ - cbarPixLength = maxX - pixExtentsMinX; - minX = maxX - cbarPixLength; - } - } - else { - minX = maxX - cbarPixWidth; - minY = maxY - cbarPixLength; - - if( (minY -yMargin*3) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = maxY - minY; + } else { + minX = maxX - cbarPixWidth; + maxY = minY + cbarPixLength; + if (maxY > pixExtentsMinY + pixExtentsHeight) { + cbarPixLength = pixExtentsMaxY - pixExtentsHeight + * yViewCoord; + maxY = minY + cbarPixLength; } - } + } - } - else if(anchorLocation == ColorBarAnchorLocation.CenterLeft){ - minX = pixExtentsMinX + pixExtentsWidth*xViewCoord ; - if(colorBarOrientation == ColorBarOrientation.Vertical){ - maxX = minX+cbarPixWidth; - minY = pixExtentsMinY + pixExtentsHeight/2 -cbarPixLength/2; - maxY = pixExtentsMinY + pixExtentsHeight/2 +cbarPixLength/2; - - if( (minY - yMargin*11) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = pixExtentsMaxY - minY; - maxY = minY+cbarPixLength; - } - - }else{ - maxX = minX + cbarPixLength; - minY = pixExtentsMinY + pixExtentsHeight/2 - cbarPixWidth/2 ; - maxY = minY + cbarPixWidth; - if(maxX >= pixExtentsMaxX) - maxX = minX + cbarPixLength*0.998; - } - - } - else if(anchorLocation == ColorBarAnchorLocation.CenterRight){ + } else if (anchorLocation == ColorBarAnchorLocation.LowerLeft) { - maxX = pixExtentsMaxX - pixExtentsWidth*xViewCoord ; + minX = pixExtentsMinX + pixExtentsWidth * xViewCoord; + maxY = pixExtentsMaxY - pixExtentsHeight * yViewCoord; - - if(colorBarOrientation == ColorBarOrientation.Vertical){ - minX = maxX - cbarPixWidth; - minY = pixExtentsMinY + pixExtentsHeight/2 -cbarPixLength/2; - maxY = pixExtentsMinY + pixExtentsHeight/2 +cbarPixLength/2; - if( (minY -yMargin*11) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = pixExtentsMaxY - minY; - maxY = minY+cbarPixLength; - } - - }else{ - minX = maxX - cbarPixLength; - minY = pixExtentsMinY + pixExtentsHeight/2 - cbarPixWidth/2 ; - maxY = minY + cbarPixWidth; - if(minX < pixExtentsMinX) - minX = maxX - cbarPixLength*0.998; - } - - - } - else if(anchorLocation == ColorBarAnchorLocation.CenterCenter){ - if(colorBarOrientation == ColorBarOrientation.Vertical){ - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixWidth/2; - maxX = minX + cbarPixWidth; - minY = pixExtentsMinY + pixExtentsHeight/2 -cbarPixLength/2; - maxY = pixExtentsMinY + pixExtentsHeight/2 +cbarPixLength/2; - - if( (minY -yMargin*11) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = pixExtentsMaxY - minY; - maxY = minY+cbarPixLength; - } - - }else{ - minY = pixExtentsMinY + pixExtentsHeight/2 -cbarPixWidth/2; - maxY = pixExtentsMinY + pixExtentsHeight/2 +cbarPixWidth/2; - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixLength/2; - maxX = minX + cbarPixLength; - } - - - } - else if(anchorLocation == ColorBarAnchorLocation.UpperCenter){ - if(colorBarOrientation == ColorBarOrientation.Vertical){ - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixWidth/2; - maxX = minX+cbarPixWidth; - minY = pixExtentsMinY + pixExtentsHeight*yViewCoord; - maxY = minY + cbarPixLength; - //If the color bar overshoots the boundary, it is brought back inside. - if(maxY > pixExtentsMinY + pixExtentsHeight ){ - cbarPixLength = pixExtentsMaxY - pixExtentsHeight*(yViewCoord); - maxY = minY + cbarPixLength; - } - - }else{ - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixLength/2; - maxX = minX + cbarPixLength; - minY = pixExtentsMinY + pixExtentsHeight*yViewCoord; - maxY = minY + cbarPixWidth; - if(maxX > pixExtentsMinX + pixExtentsWidth ){ - cbarPixWidth = pixExtentsMaxX - pixExtentsWidth; - maxX = minX + cbarPixWidth; - } - } - - - }else if (anchorLocation == ColorBarAnchorLocation.LowerCenter){ - if(colorBarOrientation == ColorBarOrientation.Vertical){ - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixWidth/2; - maxX = minX+cbarPixWidth; - maxY = pixExtentsMaxY- pixExtentsHeight*yViewCoord; - minY = maxY - cbarPixLength; - - if( (minY -yMargin*11) < pixExtentsMinY ){ - minY = pixExtentsMinY + yMargin*11; - cbarPixLength = pixExtentsMaxY - minY; - maxY = minY+cbarPixLength; - } - - }else{ - minX = pixExtentsMinX + pixExtentsWidth/2 - cbarPixLength/2; - maxX = minX + cbarPixLength; - maxY = pixExtentsMaxY- pixExtentsHeight*yViewCoord; + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + maxX = minX + cbarPixLength; minY = maxY - cbarPixWidth; - } - - } - else { - return; - } - - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - intrvlXsize = cbarPixLength/numIntrvls; - intrvlYsize = cbarPixWidth; - } - else { - intrvlYsize = cbarPixLength/numIntrvls; - intrvlXsize = cbarPixWidth; - } + if (maxX > pixExtentsMaxX) { + cbarPixLength = pixExtentsMaxX - minX; + maxX = minX + cbarPixLength * 0.999; - double intMinX=minX; - double intMaxX=0; - double intMinY=minY; - double intMaxY=0; - - double nonInfRangeLength = cbarPixLength; - - if( colorBar.getIntervalMin(0) == Float.NEGATIVE_INFINITY ) { - nonInfRangeLength -= cbarPixLength/numIntrvls; - } - if( colorBar.getIntervalMax(numIntrvls-1) == Float.POSITIVE_INFINITY ) { - nonInfRangeLength -= cbarPixLength/numIntrvls; - } + } + } else { - + maxX = minX + cbarPixWidth; + minY = maxY - cbarPixLength; + if ((minY - yMargin * 3) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = maxY - minY; + } - if(colorBar.getShowLabels() && unitStr != null && !unitStr.isEmpty() && numIntrvls > 0){ - DrawableString unitStrToDraw = new DrawableString(unitStr, colorOfAllLabels); - textX = minX; - textY = minY - yMargin*3; - unitStrToDraw.setCoordinates(textX, textY); - if(colorBarOrientation == ColorBarOrientation.Vertical - &&( anchorLocation == ColorBarAnchorLocation.LowerRight - || anchorLocation == ColorBarAnchorLocation.CenterRight - || anchorLocation == ColorBarAnchorLocation.UpperRight)) - unitStrToDraw.horizontalAlignment = HorizontalAlignment.RIGHT; - - target.drawStrings(unitStrToDraw); - } + } - double pixPerUnit = nonInfRangeLength/colorBar.getDiscreteRange(); + } else if (anchorLocation == ColorBarAnchorLocation.LowerRight) { - try { - int startIndex = 0; - int endIndex = numIntrvls; + maxX = pixExtentsMaxX - pixExtentsWidth * xViewCoord; + maxY = pixExtentsMaxY - pixExtentsHeight * yViewCoord; - if ( colorBar != null ){ - if (colorBar.getReverseOrder()){ - startIndex = numIntrvls - 1; - endIndex = -1; - } - - int r = startIndex; - - while ( startIndex != -1 && startIndex != endIndex){ - // compute the new maxX and Ys for the interval + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + minX = maxX - cbarPixLength; + minY = maxY - cbarPixWidth; + if (minX < pixExtentsMinX) { + cbarPixLength = maxX - pixExtentsMinX; + minX = maxX - cbarPixLength; + } + } else { + minX = maxX - cbarPixWidth; + minY = maxY - cbarPixLength; - if( colorBar.getDrawToScale() ) { - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - if( colorBar.getIntervalMin(r) == Float.NEGATIVE_INFINITY || - colorBar.getIntervalMax(r) == Float.POSITIVE_INFINITY ) { - intrvlXsize = cbarPixLength/numIntrvls; - } - else { - intrvlXsize = pixPerUnit * - (double)(colorBar.getIntervalMax(r) - colorBar.getIntervalMin(r)); - } - } - else { - if( colorBar.getIntervalMin(r) == Float.NEGATIVE_INFINITY || - colorBar.getIntervalMax(r) == Float.POSITIVE_INFINITY ) { - intrvlYsize = cbarPixLength/numIntrvls; - } - else { - intrvlYsize = pixPerUnit * - (double)(colorBar.getIntervalMax(r) - colorBar.getIntervalMin(r)); - } - } - } + if ((minY - yMargin * 3) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = maxY - minY; + } + } - intMaxX = intMinX + intrvlXsize; - intMaxY = intMinY + intrvlYsize; - + } else if (anchorLocation == ColorBarAnchorLocation.CenterLeft) { + minX = pixExtentsMinX + pixExtentsWidth * xViewCoord; + if (colorBarOrientation == ColorBarOrientation.Vertical) { + maxX = minX + cbarPixWidth; + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixLength + / 2; + maxY = pixExtentsMinY + pixExtentsHeight / 2 + cbarPixLength + / 2; - RGB currentIntrvlColor = colorBar.getRGB( r ); - if(!colorBar.isDrawBoxAroundColorBar())//requirement for the GEMPAK parameter CLRBAR - colorOfThisLabel = new RGB ( currentIntrvlColor.red, - currentIntrvlColor.green, - currentIntrvlColor.blue); - - PixelExtent eachShadedRectangleExtent = new PixelExtent( intMinX, intMaxX, intMinY, intMaxY); - if ( currentIntrvlColor != null ){ - target.drawShadedRect( eachShadedRectangleExtent, currentIntrvlColor, 1.0, null ); - } + if ((minY - yMargin * 11) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = pixExtentsMaxY - minY; + maxY = minY + cbarPixLength; + } - String tmpLbl = colorBar.getLabelString( r ); - labelStr = ( tmpLbl != null ) ? new String ( tmpLbl ) : null; - - if( labelStr != null && labelStr.compareTo("NaN") != 0) { - - double lblX = intMinX; - - double lblY = intMinY; - - HorizontalAlignment labelHorizAlign = getLabelHorizAlignment( - colorBarOrientation, anchorLocation, (r == 0), false ); + } else { + maxX = minX + cbarPixLength; + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixWidth / 2; + maxY = minY + cbarPixWidth; + if (maxX >= pixExtentsMaxX) + maxX = minX + cbarPixLength * 0.998; + } - VerticalAlignment labelVertAlign = getLabelVertAlignment( - colorBarOrientation, anchorLocation, (r == 0), false ); + } else if (anchorLocation == ColorBarAnchorLocation.CenterRight) { - /* - * Fix for the labels flying off when the zoom or the underlying area is changed: - * Create a separate pixelextent from the coordinates of each interval in the colorbar - * Get the label coordinates from this new pixelextent.(Anyhow, the label coordinates are - * dependant on the coordinates of the corresponding colorbar interval. ) - */ - PixelExtent pixEx = new PixelExtent(eachShadedRectangleExtent.getMinX(), - eachShadedRectangleExtent.getMaxX(), - eachShadedRectangleExtent.getMinY(), - eachShadedRectangleExtent.getMaxY()); - lblX = pixEx.getMinX(); - if(colorBar.getClass().getSimpleName().compareTo("ColorBar") == 0 ){ - - //lblX = intMaxX; - - lblY = pixEx.getMaxY(); - } - else{ - lblY = pixEx.getMinY(); - } + maxX = pixExtentsMaxX - pixExtentsWidth * xViewCoord; - - if( (anchorLocation == ColorBarAnchorLocation.LowerLeft - || anchorLocation == ColorBarAnchorLocation.UpperLeft - || anchorLocation == ColorBarAnchorLocation.CenterLeft - || anchorLocation == ColorBarAnchorLocation.CenterCenter - || anchorLocation == ColorBarAnchorLocation.LowerCenter - || anchorLocation == ColorBarAnchorLocation.UpperCenter - ) && - colorBarOrientation == ColorBarOrientation.Vertical ) { - lblX += cbarPixWidth ; - - } - else if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - if(colorBar.getClass().getSimpleName().compareTo("ColorBar") == 0 ){ - lblX = pixEx.getMaxX(); - lblY+= yScaleFactor; - } - else - lblY+= cbarPixWidth; - - } - - if(colorBar.isAlignLabelInTheMiddleOfInterval() ){ - //typically for radar legends - if(colorBarOrientation == ColorBarOrientation.Vertical){ - lblY += yScaleFactor*23; - }else{ - lblX+= xScaleFactor*30; - } - - } - + if (colorBarOrientation == ColorBarOrientation.Vertical) { + minX = maxX - cbarPixWidth; + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixLength + / 2; + maxY = pixExtentsMinY + pixExtentsHeight / 2 + cbarPixLength + / 2; + if ((minY - yMargin * 11) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = pixExtentsMaxY - minY; + maxY = minY + cbarPixLength; + } - DrawableString strToDraw = new DrawableString(labelStr,colorOfThisLabel); - strToDraw.horizontalAlignment = labelHorizAlign; - strToDraw.verticallAlignment = labelVertAlign; - if(colorBar.getShowLabels()){ - strToDraw.setCoordinates(lblX, lblY ); - target.drawStrings(strToDraw); - } + } else { + minX = maxX - cbarPixLength; + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixWidth / 2; + maxY = minY + cbarPixWidth; + if (minX < pixExtentsMinX) + minX = maxX - cbarPixLength * 0.998; + } - } - + } else if (anchorLocation == ColorBarAnchorLocation.CenterCenter) { + if (colorBarOrientation == ColorBarOrientation.Vertical) { + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixWidth / 2; + maxX = minX + cbarPixWidth; + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixLength + / 2; + maxY = pixExtentsMinY + pixExtentsHeight / 2 + cbarPixLength + / 2; - // increment the interval x&y - if( colorBarOrientation == ColorBarOrientation.Horizontal ) { - intMinX = intMaxX; - } - else { - intMinY = intMaxY; - } - - if ( startIndex > endIndex ){ - r--; - startIndex--; - } - else{ - r++; - startIndex++; - } - } + if ((minY - yMargin * 11) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = pixExtentsMaxY - minY; + maxY = minY + cbarPixLength; + } - // draw the last label - - String tmpLbl = colorBar.getLabelString( numIntrvls ); - - labelStr = ( tmpLbl != null ) ? new String ( tmpLbl ) : null; - - if( labelStr != null && labelStr.compareTo("NaN") != 0) { - - double lblX = intMinX; - double lblY = intMinY; + } else { + minY = pixExtentsMinY + pixExtentsHeight / 2 - cbarPixWidth / 2; + maxY = pixExtentsMinY + pixExtentsHeight / 2 + cbarPixWidth / 2; + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixLength / 2; + maxX = minX + cbarPixLength; + } - if(colorBar.getClass().getSimpleName().compareTo("ColorBar") == 0 ){ - if(colorBarOrientation == ColorBarOrientation.Vertical ){ - intMaxY = intMinY - (numIntrvls) * intrvlYsize; - lblY = intMaxY + yScaleFactor*5; - lblX = ( ( anchorLocation == ColorBarAnchorLocation.UpperRight - || anchorLocation == ColorBarAnchorLocation.CenterRight - || anchorLocation == ColorBarAnchorLocation.LowerRight)? - intMinX:intMaxX); - }else{ - - lblX = minX + xScaleFactor*20; - lblY = intMaxY; - } - } - + } else if (anchorLocation == ColorBarAnchorLocation.UpperCenter) { + if (colorBarOrientation == ColorBarOrientation.Vertical) { + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixWidth / 2; + maxX = minX + cbarPixWidth; + minY = pixExtentsMinY + pixExtentsHeight * yViewCoord; + maxY = minY + cbarPixLength; + // If the color bar overshoots the boundary, it is brought back + // inside. + if (maxY > pixExtentsMinY + pixExtentsHeight) { + cbarPixLength = pixExtentsMaxY - pixExtentsHeight + * (yViewCoord); + maxY = minY + cbarPixLength; + } - - HorizontalAlignment labelHorizAlign = getLabelHorizAlignment( - colorBarOrientation, anchorLocation, - false, true ); + } else { + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixLength / 2; + maxX = minX + cbarPixLength; + minY = pixExtentsMinY + pixExtentsHeight * yViewCoord; + maxY = minY + cbarPixWidth; + if (maxX > pixExtentsMinX + pixExtentsWidth) { + cbarPixWidth = pixExtentsMaxX - pixExtentsWidth; + maxX = minX + cbarPixWidth; + } + } - VerticalAlignment labelVertAlign = getLabelVertAlignment( - colorBarOrientation, anchorLocation, - false, true ); - - if(!colorBar.isDrawBoxAroundColorBar()) - colorOfThisLabel = colorBar.getRGB(numIntrvls-1);//requirement for the GEMPAK parameter CLRBAR + } else if (anchorLocation == ColorBarAnchorLocation.LowerCenter) { + if (colorBarOrientation == ColorBarOrientation.Vertical) { + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixWidth / 2; + maxX = minX + cbarPixWidth; + maxY = pixExtentsMaxY - pixExtentsHeight * yViewCoord; + minY = maxY - cbarPixLength; - DrawableString strToDraw = new DrawableString(labelStr,colorOfThisLabel); - strToDraw.horizontalAlignment = labelHorizAlign; - strToDraw.verticallAlignment = labelVertAlign; + if ((minY - yMargin * 11) < pixExtentsMinY) { + minY = pixExtentsMinY + yMargin * 11; + cbarPixLength = pixExtentsMaxY - minY; + maxY = minY + cbarPixLength; + } - if(colorBar.getShowLabels()){ - strToDraw.setCoordinates(lblX, lblY ); - target.drawStrings(strToDraw); - } + } else { + minX = pixExtentsMinX + pixExtentsWidth / 2 - cbarPixLength / 2; + maxX = minX + cbarPixLength; + maxY = pixExtentsMaxY - pixExtentsHeight * yViewCoord; + minY = maxY - cbarPixWidth; + } - } + } else { + return; + } - // draw the border around the colorbar - if (numIntrvls > 0 && colorBar.isDrawBoxAroundColorBar()) { - //check for 'numIntrvls' gets rid of the ghost outline if the colormap was cleared - colorBarExtent = new PixelExtent( minX, maxX, minY, maxY ); - target.drawRect(colorBarExtent, colorOfAllLabels, 1.0f, 1.0d); - } - } + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + intrvlXsize = cbarPixLength / numIntrvls; + intrvlYsize = cbarPixWidth; - } catch (VizException e) { - } - - } - - private HorizontalAlignment getLabelHorizAlignment( ColorBarOrientation orient, ColorBarAnchorLocation anchor, - boolean isFirst, boolean isLast ) { - ColorBarAnchorLocation cBarAnchorLoc = cBarData.getColorbar().getAnchorLoc(); - if( cBarData.getColorbar().getOrientation() == ColorBarOrientation.Vertical ) { - if( cBarAnchorLoc == ColorBarAnchorLocation.UpperLeft || - cBarAnchorLoc == ColorBarAnchorLocation.LowerLeft || - cBarAnchorLoc == ColorBarAnchorLocation.CenterLeft || - cBarAnchorLoc == ColorBarAnchorLocation.CenterCenter || - cBarAnchorLoc == ColorBarAnchorLocation.UpperCenter || - cBarAnchorLoc == ColorBarAnchorLocation.LowerCenter) { - return HorizontalAlignment.LEFT; - } - else {// on the right - return HorizontalAlignment.RIGHT; - } - } - else { // Horizontal - if( isFirst || isLast) { - return HorizontalAlignment.RIGHT; - } -// else if( isLast ) { -// return HorizontalAlignment.RIGHT; -// } - else { - return HorizontalAlignment.CENTER; - } - } - } - - private VerticalAlignment getLabelVertAlignment( ColorBarOrientation orient, ColorBarAnchorLocation anchor, - boolean isFirst, boolean isLast ) { - if( cBarData.getColorbar().getOrientation() == ColorBarOrientation.Horizontal ) { - return VerticalAlignment.TOP; - } - else { - if( isFirst ) { - return VerticalAlignment.BOTTOM; - } - else if( isLast ) { - return VerticalAlignment.BOTTOM; // - } - else { - return VerticalAlignment.MIDDLE; - } - } - } + } else { + intrvlYsize = cbarPixLength / numIntrvls; + intrvlXsize = cbarPixWidth; + } - @Override - protected void disposeInternal() { - // TODO Auto-generated method stub - - } + double intMinX = minX; + double intMaxX = 0; + double intMinY = minY; + double intMaxY = 0; + + double nonInfRangeLength = cbarPixLength; + + if (colorBar.getIntervalMin(0) == Float.NEGATIVE_INFINITY) { + nonInfRangeLength -= cbarPixLength / numIntrvls; + } + if (colorBar.getIntervalMax(numIntrvls - 1) == Float.POSITIVE_INFINITY) { + nonInfRangeLength -= cbarPixLength / numIntrvls; + } + + if (colorBar.getShowLabels() && unitStr != null && !unitStr.isEmpty() + && numIntrvls > 0) { + DrawableString unitStrToDraw = new DrawableString(unitStr, + colorOfAllLabels); + textX = minX; + textY = minY - yMargin * 3; + unitStrToDraw.setCoordinates(textX, textY); + if (colorBarOrientation == ColorBarOrientation.Vertical + && (anchorLocation == ColorBarAnchorLocation.LowerRight + || anchorLocation == ColorBarAnchorLocation.CenterRight || anchorLocation == ColorBarAnchorLocation.UpperRight)) + unitStrToDraw.horizontalAlignment = HorizontalAlignment.RIGHT; + + target.drawStrings(unitStrToDraw); + } + + double pixPerUnit = nonInfRangeLength / colorBar.getDiscreteRange(); + + try { + int startIndex = 0; + int endIndex = numIntrvls; + + if (colorBar != null) { + if (colorBar.getReverseOrder()) { + startIndex = numIntrvls - 1; + endIndex = -1; + } + + int r = startIndex; + + while (startIndex != -1 && startIndex != endIndex) { + // compute the new maxX and Ys for the interval + + if (colorBar.getDrawToScale()) { + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + if (colorBar.getIntervalMin(r) == Float.NEGATIVE_INFINITY + || colorBar.getIntervalMax(r) == Float.POSITIVE_INFINITY) { + intrvlXsize = cbarPixLength / numIntrvls; + } else { + intrvlXsize = pixPerUnit + * (double) (colorBar.getIntervalMax(r) - colorBar + .getIntervalMin(r)); + } + } else { + if (colorBar.getIntervalMin(r) == Float.NEGATIVE_INFINITY + || colorBar.getIntervalMax(r) == Float.POSITIVE_INFINITY) { + intrvlYsize = cbarPixLength / numIntrvls; + } else { + intrvlYsize = pixPerUnit + * (double) (colorBar.getIntervalMax(r) - colorBar + .getIntervalMin(r)); + } + } + } + + intMaxX = intMinX + intrvlXsize; + intMaxY = intMinY + intrvlYsize; + + RGB currentIntrvlColor = colorBar.getRGB(r); + if (!colorBar.isDrawBoxAroundColorBar()) + // requirement for the GEMPAK parameter CLRBAR + colorOfThisLabel = new RGB(currentIntrvlColor.red, + currentIntrvlColor.green, + currentIntrvlColor.blue); + + PixelExtent eachShadedRectangleExtent = new PixelExtent( + intMinX, intMaxX, intMinY, intMaxY); + if (currentIntrvlColor != null) { + target.drawShadedRect(eachShadedRectangleExtent, + currentIntrvlColor, 1.0, null); + } + + int rText = colorBar.getReverseOrder() ? r : r + 1; + String tmpLbl = colorBar.getLabelString(rText); + labelStr = (tmpLbl != null) ? new String(tmpLbl) : null; + + if (labelStr != null && labelStr.compareTo("NaN") != 0) { + + double lblX = intMinX; + + double lblY = intMinY; + + HorizontalAlignment labelHorizAlign = getLabelHorizAlignment( + colorBarOrientation, anchorLocation, + (rText == 0), false); + + VerticalAlignment labelVertAlign = getLabelVertAlignment( + colorBarOrientation, anchorLocation, + (rText == 0), false); + + /* + * Fix for the labels flying off when the zoom or the + * underlying area is changed: Create a separate + * pixelextent from the coordinates of each interval in + * the colorbar Get the label coordinates from this new + * pixelextent.(Anyhow, the label coordinates are + * dependent on the coordinates of the corresponding + * colorbar interval. ) + */ + PixelExtent pixEx = new PixelExtent( + eachShadedRectangleExtent.getMinX(), + eachShadedRectangleExtent.getMaxX(), + eachShadedRectangleExtent.getMinY(), + eachShadedRectangleExtent.getMaxY()); + lblX = pixEx.getMinX(); + if (colorBar.getClass().getSimpleName() + .compareTo("ColorBar") == 0) { + + // lblX = intMaxX; + + lblY = pixEx.getMaxY(); + } else { + lblY = pixEx.getMinY(); + } + + if ((anchorLocation == ColorBarAnchorLocation.LowerLeft + || anchorLocation == ColorBarAnchorLocation.UpperLeft + || anchorLocation == ColorBarAnchorLocation.CenterLeft + || anchorLocation == ColorBarAnchorLocation.CenterCenter + || anchorLocation == ColorBarAnchorLocation.LowerCenter || anchorLocation == ColorBarAnchorLocation.UpperCenter) + && colorBarOrientation == ColorBarOrientation.Vertical) { + lblX += cbarPixWidth; + + } else if (colorBarOrientation == ColorBarOrientation.Horizontal) { + if (colorBar.getClass().getSimpleName() + .compareTo("ColorBar") == 0) { + lblX = pixEx.getMaxX(); + lblY += yScaleFactor; + } else + lblY += cbarPixWidth; + + } + + if (colorBar.isAlignLabelInTheMiddleOfInterval()) { + // typically for radar legends + if (colorBarOrientation == ColorBarOrientation.Vertical) { + lblY += yScaleFactor * 23; + } else { + lblX += xScaleFactor * 30; + } + + } + + DrawableString strToDraw = new DrawableString(labelStr, + colorOfThisLabel); + strToDraw.horizontalAlignment = labelHorizAlign; + strToDraw.verticallAlignment = labelVertAlign; + if (colorBar.getShowLabels()) { + strToDraw.setCoordinates(lblX, lblY); + target.drawStrings(strToDraw); + } + + } + + // increment the interval x&y + if (colorBarOrientation == ColorBarOrientation.Horizontal) { + intMinX = intMaxX; + } else { + intMinY = intMaxY; + } + + if (startIndex > endIndex) { + r--; + startIndex--; + } else { + r++; + startIndex++; + } + } + + // draw the last label + + String tmpLbl = colorBar.getLabelString(colorBar + .getReverseOrder() ? numIntrvls : 0); + + labelStr = (tmpLbl != null) ? new String(tmpLbl) : null; + + if (labelStr != null && labelStr.compareTo("NaN") != 0) { + + double lblX = intMinX; + double lblY = intMinY; + + if (colorBar.getClass().getSimpleName() + .compareTo("ColorBar") == 0) { + if (colorBarOrientation == ColorBarOrientation.Vertical) { + intMaxY = intMinY - (numIntrvls) * intrvlYsize; + lblY = colorBar.getReverseOrder() ? intMaxY + /* + yScaleFactor * 5 */: intMaxY + yScaleFactor + * 20; + lblX = ((anchorLocation == ColorBarAnchorLocation.UpperRight + || anchorLocation == ColorBarAnchorLocation.CenterRight || anchorLocation == ColorBarAnchorLocation.LowerRight) ? intMinX + : intMaxX); + } else { + + lblX = colorBar.getReverseOrder() ? minX + + xScaleFactor * 20 : minX + xScaleFactor + * 5; + lblY = intMaxY; + } + } + + HorizontalAlignment labelHorizAlign = getLabelHorizAlignment( + colorBarOrientation, anchorLocation, false, true); + + VerticalAlignment labelVertAlign = getLabelVertAlignment( + colorBarOrientation, anchorLocation, false, true); + + if (!colorBar.isDrawBoxAroundColorBar()) + // requirement for the GEMPAK parameter CLRBAR + colorOfThisLabel = colorBar.getRGB(numIntrvls - 1); + + DrawableString strToDraw = new DrawableString(labelStr, + colorOfThisLabel); + strToDraw.horizontalAlignment = labelHorizAlign; + strToDraw.verticallAlignment = labelVertAlign; + + if (colorBar.getShowLabels()) { + strToDraw.setCoordinates(lblX, lblY); + target.drawStrings(strToDraw); + } + + } + + // draw the border around the colorbar + if (numIntrvls > 0 && colorBar.isDrawBoxAroundColorBar()) { + // check for 'numIntrvls' gets rid of the ghost outline if + // the colormap was cleared + colorBarExtent = new PixelExtent(minX, maxX, minY, maxY); + target.drawRect(colorBarExtent, colorOfAllLabels, 1.0f, + 1.0d); + } + } + + } catch (VizException e) { + } + + } + + private HorizontalAlignment getLabelHorizAlignment( + ColorBarOrientation orient, ColorBarAnchorLocation anchor, + boolean isFirst, boolean isLast) { + ColorBarAnchorLocation cBarAnchorLoc = cBarData.getColorbar() + .getAnchorLoc(); + if (cBarData.getColorbar().getOrientation() == ColorBarOrientation.Vertical) { + if (cBarAnchorLoc == ColorBarAnchorLocation.UpperLeft + || cBarAnchorLoc == ColorBarAnchorLocation.LowerLeft + || cBarAnchorLoc == ColorBarAnchorLocation.CenterLeft + || cBarAnchorLoc == ColorBarAnchorLocation.CenterCenter + || cBarAnchorLoc == ColorBarAnchorLocation.UpperCenter + || cBarAnchorLoc == ColorBarAnchorLocation.LowerCenter) { + return HorizontalAlignment.LEFT; + } else {// on the right + return HorizontalAlignment.RIGHT; + } + } else { // Horizontal + if (isFirst || isLast) { + return HorizontalAlignment.RIGHT; + } + // else if( isLast ) { + // return HorizontalAlignment.RIGHT; + // } + else { + return HorizontalAlignment.CENTER; + } + } + } + + private VerticalAlignment getLabelVertAlignment(ColorBarOrientation orient, + ColorBarAnchorLocation anchor, boolean isFirst, boolean isLast) { + if (cBarData.getColorbar().getOrientation() == ColorBarOrientation.Horizontal) { + return VerticalAlignment.TOP; + } else { + if (isFirst) { + return VerticalAlignment.BOTTOM; + } else if (isLast) { + return VerticalAlignment.BOTTOM; + } else { + return VerticalAlignment.MIDDLE; + } + } + } + + @Override + protected void disposeInternal() { + // TODO Auto-generated method stub + + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/META-INF/MANIFEST.MF index 0d113aea17..e8214e171a 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/META-INF/MANIFEST.MF @@ -21,6 +21,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.raytheon.uf.edex.decodertools.core, com.vividsolutions.jts.geom, gov.noaa.nws.ncep.common.dataplugin.ncscat, + gov.noaa.nws.ncep.gempak.parameters.colorbar, gov.noaa.nws.ncep.viz.ui.display, javax.measure.unit Export-Package: gov.noaa.nws.ncep.viz.rsc.ncscat, diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java index ea253694cb..38961d7dff 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java @@ -2,6 +2,7 @@ package gov.noaa.nws.ncep.viz.rsc.ncscat.rsc; import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatPoint; import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatRecord; +import gov.noaa.nws.ncep.gempak.parameters.colorbar.ColorBarOrientation; import gov.noaa.nws.ncep.ui.pgen.display.DisplayElementFactory; import gov.noaa.nws.ncep.ui.pgen.display.IDisplayable; import gov.noaa.nws.ncep.ui.pgen.display.IVector; @@ -80,6 +81,10 @@ import com.vividsolutions.jts.geom.Coordinate; * (instead of waiting for ANCR.paintInternal() to do it) so * long CGM retrieval and parsing is done by the InitJob, and thus * (1) user sees "Initializing..." and (2) GUI doesn't lock up + * 10 Oct 2014 R4864 B. Hebbard (TTR 986) ColorBar plotting high to low when in horizontal; + * regression caused by reverseOrder enhancement for imagery + * resources (in vertical). Fix: Set reverseOrder for NCSCAT colorbars + * to false for horizontal and true for vertical. * * * @@ -393,9 +398,11 @@ public class NcscatResource extends // create a system resource for the colorBar and add it to the resource // list. // + ColorBar colorBar1 = ncscatResourceData.getColorBar1(); + colorBar1 + .setReverseOrder(colorBar1.getOrientation() == ColorBarOrientation.Vertical); cbar1RscPair = ResourcePair - .constructSystemResourcePair(new ColorBarResourceData( - ncscatResourceData.getColorBar1())); + .constructSystemResourcePair(new ColorBarResourceData(colorBar1)); getDescriptor().getResourceList().add(cbar1RscPair); getDescriptor().getResourceList().instantiateResources(getDescriptor(), @@ -403,6 +410,9 @@ public class NcscatResource extends cbar1Resource = (ColorBarResource) cbar1RscPair.getResource(); + ColorBar colorBar2 = ncscatResourceData.getColorBar2(); + colorBar2 + .setReverseOrder(colorBar2.getOrientation() == ColorBarOrientation.Vertical); cbar2RscPair = ResourcePair .constructSystemResourcePair(new ColorBarResourceData( ncscatResourceData.getColorBar2())); @@ -699,18 +709,23 @@ public class NcscatResource extends cbar2Resource = (ColorBarResource) cbar2RscPair.getResource(); } else if (!ncscatResourceData.use2ndColorForRainEnable && isCbar2Enabled) { - // this will cause the ResourceCatalog to dispose of the resource so - // we will - // need to create a new one here. + // this will cause the ResourceCatalog to dispose of the + // resource so we will need to create a new one here. getDescriptor().getResourceList().remove(cbar2RscPair); cbar2RscPair = null; cbar2Resource = null; } - cbar1Resource.setColorBar(ncscatResourceData.getColorBar1()); + ColorBar colorBar1 = ncscatResourceData.getColorBar1(); + colorBar1 + .setReverseOrder(colorBar1.getOrientation() == ColorBarOrientation.Vertical); + cbar1Resource.setColorBar(colorBar1); if (cbar2Resource != null) { - cbar2Resource.setColorBar(ncscatResourceData.getColorBar2()); + ColorBar colorBar2 = ncscatResourceData.getColorBar2(); + colorBar2 + .setReverseOrder(colorBar2.getOrientation() == ColorBarOrientation.Vertical); + cbar2Resource.setColorBar(colorBar2); } } From 2d2ded41d3da5dfeaea575b48fef438b4e7b0073 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Fri, 21 Nov 2014 08:28:21 -0500 Subject: [PATCH 13/19] VLab Issue #4865 - MISC/ASCT latest Data string appears incorrectly This commit fixes #4865; refs #4864 Change-Id: I024a86831425f7eae776a00b9d6cf07993e74932 Former-commit-id: b53bb2c40e227d363c4287b75f72614c628f972b [formerly b53bb2c40e227d363c4287b75f72614c628f972b [formerly 9559830d4cbcf9e77cb269403c4ac6cca8a88796]] Former-commit-id: 8156498ddaad433cbfb7a5160fcc8d8017deb9ba Former-commit-id: 717629242fffe48ca63531ad7fadb651ddcf4091 --- .../common/dataplugin/ncscat/NcscatMode.java | 220 ++++++ .../plugin/ncscat/decoder/NcscatDecoder.java | 81 +-- .../plugin/ncscat/util/NcscatProcessing.java | 632 +++++++++--------- .../rsc/ncscat/rsc/EditNcscatAttrsDialog.java | 1 + .../ncep/viz/rsc/ncscat/rsc/NcscatMode.java | 120 ---- .../viz/rsc/ncscat/rsc/NcscatResource.java | 5 +- .../rsc/ncscat/rsc/NcscatResourceData.java | 1 + 7 files changed, 558 insertions(+), 502 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatMode.java delete mode 100644 ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatMode.java diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatMode.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatMode.java new file mode 100644 index 0000000000..730bea429c --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/NcscatMode.java @@ -0,0 +1,220 @@ +/** + * + */ +package gov.noaa.nws.ncep.common.dataplugin.ncscat; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * NcscatMode - Enum class to centralize and encapsulate all the things that + * vary among different satellite and data feed types. + * + * //TODO: Consider moving this information entirely to the bundle and/or + * preferences (.xml/.prm) files, so the Java code can be completely agnostic + * about satellite data types; would allow extended 'configurability', at the + * expense of slightly longer bundle/preference files... + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 02 Jun 2010  235B       B. Hebbard  Initial creation.
+ * 03 Feb 2011  235E       B. Hebbard  Add support for ambiguity variants.
+ * 16 Aug 2012             B. Hebbard  Add OSCAT / OSCAT_HI
+ * 11 Apr 2014  1128       B. Hebbard  Add longitudeCoding field; change wind sense from boolean to enum.
+ * 21 Oct 2014  R4865      B. Hebbard  (TTR 984) Add file-header length and reportType fields to enable refactor to make decoding more robust (and thereby prevent date and other corruption)
+ * 
+ * 
+ * + * @author bhebbard + * @version 1.0 + */ + +public enum NcscatMode { + + // The only ordering constraint here is that if A.pointsPerRow divides + // B.pointsPerRow and A and B have the same byteOrder, then A should come + // before B. (Currently, no such cases exist.) This is so that we can check + // an unknown data file for 'consistency' with these types, in order, and + // choose the first one that matches. (In the hypothetical case above, A and + // B could both pass consistency checking, but we'd want to choose A.) + + // @formatter:off ppr hdr + QUIKSCAT ( 76, 0, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "quikscat" ), + QUIKSCAT_HI ( 152, 0, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "quikscat-hi"), + ASCAT ( 42, 0, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "ascat"), + ASCAT_HI ( 82, 0, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "ascat-hi"), + EXASCT ( 42, 0, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN, "Exasct"), + EXASCT_HI ( 82, 0, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN, "Exasct-hi"), + OSCAT ( 36, 0, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "oscat"), + OSCAT_HI ( 76, 0, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN, "oscat-hi"), + WSCAT ( 79, 56, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.SIGNED, ByteOrder.LITTLE_ENDIAN, "wscat"), + UNKNOWN ( 76, 0, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN, "unknown"); + // @formatter:on + + private int pointsPerRow; // number of Wind Vector Cell in each scan row + // across satellite track + + private WindDirectionSense windDirectionSense; // is the numeric wind + // direction the "from" + // (METEOROLOGICAL) + // direction, or the "to" + // (OCEANOGRAPHIC) direction? + + private LongitudeCoding longitudeCoding; // is the two-byte value a SIGNED + // (-18000 -- +18000) or UNSIGNED + // (0 -- 36000) representation of + // the (scaled by 100) longitude + // east of Greenwich? + + private ByteOrder byteOrder; // endianess of data in the byte stream + + private String reportType; // string to use in reportType field of DB + + private int valuesPerPoint = 9; // number of (short int) data values per + // point + + private int bytesPerValue = 2; // all are short int + + private int fileHeaderLength; // length in bytes of per-file header field, + // if any, in input file, before repeating + // per-row data begins; of interest to decoder + + private int rowHeaderLength = 8; // length in bytes of per-row header field + // (2 bytes each for day, hour, min, sec) + + private int bytesPerRow; // length in bytes of each row, comprising row + // header and all data values for all points in + // that row + + public int getBytesPerRow() { + return bytesPerRow; + } + + // Constructor + NcscatMode(int pointsPerRow, int fileHeaderLength, + WindDirectionSense windDirectionSense, + LongitudeCoding longitudeCoding, ByteOrder byteOrder, + String reportType) { + this.pointsPerRow = pointsPerRow; + this.fileHeaderLength = fileHeaderLength; + this.windDirectionSense = windDirectionSense; + this.longitudeCoding = longitudeCoding; + this.byteOrder = byteOrder; + this.reportType = reportType; + + bytesPerRow = rowHeaderLength + pointsPerRow * valuesPerPoint + * bytesPerValue; + } + + public String getReportType() { + return reportType; + } + + public int getPointsPerRow() { + return pointsPerRow; + } + + public int getFileHeaderLength() { + return fileHeaderLength; + } + + public WindDirectionSense getWindDirectionSense() { + return windDirectionSense; + } + + public LongitudeCoding getLongitudeCoding() { + return longitudeCoding; + } + + public ByteOrder getByteOrder() { + return byteOrder; + } + + public enum WindDirectionSense { // numeric direction value gives... + METEOROLOGICAL, // degrees FROM which wind is blowing + OCEANOGRAPHIC // degrees TO which wind is blowing + } + + public enum LongitudeCoding { // 2-byte wvc_lon (Wind Vector Cell - + // longitude) field is (x0.01 deg)... + SIGNED, // SIGNED short (-18000..+18000) + UNSIGNED // UNSIGNED short (0..36000 east of Greenwich) + } + + public static NcscatMode stringToMode(String name) { + // Given a string, return the corresponding enum + NcscatMode returnValue = null; + name = name.toUpperCase(); + name = name.replaceAll("-", "_"); + // TODO: Remove ambiguity number?? + try { + returnValue = valueOf(name); + } catch (IllegalArgumentException e) { + // TODO: Signal unrecognized Ncscat mode string + returnValue = UNKNOWN; + } + return returnValue; + } + + public boolean consistentWith(ByteBuffer byteBuffer) { + // Given a ByteBuffer containing ingested binary data of unknown + // satellite type (mode), determine whether data are consistent + // with "this" mode. We do this by seeing if date/hour fields + // repeat where they would be expected to appear, and contain + // reasonable values for those fields. + + // TODO: Consider moving this to decoder...? (Kind of prefer + // encapsulating it here, but also like enums to be rather + // minimalistic...? -bh) + + byteBuffer.order(byteOrder); + int base = fileHeaderLength; + for (int cycle = 0; cycle < 2; cycle++) { + + // DAY (of year) candidate fields of consecutive rows out of + // range... + short thisCandidateDayOfYear = byteBuffer.getShort(base); + short nextCandidateDayOfYear = byteBuffer.getShort(base + + bytesPerRow); + if (thisCandidateDayOfYear < 1 || thisCandidateDayOfYear > 366 + || nextCandidateDayOfYear < 1 + || nextCandidateDayOfYear > 366) + // ...means (right away) data can't be this type + return false; + // ...but if they don't match... + if (thisCandidateDayOfYear != nextCandidateDayOfYear) { + // ...can't rule it out (since first two rows could straddle a + // day boundary)...but can skip checking hour and go to check + // next pair of rows... + break; + } + + // HOUR candidate fields (of consecutive rows) in range...? + short thisCandidateHour = byteBuffer.getShort(base + 2); + short nextCandidateHour = byteBuffer.getShort(base + 2 + + bytesPerRow); + if (thisCandidateHour < 0 || thisCandidateHour > 23 + || nextCandidateHour < 0 || nextCandidateHour > 23) + return false; + // ...and if they do match (as well as day field above), then we + // conclude consistency + if (byteBuffer.getShort(base) == byteBuffer.getShort(base + + bytesPerRow)) { + return true; + } + // ...but if they don't, again, first two rows could straddle an + // hour boundary, so go to next pair of rows (cycle)... + base += bytesPerRow; + } + // We've made it through 2 consecutive cycles, and neither (1st/2nd + // nor 2nd/3rd) day+hour match, so conclude (assuming real consecutive + // rows are not separated by an hour or more) data not consistent with + // this type + return false; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoder.java index de3f3f3a8b..2ae65aaa39 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoder.java @@ -2,7 +2,8 @@ * * Ncscat Decoder * - * This java class decodes Ascat quikscat (NESDIS File) raw data. + * This Java class decodes ocean winds scatterometer/radiometer (NESDIS File) raw data. + * * HISTORY * * Date Author Description @@ -10,6 +11,7 @@ * 11/2009 Uma Josyula Initial creation * 01/2011 B. Hebbard Handle ambiguity variants * 07/2012 B. Hebbard Handle OSCAT / OSCAT_HI + * 10/2014 B. Hebbard Get reportType from NcscatMode, instead of if-then-else'ing over hardcode integer lengths * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -67,7 +69,7 @@ public class NcscatDecoder extends AbstractDecoder { NcscatProcessing sProcess = new NcscatProcessing(); sProcess.setInputFileName(plugin); messageData = sProcess.separate(data); - recLength = NcscatProcessing.getRecordLength(); + recLength = sProcess.getRecordLength(); if (messageData != null) { record = new NcscatRecord(); @@ -76,38 +78,7 @@ public class NcscatDecoder extends AbstractDecoder { record.setEndTime(sProcess.getEndTime()); record.setRecordLength(recLength); record.setDataTime(new DataTime(sProcess.getStartTime())); - - if (record.getRecordLength() == 688) { - - if (plugin.equalsIgnoreCase("oscat")) { - record.setReportType("oscat-hi"); - } else { - record.setReportType("quikscat"); - } - } else if (record.getRecordLength() == 1372) { - record.setReportType("quikscat-hi"); - } else if (record.getRecordLength() == 382) { - - if (plugin.equalsIgnoreCase("ascatx")) { - - record.setReportType("Exasct"); - } else { - - record.setReportType("ascat"); - } - } else if (record.getRecordLength() == 742) { - - if (plugin.equalsIgnoreCase("ascatx")) { - - record.setReportType("Exasct-hi"); - } else { - record.setReportType("ascat-hi"); - } - } else if (record.getRecordLength() == 328) { - record.setReportType("oscat"); - } else if (record.getRecordLength() == 715) { - record.setReportType("wscat"); - } + record.setReportType(sProcess.getNcscatMode().getReportType()); // If this is an (numbered) 'ambiguity' variant, add suffix to // reportType @@ -178,20 +149,16 @@ public class NcscatDecoder extends AbstractDecoder { } // TODO: Review this temporary fix by BH to see if a broader // refactor might be better. + // Problem: Without the added 'else' below, non-local variable - // "plugin" will - // retain its previous value if the pattern matcher fails above; - // this will happen - // if the file suffix/extension (after the ".") is shorter than 5 - // characters. - // Scenario: A file with suffix ".ascatx" is ingested, then later a - // ".qsct" file. + // "plugin" will retain its previous value if the pattern matcher + // fails above; this will happen if the file suffix/extension (after + // the ".") is shorter than 5 characters. Scenario: A file with + // suffix ".ascatx" is ingested, then later a ".qsct" file. // Variable "plugin" will be set to "ascatx" by the first, but will - // retain this - // same value for the second; logic in NcscatProcessing.doSeparate() - // will as a - // result interpret the big-endian ".qsct" data as little endian - // format. + // retain this same value for the second; logic in + // NcscatProcessing.doSeparate() will as a result interpret the + // big-endian ".qsct" data as little endian format. // Alternate (better): Could make "plugin" local to this method else { plugin = ""; @@ -200,20 +167,14 @@ public class NcscatDecoder extends AbstractDecoder { // NcscatProcessing // Handle ambiguity variants: In addition to files containing the - // primary - // (greatest likelihood) wind vector solutions, for some data types - // we also - // receive (typically 2 or 4) 'ambiguity' variants for the same - // point locations, - // but with (lesser likelihood) solutions. Since these cannot be - // distinguished - // from the primary files based on data format/content alone, we - // look for a - // (prearranged) telltale pattern somewhere in the file name. If - // found, we - // remember the indicated ambiguity number, for later tagging of the - // database - // record. + // primary (greatest likelihood) wind vector solutions, for some + // data types we also receive (typically 2 or 4) 'ambiguity' + // variants for the same point locations, but with (lesser + // likelihood) solutions. Since these cannot be distinguished from + // the primary files based on data format/content alone, we + // look for a (prearranged) telltale pattern somewhere in the file + // name. If found, we remember the indicated ambiguity number, for + // later tagging of the database record. pattern = Pattern.compile("ambig([1-9])"); matcher = pattern.matcher(fileName); if (matcher.find()) { diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/NcscatProcessing.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/NcscatProcessing.java index 2a4591280e..1836da5379 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/NcscatProcessing.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/NcscatProcessing.java @@ -7,14 +7,18 @@ *
  * Uma Josyula                               11/2009         Creation
  * B. Hebbard                                07/2012         Handle OSCAT / OSCAT_HI
+ * B. Hebbard        R4865/TTR984            10/2014         Tighten code that infers satellite type
+ *                                                           (from date/hour field recurrence) and
+ *                                                           date handling to prevent garbage from being
+ *                                                           interpreted as dates decades in the future.
  * 
* * This code has been developed by the SIB for use in the AWIPS system. */ - package gov.noaa.nws.ncep.edex.plugin.ncscat.util; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode; import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatPoint; import java.nio.ByteBuffer; @@ -24,369 +28,357 @@ import java.util.Calendar; import java.util.List; import java.util.NoSuchElementException; -import javax.xml.bind.JAXBException; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.log4j.Logger; -import com.raytheon.uf.common.serialization.SerializationUtil; - - public class NcscatProcessing { + private final Logger log = Logger.getLogger(getClass().getName()); + private final Log theLogger = LogFactory.getLog(getClass()); - private final Logger log = Logger.getLogger(getClass().getName()); - private final Log theLogger = LogFactory.getLog(getClass()); - private List item; - List newMessage=null; - NcscatPoint sPointObj ; - private Calendar endTime ; - private static int scatNumber ; - private Calendar startTime; - private static int recordLength; - private String inputFileName; + private List item; + List newMessage = null; - public NcscatProcessing() { - } + NcscatPoint sPointObj; - public byte[] separate(byte[] data) { - doSeparate(data); - try { - if(newMessage ==null){ - return (byte[])null; - } - else { - byte[] tempBytes = listByteTobyteArray(newMessage); - return tempBytes; - } + private Calendar endTime; - } catch (NoSuchElementException e) { - return (byte[])null; - } + private int scatNumber; - } + private Calendar startTime; + private int recordLength; - /** - * @param message - * separate bulletins - */ - private void doSeparate(byte[] message) { - int ji=0; - int n = 0,doubleNcscat =0,scatXLen =0; - ByteBuffer byteBuffer = null; - byteBuffer = ByteBuffer.allocate(message.length); - byteBuffer.put(message,0,message.length); - int bitNum =0; - int tempLength=message.length; - int day,hour,min,sec; + private String inputFileName; - startTime = Calendar.getInstance(); - endTime = Calendar.getInstance(); + private NcscatMode ncscatMode; - // Attempt to discriminate type of data by looking for 'period' of repeating date+hour fields. - // TODO !! Guard against false negative which could occur if first 2 times straddle hour boundary, - // !! possibly by checking for match EITHER 1st-&-2nd OR 2nd-&-3rd - if ((byteBuffer.getShort(0) == byteBuffer.getShort(1484)) && (byteBuffer.getShort(2) == byteBuffer.getShort(1486))) { - // ASCAT_HI or EXASCT_HI (...which are big and little endian, respectively) - n=1476; - scatNumber=82; - recordLength=742; - } - else if((byteBuffer.getShort(0)== byteBuffer.getShort(764)) &&(byteBuffer.getShort(2)== byteBuffer.getShort(766))) { - // ASCAT or EXASCT (...which are big and little endian, respectively) - n=756; - scatNumber=42; - recordLength=382; - } - else if ((byteBuffer.getShort(0)== byteBuffer.getShort(1376)) &&(byteBuffer.getShort(2)== byteBuffer.getShort(1378))) { - // QUIKSCAT -OR- OSCAT_HI (...which are big and little endian, respectively) - n=1368; - scatNumber = 76; - recordLength =688; - } - else if ((byteBuffer.getShort(0) == byteBuffer.getShort(656)) && (byteBuffer.getShort(2) == byteBuffer.getShort(658))) { - // OSCAT - n=648; - scatNumber = 36; - recordLength = 328; - } - else if ((byteBuffer.getShort(0) == byteBuffer.getShort(2744)) && (byteBuffer.getShort(2) == byteBuffer.getShort(2746))) { - // QUIKSCAT_HI - n=2736; - recordLength = 1372; - scatNumber = 152; - } - else if((byteBuffer.getShort(56)== byteBuffer.getShort(1486)) &&(byteBuffer.getShort(58)== byteBuffer.getShort(1488))){ - // WSAT - n=1422; - scatNumber=79; - recordLength=715; - //TODO: Review this temporary fix by BH to see if a broader refactor might be better. - // For WindSat -- which has a 56-byte header once per file, remove it from the - // message array here, so we don't have to mess with it separately later. - tempLength=message.length - 56; - byte[] xmessage = new byte[tempLength]; - for (int i = 0; i(tempLength); - - while(bitNum 0) { + // If there is a file header (separate from per-row headers), remove + // it from the message array here, so we don't have to mess with it + // separately later. + tempLength = message.length - ncscatMode.getFileHeaderLength(); + byte[] xmessage = new byte[tempLength]; + for (int i = 0; i < tempLength; i++) { + xmessage[i] = message[i + ncscatMode.getFileHeaderLength()]; + } + message = xmessage; + byteBuffer.clear(); + byteBuffer = null; + byteBuffer = ByteBuffer.allocate(tempLength); + byteBuffer.put(message, 0, tempLength); + } + + // Endianess correction must be applied to the 4-short date/time field + // on each line. Here we set the ByteOrder of the byteBuffer, so + // that the 4 getShort(...) calls below will do the byte-flipping for + // us. + // + ByteOrder byteOrder = ncscatMode.getByteOrder(); + byteBuffer.order(byteOrder); + + try { + if (message != null) { + int ji = 0; + int dNcscatMult = 0; + int doubleNcscat = scatNumber * 2; + int scatXLen = doubleNcscat * 9 + 8; + int byteNum = 0; + + // Make a pass through all rows in file, just to determine + // earliest and latest times + int day, hour, min, sec; + while (ji < tempLength) { + day = byteBuffer.getShort(ji); + hour = byteBuffer.getShort(ji + 2); + min = byteBuffer.getShort(ji + 4); + sec = byteBuffer.getShort(ji + 6); + + if (day < 1 || day > 366 || hour < 0 || hour > 23 + || min < 0 || min > 59 || sec < 0 || sec > 60) { + // TODO log error? + break;// TODO continue? + } + + if (ji < 8) { // first row + startTime.set(Calendar.DAY_OF_YEAR, day); + startTime.set(Calendar.HOUR_OF_DAY, hour); + startTime.set(Calendar.MINUTE, min); + startTime.set(Calendar.SECOND, sec); + } + + // Don't know ahead of time which row will be last + // so set each time; last one will remain endTime + endTime.set(Calendar.DAY_OF_YEAR, day); + endTime.set(Calendar.HOUR_OF_DAY, hour); + endTime.set(Calendar.MINUTE, min); + endTime.set(Calendar.SECOND, sec); + + ji = ji + scatXLen; + + }// for while + + // Time bounds scan done; now go back through the row data and + // rearrange as needed. + + newMessage = new ArrayList(tempLength); + + while (byteNum < tempLength) { + int consByteNum = byteNum; + while (byteNum < consByteNum + 8) { + + // Here we again apply endianess correction to the + // 4-short date/time field on each row. Above (via the + // ByteBuffer) was just for determining startTime and + // endTime of the entire data set. Here we do it again + // as the 'message' array is moved to newMessage + // (ArrayList) for later return and eventual writing to + // the HDF5 data for each scan row. Note that the + // byte-swapping is done below for the data fields in + // each row following the leading date/time (in the + // process of regrouping the data so data for each point + // is together); here we do it for the date as well + // (where no other regrouping is required). + // + int offsetInDate = byteNum - consByteNum; // 0 thru 7 + if (byteOrder == ByteOrder.LITTLE_ENDIAN) { + // need to flip the 2 bytes of each short; map 0 1 2 + // 3 4 5 6 7 to 1 0 3 2 5 4 7 6, respectively + offsetInDate = offsetInDate / 2 * 2 + + (1 - offsetInDate % 2); + } + newMessage.add((Byte) message[consByteNum + + offsetInDate]); + byteNum++; + }// date field 8 bytes + + // Done with row header (date/time); now start on the data + // for points in that row. (consByteNum is index of first + // byte of such data .) + + consByteNum = byteNum; + + // In the incoming data for a row, all values for each + // single parameter are grouped together (for all points in + // the row). The following code "shuffles" things so that + // all values for a single point are grouped together + // (that is, all parameters for a given point). In the + // process, proper endianess order is set for the two bytes + // making up each data value. + + while ((scatXLen * dNcscatMult + 7) <= byteNum + && byteNum < (scatXLen * (dNcscatMult + 1))) { + int calc = 0; + for (int qNoIndex = 0; qNoIndex < doubleNcscat; qNoIndex++) { + for (int rou = 0; rou <= 8; rou++) { + if (byteNum < tempLength) { + calc = consByteNum + doubleNcscat * rou + + qNoIndex; + if (byteOrder == ByteOrder.LITTLE_ENDIAN) { + // swap the two bytes making up the + // short + newMessage.add(message[calc + 1]); + byteNum++; + newMessage.add(message[calc]); + byteNum++; + } else { // ByteOrder.BIG_ENDIAN + // preserve order of the two bytes + // making up the short + newMessage.add(message[calc]); + byteNum++; + newMessage.add(message[calc + 1]); + byteNum++; + } + } // end of if + } // end of for rou + qNoIndex++; + } // end of for qNoIndex + dNcscatMult++; + } // end of while + + } // while (each row) + + }// if message is not null + }// end of try block + catch (Exception e) { + e.printStackTrace(); + if (log.isInfoEnabled()) { + log.info("No valid records found!"); + } + theLogger.warn("No valid records found!"); + } + return; + } + + public NcscatMode getNcscatMode() { + return ncscatMode; + } + + /** + * processHDF5Data -- SHOULD NOT BE USED IN PRESENT FORM Please see + * NcscatResource.processHDF5Data(...) * * @return List * * @deprecated Please see NcscatResource.processHDF5Data(...) */ @Deprecated + public List processHDF5Data(byte[] hdf5Msg) { + int ji = 0, bitNum = 0; + int day, hour, min, sec; + item = new ArrayList(); + // TODO - Caution! Separate startTime Calendar object needs to be + // allocated for each point row, since will be shared by all points + // in that row. See below. + startTime = Calendar.getInstance(); + ByteBuffer byteBuffer = null; + byteBuffer = ByteBuffer.allocate(hdf5Msg.length); + byteBuffer.put(hdf5Msg, 0, hdf5Msg.length); + while (ji < hdf5Msg.length) { - public List processHDF5Data(byte[] hdf5Msg){ - int ji=0, bitNum=0; - int day,hour,min,sec; - item= new ArrayList(); - // TODO - Caution! Separate startTime Calendar object needs to be allocated - // for each point row, since will be shared by all points - // in that row. See below. - startTime = Calendar.getInstance(); - ByteBuffer byteBuffer = null; - byteBuffer = ByteBuffer.allocate(hdf5Msg.length); - byteBuffer.put(hdf5Msg,0,hdf5Msg.length); + day = byteBuffer.getShort(bitNum); + hour = byteBuffer.getShort(bitNum + 2); + min = byteBuffer.getShort(bitNum + 4); + sec = byteBuffer.getShort(bitNum + 6); + ji = ji + 8; + bitNum = bitNum + 8; + // TODO - Caution! Need to allocate new startTime here... + startTime.set(Calendar.DAY_OF_YEAR, day); + startTime.set(Calendar.HOUR_OF_DAY, hour); + startTime.set(Calendar.MINUTE, min); + startTime.set(Calendar.SECOND, sec); + for (int j = ji; j < ji + scatNumber * 18 + && bitNum < hdf5Msg.length; j = j + 18) { + sPointObj = new NcscatPoint(); + // TODO - continued - otherwise all points in all rows get same + // time here + sPointObj.setStTime(startTime); + sPointObj.setLat(byteBuffer.getShort(j)); + sPointObj.setLon(byteBuffer.getShort(j + 2)); + sPointObj.setIql(byteBuffer.getShort(j + 4)); + sPointObj.setIsp(byteBuffer.getShort(j + 6)); + sPointObj.setIdr(byteBuffer.getShort(j + 8)); + sPointObj.setIrn(byteBuffer.getShort(j + 10)); + sPointObj.setIb1(byteBuffer.getShort(j + 12)); + sPointObj.setIb2(byteBuffer.getShort(j + 14)); + sPointObj.setIb3(byteBuffer.getShort(j + 16)); + bitNum = bitNum + 18; + item.add(sPointObj); - while ( ji < hdf5Msg.length) { + }// for - day = byteBuffer.getShort(bitNum) ; - hour= byteBuffer.getShort(bitNum+2); - min = byteBuffer.getShort(bitNum+4); - sec = byteBuffer.getShort(bitNum+6); - ji=ji+8; - bitNum=bitNum+8; - // TODO - Caution! Need to allocate new startTime here... - startTime.set(Calendar.DAY_OF_YEAR, day); - startTime.set(Calendar.HOUR_OF_DAY, hour); - startTime.set(Calendar.MINUTE, min); - startTime.set(Calendar.SECOND, sec); - for(int j=ji;j temp) { + byte[] byteArray = new byte[temp.size()]; + int jkl = 0; + for (Byte current : temp) { + byteArray[jkl] = current; + jkl++; + } - public Calendar getEndTime() { - return endTime; - } - public void setEndTime(Calendar endTime) { - this.endTime = endTime; - } + return byteArray; + } - private static byte[] listByteTobyteArray(List temp) { - byte[] byteArray = new byte[temp.size()]; - int jkl=0; - for(Byte current:temp){ - byteArray[jkl] =current; - jkl++; - } + public int getRecordLength() { + return recordLength; + } - return byteArray; - } + public void setRecordLength(int recordLength) { + this.recordLength = recordLength; + } - public static int getRecordLength() { - return recordLength; - } + public String getInputFileName() { + return inputFileName; + } - public static void setRecordLength(int recordLength) { - NcscatProcessing.recordLength = recordLength; - } - public String getInputFileName() { - return inputFileName; - } - - public void setInputFileName(String inputFileName) { - this.inputFileName = inputFileName; - } + public void setInputFileName(String inputFileName) { + this.inputFileName = inputFileName; + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/EditNcscatAttrsDialog.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/EditNcscatAttrsDialog.java index a9bb0b5667..5b204f7bd9 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/EditNcscatAttrsDialog.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/EditNcscatAttrsDialog.java @@ -1,5 +1,6 @@ package gov.noaa.nws.ncep.viz.rsc.ncscat.rsc; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode; import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; import gov.noaa.nws.ncep.viz.resources.attributes.AbstractEditResourceAttrsDialog; diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatMode.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatMode.java deleted file mode 100644 index 59e65808ea..0000000000 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatMode.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * - */ -package gov.noaa.nws.ncep.viz.rsc.ncscat.rsc; - -import java.nio.ByteOrder; - -/** - * NcscatMode - Enum class to centralize and encapsulate all the things that - * vary among different satellite and data feed types. - * - * //TODO: Consider moving this information entirely to the bundle and/or - * preferences (.xml/.prm) files, so the Java code can be completely agnostic - * about satellite data types; would allow extended 'configurability', at the - * expense of slightly longer bundle/preference files... - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * - *
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 02 Jun 2010  235B       B. Hebbard  Initial creation.
- * 03 Feb 2011  235E       B. Hebbard  Add support for ambiguity variants.
- * 16 Aug 2012             B. Hebbard  Add OSCAT / OSCAT_HI
- * 11 Apr 2014  1128       B. Hebbard  Add longitudeCoding field; change wind sense from boolean to enum.
- * 
- * 
- * - * @author bhebbard - * @version 1.0 - */ - -public enum NcscatMode { - - // @formatter:off - QUIKSCAT ( 76, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ), - QUIKSCAT_HI ( 152, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ), - ASCAT ( 42, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ), - ASCAT_HI ( 82, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ), - EXASCT ( 42, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN ), - EXASCT_HI ( 82, WindDirectionSense.OCEANOGRAPHIC, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN ), - OSCAT ( 36, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ), - OSCAT_HI ( 76, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.LITTLE_ENDIAN ), - WSCAT ( 79, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.SIGNED, ByteOrder.LITTLE_ENDIAN ), - UNKNOWN ( 76, WindDirectionSense.METEOROLOGICAL, LongitudeCoding.UNSIGNED, ByteOrder.BIG_ENDIAN ); - // @formatter:on - - private int pointsPerRow; // number of Wind Vector Cell in each scan row - // across satellite track - - private WindDirectionSense windDirectionSense; // is the numeric wind - // direction the "from" - // (METEOROLOGICAL) - // direction, or the "to" - // (OCEANOGRAPHIC) direction? - - private LongitudeCoding longitudeCoding; // is the two-byte value a SIGNED - // (-18000 -- +18000) or UNSIGNED - // (0 -- 36000) representation of - // the (scaled by 100) longitude - // east of Greenwich? - - private ByteOrder byteOrder; // endianess of data in the byte stream - - // TODO: could add more here, to simplify (switch) code with more table - // driven logic. But see above note about .xml/.prm... - - // Constructor - NcscatMode(int pointsPerRow, WindDirectionSense windDirectionSense, - LongitudeCoding longitudeCoding, ByteOrder byteOrder) { - this.pointsPerRow = pointsPerRow; - this.windDirectionSense = windDirectionSense; - this.longitudeCoding = longitudeCoding; - this.byteOrder = byteOrder; - } - - public int getPointsPerRow() { - return pointsPerRow; - } - - public WindDirectionSense getWindDirectionSense() { - return windDirectionSense; - } - - public LongitudeCoding getLongitudeCoding() { - return longitudeCoding; - } - - public ByteOrder getByteOrder() { - return byteOrder; - } - - public static NcscatMode stringToMode(String name) { - // Given a string, return the corresponding enum - NcscatMode returnValue = null; - name = name.toUpperCase(); - name = name.replaceAll("-", "_"); - // TODO: Remove ambiguity number?? - try { - returnValue = valueOf(name); - } catch (IllegalArgumentException e) { - // TODO: Signal unrecognized Ncscat mode string - returnValue = UNKNOWN; - } - return returnValue; - } - - public enum WindDirectionSense { // numeric direction value gives... - METEOROLOGICAL, // degrees FROM which wind is blowing - OCEANOGRAPHIC // degrees TO which wind is blowing - } - - public enum LongitudeCoding { // 2-byte wvc_lon (Wind Vector Cell - - // longitude) field is (x0.01 deg)... - SIGNED, // SIGNED short (-18000..+18000) - UNSIGNED // UNSIGNED short (0..36000 east of Greenwich) - } - -} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java index 38961d7dff..1664dcb45c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResource.java @@ -1,7 +1,10 @@ package gov.noaa.nws.ncep.viz.rsc.ncscat.rsc; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode; import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatPoint; import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatRecord; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode.LongitudeCoding; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode.WindDirectionSense; import gov.noaa.nws.ncep.gempak.parameters.colorbar.ColorBarOrientation; import gov.noaa.nws.ncep.ui.pgen.display.DisplayElementFactory; import gov.noaa.nws.ncep.ui.pgen.display.IDisplayable; @@ -13,8 +16,6 @@ import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource; import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResource; import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResourceData; -import gov.noaa.nws.ncep.viz.rsc.ncscat.rsc.NcscatMode.LongitudeCoding; -import gov.noaa.nws.ncep.viz.rsc.ncscat.rsc.NcscatMode.WindDirectionSense; import gov.noaa.nws.ncep.viz.ui.display.ColorBar; import gov.noaa.nws.ncep.viz.ui.display.NCMapDescriptor; diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResourceData.java index 79382a646b..ef6b6a2b9c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResourceData.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.ncscat/src/gov/noaa/nws/ncep/viz/rsc/ncscat/rsc/NcscatResourceData.java @@ -4,6 +4,7 @@ import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; import gov.noaa.nws.ncep.viz.resources.attributes.RGBColorAdapter; import gov.noaa.nws.ncep.viz.ui.display.ColorBar; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode; import gov.noaa.nws.ncep.ui.pgen.display.IVector.VectorType; import java.util.regex.Matcher; From d19283fc08588750dcd0742bc7060092a9d2f293 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Fri, 21 Nov 2014 10:29:23 -0500 Subject: [PATCH 14/19] VLab Issue #5398 - Fixing improper formatting of SIGMETs This commit fixes #5398 and refs #4926 Change-Id: I64987bedec9013b9944b88bfd08bc9453cdae632 Former-commit-id: 633a2dee6fd23a22657650f1b465e6954d9ccb7d [formerly 633a2dee6fd23a22657650f1b465e6954d9ccb7d [formerly d128530f757eaaa2573c7466c9e4d09fe149289f]] Former-commit-id: 585e5bae2761c01bd00a4819fcca367bfa4ca6b3 Former-commit-id: a088743a1e79a63c69bbf09567ef6493550d4471 --- .../ui/pgen/attrdialog/SigmetAttrDlg.java | 297 ++- .../ui/pgen/attrdialog/SigmetCommAttrDlg.java | 55 +- .../noaa/nws/ncep/viz/common/SnapUtil.java | 1833 +++++++++-------- 3 files changed, 1266 insertions(+), 919 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetAttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetAttrDlg.java index 75530c0f06..c96a56552d 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetAttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetAttrDlg.java @@ -101,6 +101,9 @@ import com.vividsolutions.jts.geom.Polygon; * 03/13 #928 B. Yin Made the button bar smaller. * 04/13 #977 S. Gilbert PGEN Database support * 09/13 TTR656 J. Wu Display for INTL_SIGMET converted from VGF. + * 09/14 TTR974 J. Wu update "editableAttrFromLine" in "setSigmet()". + * 10/14 TTR433 J. Wu Set input verification/output format for Phenom Lat/Lon. + * 10/14 TTR722 J. Wu Display TC center/Movement/FL level for ISOLATED TC. * * * @author gzhang @@ -209,6 +212,16 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { private HashMap controlEnablerMap = new HashMap(); + /** + * Colors to indicate if Phenom lat/lon input is in correct format. + */ + private final Color wrongFormatColor = Color.red; + + private final Color rightFormatColor = Color.green; + + /** + * Constructor. + */ protected SigmetAttrDlg(Shell parShell) throws VizException { super(parShell); } @@ -764,11 +777,19 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { @Override public void focusLost(FocusEvent e) { - if (SigmetAttrDlg.this.getEditableAttrPhenomLat() != null) + if (SigmetAttrDlg.this.getEditableAttrPhenomLat() != null) { txtPheLat.setText(SigmetAttrDlg.this .getEditableAttrPhenomLat()); - else - txtPheLat.setText("???"); + setBackgroundColor(txtPheLat, rightFormatColor); + } else { + /* + * "???" causes inconvenience for copy/paste. Instead, + * use Color as hint. + */ + // txtPheLat.setText("???"); + txtPheLat.setText(""); + setBackgroundColor(txtPheLat, wrongFormatColor); + } } }); @@ -796,11 +817,19 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { @Override public void focusLost(FocusEvent e) { - if (SigmetAttrDlg.this.getEditableAttrPhenomLon() != null) + if (SigmetAttrDlg.this.getEditableAttrPhenomLon() != null) { txtPheLon.setText(SigmetAttrDlg.this .getEditableAttrPhenomLon()); - else - txtPheLon.setText("???"); + setBackgroundColor(txtPheLon, rightFormatColor); + } else { + /* + * "???" causes inconvenience for copy/paste. Instead, + * use Color as hint. + */ + // txtPheLon.setText("???"); + txtPheLon.setText(""); + setBackgroundColor(txtPheLon, wrongFormatColor); + } } }); @@ -1397,8 +1426,8 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { .getPoints().toArray(new Coordinate[] {}); /* - * Added "trim()" since SIGMETs VGFs has no "editableAttrFromLine" and it is - * defaulted as " " when converted into XML - (J. Wu). + * Added "trim()" since SIGMETs VGFs has no "editableAttrFromLine" + * and it is defaulted as " " when converted into XML - (J. Wu). */ if (coors != null) { if (editableAttrFromLine == null @@ -1522,7 +1551,6 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { private String convertTimeStringPlusHourInHMS(String timeString, int plusHour, boolean dayNeeded) { Calendar c = Calendar.getInstance(); - System.out.println("____________timeString: " + timeString); c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(timeString.substring(0, 2))); c.set(Calendar.HOUR_OF_DAY, @@ -1996,14 +2024,14 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { @Override public void createButtonsForButtonBar(Composite parent) { - - ((GridLayout) parent.getLayout()).verticalSpacing = 0; - ((GridLayout) parent.getLayout()).marginHeight = 3; - + + ((GridLayout) parent.getLayout()).verticalSpacing = 0; + ((GridLayout) parent.getLayout()).marginHeight = 3; + createButton(parent, IDialogConstants.OK_ID, "Save", true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); - + getButton(IDialogConstants.OK_ID).setLayoutData( new GridData(ctrlBtnWidth, ctrlBtnHeight)); getButton(IDialogConstants.CANCEL_ID).setLayoutData( @@ -2204,18 +2232,25 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { Sigmet sig = ((Sigmet) SigmetAttrDlg.this.drawingLayer .getSelectedDE()); - if (SigmetAttrDlg.this.ISOLATED.equals(sig.getType())) { + + /* + * TTR 722 - This "if" causes "ISOLATED" TC center not + * displaying. So we commented it out. + * + * if (SigmetAttrDlg.this.ISOLATED.equals(sig.getType())) { + * sb.append(" ").append("NEAR"); // + * sb.append(" ").append(sig.getLinePoints()[0].y); // + * sb.append(" ").append(sig.getLinePoints()[0].x); } else { + */ + if (SigmetAttrDlg.this.getEditableAttrPhenomLat() != null + && SigmetAttrDlg.this.getEditableAttrPhenomLon() != null) { sb.append(" ").append("NEAR"); - // sb.append(" ").append(sig.getLinePoints()[0].y); - // sb.append(" ").append(sig.getLinePoints()[0].x); - } else { - if ( SigmetAttrDlg.this.getEditableAttrPhenomLat() != null - && SigmetAttrDlg.this.getEditableAttrPhenomLon() != null ) { - sb.append(" ").append("NEAR"); - sb.append(" ").append(SigmetAttrDlg.this.getEditableAttrPhenomLat()); - sb.append(SigmetAttrDlg.this.getEditableAttrPhenomLon()); - } + sb.append(" ").append( + SigmetAttrDlg.this.getEditableAttrPhenomLat()); + sb.append(" ").append( + SigmetAttrDlg.this.getEditableAttrPhenomLon()); } + // } sb.append(" ").append("AT "); sb.append(getTimeStringPlusHourInHMS(0).substring(0, 4));// C @@ -2227,6 +2262,11 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { // --------------- movement String movement = SigmetAttrDlg.this.getEditableAttrMovement(); + + if (movement == null) { + movement = "STNRY"; + } + if ("STNRY".equals(movement)) { sb.append(" ").append("STNR. "); } else if ("MVG".equals(movement)) { @@ -2292,7 +2332,8 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { String tops = SigmetAttrDlg.this.getEditableAttrLevel(); - if ("FCST".equals(tops) || isTropCyc) { + if ("FCST".equals(tops)) { + // if ("FCST".equals(tops) || isTropCyc) { sb.append(tops.equals("-none-") ? "" : tops).append(" "); sb.append(SigmetAttrDlg.this.getEditableAttrLevelInfo1()) .append(" "); @@ -2339,7 +2380,7 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { sb.append(" ").append("NM CENTER."); } else { sb.append(" ").append("WI "); - sb.append((int)SigmetAttrDlg.this.getWidth()); + sb.append((int) SigmetAttrDlg.this.getWidth()); sb.append(" ").append("NM OF "); for (int i = 0; i < lineArray.length - 1; i++) sb.append(" ").append(lineArray[i]); @@ -2363,7 +2404,7 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { } else {// line with LINE_SEPERATER sb.append(" ").append("WI "); - sb.append((int)SigmetAttrDlg.this.getWidth()); + sb.append((int) SigmetAttrDlg.this.getWidth()); sb.append(" ").append("NM "); sb.append(getLineTypeForSOL(lineType));// [lineArray.length-2]);//watch // out for index @@ -2648,9 +2689,15 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { // ((Sigmet)sigmet).getType() ) ); } } + if (txtInfo != null && !txtInfo.isDisposed() && s != null) this.resetText(s, txtInfo); + // TTR 974 - "editableAttrFromLine" needs update as well. + if (sigmet != null && s != null) { + ((Sigmet) sigmet).setEditableAttrFromLine(s); + } + } private void init() { @@ -2787,9 +2834,45 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { withExpandedArea = false;// ??? } + /* + * This method validates the input lat or lon are in the specified formats + * as below since AWC receives info in various formats from TACs around the + * world) and be convertyed later into specified formats. + * + * This a new requirement from AWC as described in AWC Sept 2014 FIT test + * report for TTR 433 - J. Wu, Oct. 7th, 2014. + * + * "N", "S", and "–" are literal; "dd" or "ddd" is degree; "mm" is minute; + * "p" is decimal degree; "(d)" is an optional degree longitude digit for + * longitudes with absolute value >= 100.0): + * + * A) "Phenom Lat" text box accepts a latitude north: Nddmm, ddmmN, dd.pN, + * Ndd.p, dd.p; Output is Nddmm. + * + * B)"Phenom Lat" text box accepts a latitude south: Sddmm, ddmmS, dd.pS, + * Sdd.p, dd.p; Output is Sddmm. + * + * C)"Phenom Lon" text box accepts a longitude west: W(d)ddmm, (d)ddmmW, + * (d)dd.pW, W(d)dd.p, -(d)dd.p; Output is W[0|1]ddmm. + * + * D)"Phenom Lon" text box accepts a longitude east: E(d)ddmm, (d)ddmmE, + * (d)dd.pE, E(d)dd.p, (d)dd.p; Output is E[0|1]ddmm. + * + * Note: + * + * (1) "N", "S", "E", "W" is not case-sensitive. + * + * (2) "N"/"S"/"E"/"W" should have been stripped of before sending in here. + * + * (3) A "-" should be placed at the beginning if "S" or "W" found in the + * input. + */ private boolean validateLatLon(String coor, boolean isLat) { - String regexLat = "(-?[0-8]?[0-9](\\.\\d*)?)|-?90(\\.[0]*)?"; - String regexLon = "(-?([1]?[0-7][1-9]|[1-9]?[0-9])?(\\.\\d*)?)|-?180(\\.[0]*)?"; + // String regexLat = "(-?[0-8]?[0-9](\\.\\d*)?)|-?90(\\.[0]*)?"; + // String regexLon = + // "(-?([1]?[0-7][1-9]|[1-9]?[0-9])?(\\.\\d*)?)|-?180(\\.[0]*)?"; + String regexLat = "(-?[0-8]?[0-9](\\.)?(\\d*)?)|-?90(\\.)?([0]*)?"; + String regexLon = "(-?([1]?[0-7][0-9]|[0]?[0-9]?[0-9])?(\\.)?(\\d*)?)|-?180(\\.)?([0]*)?"; java.util.regex.Matcher m; if (isLat) { @@ -2860,11 +2943,13 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { Coordinate coor = coors[i]; result.append(coor.y >= 0 ? "N" : "S"); - long y = ((int) Math.abs(coor.y)*100) + Math.round( Math.abs(coor.y-(int)(coor.y))*60); + long y = ((int) Math.abs(coor.y) * 100) + + Math.round(Math.abs(coor.y - (int) (coor.y)) * 60); result.append(new DecimalFormat(FOUR_ZERO).format(y)); result.append(coor.x >= 0 ? " E" : " W"); - long x = ((int) Math.abs(coor.x))*100 + Math.round(Math.abs(coor.x-(int)(coor.x))*60); + long x = ((int) Math.abs(coor.x)) * 100 + + Math.round(Math.abs(coor.x - (int) (coor.x)) * 60); result.append(new DecimalFormat(FIVE_ZERO).format(x)); @@ -2943,28 +3028,143 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { return null; } + /* + * This method validates the input lat or lon are in the specified formats + * and format it into a specfied form as described below: + * + * This a new requirement from AWC as described in AWC Sept 2014 FIT test + * report for TTR 433 - J. Wu, Oct. 7th, 2014. + * + * "N", "S", and "–" are literal; "dd" or "ddd" is degree; "mm" is minute; + * "p" is decimal degree; "(d)" is an optional degree longitude digit for + * longitudes with absolute value >= 100.0): + * + * A) "Phenom Lat" text box accepts a latitude north: Nddmm, ddmmN, dd.pN, + * Ndd.p, dd.p; Output is Nddmm. + * + * B)"Phenom Lat" text box accepts a latitude south: Sddmm, ddmmS, dd.pS, + * Sdd.p, dd.p; Output is Sddmm. + * + * C)"Phenom Lon" text box accepts a longitude west: W(d)ddmm, (d)ddmmW, + * (d)dd.pW, W(d)dd.p, -(d)dd.p; Output is W[0|1]ddmm. + * + * D)"Phenom Lon" text box accepts a longitude east: E(d)ddmm, (d)ddmmE, + * (d)dd.pE, E(d)dd.p, (d)dd.p; Output is E[0|1]ddmm. + * + * Note: "N", "S", "E", "W" is not case-sensitive here. + */ private String getPhenomLatLon(String input, boolean isLat) { - if (input.startsWith("S") || input.startsWith("s") - || input.startsWith("W") || input.startsWith("w") - || input.endsWith("S") || input.endsWith("s") - || input.endsWith("W") || input.endsWith("w")) + input = input.toUpperCase(); + if ((isLat && (input.startsWith("S") || input.endsWith("S"))) + || (!isLat && (input.startsWith("W") || input.endsWith("W")))) { input = "-" + input; + } + + /* + * remove characters that is not a digit, -, or decimal point. + */ input = input.replaceAll("[^-0-9.]", ""); + /* + * Format the output to the desired form. + */ StringBuilder result = new StringBuilder(); if (!"".equals(input) && !"-".equals(input) && validateLatLon(input, isLat)) { - Double value = Double.parseDouble(input); - if (isLat) { - result.append(value >= 0.0 ? "N" : "S"); - double y = (double) Math.abs(value); - result.append(y); + if (!input.contains(".")) { + + /* + * Padding to make lat as "ddmm" and lon as "dddmm". + */ + String istr = input.replaceAll("-", ""); + int len = istr.length(); + String ostr = ""; + int val = Integer.parseInt(istr); + if (isLat) { + if (len == 1) { + ostr += ("0" + istr + "00"); + } else if (len == 2) { + if (val <= 90) + ostr += (istr + "00"); + } else if (len == 3) { + if (val <= 900) + ostr += (istr + "0"); + } else { + String tmp = istr.substring(0, 4); + if (Integer.parseInt(tmp) <= 9000) { + ostr += tmp; + } + } + } else { + if (len == 1) { + ostr += ("00" + istr + "00"); + } else if (len == 2) { + ostr += ("0" + istr + "00"); + } else if (len == 3) { + if (val <= 180) { + ostr += (istr + "00"); + } else { + ostr += ("0" + istr + "0"); + } + } else if (len == 4) { + if (val > 180) { + ostr += ("0" + istr); + } else if (val >= 100) { + ostr += (val + "00"); + } else if (val >= 10) { + ostr += ("0" + val + "00"); + } else { + ostr += ("00" + val + "00"); + } + + } else { + String tmp = istr.substring(0, 5); + if (Integer.parseInt(tmp) <= 18000) { + ostr += tmp; + } + } + } + + if (ostr.length() > 0) { + if (isLat) { + result.append(input.startsWith("-") ? "S" : "N"); + } else { + result.append(input.startsWith("-") ? "W" : "E"); + } + } + + result.append(ostr); + } else { - result.append(value >= 0.0 ? " E" : " W"); - double x = (double) Math.abs(value); - result.append(x); + /* + * Convert to degree and minutes and then padding to make lat as + * "ddmm" and lon as "dddmm". + */ + Double value = Double.parseDouble(input); + int deg = value.intValue(); + + Double minute = (Math.abs(value - deg)) * 60.0; + int mm = (int) Math.round(minute); + + deg = Math.abs(deg); + + if (isLat) { + result.append(value >= 0.0 ? "N" : "S"); + String dstr = (deg < 10) ? ("0" + deg) : ("" + deg); + result.append(dstr); + String mstr = (mm < 10) ? ("0" + mm) : ("" + mm); + result.append(mstr); + + } else { + result.append(value >= 0.0 ? "E" : "W"); + String dstr = (deg < 10) ? ("00" + deg) + : ((deg < 100) ? ("0" + deg) : ("" + deg)); + result.append(dstr); + String mstr = (mm < 10) ? ("0" + mm) : ("" + mm); + result.append(mstr); + } } return result.toString().trim(); @@ -3108,4 +3308,15 @@ public class SigmetAttrDlg extends AttrDlg implements ISigmet { this.setEditableAttrSeqNum(sig.getEditableAttrSeqNum()); } + + /* + * Sets the background color for a SWT control. + */ + private void setBackgroundColor(Control ww, Color color) { + org.eclipse.swt.graphics.Color clr = new org.eclipse.swt.graphics.Color( + ww.getDisplay(), color.getRed(), color.getGreen(), + color.getBlue()); + ww.setBackground(clr); + clr.dispose(); + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetCommAttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetCommAttrDlg.java index 9946b7cd14..0bb4cf191d 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetCommAttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/SigmetCommAttrDlg.java @@ -81,6 +81,7 @@ import com.vividsolutions.jts.io.WKBReader; * 11/12 #873 B. Yin Pass sigmet type "CONV_SIGMET" for snapping. * 03/13 #928 B. Yin Made the button bar smaller. * 04/29 #977 S. Gilbert PGEN Database support + * 04/29 #726 J. Wu Remove the line breaker when saving vor list into file. * * * @author gzhang @@ -538,7 +539,7 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { txtInfo = new Text(top2, style); txtInfo.setFont(txtfont); attrControlMap.put("editableAttrFromLine", txtInfo); - GridData gData = new GridData(600, 48); + GridData gData = new GridData(650, 48); gData.horizontalSpan = 8; txtInfo.setLayoutData(gData); txtInfo.setText(this.getEditableAttrFromLine()); @@ -740,13 +741,13 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { @Override public void createButtonsForButtonBar(Composite parent) { - ((GridLayout) parent.getLayout()).verticalSpacing = 0; - ((GridLayout) parent.getLayout()).marginHeight = 3; - + ((GridLayout) parent.getLayout()).verticalSpacing = 0; + ((GridLayout) parent.getLayout()).marginHeight = 3; + createButton(parent, IDialogConstants.OK_ID, "Save", true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); - + getButton(IDialogConstants.OK_ID).setLayoutData( new GridData(ctrlBtnWidth, ctrlBtnHeight)); getButton(IDialogConstants.CANCEL_ID).setLayoutData( @@ -775,7 +776,8 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { if (dataURI != null) { try { StorageUtils.storeDerivedProduct(dataURI, - txtSave.getText(), "TEXT", txtInfo.getText()); + txtSave.getText(), "TEXT", txtInfo.getText() + .replaceAll("-\n", "-")); } catch (PgenStorageException e) { StorageUtils.showError(e); } @@ -801,13 +803,32 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { String forecaster = System.getProperty("user.name"); ProductTime refTime = new ProductTime(); - Product defaultProduct = new Product( - SigmetCommAttrDlg.this.pgenType, - SigmetCommAttrDlg.this.pgenType, forecaster, null, refTime, - layerList); - // defaultProduct.addLayer(defaultLayer); - defaultProduct.setOutputFile(SigmetCommAttrDlg.this.drawingLayer - .buildActivityLabel(defaultProduct)); + String pname = SigmetCommAttrDlg.this.drawingLayer + .getActiveProduct().getName(); + String ptype = SigmetCommAttrDlg.this.drawingLayer + .getActiveProduct().getType(); + + pname = (pname == null) ? "Default" : pname; + ptype = (ptype == null) ? "Default" : ptype; + + Product defaultProduct = new Product(pname, ptype, forecaster, + null, refTime, layerList); + /* + * + * Product defaultProduct = new Product( + * SigmetCommAttrDlg.this.pgenType, SigmetCommAttrDlg.this.pgenType, + * forecaster, null, refTime, layerList); + */ + String plabel = SigmetCommAttrDlg.this.drawingLayer + .getActiveProduct().getOutputFile(); + if (plabel == null) { + plabel = SigmetCommAttrDlg.this.drawingLayer + .buildActivityLabel(defaultProduct); + } + defaultProduct.setOutputFile(plabel); + // defaultProduct.setOutputFile(SigmetCommAttrDlg.this.drawingLayer + // .buildActivityLabel(defaultProduct)); + defaultProduct.setCenter(PgenUtil.getCurrentOffice()); try { @@ -838,7 +859,7 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { txtInfo = new Text(top, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.WRAP); txtInfo.setFont(txtfont); - GridData gData = new GridData(512, 300); + GridData gData = new GridData(672, 300); gData.horizontalSpan = 3; txtInfo.setLayoutData(gData); txtInfo.setText(getFileContent()); @@ -1048,9 +1069,9 @@ public class SigmetCommAttrDlg extends AttrDlg implements ISigmet { try { stateGeo = (MultiPolygon) wkbReader.read(wkb); } catch (Exception e) { - System.out - .println("___ Error: SigmetCommAttrDlg: getAreaString(): " - + e.getMessage()); + // System.out + // .println("___ Error: SigmetCommAttrDlg: getAreaString(): " + // + e.getMessage()); } if (stateGeo != null) { diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/SnapUtil.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/SnapUtil.java index c317cbf3ab..db728ffaac 100644 --- a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/SnapUtil.java +++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/SnapUtil.java @@ -1,17 +1,26 @@ package gov.noaa.nws.ncep.viz.common; -import gov.noaa.nws.ncep.viz.common.dbQuery.NcDirectDbQuery; import gov.noaa.nws.ncep.edex.common.stationTables.Station; import gov.noaa.nws.ncep.edex.common.stationTables.StationTable; +import gov.noaa.nws.ncep.viz.common.dbQuery.NcDirectDbQuery; import gov.noaa.nws.ncep.viz.localization.NcPathManager; import gov.noaa.nws.ncep.viz.localization.NcPathManager.NcPathConstants; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + import org.geotools.referencing.GeodeticCalculator; import org.geotools.referencing.datum.DefaultEllipsoid; -import java.io.*; -import java.util.*; - import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage; import com.raytheon.uf.viz.core.exception.VizException; import com.vividsolutions.jts.geom.Coordinate; @@ -29,885 +38,991 @@ import com.vividsolutions.jts.geom.Envelope; * 03/2012 S. Gurung Fixed a bug while getting VOR text * 11/2012 873 B. Yin When snapping, check sigmet type to make sure * no space between distance and direction for CONV_SIGMET. - * + * 10/2014 TTR726 J. Wu Add "-" or " TO " at the end of vor text line. + * * * - * @author sgurung + * @author sgurung */ public class SnapUtil { - - public static List VOR_STATION_LIST; - - public static final String GFA_TEXT = new String( "GFA_TYPE" ); - - public static final String[] DIRECT_ARRAY = new String[]{ "N","NNE","NE","ENE","E","ESE","SE","SSE", - "S","SSW","SW","WSW","W","WNW","NW","NNW"}; - private static final Map compassPtsAzimuths = new HashMap(); - private static final Map compassPtsAzimuthsMinus = new HashMap(); - - /* - * Nautical miles to meters - */ - public static final float NM2M = 1852.0f; - - static{ - File stnFile = NcPathManager.getInstance().getStaticFile( - NcPathConstants.VORS_STN_TBL ); - VOR_STATION_LIST = new StationTable( stnFile.getAbsolutePath() ).getStationList(); + public static List VOR_STATION_LIST; - initCompassPtsAzimuths(); - } - - public static String getAzimuthInNSWEString(double azimuth){ - if(azimuth > -11.25 && azimuth <= 11.25) return DIRECT_ARRAY[0]; - if(azimuth > 11.25 && azimuth <= 33.75) return DIRECT_ARRAY[1]; - if(azimuth > 33.75 && azimuth <= 56.25) return DIRECT_ARRAY[2]; - if(azimuth > 56.25 && azimuth <= 78.75) return DIRECT_ARRAY[3]; - if(azimuth > 78.75 && azimuth <= 101.25) return DIRECT_ARRAY[4]; - if(azimuth > 101.25 && azimuth <= 123.75) return DIRECT_ARRAY[5]; - if(azimuth > 123.75 && azimuth <= 146.25) return DIRECT_ARRAY[6]; - if(azimuth > 146.25 && azimuth <= 168.75) return DIRECT_ARRAY[7]; - if(azimuth > 168.75 || azimuth <= -168.75) return DIRECT_ARRAY[8]; - if(azimuth > -168.75&& azimuth <= -146.25) return DIRECT_ARRAY[9]; - if(azimuth > -146.25&& azimuth <= -123.75) return DIRECT_ARRAY[10]; - if(azimuth > -123.75&& azimuth <= -101.25) return DIRECT_ARRAY[11]; - if(azimuth > -101.25&& azimuth <= -78.75) return DIRECT_ARRAY[12]; - if(azimuth > -78.75 && azimuth <= -56.25) return DIRECT_ARRAY[13]; - if(azimuth > -56.25 && azimuth <= -33.75) return DIRECT_ARRAY[14]; - else /* azimuth > -33.75&&<= -11.25 */ return DIRECT_ARRAY[15]; - } + public static final String GFA_TEXT = new String("GFA_TYPE"); - /** - * Parameters: - * - * List coors: the points to be snapped - * List stnList: (NOT USED for reference: the stations to snap upon) - * int rounding: 5nm, 10nm,... - * boolean compassPts8: true: 8-point; false: 16-point. - */ - - public static ArrayList getSnapWithStation(List coors, - List stnList, int rounding, int numOfCompassPts){ - return getSnapWithStation(coors, stnList, rounding, numOfCompassPts, true); - } + public static final String[] DIRECT_ARRAY = new String[] { "N", "NNE", + "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", + "WNW", "NW", "NNW" }; - /** - * Parameters: - * - * @param coors List the points to be snapped - * @param stnList List (NOT USED for reference: the stations to snap upon) - * @param rounding int 5nm, 10nm,... - * @param numOfCompassPts - * @param useJTS - * @return - */ - public static ArrayList getSnapWithStation(List coors, - List stnList, int rounding, int numOfCompassPts, boolean useJTS){ - -// String nonSnappingMsg = "SOME OR ALL POINTS NOT SNAPPED, ORIGINAL POINTS USED!"; - - if( ! SnapVOR.isSnappable(coors) || stnList==null) { -// SnapVOR.openMsgBox(nonSnappingMsg); - ArrayList nlist = new ArrayList(); - nlist.addAll( coors ); - return nlist; - } - - ArrayList snapPtsList = new ArrayList(); + private static final Map compassPtsAzimuths = new HashMap(); - GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); - TreeMap treeMap = new TreeMap(); - - Coordinate coor = null; - - //coor NOT actually used, keep for reference. - stnList=SnapVOR.getSnapStns(coor, numOfCompassPts); - - for(int i=0; coors!=null && i) coors; - - }else{//use pre-calculated VOR-snapping points, wrapped as Stations too. - - double distance = treeMap.firstKey(); - Station vorStn = treeMap.get(distance); - snapPtsList.add(new Coordinate(vorStn.getLongitude(),vorStn.getLatitude())); - } - - treeMap.clear(); - } - - return snapPtsList; - } - - /** - * Populates treeMap with the stations sorted by distance. - * - * @param treeMap - * @param stnList - * @param gc - * @param coor - * @param useJTS - */ - public static void populateStationsTreeMap(TreeMap treeMap, - List stnList, GeodeticCalculator gc, Coordinate coor, boolean useJTS) { - double geoDistance = Double.NaN; - for (Station stn : stnList) { - if(useJTS) { - gc.setStartingGeographicPoint(stn.getLongitude(), stn.getLatitude()); - gc.setDestinationGeographicPoint(coor.x, coor.y); - try { - geoDistance = gc.getOrthodromicDistance(); - } catch (ArithmeticException e) { - try { - geoDistance = DefaultEllipsoid.WGS84.orthodromicDistance(stn.getLongitude(), - stn.getLatitude(), coor.x, coor.y); - } catch (ArithmeticException ee) { - geoDistance = Double.NaN; - } - } - } else { - double dx = coor.x -stn.getLongitude(); - double dy = coor.y -stn.getLatitude(); - geoDistance = dx*dx + dy*dy; - } + private static final Map compassPtsAzimuthsMinus = new HashMap(); - treeMap.put(geoDistance, stn);// TODO: handle gc ArithmeticException + /* + * Nautical miles to meters + */ + public static final float NM2M = 1852.0f; - } - } - - /* - * Parameters: - * - * List coors: the points to be snapped - * List coorList: the points to snap upon in Coordinate format - * int rounding: 5nm, 10nm,... - * boolean compassPts8: true: 8-point; false: 16-point. - */ - public static ArrayList getSnapWithCoordinates(ArrayList coors, - List coorList, int rounding, int numOfCompassPts, boolean useJTS){ - - List stnList = new ArrayList(); - - for(Coordinate coor : coorList){ - Station s = new Station(); - s.setLongitude((float)coor.x); - s.setLatitude((float)coor.y); - stnList.add(s); - } - - return getSnapWithStation(coors, stnList, rounding, numOfCompassPts, useJTS); - } - - /* - * parameters: - * - * azimuth: the actual direction - * numOfCompassPts: common Compass Point: 4/8/16/32, etc; a non-regular point will be coerced into - * the closest regular one - */ - - public static double getSnapDir(double azimuth, int numOfCompassPts){ - - double[] ap = getAzimuths(numOfCompassPts, true), am = getAzimuths(numOfCompassPts,false); - TreeMap treeMap = new TreeMap(); - - if(azimuth == 0){ - return 0; - }else if(azimuth > 0){ - for(double d : ap) treeMap.put(Math.abs(d - azimuth),d); - }else{ - for(double dd : am) treeMap.put(Math.abs(dd - azimuth),dd); - } - - return treeMap.get(treeMap.firstKey()); - } - - /* - * parameters: - * - * d: the actual distance to be rounded - * rounding: 10nm, 5nm, etc - */ - - public static double getSnapDistance(double d, int rounding){ - - if(rounding <= 0) rounding = 10;//default - - int distance = (int)(d/NM2M); - int nm = distance / rounding; - double remain = distance % rounding; - if(remain >= ( ((double)rounding)/2) ) nm++; - - return rounding*nm*NM2M; - } - - private static void initCompassPtsAzimuths(){ + static { + File stnFile = NcPathManager.getInstance().getStaticFile( + NcPathConstants.VORS_STN_TBL); + VOR_STATION_LIST = new StationTable(stnFile.getAbsolutePath()) + .getStationList(); - compassPtsAzimuths.put(1, new double[]{0}); - compassPtsAzimuthsMinus.put(1, new double[]{0}); - - compassPtsAzimuths.put(2, new double[]{0,180}); - compassPtsAzimuthsMinus.put(2, new double[]{0,-180}); - - compassPtsAzimuths.put(4, new double[]{0,90,180}); - compassPtsAzimuthsMinus.put(4, new double[]{0,-90,-180}); - - compassPtsAzimuths.put(6, new double[]{0,60,120,180}); - compassPtsAzimuthsMinus.put(6, new double[]{0,-60,-120,-180}); - - compassPtsAzimuths.put(8, new double[]{0,45,90,135,180}); - compassPtsAzimuthsMinus.put(8, new double[]{0,-45,-90,-135,-180}); - - compassPtsAzimuths.put(10, new double[]{0,36,72,108,144,180}); - compassPtsAzimuthsMinus.put(10, new double[]{0,-36,-72,-108,-144,-180}); - - compassPtsAzimuths.put(12, new double[]{0,30,60,90,120,150,180}); - compassPtsAzimuthsMinus.put(12, new double[]{0,-30,-60,-90,-120,-150,-180}); - - compassPtsAzimuths.put(16, new double[]{0,22.5,45,67.5,90,112.5,135,157.5,180}); - compassPtsAzimuthsMinus.put(16, new double[]{0,-22.5,-45,-67.5,-90,-112.5,-135,-157.5,-180}); - - compassPtsAzimuths.put(18, new double[]{0,20,40,60,80,100,120,140,160,180}); - compassPtsAzimuthsMinus.put(18, new double[]{0,-20,-40,-60,-80,-100,-120,-140,-160,-180}); - - compassPtsAzimuths.put(32, - new double[]{0,11.25,22.5,33.75,45,56.25,67.5,78.75,90,101.25,112.5,123.75,135,146.25,157.5,168.75,180}); - compassPtsAzimuthsMinus.put(32, - new double[]{0,-11.25,-22.5,-33.75,-45,-56.25,-67.5,-78.75,-90,-101.25,-112.5,-123.75,-135,-146.25,-157.5,-168.75,-180}); - - } - - private static int getCompassPoint(int pts){ - - Set keys = compassPtsAzimuths.keySet(); - - if(keys.contains( pts ) ) - return pts; - - if(pts <= 0 || pts > 360) - return 8;//default; - - TreeMap map = new TreeMap(); - - for(Integer i : keys) - map.put(Math.abs(pts-i), i); - - return map.get(map.firstKey()); - } - - - public static double[] getAzimuths(int numOfCompassPts, boolean positive){ - - int key = getCompassPoint(numOfCompassPts); - - return positive - ? compassPtsAzimuths.get(key) - : compassPtsAzimuthsMinus.get(key); - } - - /** - * Creates a text from the coordinates with respect to VOR stations. - * - * @param coors - * @param vorConnector - * @param lineType - * @param numPerLines number of coordinates per line, if negative, then Integer.MAX_VALUE is used instead. - * @param isSnapped boolean if the coors have been snapped - * @return VOR text string - */ - public static String getVORText(Coordinate[] coors, String vorConnector, String lineType, int numPerLines, boolean isSnapped) { - return getVORText(coors, vorConnector, lineType, numPerLines, isSnapped, true, false ); - } - - /** - * Creates a text from the coordinates with respect to VOR stations. - * - * @param coors - * @param vorConnector - * @param lineType - * @param numPerLines number of coordinates per line, if negative, then Integer.MAX_VALUE is used instead. - * @param isSnapped boolean if the coors have been snapped - * @param useJTS boolean false to speed up the calculation (bypass the use of JTS library), true by default - * @return VOR text string - */ - public static String getVORText(Coordinate[] coors, String vorConnector, String lineType, int numPerLines, - boolean isSnapped, boolean useJTS, boolean isGfa ) { - return getVORText(coors, vorConnector, lineType, numPerLines, isSnapped, true, isGfa, null); - } - - /** - * Creates a text from the coordinates with respect to VOR stations. - * - * @param coors - * @param vorConnector - * @param lineType - * @param numPerLines number of coordinates per line, if negative, then Integer.MAX_VALUE is used instead. - * @param isSnapped boolean if the coors have been snapped - * @param useJTS boolean false to speed up the calculation (bypass teh use of JTS library), true by default - * @param sigmetType the type of sigmet - * @return VOR text string - */ - public static String getVORText(Coordinate[] coors, String vorConnector, String lineType, int numPerLines, - boolean isSnapped, boolean useJTS, boolean isGfa, String sigmetType) { - - if (lineType != null && lineType.startsWith("Line")) { - coors = reorderLineCoordinates(coors); - } else if ("Area".equals(lineType)) { - coors = reorderAreaCoordinates(coors); - } - - if( isSnapped ) - return SnapVOR.getSnapVORTxt(coors, vorConnector, lineType, useJTS, isGfa ); - - List list = VOR_STATION_LIST; - GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); - - TreeMap treeMap = new TreeMap(); - ArrayList resultList = new ArrayList(); - - for(Coordinate coor : coors){ - - populateStationsTreeMap(treeMap, list, gc, coor, useJTS); - - double distance = treeMap.firstKey(); - Station vorStn = treeMap.get(distance); - gc.setStartingGeographicPoint(vorStn.getLongitude(), vorStn.getLatitude()); - gc.setDestinationGeographicPoint(coor.x, coor.y); - - String azimuth = getAzimuthInNSWEString(gc.getAzimuth()); - - //resultList.add(new VORStation(vorStn.getStid(),azimuth,""+(int)(Math.round(distance/PgenUtil.NM2M)))); - /* - * Round distance to the nearest 10 nautical miles; - * If convective outlook and less than 30 nm, set to 0. - */ - distance = getSnapDistance(distance,10)/NM2M; - if ("OUTL_SIGMET".equals(sigmetType) && (int)distance < 30) - distance = 0; - - resultList.add(new VORStation(vorStn.getStid(),azimuth,""+(int) distance)); - treeMap.clear(); - } - - if(numPerLines < 0) numPerLines=Integer.MAX_VALUE; - - StringBuilder result = new StringBuilder(); - String first =""; - int count = 0; - for(VORStation vs : resultList) { - if ( isGfa ) { - vs.setPgenType( GFA_TEXT ); - } - else if ("CONV_SIGMET".equals(sigmetType) || "NCON_SIGMET".equals(sigmetType) || "OUTL_SIGMET".equals(sigmetType)){ - vs.setPgenType( sigmetType); - } - - if(count==0) first = vs.toString();//first vor at the end for AREA - result.append(vs.toString() + ( ((++count)%numPerLines)==0 ? "\n" : vorConnector )); - } - String resultString = "Area".equals(lineType) - ? result.append(first).toString() - : result.substring(0, result.lastIndexOf(vorConnector));; - return resultString; + initCompassPtsAzimuths(); } - /* - * This function reorders (Line) processing of points to do either west-to-east - * or north-to-south. West-to-east defined as all points within W2ELIM - * degrees of one another. - * - * @param coors the coordinates containing the lats and lons - * @return newCoors reordered coordinates - * - */ - public static Coordinate[] reorderLineCoordinates(Coordinate[] coors) { - - if (coors == null) - return coors; - - final int N2S = 0, W2E = 1; - final double W2ELIM = 0.1; - - int lineOrder = N2S; - boolean reverse = false; - double minLat, maxLat, dLat; - int numPoints = coors.length; - - minLat = coors[0].y; - maxLat = minLat; - - for ( Coordinate coor : coors ) { - minLat = Math.min(minLat, coor.y); - maxLat = Math.max(maxLat, coor.y); - } - - dLat = Math.abs(maxLat - minLat); - - if ( dLat <= W2ELIM ) - lineOrder = W2E; - - if ( lineOrder == N2S && coors[0].y < coors[numPoints -1].y ) - reverse = true; - if ( lineOrder == W2E && coors[0].x > coors[numPoints - 1].x ) - reverse = true; - - Coordinate[] newCoors = new Coordinate[numPoints]; - if ( reverse ) { - for ( int i=0; i maxLat ) { - iptr = i; - maxLat = coor.y; - } - } - - /* - * Check directions for each adjacent point; the point with - * the smallest angle from north is in the clockwise direction. - */ - if ( iptr != 0 ) - dirPrev = getDirection (coors[iptr-1], coors[iptr]); + public static String getAzimuthInNSWEString(double azimuth) { + if (azimuth > -11.25 && azimuth <= 11.25) + return DIRECT_ARRAY[0]; + if (azimuth > 11.25 && azimuth <= 33.75) + return DIRECT_ARRAY[1]; + if (azimuth > 33.75 && azimuth <= 56.25) + return DIRECT_ARRAY[2]; + if (azimuth > 56.25 && azimuth <= 78.75) + return DIRECT_ARRAY[3]; + if (azimuth > 78.75 && azimuth <= 101.25) + return DIRECT_ARRAY[4]; + if (azimuth > 101.25 && azimuth <= 123.75) + return DIRECT_ARRAY[5]; + if (azimuth > 123.75 && azimuth <= 146.25) + return DIRECT_ARRAY[6]; + if (azimuth > 146.25 && azimuth <= 168.75) + return DIRECT_ARRAY[7]; + if (azimuth > 168.75 || azimuth <= -168.75) + return DIRECT_ARRAY[8]; + if (azimuth > -168.75 && azimuth <= -146.25) + return DIRECT_ARRAY[9]; + if (azimuth > -146.25 && azimuth <= -123.75) + return DIRECT_ARRAY[10]; + if (azimuth > -123.75 && azimuth <= -101.25) + return DIRECT_ARRAY[11]; + if (azimuth > -101.25 && azimuth <= -78.75) + return DIRECT_ARRAY[12]; + if (azimuth > -78.75 && azimuth <= -56.25) + return DIRECT_ARRAY[13]; + if (azimuth > -56.25 && azimuth <= -33.75) + return DIRECT_ARRAY[14]; else - dirPrev = getDirection (coors[numPoints-1], coors[iptr]); + /* azimuth > -33.75&&<= -11.25 */return DIRECT_ARRAY[15]; + } - if ( iptr != numPoints-1 ) - dirNext = getDirection (coors[iptr+1], coors[iptr]); - else - dirNext = getDirection (coors[0], coors[iptr]); + /** + * Parameters: + * + * List coors: the points to be snapped List stnList: + * (NOT USED for reference: the stations to snap upon) int rounding: 5nm, + * 10nm,... boolean compassPts8: true: 8-point; false: 16-point. + */ + + public static ArrayList getSnapWithStation( + List coors, List stnList, int rounding, + int numOfCompassPts) { + return getSnapWithStation(coors, stnList, rounding, numOfCompassPts, + true); + } + + /** + * Parameters: + * + * @param coors + * List the points to be snapped + * @param stnList + * List (NOT USED for reference: the + * stations to snap upon) + * @param rounding + * int 5nm, 10nm,... + * @param numOfCompassPts + * @param useJTS + * @return + */ + public static ArrayList getSnapWithStation( + List coors, List stnList, int rounding, + int numOfCompassPts, boolean useJTS) { + + // String nonSnappingMsg = + // "SOME OR ALL POINTS NOT SNAPPED, ORIGINAL POINTS USED!"; + + if (!SnapVOR.isSnappable(coors) || stnList == null) { + // SnapVOR.openMsgBox(nonSnappingMsg); + ArrayList nlist = new ArrayList(); + nlist.addAll(coors); + return nlist; + } + + ArrayList snapPtsList = new ArrayList(); + + GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); + TreeMap treeMap = new TreeMap(); + + Coordinate coor = null; + + // coor NOT actually used, keep for reference. + stnList = SnapVOR.getSnapStns(coor, numOfCompassPts); + + for (int i = 0; coors != null && i < coors.size(); i++) {// keep the + // order in + // snapPtsList + coor = coors.get(i); + + populateStationsTreeMap(treeMap, stnList, gc, coor, useJTS); + + if (treeMap.isEmpty()) { + + // SnapVOR.openMsgBox(nonSnappingMsg); + return (ArrayList) coors; + + } else {// use pre-calculated VOR-snapping points, wrapped as + // Stations too. + + double distance = treeMap.firstKey(); + Station vorStn = treeMap.get(distance); + snapPtsList.add(new Coordinate(vorStn.getLongitude(), vorStn + .getLatitude())); + } + + treeMap.clear(); + } + + return snapPtsList; + } + + /** + * Populates treeMap with the stations sorted by distance. + * + * @param treeMap + * @param stnList + * @param gc + * @param coor + * @param useJTS + */ + public static void populateStationsTreeMap( + TreeMap treeMap, List stnList, + GeodeticCalculator gc, Coordinate coor, boolean useJTS) { + double geoDistance = Double.NaN; + for (Station stn : stnList) { + if (useJTS) { + gc.setStartingGeographicPoint(stn.getLongitude(), + stn.getLatitude()); + gc.setDestinationGeographicPoint(coor.x, coor.y); + try { + geoDistance = gc.getOrthodromicDistance(); + } catch (ArithmeticException e) { + try { + geoDistance = DefaultEllipsoid.WGS84 + .orthodromicDistance(stn.getLongitude(), + stn.getLatitude(), coor.x, coor.y); + } catch (ArithmeticException ee) { + geoDistance = Double.NaN; + } + } + } else { + double dx = coor.x - stn.getLongitude(); + double dy = coor.y - stn.getLatitude(); + geoDistance = dx * dx + dy * dy; + } + + treeMap.put(geoDistance, stn);// TODO: handle gc ArithmeticException + + } + } + + /* + * Parameters: + * + * List coors: the points to be snapped List + * coorList: the points to snap upon in Coordinate format int rounding: 5nm, + * 10nm,... boolean compassPts8: true: 8-point; false: 16-point. + */ + public static ArrayList getSnapWithCoordinates( + ArrayList coors, List coorList, + int rounding, int numOfCompassPts, boolean useJTS) { + + List stnList = new ArrayList(); + + for (Coordinate coor : coorList) { + Station s = new Station(); + s.setLongitude((float) coor.x); + s.setLatitude((float) coor.y); + stnList.add(s); + } + + return getSnapWithStation(coors, stnList, rounding, numOfCompassPts, + useJTS); + } + + /* + * parameters: + * + * azimuth: the actual direction numOfCompassPts: common Compass Point: + * 4/8/16/32, etc; a non-regular point will be coerced into the closest + * regular one + */ + + public static double getSnapDir(double azimuth, int numOfCompassPts) { + + double[] ap = getAzimuths(numOfCompassPts, true), am = getAzimuths( + numOfCompassPts, false); + TreeMap treeMap = new TreeMap(); + + if (azimuth == 0) { + return 0; + } else if (azimuth > 0) { + for (double d : ap) + treeMap.put(Math.abs(d - azimuth), d); + } else { + for (double dd : am) + treeMap.put(Math.abs(dd - azimuth), dd); + } + + return treeMap.get(treeMap.firstKey()); + } + + /* + * parameters: + * + * d: the actual distance to be rounded rounding: 10nm, 5nm, etc + */ + + public static double getSnapDistance(double d, int rounding) { + + if (rounding <= 0) + rounding = 10;// default + + int distance = (int) (d / NM2M); + int nm = distance / rounding; + double remain = distance % rounding; + if (remain >= (((double) rounding) / 2)) + nm++; + + return rounding * nm * NM2M; + } + + private static void initCompassPtsAzimuths() { + + compassPtsAzimuths.put(1, new double[] { 0 }); + compassPtsAzimuthsMinus.put(1, new double[] { 0 }); + + compassPtsAzimuths.put(2, new double[] { 0, 180 }); + compassPtsAzimuthsMinus.put(2, new double[] { 0, -180 }); + + compassPtsAzimuths.put(4, new double[] { 0, 90, 180 }); + compassPtsAzimuthsMinus.put(4, new double[] { 0, -90, -180 }); + + compassPtsAzimuths.put(6, new double[] { 0, 60, 120, 180 }); + compassPtsAzimuthsMinus.put(6, new double[] { 0, -60, -120, -180 }); + + compassPtsAzimuths.put(8, new double[] { 0, 45, 90, 135, 180 }); + compassPtsAzimuthsMinus + .put(8, new double[] { 0, -45, -90, -135, -180 }); + + compassPtsAzimuths.put(10, new double[] { 0, 36, 72, 108, 144, 180 }); + compassPtsAzimuthsMinus.put(10, new double[] { 0, -36, -72, -108, -144, + -180 }); + + compassPtsAzimuths.put(12, + new double[] { 0, 30, 60, 90, 120, 150, 180 }); + compassPtsAzimuthsMinus.put(12, new double[] { 0, -30, -60, -90, -120, + -150, -180 }); + + compassPtsAzimuths.put(16, new double[] { 0, 22.5, 45, 67.5, 90, 112.5, + 135, 157.5, 180 }); + compassPtsAzimuthsMinus.put(16, new double[] { 0, -22.5, -45, -67.5, + -90, -112.5, -135, -157.5, -180 }); + + compassPtsAzimuths.put(18, new double[] { 0, 20, 40, 60, 80, 100, 120, + 140, 160, 180 }); + compassPtsAzimuthsMinus.put(18, new double[] { 0, -20, -40, -60, -80, + -100, -120, -140, -160, -180 }); + + compassPtsAzimuths.put(32, new double[] { 0, 11.25, 22.5, 33.75, 45, + 56.25, 67.5, 78.75, 90, 101.25, 112.5, 123.75, 135, 146.25, + 157.5, 168.75, 180 }); + compassPtsAzimuthsMinus.put(32, new double[] { 0, -11.25, -22.5, + -33.75, -45, -56.25, -67.5, -78.75, -90, -101.25, -112.5, + -123.75, -135, -146.25, -157.5, -168.75, -180 }); + + } + + private static int getCompassPoint(int pts) { + + Set keys = compassPtsAzimuths.keySet(); + + if (keys.contains(pts)) + return pts; + + if (pts <= 0 || pts > 360) + return 8;// default; + + TreeMap map = new TreeMap(); + + for (Integer i : keys) + map.put(Math.abs(pts - i), i); + + return map.get(map.firstKey()); + } + + public static double[] getAzimuths(int numOfCompassPts, boolean positive) { + + int key = getCompassPoint(numOfCompassPts); + + return positive ? compassPtsAzimuths.get(key) : compassPtsAzimuthsMinus + .get(key); + } + + /** + * Creates a text from the coordinates with respect to VOR stations. + * + * @param coors + * @param vorConnector + * @param lineType + * @param numPerLines + * number of coordinates per line, if negative, then + * Integer.MAX_VALUE is used instead. + * @param isSnapped + * boolean if the coors have been snapped + * @return VOR text string + */ + public static String getVORText(Coordinate[] coors, String vorConnector, + String lineType, int numPerLines, boolean isSnapped) { + return getVORText(coors, vorConnector, lineType, numPerLines, + isSnapped, true, false); + } + + /** + * Creates a text from the coordinates with respect to VOR stations. + * + * @param coors + * @param vorConnector + * @param lineType + * @param numPerLines + * number of coordinates per line, if negative, then + * Integer.MAX_VALUE is used instead. + * @param isSnapped + * boolean if the coors have been snapped + * @param useJTS + * boolean false to speed up the calculation (bypass + * the use of JTS library), true by default + * @return VOR text string + */ + public static String getVORText(Coordinate[] coors, String vorConnector, + String lineType, int numPerLines, boolean isSnapped, + boolean useJTS, boolean isGfa) { + return getVORText(coors, vorConnector, lineType, numPerLines, + isSnapped, true, isGfa, null); + } + + /** + * Creates a text from the coordinates with respect to VOR stations. + * + * @param coors + * @param vorConnector + * @param lineType + * @param numPerLines + * number of coordinates per line, if negative, then + * Integer.MAX_VALUE is used instead. + * @param isSnapped + * boolean if the coors have been snapped + * @param useJTS + * boolean false to speed up the calculation (bypass + * teh use of JTS library), true by default + * @param sigmetType + * the type of sigmet + * @return VOR text string + */ + public static String getVORText(Coordinate[] coors, String vorConnector, + String lineType, int numPerLines, boolean isSnapped, + boolean useJTS, boolean isGfa, String sigmetType) { + + if (lineType != null && lineType.startsWith("Line")) { + coors = reorderLineCoordinates(coors); + } else if ("Area".equals(lineType)) { + coors = reorderAreaCoordinates(coors); + } + + if (isSnapped) + return SnapVOR.getSnapVORTxt(coors, vorConnector, lineType, useJTS, + isGfa); + + List list = VOR_STATION_LIST; + GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); + + TreeMap treeMap = new TreeMap(); + ArrayList resultList = new ArrayList(); + + for (Coordinate coor : coors) { + + populateStationsTreeMap(treeMap, list, gc, coor, useJTS); + + double distance = treeMap.firstKey(); + Station vorStn = treeMap.get(distance); + gc.setStartingGeographicPoint(vorStn.getLongitude(), + vorStn.getLatitude()); + gc.setDestinationGeographicPoint(coor.x, coor.y); + + String azimuth = getAzimuthInNSWEString(gc.getAzimuth()); + + // resultList.add(new + // VORStation(vorStn.getStid(),azimuth,""+(int)(Math.round(distance/PgenUtil.NM2M)))); + /* + * Round distance to the nearest 10 nautical miles; If convective + * outlook and less than 30 nm, set to 0. + */ + distance = getSnapDistance(distance, 10) / NM2M; + if ("OUTL_SIGMET".equals(sigmetType) && (int) distance < 30) + distance = 0; + + resultList.add(new VORStation(vorStn.getStid(), azimuth, "" + + (int) distance)); + treeMap.clear(); + } + + if (numPerLines < 0) + numPerLines = Integer.MAX_VALUE; + + StringBuilder result = new StringBuilder(); + String first = ""; + int count = 0; + for (VORStation vs : resultList) { + if (isGfa) { + vs.setPgenType(GFA_TEXT); + } else if ("CONV_SIGMET".equals(sigmetType) + || "NCON_SIGMET".equals(sigmetType) + || "OUTL_SIGMET".equals(sigmetType)) { + vs.setPgenType(sigmetType); + } + + if (count == 0) + first = vs.toString();// first vor at the end for AREA + // TTR 726 (10/2014): still need a vorConnect at the end of line. + result.append(vs.toString() + + (((++count) % numPerLines) == 0 ? (vorConnector + "\n") + : vorConnector)); + } + String resultString = "Area".equals(lineType) ? result.append(first) + .toString() : result.substring(0, + result.lastIndexOf(vorConnector)); + ; + return resultString; + } + + /* + * This function reorders (Line) processing of points to do either + * west-to-east or north-to-south. West-to-east defined as all points within + * W2ELIM degrees of one another. + * + * @param coors the coordinates containing the lats and lons + * + * @return newCoors reordered coordinates + */ + public static Coordinate[] reorderLineCoordinates(Coordinate[] coors) { + + if (coors == null) + return coors; + + final int N2S = 0, W2E = 1; + final double W2ELIM = 0.1; + + int lineOrder = N2S; + boolean reverse = false; + double minLat, maxLat, dLat; + int numPoints = coors.length; + + minLat = coors[0].y; + maxLat = minLat; + + for (Coordinate coor : coors) { + minLat = Math.min(minLat, coor.y); + maxLat = Math.max(maxLat, coor.y); + } + + dLat = Math.abs(maxLat - minLat); + + if (dLat <= W2ELIM) + lineOrder = W2E; + + if (lineOrder == N2S && coors[0].y < coors[numPoints - 1].y) + reverse = true; + if (lineOrder == W2E && coors[0].x > coors[numPoints - 1].x) + reverse = true; Coordinate[] newCoors = new Coordinate[numPoints]; - - if ( dirNext < dirPrev ) { - i = 0; - for ( j = iptr; j < numPoints; j++ ) { - newCoors[i] = coors[j]; - i++; - } - for ( j = 0; j < iptr; j++ ) { - newCoors[i] = coors[j]; - i++; - } + if (reverse) { + for (int i = 0; i < numPoints; i++) { + newCoors[i] = coors[numPoints - 1 - i]; + } + } else { + newCoors = coors; } - else { - i = 0; - for ( j = iptr; j >= 0; j-- ) { - newCoors[i] = coors[j]; - i++; - } - for ( j = numPoints-1; j > iptr; j-- ) { - newCoors[i] = coors[j]; - i++; - } - } - + return newCoors; - } - - /* - * This function figures out the direction from point 1 to point 2. - * - * @param coor1 coordinates for point 1 - * @param coor2 coordinates for point 2 - * @return dir direction from point 1 to point 2 - * - */ - public static double getDirection(Coordinate coor1, Coordinate coor2) { - - final double PI = 3.14159265, - HALFPI = PI / 2.0, - RTD = 180.0 / PI, - DTR = PI / 180.0; - - double lat1d, lat2d, lon1d = 0.0,lon2d = 0.0; - double dir, dLon, theta, alpha, val, tang; - - lat1d = (double) coor1.y * DTR; - lat2d = (double) coor2.y * DTR; - - if (Math.abs(coor1.x - coor2.x) < 180.0F) { - lon1d = ((double) (coor1.x + 360.0) % 360.0) * DTR; - lon2d = ((double) (coor2.x + 360.0) % 360.0) * DTR; - } - - dLon = lon1d - lon2d; - - if (Math.abs(lat2d - HALFPI) < 0.000001) { - dir = 180.0F; - } - else if (Math.abs(-lat2d - HALFPI) < 0.000001) { - dir = 0.0F; - } - else { - val = (double)( Math.sin(lat1d) * Math.sin(lat2d) + - Math.cos(lat1d) * Math.cos(lat2d) * Math.cos(dLon) ); - - if ( -1.0 <= val && val <= 1.0 ) { - theta = Math.acos(val); - - if (Math.abs(theta - 0.0) < 0.000001) { - dir = 0.0F; - } - else { - tang = ( Math.sin(lat1d) - Math.sin(lat2d) * Math.cos(theta) ) / - ( Math.cos(lat2d) * Math.sin(theta) ); - tang = Math.min( tang, 1.0 ); - tang = Math.max( tang, -1.0 ); - alpha = Math.acos( tang ); - - dir = (float)(alpha*RTD); - if ( dLon < 0.0 ) dir = 360.0 - dir; - } - } - else { - dir = 0.0; - } - } - - return dir; - } - - public static class VORStation extends Station{ - String name; - String azimuth; - String distance; - String pgenType=""; - - VORStation(String n,String z, String d){name=n;azimuth=z;distance=d;} - public void setPgenType(String pt){ this.pgenType = pt;} - - public String toString() { - if ("0".equals(distance)) { - return name; - } - - if("CONV_SIGMET".equalsIgnoreCase(pgenType) || - "NCON_SIGMET".equalsIgnoreCase(pgenType) || - "OUTL_SIGMET".equalsIgnoreCase(pgenType) ){ - return distance + azimuth + " " + name; - } - //For GFA - should be (30NNW LGC"), not "30 NNW LGC" - else if ( GFA_TEXT.equalsIgnoreCase( pgenType ) ){ - return distance + azimuth + " " + name; - } - - return distance + " " + azimuth + " " + name; - } } - - /** - * class for the Snapping to pre-calculated VOR points. - * - * @author gzhang - * - */ - public static class SnapVOR{ - - //query string parts - private static final String dbTable = "stns.snap";//"stns.snap_8"; - private static final String nameField = "station_name"; - private static final String latField = "latitude"; - private static final String lonField = "longitude"; - - //for snapped point-to-vor lookup - public static final Map coorStnMap = new HashMap(); - //envelops cannot cover all corner cases - private static List stnList = new ArrayList(); - - static{ - initSnapData(); - stnList.addAll(coorStnMap.values()); - } - - /** - * load the pre-calculted snapping VOR stations - * from the DB - * @return - */ - public static void initSnapData(){ - List allBounds = null; - StringBuilder query = new StringBuilder(); - - query.append( - "Select " - +nameField - + " , " - +latField - + " , " - +lonField - + " FROM " - + dbTable); - - try { - allBounds = NcDirectDbQuery.executeQuery( - query.toString(), "ncep", QueryLanguage.SQL); - }catch (VizException ve ){ - ve.printStackTrace(); - }catch (Throwable te){ - System.out.println("ERROR: "+te.getMessage()); - } - - if(allBounds == null || allBounds.size() == 0){ - System.out.println("*** Error loading data! "); - return; - } - - for(Object[] obs : allBounds){ - if(obs == null || obs.length < 3){ - continue; - } - - String n = (String)obs[0]; - if(n == null){ - n = ""; - }else{ - if(n.contains("_")){ - n = n.substring(n.indexOf("_")+1); - } - } - - String azimuth = getVORNameDirDist((String)obs[0])[1]; - - if(azimuth != null){ - - VORStation stn = new VORStation( - getVORNameDirDist((String)obs[0])[0], - azimuth, - getVORNameDirDist((String)obs[0])[2]); - - stn.setLatitude(((Double)obs[1]).floatValue()); - stn.setLongitude(((Double)obs[2]).floatValue()); - - Coordinate nCoor = new Coordinate( ((Double)obs[2]).floatValue(),((Double)obs[1]).floatValue()); - - coorStnMap.put(nCoor, stn); - } - } - } - - /** - * parse the stn name to get name, dir, dist - * - * @param String: station_name field from the snap table in ncep DB; - * @return String[]: elements: name,azimuth,distance; - */ - private static String[] getVORNameDirDist(String n){ - String[] ndd = null; - - if(n == null){ - ndd = new String[]{"","",""}; - }else{ - if(n.contains("_")){// i.e. 20N_YSJ - String name = n.substring(n.indexOf("_")+1); - - String dirDist = n.substring(0,n.indexOf("_")); - char[] c = dirDist.toCharArray(); - int dirIndex = -1; - for(int i=0; i 0 && dirIndex < n.indexOf("_")){ - dist = n.substring(0, dirIndex); - dir = n.substring(dirIndex, n.indexOf("_")); - } - - ndd = new String[]{name, dir, dist }; - - }else{//i.e. YSJ - ndd = new String[]{n,"","" }; - } - } - - return ndd; - } - - /** - * check the coordinate to get snap stations. - * @param stn: NOT USED (for Envlope:coordinate to be checked) - * @param numOfCompassPts: 8, 16,etc - * @return List all the snapping point stations - */ - public static List getSnapStns(Coordinate stn, int numOfCompassPts){ - - if(numOfCompassPts == 16) - return stnList; - - List list = stnList; - List list8 = null; - - /* - * list8 calculated for space consummation consideration - */ - if(numOfCompassPts == 8){ - list8 = new ArrayList(); - for( Station s : list){ - String a = ((VORStation)s).azimuth; - if( a != null && a.length() < 3 ){ - list8.add(s); - } - } - return list8; - } - - //being defensive - return new ArrayList(); - } - - /** - * Write out snap points location in the format of a "lpi" file to be - * loaded as an overlay. - * - * @param filename file to be written into - */ - public static void writeSnapStations ( String filename ){ - - Writer output = null; - File file = new File( "/export/cdbsrv/jwu/workbak/pgen/snaps.txt" ); - try { - FileWriter fw = new FileWriter( file ); - output = new BufferedWriter( fw ); + /* + * This function reorders a closed polygon into a clockwise fashion and the + * first point is the northernmost point. + * + * @param coors the coordinates containing the lats and lons + * + * @return newCoors reordered coordinates + */ + public static Coordinate[] reorderAreaCoordinates(Coordinate[] coors) { - for( Station s : stnList ){ - - String c = new String( ((VORStation)s).getLatitude() + "\t" + - ((VORStation)s).getLongitude() + "\t\t160\t\tnull\n" ); - output.write( c ); - } - - output.close(); - - } - catch ( IOException e ) { - e.printStackTrace(); - } - - } + if (coors == null) + return coors; - /** - * return the snapped VOR stations texts - * @param Coordinate[]: snapped points - * @param connector: "-" or " TO " - * @param lineType: Area or Line:ESOL - * @return String: VOR text - */ - public static String getSnapVORTxt(Coordinate[] coors, String connector, String lineType, boolean useJts, - boolean isGfa ){ - String txt = ""; - String pgenType = "-".equals(connector) ? "CONV_SIGMET" : "";//2010-05-14 work around TODO: - - StringBuilder sb = new StringBuilder(); - - for(int i=0; i coors){ - - if( coors == null || coors.size() == 0) - return false; - - boolean snappable = true; - - /* - * check if the points located inside one of - * the three envelopes: - * continental US, Alask, and Hawaii. - */ - Envelope envContUS = new Envelope(-130,-60,20,55); - //Envelope envAK = new Envelope(180, -130, 45,75);//double check - //Envelope envHA = new Envelope(-165,-150,15,27); //double check - - for(Coordinate c : coors){ - if( ! envContUS.contains(c)){// && ! envAK.contains(c) && ! envHA.contains(c) ){ - snappable = false; - break; - } - } - return snappable; - } - - } + int numPoints = coors.length; + int iptr = 0, i, j; + double maxLat, dirNext, dirPrev; - public static Coordinate getNorthMostPoint(Coordinate[] coors){ - if(coors == null || coors.length == 0) return new Coordinate();// or null? - - TreeMap map = new TreeMap(); - - for(Coordinate coor : coors) map.put(coor.y, coor); - - return map.get(map.lastKey()); - } + /* + * Re-order processing of points to do northernmost first and proceed + * clockwise. + */ + maxLat = -90.0; + for (i = 0; i < numPoints; i++) { + Coordinate coor = coors[i]; + if (coor.y > maxLat) { + iptr = i; + maxLat = coor.y; + } + } + + /* + * Check directions for each adjacent point; the point with the smallest + * angle from north is in the clockwise direction. + */ + if (iptr != 0) + dirPrev = getDirection(coors[iptr - 1], coors[iptr]); + else + dirPrev = getDirection(coors[numPoints - 1], coors[iptr]); + + if (iptr != numPoints - 1) + dirNext = getDirection(coors[iptr + 1], coors[iptr]); + else + dirNext = getDirection(coors[0], coors[iptr]); + + Coordinate[] newCoors = new Coordinate[numPoints]; + + if (dirNext < dirPrev) { + i = 0; + for (j = iptr; j < numPoints; j++) { + newCoors[i] = coors[j]; + i++; + } + for (j = 0; j < iptr; j++) { + newCoors[i] = coors[j]; + i++; + } + } else { + i = 0; + for (j = iptr; j >= 0; j--) { + newCoors[i] = coors[j]; + i++; + } + for (j = numPoints - 1; j > iptr; j--) { + newCoors[i] = coors[j]; + i++; + } + } + + return newCoors; + } + + /* + * This function figures out the direction from point 1 to point 2. + * + * @param coor1 coordinates for point 1 + * + * @param coor2 coordinates for point 2 + * + * @return dir direction from point 1 to point 2 + */ + public static double getDirection(Coordinate coor1, Coordinate coor2) { + + final double PI = 3.14159265, HALFPI = PI / 2.0, RTD = 180.0 / PI, DTR = PI / 180.0; + + double lat1d, lat2d, lon1d = 0.0, lon2d = 0.0; + double dir, dLon, theta, alpha, val, tang; + + lat1d = (double) coor1.y * DTR; + lat2d = (double) coor2.y * DTR; + + if (Math.abs(coor1.x - coor2.x) < 180.0F) { + lon1d = ((double) (coor1.x + 360.0) % 360.0) * DTR; + lon2d = ((double) (coor2.x + 360.0) % 360.0) * DTR; + } + + dLon = lon1d - lon2d; + + if (Math.abs(lat2d - HALFPI) < 0.000001) { + dir = 180.0F; + } else if (Math.abs(-lat2d - HALFPI) < 0.000001) { + dir = 0.0F; + } else { + val = (double) (Math.sin(lat1d) * Math.sin(lat2d) + Math.cos(lat1d) + * Math.cos(lat2d) * Math.cos(dLon)); + + if (-1.0 <= val && val <= 1.0) { + theta = Math.acos(val); + + if (Math.abs(theta - 0.0) < 0.000001) { + dir = 0.0F; + } else { + tang = (Math.sin(lat1d) - Math.sin(lat2d) * Math.cos(theta)) + / (Math.cos(lat2d) * Math.sin(theta)); + tang = Math.min(tang, 1.0); + tang = Math.max(tang, -1.0); + alpha = Math.acos(tang); + + dir = (float) (alpha * RTD); + if (dLon < 0.0) + dir = 360.0 - dir; + } + } else { + dir = 0.0; + } + } + + return dir; + } + + public static class VORStation extends Station { + String name; + + String azimuth; + + String distance; + + String pgenType = ""; + + VORStation(String n, String z, String d) { + name = n; + azimuth = z; + distance = d; + } + + public void setPgenType(String pt) { + this.pgenType = pt; + } + + public String toString() { + if ("0".equals(distance)) { + return name; + } + + if ("CONV_SIGMET".equalsIgnoreCase(pgenType) + || "NCON_SIGMET".equalsIgnoreCase(pgenType) + || "OUTL_SIGMET".equalsIgnoreCase(pgenType)) { + return distance + azimuth + " " + name; + } + // For GFA - should be (30NNW LGC"), not "30 NNW LGC" + else if (GFA_TEXT.equalsIgnoreCase(pgenType)) { + return distance + azimuth + " " + name; + } + + return distance + " " + azimuth + " " + name; + } + } + + /** + * class for the Snapping to pre-calculated VOR points. + * + * @author gzhang + * + */ + public static class SnapVOR { + + // query string parts + private static final String dbTable = "stns.snap";// "stns.snap_8"; + + private static final String nameField = "station_name"; + + private static final String latField = "latitude"; + + private static final String lonField = "longitude"; + + // for snapped point-to-vor lookup + public static final Map coorStnMap = new HashMap(); + + // envelops cannot cover all corner cases + private static List stnList = new ArrayList(); + + static { + initSnapData(); + stnList.addAll(coorStnMap.values()); + } + + /** + * load the pre-calculted snapping VOR stations from the DB + * + * @return + */ + public static void initSnapData() { + List allBounds = null; + StringBuilder query = new StringBuilder(); + + query.append("Select " + nameField + " , " + latField + " , " + + lonField + " FROM " + dbTable); + + try { + allBounds = NcDirectDbQuery.executeQuery(query.toString(), + "ncep", QueryLanguage.SQL); + } catch (VizException ve) { + ve.printStackTrace(); + } catch (Throwable te) { + System.out.println("ERROR: " + te.getMessage()); + } + + if (allBounds == null || allBounds.size() == 0) { + System.out.println("*** Error loading data! "); + return; + } + + for (Object[] obs : allBounds) { + if (obs == null || obs.length < 3) { + continue; + } + + String n = (String) obs[0]; + if (n == null) { + n = ""; + } else { + if (n.contains("_")) { + n = n.substring(n.indexOf("_") + 1); + } + } + + String azimuth = getVORNameDirDist((String) obs[0])[1]; + + if (azimuth != null) { + + VORStation stn = new VORStation( + getVORNameDirDist((String) obs[0])[0], azimuth, + getVORNameDirDist((String) obs[0])[2]); + + stn.setLatitude(((Double) obs[1]).floatValue()); + stn.setLongitude(((Double) obs[2]).floatValue()); + + Coordinate nCoor = new Coordinate( + ((Double) obs[2]).floatValue(), + ((Double) obs[1]).floatValue()); + + coorStnMap.put(nCoor, stn); + } + } + } + + /** + * parse the stn name to get name, dir, dist + * + * @param String + * : station_name field from the snap table in ncep DB; + * @return String[]: elements: name,azimuth,distance; + */ + private static String[] getVORNameDirDist(String n) { + String[] ndd = null; + + if (n == null) { + ndd = new String[] { "", "", "" }; + } else { + if (n.contains("_")) {// i.e. 20N_YSJ + String name = n.substring(n.indexOf("_") + 1); + + String dirDist = n.substring(0, n.indexOf("_")); + char[] c = dirDist.toCharArray(); + int dirIndex = -1; + for (int i = 0; i < c.length; i++) { + if (c[i] == 'N' || c[i] == 'E' || c[i] == 'S' + || c[i] == 'W') { + dirIndex = i; + break; + } + } + + String dist = "";// n.contains("0") ? n.substring(0, + // n.indexOf("0")+1) : ""; + String dir = "";// n.substring(n.indexOf("0")+1, + // n.indexOf("_")); + + if (dirIndex > 0 && dirIndex < n.indexOf("_")) { + dist = n.substring(0, dirIndex); + dir = n.substring(dirIndex, n.indexOf("_")); + } + + ndd = new String[] { name, dir, dist }; + + } else {// i.e. YSJ + ndd = new String[] { n, "", "" }; + } + } + + return ndd; + } + + /** + * check the coordinate to get snap stations. + * + * @param stn + * : NOT USED (for Envlope:coordinate to be checked) + * @param numOfCompassPts + * : 8, 16,etc + * @return List all the snapping point stations + */ + public static List getSnapStns(Coordinate stn, + int numOfCompassPts) { + + if (numOfCompassPts == 16) + return stnList; + + List list = stnList; + List list8 = null; + + /* + * list8 calculated for space consummation consideration + */ + if (numOfCompassPts == 8) { + list8 = new ArrayList(); + for (Station s : list) { + String a = ((VORStation) s).azimuth; + if (a != null && a.length() < 3) { + list8.add(s); + } + } + return list8; + } + + // being defensive + return new ArrayList(); + } + + /** + * Write out snap points location in the format of a "lpi" file to be + * loaded as an overlay. + * + * @param filename + * file to be written into + */ + public static void writeSnapStations(String filename) { + + Writer output = null; + File file = new File("/export/cdbsrv/jwu/workbak/pgen/snaps.txt"); + try { + FileWriter fw = new FileWriter(file); + output = new BufferedWriter(fw); + + for (Station s : stnList) { + + String c = new String(((VORStation) s).getLatitude() + "\t" + + ((VORStation) s).getLongitude() + + "\t\t160\t\tnull\n"); + output.write(c); + } + + output.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + /** + * return the snapped VOR stations texts + * + * @param Coordinate + * []: snapped points + * @param connector + * : "-" or " TO " + * @param lineType + * : Area or Line:ESOL + * @return String: VOR text + */ + public static String getSnapVORTxt(Coordinate[] coors, + String connector, String lineType, boolean useJts, boolean isGfa) { + String txt = ""; + String pgenType = "-".equals(connector) ? "CONV_SIGMET" : "";// 2010-05-14 + // work + // around + // TODO: + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < coors.length; i++) { + VORStation vStn = coorStnMap.get(coors[i]);// TODO: + // getVORStn(Coordinate + // stn, int + // numOfCompassPts) + + // for out of range of VOR stations elements + if (vStn == null) { + return getVORText(coors, connector, lineType, 6, false, + useJts, isGfa); + } + + vStn.setPgenType(pgenType);// for getting different string + // formatting + if (isGfa) { + vStn.setPgenType(GFA_TEXT); + } + sb.append(vStn.toString().trim());// TODO: text format + // differences + sb.append(connector); + } + if ("Area".equals(lineType)) { + txt = sb.append(sb.substring(0, sb.indexOf(connector))) + .toString(); + } else { + txt = sb.toString().substring(0, sb.lastIndexOf(connector)); + } + + return txt; + } + + /** + * check if the points within reasonable(250NM) snapping range. + * + * @param coors + * : points to be checked + * @return: true snappable; false otherwise. + */ + public static boolean isSnappable(List coors) { + + if (coors == null || coors.size() == 0) + return false; + + boolean snappable = true; + + /* + * check if the points located inside one of the three envelopes: + * continental US, Alask, and Hawaii. + */ + Envelope envContUS = new Envelope(-130, -60, 20, 55); + // Envelope envAK = new Envelope(180, -130, 45,75);//double check + // Envelope envHA = new Envelope(-165,-150,15,27); //double check + + for (Coordinate c : coors) { + if (!envContUS.contains(c)) {// && ! envAK.contains(c) && ! + // envHA.contains(c) ){ + snappable = false; + break; + } + } + return snappable; + } + + } + + public static Coordinate getNorthMostPoint(Coordinate[] coors) { + if (coors == null || coors.length == 0) + return new Coordinate();// or null? + + TreeMap map = new TreeMap(); + + for (Coordinate coor : coors) + map.put(coor.y, coor); + + return map.get(map.lastKey()); + } } From 3adfb23074c4bf5b2acc5c381f575488196e8d43 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Fri, 21 Nov 2014 10:34:29 -0500 Subject: [PATCH 15/19] VLab Issue #4078 - Adding RD for Day/Night Terminator Overlay Change-Id: I2859c9193b69a6cab19256e93a59541a7c4f4e9f Former-commit-id: c8f2b8e3bf38d545f532ef153d89d0b9fd8bc65f [formerly c8f2b8e3bf38d545f532ef153d89d0b9fd8bc65f [formerly 713f097be6a0ced7a0b4e5fa45e12083be8faeec]] Former-commit-id: 54e40962af50ecfbb647484fe17d1e4d42cee2e4 Former-commit-id: 35a6d9ae6b4153b64a194931b784b00700c0c84f --- .../DayNightTerminator/DayNightTerminator.xml | 15 +++++++++++++++ .../OVERLAYS/DayNightTerminator/default.attr | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/DayNightTerminator.xml create mode 100644 ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/default.attr diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/DayNightTerminator.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/DayNightTerminator.xml new file mode 100644 index 0000000000..a356739dee --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/DayNightTerminator.xml @@ -0,0 +1,15 @@ + + + DayNightTerminator + OVERLAY + + DayNightTerminatorOverlay + + + CLOSEST_BEFORE_OR_AFTER + 0 + USE_DATA_TIMES + 10 + 24 + BasicWX_US + diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/default.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/default.attr new file mode 100644 index 0000000000..36039dc4bf --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/OVERLAYS/DayNightTerminator/default.attr @@ -0,0 +1,17 @@ +termLineColor=RGB {0, 0, 255} +termLineWidth=1 +termLineStyle=SOLID +displaySun=true +sunMarkerColor=RGB {255, 165, 79} +sunMarkerType=ASTERISK +sunMarkerSize=1.3 +sunMarkerWidth=2 +displayMidnightMeridian=true +midnightMeridianLineColor=RGB {127, 127, 127} +midnightMeridianLineWidth=1 +midnightMeridianLineStyle=SHORT_DASHED +applyShading=false +shadeAlpha=0.5 +shadePattern=SOLID +dayShadeColor=RGB {255, 165, 0} +nightShadeColor=RGB {30, 30, 163} \ No newline at end of file From 82c1af1da1092d94892f936c72711492d519907f Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Tue, 25 Nov 2014 10:59:01 -0500 Subject: [PATCH 16/19] VLab Issue #5156 - Change Text display in NCP Point Data station model Change-Id: Ib33c90ac5d113ade34f3c25822685220771c570e Former-commit-id: d539f7092d66995b61791b903c261bbdc9913da8 [formerly d539f7092d66995b61791b903c261bbdc9913da8 [formerly b130dce1753c3ff691405e2edafcded8a511df59]] Former-commit-id: d38edc9cf61b33992d3543355216760ddc07974e Former-commit-id: 4d0a203b4f3bd7d1187fac5d727020bd9a8c96d3 --- .../plotModels/NcPlotImageCreator.java | 185 ++++++----- .../plotdata/rsc/EditPlotModelComposite.java | 291 ++++++++++++------ 2 files changed, 302 insertions(+), 174 deletions(-) diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java index 09c26cf75c..01c8bcb991 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/plotModels/NcPlotImageCreator.java @@ -56,6 +56,7 @@ import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IFont.Style; import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.jobs.JobPool; @@ -79,7 +80,9 @@ import com.vividsolutions.jts.geom.Coordinate; * 06/17/2014 923 S. Russell altered method setUpSymbolMappingTables() * 06/17/2014 923 S. Russell altered method createRenderableData() * 07/08/2014 TTR1027 B. Hebbard Force createRenderableData to recreate wind vectors each time. - * 09/10/2014 Redmine 4230 S. Russell Fix wind barb/brbk menu option in plot model dialog box + * 09/10/2014 Redmine 4230 S. Russell Fix wind barb/brbk menu option in plot model dialog box + * 11/03/2014 Redmine 5156 B. Hebbard Allow use of system fonts in addition to file-based 3 + * 11/06/2014 Redmine 5156 B. Hebbard Rename Helvetica & Times lookalike fonts/files to make clear they aren't Java/AWT logical SansSerif & Serif */ public class NcPlotImageCreator { @@ -162,42 +165,42 @@ public class NcPlotImageCreator { .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "cour.pfa"); - private static final File SERIF_NORMAL_FONT_FILE = NcPathManager + private static final File TIMES_LIKE_NORMAL_FONT_FILE = NcPathManager .getInstance() .getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "VeraSe.ttf"); - private static final File SERIF_BOLD_FONT_FILE = NcPathManager + private static final File TIMES_LIKE_BOLD_FONT_FILE = NcPathManager .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "l049016t.pfa"); - private static final File SERIF_ITALIC_FONT_FILE = NcPathManager + private static final File TIMES_LIKE_ITALIC_FONT_FILE = NcPathManager .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "l049033t.pfa"); - private static final File SERIF_BOLD_ITALIC_FONT_FILE = NcPathManager + private static final File TIMES_LIKE_BOLD_ITALIC_FONT_FILE = NcPathManager .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "l049036t.pfa"); - private static final File SANS_SERIF_NORMAL_FONT_FILE = NcPathManager + private static final File HELVETICA_LIKE_NORMAL_FONT_FILE = NcPathManager .getInstance() .getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "luxisr.ttf"); - private static final File SANS_SERIF_ITALIC_FONT_FILE = NcPathManager + private static final File HELVETICA_LIKE_ITALIC_FONT_FILE = NcPathManager .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "luxisri.ttf"); - private static final File SANS_SERIF_BOLD_FONT_FILE = NcPathManager + private static final File HELVETICA_LIKE_BOLD_FONT_FILE = NcPathManager .getInstance() .getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "luxisb.ttf"); - private static final File SANS_SERIF_BOLD_ITALIC_FONT_FILE = NcPathManager + private static final File HELVETICA_LIKE_BOLD_ITALIC_FONT_FILE = NcPathManager .getInstance().getStaticFile( NcPathManager.NcPathConstants.FONT_FILES_DIR + "luxisbi.ttf"); @@ -210,21 +213,21 @@ public class NcPlotImageCreator { private static IFont COURIER_BOLD_ITALIC_FONT = null; - private static IFont SERIF_BOLD_ITALIC_FONT = null; + private static IFont TIMES_LIKE_BOLD_ITALIC_FONT = null; - private static IFont SANS_SERIF_BOLD_ITALIC_FONT = null; + private static IFont HELVETICA_LIKE_BOLD_ITALIC_FONT = null; - private static IFont SERIF_BOLD_FONT = null; + private static IFont TIMES_LIKE_BOLD_FONT = null; - private static IFont SANS_SERIF_BOLD_FONT = null; + private static IFont HELVETICA_LIKE_BOLD_FONT = null; - private static IFont SERIF_ITALIC_FONT = null; + private static IFont TIMES_LIKE_ITALIC_FONT = null; - private static IFont SANS_SERIF_ITALIC_FONT = null; + private static IFont HELVETICA_LIKE_ITALIC_FONT = null; - private static IFont SERIF_NORMAL_FONT = null; + private static IFont TIMES_LIKE_NORMAL_FONT = null; - private static IFont SANS_SERIF_NORMAL_FONT = null; + private static IFont HELVETICA_LIKE_NORMAL_FONT = null; private RGB defaultColor; @@ -348,31 +351,32 @@ public class NcPlotImageCreator { COURIER_NORMAL_FONT = target.initializeFont(COURIER_NORMAL_FONT_FILE, IFont.FontType.TYPE1, initialFontSize, null); - SERIF_BOLD_FONT = target.initializeFont(SERIF_BOLD_FONT_FILE, + TIMES_LIKE_BOLD_FONT = target.initializeFont(TIMES_LIKE_BOLD_FONT_FILE, IFont.FontType.TYPE1, initialFontSize, new IFont.Style[] { IFont.Style.BOLD }); - SERIF_BOLD_ITALIC_FONT = target.initializeFont( - SERIF_BOLD_ITALIC_FONT_FILE, IFont.FontType.TYPE1, + TIMES_LIKE_BOLD_ITALIC_FONT = target.initializeFont( + TIMES_LIKE_BOLD_ITALIC_FONT_FILE, IFont.FontType.TYPE1, initialFontSize, new IFont.Style[] { IFont.Style.BOLD, IFont.Style.ITALIC }); - SERIF_ITALIC_FONT = target.initializeFont(SERIF_ITALIC_FONT_FILE, - IFont.FontType.TYPE1, initialFontSize, - new IFont.Style[] { IFont.Style.ITALIC }); - SERIF_NORMAL_FONT = target.initializeFont(SERIF_NORMAL_FONT_FILE, - IFont.FontType.TRUETYPE, initialFontSize, null); - - SANS_SERIF_BOLD_FONT = target.initializeFont(SANS_SERIF_BOLD_FONT_FILE, - IFont.FontType.TRUETYPE, initialFontSize, - new IFont.Style[] { IFont.Style.BOLD }); - SANS_SERIF_BOLD_ITALIC_FONT = target.initializeFont( - SANS_SERIF_BOLD_ITALIC_FONT_FILE, IFont.FontType.TRUETYPE, - initialFontSize, new IFont.Style[] { IFont.Style.BOLD, - IFont.Style.ITALIC }); - SANS_SERIF_ITALIC_FONT = target.initializeFont( - SANS_SERIF_ITALIC_FONT_FILE, IFont.FontType.TRUETYPE, + TIMES_LIKE_ITALIC_FONT = target.initializeFont( + TIMES_LIKE_ITALIC_FONT_FILE, IFont.FontType.TYPE1, initialFontSize, new IFont.Style[] { IFont.Style.ITALIC }); - SANS_SERIF_NORMAL_FONT = target.initializeFont( - SANS_SERIF_NORMAL_FONT_FILE, IFont.FontType.TRUETYPE, + TIMES_LIKE_NORMAL_FONT = target.initializeFont( + TIMES_LIKE_NORMAL_FONT_FILE, IFont.FontType.TRUETYPE, + initialFontSize, null); + + HELVETICA_LIKE_BOLD_FONT = target.initializeFont( + HELVETICA_LIKE_BOLD_FONT_FILE, IFont.FontType.TRUETYPE, + initialFontSize, new IFont.Style[] { IFont.Style.BOLD }); + HELVETICA_LIKE_BOLD_ITALIC_FONT = target.initializeFont( + HELVETICA_LIKE_BOLD_ITALIC_FONT_FILE, IFont.FontType.TRUETYPE, + initialFontSize, new IFont.Style[] { IFont.Style.BOLD, + IFont.Style.ITALIC }); + HELVETICA_LIKE_ITALIC_FONT = target.initializeFont( + HELVETICA_LIKE_ITALIC_FONT_FILE, IFont.FontType.TRUETYPE, + initialFontSize, new IFont.Style[] { IFont.Style.ITALIC }); + HELVETICA_LIKE_NORMAL_FONT = target.initializeFont( + HELVETICA_LIKE_NORMAL_FONT_FILE, IFont.FontType.TRUETYPE, initialFontSize, null); Tracer.print("< Exit"); } @@ -513,7 +517,6 @@ public class NcPlotImageCreator { pme.setPosition("WD"); } - // Redmine 4230 // NcPlotImageCreator will not process BRBK unless it has // the abstract ( not on thcae grid of plot model buttons ) @@ -641,12 +644,15 @@ public class NcPlotImageCreator { if (COURIER_BOLD_FONT == null || COURIER_ITALIC_FONT == null || COURIER_NORMAL_FONT == null - || COURIER_BOLD_ITALIC_FONT == null || SERIF_BOLD_FONT == null - || SERIF_ITALIC_FONT == null || SERIF_BOLD_ITALIC_FONT == null - || SERIF_NORMAL_FONT == null || SANS_SERIF_ITALIC_FONT == null - || SANS_SERIF_BOLD_ITALIC_FONT == null - || SANS_SERIF_NORMAL_FONT == null - || SANS_SERIF_BOLD_FONT == null) { + || COURIER_BOLD_ITALIC_FONT == null + || TIMES_LIKE_BOLD_FONT == null + || TIMES_LIKE_ITALIC_FONT == null + || TIMES_LIKE_BOLD_ITALIC_FONT == null + || TIMES_LIKE_NORMAL_FONT == null + || HELVETICA_LIKE_ITALIC_FONT == null + || HELVETICA_LIKE_BOLD_ITALIC_FONT == null + || HELVETICA_LIKE_NORMAL_FONT == null + || HELVETICA_LIKE_BOLD_FONT == null) { initializeFonts(); } @@ -664,33 +670,58 @@ public class NcPlotImageCreator { else if (fontName.compareTo("Times") == 0) { if (fontStyle.compareTo("Bold") == 0) { - font = SERIF_BOLD_FONT; + font = TIMES_LIKE_BOLD_FONT; } else if (fontStyle.compareTo("Italic") == 0) { - font = SERIF_ITALIC_FONT; + font = TIMES_LIKE_ITALIC_FONT; } else if (fontStyle.compareTo("Bold-Italic") == 0) { - font = SERIF_BOLD_ITALIC_FONT; + font = TIMES_LIKE_BOLD_ITALIC_FONT; } else { - font = SERIF_NORMAL_FONT; + font = TIMES_LIKE_NORMAL_FONT; } - } else { + } + + else if (fontName.compareTo("Helvetica") == 0) { if (fontStyle.compareTo("Bold") == 0) { - font = SANS_SERIF_BOLD_FONT; + font = HELVETICA_LIKE_BOLD_FONT; } else if (fontStyle.compareTo("Italic") == 0) { - font = SANS_SERIF_ITALIC_FONT; + font = HELVETICA_LIKE_ITALIC_FONT; } else if (fontStyle.compareTo("Bold-Italic") == 0) { - font = SANS_SERIF_BOLD_ITALIC_FONT; + font = HELVETICA_LIKE_BOLD_ITALIC_FONT; } else { - font = SANS_SERIF_NORMAL_FONT; + font = HELVETICA_LIKE_NORMAL_FONT; } } + else { // use a system (name-based) font, instead of a file-based one + Style[] styles = null; + if (fontStyle.equals("Bold")) { + styles = new Style[] { Style.BOLD }; + } else if (fontStyle.equals("Italic")) { + styles = new Style[] { Style.ITALIC }; + } else if (fontStyle.equals("Bold-Italic")) { + styles = new Style[] { Style.BOLD, Style.ITALIC }; + } + IDisplayPane displayPane = NcDisplayMngr.getActiveNatlCntrsEditor() + .getActiveDisplayPane(); + IGraphicsTarget target = displayPane.getTarget(); + font = target.initializeFont(fontName, fontSize, styles); + // TODO in this case, need to worry about disposal of the font + // later? + } + if (font != null && fontSize != initialFontSize) { font = font.deriveWithSize(fontSize); } if (font != null) { font.setMagnification(1); + + /* + * set smoothing and scaleFont to false to disable anti-aliasing + * (which cause the fuzziness of the text). + */ font.setScaleFont(false); + font.setSmoothing(false); } Tracer.print("< Exit"); @@ -3111,44 +3142,44 @@ public class NcPlotImageCreator { COURIER_NORMAL_FONT = null; } - if (SERIF_BOLD_FONT != null) { - SERIF_BOLD_FONT.dispose(); - SERIF_BOLD_FONT = null; + if (TIMES_LIKE_BOLD_FONT != null) { + TIMES_LIKE_BOLD_FONT.dispose(); + TIMES_LIKE_BOLD_FONT = null; } - if (SERIF_BOLD_ITALIC_FONT != null) { - SERIF_BOLD_ITALIC_FONT.dispose(); - SERIF_BOLD_ITALIC_FONT = null; + if (TIMES_LIKE_BOLD_ITALIC_FONT != null) { + TIMES_LIKE_BOLD_ITALIC_FONT.dispose(); + TIMES_LIKE_BOLD_ITALIC_FONT = null; } - if (SERIF_ITALIC_FONT != null) { - SERIF_ITALIC_FONT.dispose(); - SERIF_ITALIC_FONT = null; + if (TIMES_LIKE_ITALIC_FONT != null) { + TIMES_LIKE_ITALIC_FONT.dispose(); + TIMES_LIKE_ITALIC_FONT = null; } - if (SERIF_NORMAL_FONT != null) { - SERIF_NORMAL_FONT.dispose(); - SERIF_NORMAL_FONT = null; + if (TIMES_LIKE_NORMAL_FONT != null) { + TIMES_LIKE_NORMAL_FONT.dispose(); + TIMES_LIKE_NORMAL_FONT = null; } - if (SANS_SERIF_BOLD_FONT != null) { - SANS_SERIF_BOLD_FONT.dispose(); - SANS_SERIF_BOLD_FONT = null; + if (HELVETICA_LIKE_BOLD_FONT != null) { + HELVETICA_LIKE_BOLD_FONT.dispose(); + HELVETICA_LIKE_BOLD_FONT = null; } - if (SANS_SERIF_BOLD_ITALIC_FONT != null) { - SANS_SERIF_BOLD_ITALIC_FONT.dispose(); - SANS_SERIF_BOLD_ITALIC_FONT = null; + if (HELVETICA_LIKE_BOLD_ITALIC_FONT != null) { + HELVETICA_LIKE_BOLD_ITALIC_FONT.dispose(); + HELVETICA_LIKE_BOLD_ITALIC_FONT = null; } - if (SANS_SERIF_ITALIC_FONT != null) { - SANS_SERIF_ITALIC_FONT.dispose(); - SANS_SERIF_ITALIC_FONT = null; + if (HELVETICA_LIKE_ITALIC_FONT != null) { + HELVETICA_LIKE_ITALIC_FONT.dispose(); + HELVETICA_LIKE_ITALIC_FONT = null; } - if (SANS_SERIF_NORMAL_FONT != null) { - SANS_SERIF_NORMAL_FONT.dispose(); - SANS_SERIF_NORMAL_FONT = null; + if (HELVETICA_LIKE_NORMAL_FONT != null) { + HELVETICA_LIKE_NORMAL_FONT.dispose(); + HELVETICA_LIKE_NORMAL_FONT = null; } Tracer.print("< Exit"); diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/EditPlotModelComposite.java b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/EditPlotModelComposite.java index 1f979d679d..11df293465 100644 --- a/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/EditPlotModelComposite.java +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.plotdata/src/gov/noaa/nws/ncep/viz/rsc/plotdata/rsc/EditPlotModelComposite.java @@ -74,6 +74,7 @@ import org.eclipse.swt.widgets.Scale; * 02/26/2013 936 Archana Removed references to the 'Standard' font. * 03/10/2014 921 S. Russell TTR 921: implemented the Clear & Reset buttons * 06/17/2014 923 S. Russell TTR 923: altered method initWidgets() + * 11/03/2014 R5156 B. Hebbard Add more textFontOptions * * * @@ -100,13 +101,19 @@ public class EditPlotModelComposite extends Composite { private Button advancedBtn = null; - private final String[] textSizeOptions = { "10", "12", "14", "16", "18", "20", "22", "24", "32" }; + private final String[] textSizeOptions = { "10", "12", "14", "16", "18", + "20", "22", "24", "32" }; - private final String[] textFontOptions = { "Courier", "Helvetica", "Times" }; + private final String[] textFontOptions = { "Courier", "Helvetica", "Times", + // "Dialog", "DialogInput", // same as SansSerif, Monospaced, resp. + "Monospaced", "SansSerif", "Serif", "Nimbus Sans L", + "Liberation Serif" }; - private final String[] textStyleOptions = { "Normal", "Italic", "Bold", "Bold-Italic" }; + private final String[] textStyleOptions = { "Normal", "Italic", "Bold", + "Bold-Italic" }; - private final String[] plotModelElementPositions = { "TC", "UL", "UC", "UR", "ML", "MC", "MR", "LL", "LC", "LR", "BC" }; + private final String[] plotModelElementPositions = { "TC", "UL", "UC", + "UR", "ML", "MC", "MR", "LL", "LC", "LR", "BC" }; private HashMap plotModelElementsUIMap = new HashMap(); @@ -142,9 +149,11 @@ public class EditPlotModelComposite extends Composite { private Label wndBrbLbl = null; - private File advancedIconFile = NcPathManager.getInstance().getStaticFile(NcPathConstants.ADVANCED_ICON_IMG);; + private File advancedIconFile = NcPathManager.getInstance().getStaticFile( + NcPathConstants.ADVANCED_ICON_IMG);; - public EditPlotModelComposite(Composite parent, int style, PlotModel pm, INatlCntrsResourceData rscData) { + public EditPlotModelComposite(Composite parent, int style, PlotModel pm, + INatlCntrsResourceData rscData) { super(parent, style); editedPlotModel = pm; this.rscData = rscData; @@ -154,12 +163,14 @@ public class EditPlotModelComposite extends Composite { mainLayout.marginWidth = 1; mainLayout.verticalSpacing = 5; topComposite.setLayout(mainLayout); - plotParamDefns = PlotParameterDefnsMngr.getInstance().getPlotParamDefns(editedPlotModel.getPlugin()); + plotParamDefns = PlotParameterDefnsMngr.getInstance() + .getPlotParamDefns(editedPlotModel.getPlugin()); createPlotModelGuiElements(); // TTR 921 - origPltMdlElmntsUIMap = new HashMap(plotModelElementsUIMap); + origPltMdlElmntsUIMap = new HashMap( + plotModelElementsUIMap); createTextAttrControls(); @@ -188,7 +199,8 @@ public class EditPlotModelComposite extends Composite { textSizeCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (seldPlotModelElemButton != null) { - seldPlotModelElemButton.getPlotModelElement().setTextSize(textSizeCombo.getText()); + seldPlotModelElemButton.getPlotModelElement().setTextSize( + textSizeCombo.getText()); if (applyToAllBtn.getSelection()) { applyTextChangesToAllParameters(); @@ -204,7 +216,8 @@ public class EditPlotModelComposite extends Composite { textFontCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (seldPlotModelElemButton != null) { - seldPlotModelElemButton.getPlotModelElement().setTextFont(textFontCombo.getText()); + seldPlotModelElemButton.getPlotModelElement().setTextFont( + textFontCombo.getText()); // if ("Standard".equals(textFontCombo.getText())) { // textStyleCombo.select(0); @@ -227,7 +240,8 @@ public class EditPlotModelComposite extends Composite { textStyleCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (seldPlotModelElemButton != null) { - seldPlotModelElemButton.getPlotModelElement().setTextStyle(textStyleCombo.getText()); + seldPlotModelElemButton.getPlotModelElement().setTextStyle( + textStyleCombo.getText()); if (applyToAllBtn.getSelection()) { applyTextChangesToAllParameters(); @@ -261,7 +275,8 @@ public class EditPlotModelComposite extends Composite { Group parmListGrp = new Group(comp, SWT.SHADOW_NONE); parmListGrp.setLayout(new GridLayout(1, false)); parmListGrp.setText("Plot Parameters"); - availParamsList = new List(parmListGrp, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL); + availParamsList = new List(parmListGrp, SWT.BORDER | SWT.SINGLE + | SWT.V_SCROLL); availParamsList.setLayoutData(gd); availParamsList.addSelectionListener(new SelectionAdapter() { @Override @@ -272,12 +287,12 @@ public class EditPlotModelComposite extends Composite { if (!seldPlotModelElemButton.isParamNameSelected()) { // seldPlotModelElemButton.setColor( ) } - //if (selectedParm.equalsIgnoreCase("PTND")) { - // swapInAComboBtn("PTND"); - //}// else a regular button - //else { + // if (selectedParm.equalsIgnoreCase("PTND")) { + // swapInAComboBtn("PTND"); + // }// else a regular button + // else { seldPlotModelElemButton.setParmName(selectedParm); - //} + // } } } }); @@ -316,23 +331,27 @@ public class EditPlotModelComposite extends Composite { Group selColorGrp = new Group(comp, SWT.SHADOW_NONE); selColorGrp.setText("Color"); - cms = new ColorMatrixSelector(selColorGrp, false, true, 22, 88, 18, 22, 28, 86, 0, 4, 5); + cms = new ColorMatrixSelector(selColorGrp, false, true, 22, 88, 18, 22, + 28, 86, 0, 4, 5); cms.setColorValue(new RGB(0, 255, 0)); cms.addListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if (seldPlotModelElemButton != null) { RGB rgb = cms.getColorValue(); - //if (seldPlotModelElemButton instanceof PlotModelElemComboButton) { - //System.out.println("==> listener using combo btn"); - //((PlotModelElemComboButton) seldPlotModelElemButton).setColor(rgb); - //((PlotModelElemComboButton) seldPlotModelElemButton).setButtonAsSelected(); - //} else { - //System.out.println("==> listener using single btn"); + // if (seldPlotModelElemButton instanceof + // PlotModelElemComboButton) { + // System.out.println("==> listener using combo btn"); + // ((PlotModelElemComboButton) + // seldPlotModelElemButton).setColor(rgb); + // ((PlotModelElemComboButton) + // seldPlotModelElemButton).setButtonAsSelected(); + // } else { + // System.out.println("==> listener using single btn"); seldPlotModelElemButton.setColor(rgb); seldPlotModelElemButton.setButtonAsSelected(); - //} + // } } } }); @@ -373,7 +392,8 @@ public class EditPlotModelComposite extends Composite { } }); - PlotModelElement pme = editedPlotModel.getPlotModelElement(plotModelElementPositions[0]); + PlotModelElement pme = editedPlotModel + .getPlotModelElement(plotModelElementPositions[0]); // create a blank element and only add it to the editedPlotModel if the // user selects a parameter. @@ -421,9 +441,10 @@ public class EditPlotModelComposite extends Composite { comp.setLayoutData(gd); - // 9 Param Buttons + // 9 Param Buttons for (int i = 1; i <= 9; i++) { - pme = editedPlotModel.getPlotModelElement(plotModelElementPositions[i]); + pme = editedPlotModel + .getPlotModelElement(plotModelElementPositions[i]); if (pme == null) { pme = new PlotModelElement(); @@ -432,15 +453,20 @@ public class EditPlotModelComposite extends Composite { try { - // the center button stores the sky coverage and wind barb params + // the center button stores the sky coverage and wind barb + // params if (plotModelElementPositions[i].equals("MC")) { - PlotModelElemCenterButton cntrBtn = new PlotModelElemCenterButton(comp, pme, editedPlotModel.getSkyCoverageElement(), editedPlotModel.getWindBarbElement()); + PlotModelElemCenterButton cntrBtn = new PlotModelElemCenterButton( + comp, pme, editedPlotModel.getSkyCoverageElement(), + editedPlotModel.getWindBarbElement()); cntrBtn.init(); - plotModelElementsUIMap.put(plotModelElementPositions[i], cntrBtn); + plotModelElementsUIMap.put(plotModelElementPositions[i], + cntrBtn); } else { pmeBtn = new PlotModelElemButton(comp, pme); pmeBtn.init(); - plotModelElementsUIMap.put(plotModelElementPositions[i], pmeBtn); + plotModelElementsUIMap.put(plotModelElementPositions[i], + pmeBtn); } }// end try @@ -488,7 +514,8 @@ public class EditPlotModelComposite extends Composite { gd.grabExcessHorizontalSpace = true; comp.setLayoutData(gd); - pme = editedPlotModel.getPlotModelElement(plotModelElementPositions[10]); + pme = editedPlotModel + .getPlotModelElement(plotModelElementPositions[10]); if (pme == null) { pme = new PlotModelElement(); pme.setPosition(plotModelElementPositions[10]); @@ -533,8 +560,10 @@ public class EditPlotModelComposite extends Composite { grp.setLayoutData(gd); - if (advancedIconFile != null && advancedIconFile.exists() && pltMdlElmt.hasAdvancedSettings()) { - Image image = new Image(Display.getCurrent(), advancedIconFile.getAbsolutePath()); + if (advancedIconFile != null && advancedIconFile.exists() + && pltMdlElmt.hasAdvancedSettings()) { + Image image = new Image(Display.getCurrent(), + advancedIconFile.getAbsolutePath()); grp.setBackgroundImage(image); grp.setToolTipText("Advanced Settings Applied."); } else { @@ -596,7 +625,8 @@ public class EditPlotModelComposite extends Composite { if (isParamNameSelected()) { for (int i = 0; i < availParamsList.getItemCount(); i++) { - if (availParamsList.getItem(i).equals(parmBtn.getText())) { + if (availParamsList.getItem(i) + .equals(parmBtn.getText())) { availParamsList.setSelection(i); break; } @@ -653,16 +683,21 @@ public class EditPlotModelComposite extends Composite { public void setButtonAsSelected() { RGB rgb = getColor(); - grp.setBackground(new Color(getParent().getDisplay(), cms.getColorValue())); + grp.setBackground(new Color(getParent().getDisplay(), cms + .getColorValue())); - seldPlotModelElemButton.parmBtn.setForeground(new Color(getParent().getDisplay(), rgb)); - seldPlotModelElemButton.parmBtn.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); - seldPlotModelElemButton.grp.setBackground(new Color(getParent().getDisplay(), rgb)); + seldPlotModelElemButton.parmBtn.setForeground(new Color(getParent() + .getDisplay(), rgb)); + seldPlotModelElemButton.parmBtn.setBackground(Display.getDefault() + .getSystemColor(SWT.COLOR_BLACK)); + seldPlotModelElemButton.grp.setBackground(new Color(getParent() + .getDisplay(), rgb)); } public void unselectButton() { // change color back to original grey - grp.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + grp.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WIDGET_BACKGROUND)); // unselect parm button parmBtn.setSelection(false); @@ -683,10 +718,13 @@ public class EditPlotModelComposite extends Composite { checkBtn.setEnabled(true); checkBtn.setSelection(true); // pltMdlElmt.getEnable() ); - parmBtn.setForeground(new Color(getParent().getDisplay(), getColor().red, getColor().green, getColor().blue)); - parmBtn.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + parmBtn.setForeground(new Color(getParent().getDisplay(), + getColor().red, getColor().green, getColor().blue)); + parmBtn.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_BLACK)); - PlotParameterDefn paramDefn = plotParamDefns.getPlotParamDefn(pltMdlElmt.getParamName()); + PlotParameterDefn paramDefn = plotParamDefns + .getPlotParamDefn(pltMdlElmt.getParamName()); if (paramDefn == null) { parmBtn.setToolTipText(""); } else { @@ -694,7 +732,8 @@ public class EditPlotModelComposite extends Composite { if (paramDefn.getDeriveParams().equals("all")) { parmBtn.setToolTipText("Derived Parameter"); } else { - parmBtn.setToolTipText("Derived from " + paramDefn.getDeriveParams()); + parmBtn.setToolTipText("Derived from " + + paramDefn.getDeriveParams()); } } else { parmBtn.setToolTipText(paramDefn.getMetParamName()); @@ -706,7 +745,8 @@ public class EditPlotModelComposite extends Composite { // the color of the text parmBtn.setForeground(new Color(getDisplay(), new RGB(0, 0, 0))); - parmBtn.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + parmBtn.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WIDGET_BACKGROUND)); parmBtn.setToolTipText(""); } @@ -736,11 +776,14 @@ public class EditPlotModelComposite extends Composite { parmBtn.setText(getButtonLabel()); // Set foreground and background color - parmBtn.setForeground(new Color(getParent().getDisplay(), getColor().red, getColor().green, getColor().blue)); - parmBtn.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + parmBtn.setForeground(new Color(getParent().getDisplay(), + getColor().red, getColor().green, getColor().blue)); + parmBtn.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_BLACK)); // - PlotParameterDefn paramDefn = plotParamDefns.getPlotParamDefn(parmName); + PlotParameterDefn paramDefn = plotParamDefns + .getPlotParamDefn(parmName); if (paramDefn == null) { parmBtn.setToolTipText(""); } else { @@ -748,7 +791,8 @@ public class EditPlotModelComposite extends Composite { if (paramDefn.getDeriveParams().equals("all")) { parmBtn.setToolTipText("Derived Parameter"); } else { - parmBtn.setToolTipText("Derived from " + paramDefn.getDeriveParams()); + parmBtn.setToolTipText("Derived from " + + paramDefn.getDeriveParams()); } } else { parmBtn.setToolTipText(paramDefn.getMetParamName()); @@ -757,7 +801,8 @@ public class EditPlotModelComposite extends Composite { } protected RGB getColor() { - return new RGB(pltMdlElmt.getColor().getRed(), pltMdlElmt.getColor().getGreen(), pltMdlElmt.getColor().getBlue()); + return new RGB(pltMdlElmt.getColor().getRed(), pltMdlElmt + .getColor().getGreen(), pltMdlElmt.getColor().getBlue()); } protected void setColor(RGB rgb) { @@ -770,7 +815,8 @@ public class EditPlotModelComposite extends Composite { private PlotModelElement wndBrbElmt = null; - public PlotModelElemCenterButton(Composite topComp, PlotModelElement pme, PlotModelElement sce, PlotModelElement wbe) { + public PlotModelElemCenterButton(Composite topComp, + PlotModelElement pme, PlotModelElement sce, PlotModelElement wbe) { super(topComp, pme); // if either is null then create a new PlotModelElement but don't // add it to the @@ -789,8 +835,12 @@ public class EditPlotModelComposite extends Composite { wndBrbElmt.setPosition("WD"); } - if (advancedIconFile != null && advancedIconFile.exists() && (skyCovElmt.hasAdvancedSettings() || wndBrbElmt.hasAdvancedSettings())) { - Image image = new Image(Display.getCurrent(), advancedIconFile.getAbsolutePath()); + if (advancedIconFile != null + && advancedIconFile.exists() + && (skyCovElmt.hasAdvancedSettings() || wndBrbElmt + .hasAdvancedSettings())) { + Image image = new Image(Display.getCurrent(), + advancedIconFile.getAbsolutePath()); grp.setBackgroundImage(image); grp.setToolTipText("Advanced Settings Applied."); } else { @@ -897,7 +947,8 @@ public class EditPlotModelComposite extends Composite { @Override public String getButtonLabel() { - if (skyCovElmt.getParamName() == null && wndBrbElmt.getParamName() == null) { + if (skyCovElmt.getParamName() == null + && wndBrbElmt.getParamName() == null) { // parmBtn.setText( getParmName() ) return super.getButtonLabel(); @@ -907,7 +958,8 @@ public class EditPlotModelComposite extends Composite { } else if (wndBrbElmt.getParamName() == null) { return skyCovElmt.getParamName(); } else { - return skyCovElmt.getParamName() + "\n" + wndBrbElmt.getParamName(); + return skyCovElmt.getParamName() + "\n" + + wndBrbElmt.getParamName(); } } @@ -980,13 +1032,15 @@ public class EditPlotModelComposite extends Composite { // if any param is selected then set the background color // ('normal' param selections are checked in the super.) // - if (wndBrbElmt.getParamName() != null || skyCovElmt.getParamName() != null) { + if (wndBrbElmt.getParamName() != null + || skyCovElmt.getParamName() != null) { // Set color in the ColorMatricSelector widget cms.setColorValue(getColor()); // Set grp background - grp.setBackground(new Color(getParent().getDisplay(), cms.getColorValue())); + grp.setBackground(new Color(getParent().getDisplay(), cms + .getColorValue())); } } @@ -995,7 +1049,9 @@ public class EditPlotModelComposite extends Composite { @Override public boolean isParamNameSelected() { - return (wndBrbElmt.getParamName() != null || skyCovElmt.getParamName() != null || pltMdlElmt.getParamName() != null); + return (wndBrbElmt.getParamName() != null + || skyCovElmt.getParamName() != null || pltMdlElmt + .getParamName() != null); } @Override @@ -1024,8 +1080,8 @@ public class EditPlotModelComposite extends Composite { String[] strArray = plotParamDefns.getAllParameterNames(false, true); - //TTR 923 remove "P03X" from the menu ( the dummy XML it comes from in - // plotParameters_obs.xml is needed to make the code run without a + // TTR 923 remove "P03X" from the menu ( the dummy XML it comes from in + // plotParameters_obs.xml is needed to make the code run without a // a significant amount of reworking ArrayList parameterNames = new ArrayList(); Collections.addAll(parameterNames, strArray); @@ -1050,7 +1106,8 @@ public class EditPlotModelComposite extends Composite { // return; // } - PlotModelElemCenterButton cntrBtn = (PlotModelElemCenterButton) plotModelElementsUIMap.get("MC"); + PlotModelElemCenterButton cntrBtn = (PlotModelElemCenterButton) plotModelElementsUIMap + .get("MC"); PlotModelElement wndBrbPme = cntrBtn.getWindBarbPlotModelElement(); PlotModelElement skyCovPme = cntrBtn.getSkyCoveragePlotModelElement(); @@ -1079,7 +1136,8 @@ public class EditPlotModelComposite extends Composite { String name = comboSky.getItem(comboSky.getSelectionIndex()); if (seldPlotModelElemButton instanceof PlotModelElemCenterButton) { - ((PlotModelElemCenterButton) seldPlotModelElemButton).setSkyCoverageParamName((name.equals("None") ? null : name)); + ((PlotModelElemCenterButton) seldPlotModelElemButton).setSkyCoverageParamName((name + .equals("None") ? null : name)); } } }); @@ -1106,7 +1164,9 @@ public class EditPlotModelComposite extends Composite { if (seldPlotModelElemButton instanceof PlotModelElemCenterButton) { // sanity // check - ((PlotModelElemCenterButton) seldPlotModelElemButton).setWindBarbParamName((name.equals("None") ? null : name)); + ((PlotModelElemCenterButton) seldPlotModelElemButton) + .setWindBarbParamName((name.equals("None") ? null + : name)); } } }); @@ -1117,7 +1177,8 @@ public class EditPlotModelComposite extends Composite { } private void setSelectedSkyAndWindParams() { - PlotModelElemCenterButton cntrBtn = (PlotModelElemCenterButton) plotModelElementsUIMap.get("MC"); + PlotModelElemCenterButton cntrBtn = (PlotModelElemCenterButton) plotModelElementsUIMap + .get("MC"); String seldSkyCovParam = cntrBtn.getSkyCovParamName(); @@ -1150,18 +1211,22 @@ public class EditPlotModelComposite extends Composite { boolean isTextApplicable = false; boolean isSymbApplicable = false; - if (seldPlotModelElemButton != null && seldPlotModelElemButton.isParamNameSelected()) { + if (seldPlotModelElemButton != null + && seldPlotModelElemButton.isParamNameSelected()) { advancedBtn.setEnabled(true); // if( seldPlotModelElemButton.getPlotModelElement().getParamName() // != null ) { - prmDefn = plotParamDefns.getPlotParamDefn(seldPlotModelElemButton.getPlotModelElement().getParamName()); + prmDefn = plotParamDefns.getPlotParamDefn(seldPlotModelElemButton + .getPlotModelElement().getParamName()); // add further constraints here on the plot class if necessary if (prmDefn != null) { - isTextApplicable = prmDefn.getPlotMode().equalsIgnoreCase("text"); - isSymbApplicable = prmDefn.getPlotMode().equalsIgnoreCase("table"); + isTextApplicable = prmDefn.getPlotMode().equalsIgnoreCase( + "text"); + isSymbApplicable = prmDefn.getPlotMode().equalsIgnoreCase( + "table"); } // if this is the center button and a 'regular' parameter isn't set // then @@ -1171,7 +1236,8 @@ public class EditPlotModelComposite extends Composite { else if (seldPlotModelElemButton instanceof PlotModelElemCenterButton) { PlotModelElemCenterButton cntrBtn = (PlotModelElemCenterButton) seldPlotModelElemButton; - if (cntrBtn.getSkyCovParamName() != null || cntrBtn.getWindBarbParamName() != null) { + if (cntrBtn.getSkyCovParamName() != null + || cntrBtn.getWindBarbParamName() != null) { // prmDefn = plotParamMngr.getParamDefn( // cntrBtn.getSkyCovParamName() ); isTextApplicable = false; @@ -1194,21 +1260,27 @@ public class EditPlotModelComposite extends Composite { applyToAllBtn.setEnabled(true); for (int i = 0; i < textSizeCombo.getItemCount(); i++) { - if (textSizeCombo.getItem(i).equals(seldPlotModelElemButton.getPlotModelElement().getTextSize())) { + if (textSizeCombo.getItem(i).equals( + seldPlotModelElemButton.getPlotModelElement() + .getTextSize())) { textSizeCombo.select(i); break; } } for (int i = 0; i < textFontCombo.getItemCount(); i++) { - if (textFontCombo.getItem(i).equalsIgnoreCase(seldPlotModelElemButton.getPlotModelElement().getTextFont())) { + if (textFontCombo.getItem(i).equalsIgnoreCase( + seldPlotModelElemButton.getPlotModelElement() + .getTextFont())) { textFontCombo.select(i); break; } } for (int i = 0; i < textStyleCombo.getItemCount(); i++) { - if (textStyleCombo.getItem(i).equalsIgnoreCase(seldPlotModelElemButton.getPlotModelElement().getTextStyle())) { + if (textStyleCombo.getItem(i).equalsIgnoreCase( + seldPlotModelElemButton.getPlotModelElement() + .getTextStyle())) { textStyleCombo.select(i); break; } @@ -1267,15 +1339,21 @@ public class EditPlotModelComposite extends Composite { private void applyTextChangesToAllParameters() { for (int i = 0; i < 11; i++) { - PlotModelElemButton pmeBtn = plotModelElementsUIMap.get(plotModelElementPositions[i]); + PlotModelElemButton pmeBtn = plotModelElementsUIMap + .get(plotModelElementPositions[i]); if (pmeBtn != null) { - PlotParameterDefn prmDefn = plotParamDefns.getPlotParamDefn(pmeBtn.getPlotModelElement().getParamName()); + PlotParameterDefn prmDefn = plotParamDefns + .getPlotParamDefn(pmeBtn.getPlotModelElement() + .getParamName()); if (prmDefn != null) { if (prmDefn.getPlotMode().equalsIgnoreCase("text")) { - pmeBtn.getPlotModelElement().setTextSize(textSizeCombo.getText()); - pmeBtn.getPlotModelElement().setTextFont(textFontCombo.getText()); - pmeBtn.getPlotModelElement().setTextStyle(textStyleCombo.getText()); + pmeBtn.getPlotModelElement().setTextSize( + textSizeCombo.getText()); + pmeBtn.getPlotModelElement().setTextFont( + textFontCombo.getText()); + pmeBtn.getPlotModelElement().setTextStyle( + textStyleCombo.getText()); } } } @@ -1313,12 +1391,16 @@ public class EditPlotModelComposite extends Composite { } String prevCondParam = pltMdlElmt.getConditionalParameter(); - ConditionalColorBar prevCondColorBar = new ConditionalColorBar(pltMdlElmt.getConditionalColorBar()); + ConditionalColorBar prevCondColorBar = new ConditionalColorBar( + pltMdlElmt.getConditionalColorBar()); - EditPlotModelElementAdvancedDialog editConditionalFilterDlg = new EditPlotModelElementAdvancedDialog(topComposite.getShell(), pltMdlElmt, plotParamDefns); + EditPlotModelElementAdvancedDialog editConditionalFilterDlg = new EditPlotModelElementAdvancedDialog( + topComposite.getShell(), pltMdlElmt, plotParamDefns); - PlotModelElement newPme = (PlotModelElement) editConditionalFilterDlg.open(topComposite.getShell().getLocation().x + topComposite.getShell().getSize().x + 10, topComposite - .getShell().getLocation().y); + PlotModelElement newPme = (PlotModelElement) editConditionalFilterDlg + .open(topComposite.getShell().getLocation().x + + topComposite.getShell().getSize().x + 10, + topComposite.getShell().getLocation().y); if (newPme != null) { pltMdlElmt = newPme; @@ -1329,20 +1411,26 @@ public class EditPlotModelComposite extends Composite { if (pltMdlElmt.hasAdvancedSettings()) { if (advancedIconFile != null && advancedIconFile.exists()) { - Image image = new Image(Display.getCurrent(), advancedIconFile.getAbsolutePath()); + Image image = new Image(Display.getCurrent(), + advancedIconFile.getAbsolutePath()); seldPlotModelElemButton.grp.setBackgroundImage(image); } - seldPlotModelElemButton.grp.setToolTipText("Advanced Settings Applied."); + seldPlotModelElemButton.grp + .setToolTipText("Advanced Settings Applied."); } else { seldPlotModelElemButton.grp.setBackgroundImage(null); seldPlotModelElemButton.grp.setToolTipText(""); } if (skycPltMdlElmt != null && wbPltMdlElmt != null) { - skycPltMdlElmt.setConditionalParameter(pltMdlElmt.getConditionalParameter()); - skycPltMdlElmt.setConditionalColorBar(pltMdlElmt.getConditionalColorBar()); - wbPltMdlElmt.setConditionalParameter(pltMdlElmt.getConditionalParameter()); - wbPltMdlElmt.setConditionalColorBar(pltMdlElmt.getConditionalColorBar()); + skycPltMdlElmt.setConditionalParameter(pltMdlElmt + .getConditionalParameter()); + skycPltMdlElmt.setConditionalColorBar(pltMdlElmt + .getConditionalColorBar()); + wbPltMdlElmt.setConditionalParameter(pltMdlElmt + .getConditionalParameter()); + wbPltMdlElmt.setConditionalColorBar(pltMdlElmt + .getConditionalColorBar()); } } @@ -1378,7 +1466,8 @@ public class EditPlotModelComposite extends Composite { // Clear special middle center button if (position.equalsIgnoreCase("MC")) { - pmecb = (PlotModelElemCenterButton) plotModelElementsUIMap.get("MC"); + pmecb = (PlotModelElemCenterButton) plotModelElementsUIMap + .get("MC"); pmecb.parmBtn.setText("Parm"); pmecb.parmBtn.setSelection(false); pmecb.checkBtn.setSelection(false); @@ -1386,9 +1475,12 @@ public class EditPlotModelComposite extends Composite { pmecb.grp.setBackground(widget_background); pmecb.parmBtn.setBackground(widget_background); pmecb.parmBtn.setForeground(widget_foreground); - editedPlotModel.removePlotModelElement(pmecb.getPlotModelElement()); - editedPlotModel.removePlotModelElement(pmecb.getSkyCoveragePlotModelElement()); - editedPlotModel.removePlotModelElement(pmecb.getWindBarbPlotModelElement()); + editedPlotModel.removePlotModelElement(pmecb + .getPlotModelElement()); + editedPlotModel.removePlotModelElement(pmecb + .getSkyCoveragePlotModelElement()); + editedPlotModel.removePlotModelElement(pmecb + .getWindBarbPlotModelElement()); pmecb.pltMdlElmt = new PlotModelElement(); pmecb.pltMdlElmt.setPosition(position); pmecb.skyCovElmt.setColorRGB(new RGB(255, 255, 255)); @@ -1403,7 +1495,8 @@ public class EditPlotModelComposite extends Composite { pmeBtn.grp.setBackground(widget_background); pmeBtn.parmBtn.setBackground(widget_background); pmeBtn.parmBtn.setForeground(widget_foreground); - editedPlotModel.removePlotModelElement(pmeBtn.getPlotModelElement()); + editedPlotModel.removePlotModelElement(pmeBtn + .getPlotModelElement()); pmeBtn.pltMdlElmt = new PlotModelElement(); pmeBtn.pltMdlElmt.setPosition(position); } @@ -1453,7 +1546,8 @@ public class EditPlotModelComposite extends Composite { blue = tpme.getColor().getBlue(); rgb = new RGB(red, green, blue); - cntrBtn = (PlotModelElemCenterButton) origPltMdlElmntsUIMap.get(position); + cntrBtn = (PlotModelElemCenterButton) origPltMdlElmntsUIMap + .get(position); cntrBtn.setColor(rgb); cntrBtn.setParmName(opme.getParamName()); cntrBtn.pltMdlElmt = opme; @@ -1526,16 +1620,19 @@ public class EditPlotModelComposite extends Composite { // System.out.print("resoure_name: " + resource_name); // System.out.println("==> resource_version: " + // resource_version); - original_resource = ResourceFactory.createResource(resource_name); + original_resource = ResourceFactory + .createResource(resource_name); origResourceData = original_resource.getResourceData(); - origAttrSet = new ResourceAttrSet(origResourceData.getRscAttrSet()); + origAttrSet = new ResourceAttrSet( + origResourceData.getRscAttrSet()); origPlotModelRscAttr = origAttrSet.getRscAttr("plotModel"); origPlotModel = (PlotModel) origPlotModelRscAttr.getAttrValue(); } else { String plugin, plotmodelname = null; plugin = editedPlotModel.getPlugin(); plotmodelname = editedPlotModel.getName(); - origPlotModel = PlotModelMngr.getInstance().getPlotModel(plugin, plotmodelname); + origPlotModel = PlotModelMngr.getInstance().getPlotModel( + plugin, plotmodelname); } } catch (Exception e) { From dbf2f42af19bab9e92dcea87ba4c5e7a05dfc8b5 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 1 Dec 2014 16:06:41 -0500 Subject: [PATCH 17/19] VLab Issue #4001 - Fix Ncuair decoder for dropsondes Change-Id: I88646f0d3f981e8b5c1902362636f48e130c8dd3 Former-commit-id: 034f028db0e57ebe5c9e73ee1af94b67ad4ba9fa [formerly 034f028db0e57ebe5c9e73ee1af94b67ad4ba9fa [formerly 929b1977b350abc7f271ee7cd3ee8e65be4efe85]] Former-commit-id: f87cc6e7fb5a767f13bc24454c48942cd73b59f3 Former-commit-id: 70f60dc8b994e19c1d520575e041b7df046b036e --- .../edex/plugin/ncuair/util/NcUairParser.java | 5 +- .../plugin/ncuair/util/NcUairShipMobile.java | 9 +- tests/.classpath | 2 + .../ncscat/decoder/NcscatDecoderTest.java | 385 ++++++++++ .../ntrans/decoder/NtransDecoderTest.java | 725 ++++++++++++++++++ 5 files changed, 1122 insertions(+), 4 deletions(-) create mode 100644 tests/unit/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoderTest.java create mode 100644 tests/unit/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoderTest.java diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairParser.java index 4bd2c33a41..123c8ad551 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairParser.java @@ -13,6 +13,7 @@ * 09/2011 Chin Chen add batch parsing methods for better performance * 09/2011 457 S. Gurung Renamed H5 to Nc and h5 to nc * 12/2013 T. Lee Fixed TTCC Wmax pressure off by factor of 10 + * 10/2014 T. Lee Fixed XXCC/XXDD indices to use TTCC/TTDD processing * * * @@ -67,9 +68,9 @@ public class NcUairParser { public static final int XXBB = 2; - public static final int XXCC = 9; + public static final int XXCC = 3; - public static final int XXDD = 10; + public static final int XXDD = 4; /** * Constructor diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairShipMobile.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairShipMobile.java index dbbe8457df..afea32113a 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairShipMobile.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncuair/src/gov/noaa/nws/ncep/edex/plugin/ncuair/util/NcUairShipMobile.java @@ -10,7 +10,8 @@ * 03/2010 210 L. Lin Initial coding * 09/2011 457 S. Gurung Renamed H5 to Nc and h5 to nc * 09/02/2014 Chin Chen fix surface height missing on some stations issue - * + * 10/2014 T. Lee Updated catch-all phrases for stnID + * * * * This code has been developed by the SIB for use in the AWIPS2 system. @@ -336,7 +337,7 @@ public class NcUairShipMobile { */ public static void Dropsonde(String report) { - final String DROP = "61616 (AF|NOAA|NASA)(\\d{1,3}) (.*) OB (\\d{2}) 62626"; + final String DROP = "61616 (AF|NOAA|NA)(\\d{1,3}) (.*) OB (\\d{2}) 62626"; Pattern dropPattern = Pattern.compile(DROP, Pattern.DOTALL); Matcher dropMatcher = dropPattern.matcher(report); @@ -354,6 +355,10 @@ public class NcUairShipMobile { + dropMatcher.group(2); stnId = dropMatcher.group(1) + dropMatcher.group(2) + dropMatcher.group(4); + } else { + System.out.println(" New dropsonde station found"); + stationNumber = "99999"; + stnId = "NEW_DROP"; } // Chin: sfcElevSolution start // if (drop2Matcher.find()) { diff --git a/tests/.classpath b/tests/.classpath index 4bf477f73e..ce8140f419 100644 --- a/tests/.classpath +++ b/tests/.classpath @@ -164,5 +164,7 @@ + + diff --git a/tests/unit/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoderTest.java b/tests/unit/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoderTest.java new file mode 100644 index 0000000000..f32223e54e --- /dev/null +++ b/tests/unit/gov/noaa/nws/ncep/edex/plugin/ncscat/decoder/NcscatDecoderTest.java @@ -0,0 +1,385 @@ +/** + + **/ +package gov.noaa.nws.ncep.edex.plugin.ncscat.decoder; + +import static org.junit.Assert.assertEquals; +import gov.noaa.nws.ncep.common.dataplugin.ncscat.NcscatMode; + +import java.nio.ByteBuffer; + +import javax.xml.bind.DatatypeConverter; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.raytheon.uf.common.time.DataTime; + +/** + * Unit Tests for NtransDecoder Class + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 20, 2014            bhebbard     Initial creation
+ * 
+ * 
+ * + * @author bhebbard + * @version 1.0 + */ + +public class NcscatDecoderTest { + + static ByteBuffer simulatedInput; + + DataTime actual, expected; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + byte[] b = DatatypeConverter.parseHexBinary(validAscatDump); + simulatedInput = ByteBuffer.wrap(b); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + simulatedInput.clear(); + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + // @formatter:off + /** + * Now, the individual test cases! + * + * + */ + // @formatter:on + + /** + * VALID CASES + */ + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_01() { + // simple case: valid ASCAT data confirmed consistent with ASCAT + // + Boolean actual = NcscatMode.ASCAT.consistentWith(simulatedInput); + // + Boolean expected = true; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_02() { + // case: valid ASCAT data NOT consistent with ASCAT_HI + // + Boolean actual = NcscatMode.ASCAT_HI.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_03() { + // case: valid ASCAT data NOT consistent with QUIKSCAT + // + Boolean actual = NcscatMode.QUIKSCAT.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + // CURRENTLY TOO BIG FOR HARDCODED DATASET; GOES PAST END OF BUFFER + // @Test + // public final void testConsistentWith_04() { + // case: valid ASCAT data NOT consistent with QUIKSCAT_HI + // + // Boolean actual = NcscatMode.QUIKSCAT_HI.consistentWith(simulatedInput); + // + // Boolean expected = false; + // + // assertEquals(expected, actual); + // } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_05() { + // case: valid ASCAT data NOT consistent with EXASCT + // + Boolean actual = NcscatMode.EXASCT.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_06() { + // case: valid ASCAT data NOT consistent with EXASCT_HI + // + Boolean actual = NcscatMode.EXASCT_HI.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_07() { + // case: valid ASCAT data NOT consistent with OSCAT + // + Boolean actual = NcscatMode.OSCAT.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_08() { + // case: valid ASCAT data NOT consistent with OSCAT_HI + // + Boolean actual = NcscatMode.OSCAT_HI.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_09() { + // case: valid ASCAT data NOT consistent with WSCAT + // + Boolean actual = NcscatMode.WSCAT.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + /** + * A "typical" scenario: + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ncscat.decoder.NcscatDecoder#consistentWith(java.nio.ByteBuffer)} + * . + */ + @Test + public final void testConsistentWith_10() { + // case: valid ASCAT data NOT consistent with WSCAT + // + Boolean actual = NcscatMode.WSCAT.consistentWith(simulatedInput); + // + Boolean expected = false; + // + assertEquals(expected, actual); + } + + // @formatter:off + private final static String validAscatDump = ( + /*00000000*/ "01 21 00 10 00 30 00 00 1a 9d 1a ae 1a bf 1a d0" + + /*00000010*/ "1a e1 1a f1 1b 02 1b 12 1b 23 1b 33 1b 43 1b 53" + + /*00000020*/ "1b 63 1b 73 1b 83 1b 92 1b a2 1b b1 1b c0 1b cf" + + /*00000030*/ "1b de 1d 49 1d 51 1d 59 1d 61 1d 69 1d 70 1d 77" + + /*00000040*/ "1d 7d 1d 83 1d 89 1d 8f 1d 94 1d 99 1d 9e 1d a2" + + /*00000050*/ "1d a6 1d a9 1d ad 1d b0 1d b2 1d b4 08 8b 08 b2" + + /*00000060*/ "08 d9 09 01 09 2a 09 54 09 7e 09 a9 09 d4 0a 00" + + /*00000070*/ "0a 2d 0a 5a 0a 88 0a b7 0a e7 0b 17 0b 48 0b 7a" + + /*00000080*/ "0b ad 0b e0 0c 14 13 e7 14 38 14 89 14 db 15 2e" + + /*00000090*/ "15 82 15 d7 16 2c 16 82 16 d9 17 30 17 88 17 e1" + + /*000000a0*/ "18 3a 18 94 18 ef 19 49 19 a5 1a 00 1a 5c 1a b9" + + /*000000b0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000000c0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000000d0*/ "00 00 00 00 00 00 00 c0 00 80 00 00 08 00 08 00" + + /*000000e0*/ "08 80 00 80 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000000f0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000100*/ "00 00 00 00 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000110*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000120*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 03 75 03 ea 01 3d" + + /*00000130*/ "01 14 01 05 01 1c 01 4f d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000140*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000150*/ "d8 f1 d8 f1 d8 f1 d8 f1 00 00 00 00 00 00 00 00" + + /*00000160*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000170*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 c0" + + /*00000180*/ "29 ad 28 3c 26 70 21 79 1d 10 1d 10 00 00 00 00" + + /*00000190*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000001a0*/ "00 00 00 00 00 00 00 00 00 00 00 00 d8 f1 d8 f1" + + /*000001b0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000001c0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000001d0*/ "d8 f1 00 02 00 02 00 01 00 01 00 02 00 02 00 02" + + /*000001e0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000001f0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000200*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000210*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000220*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000230*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000240*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000250*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000260*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000270*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000280*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000290*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002a0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002b0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002c0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002d0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002e0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000002f0*/ "00 00 00 00 00 00 00 00 00 00 00 00 01 21 00 10" + + /*00000300*/ "00 30 00 00 1a ab 1a bc 1a ce 1a df 1a ef 1b 00" + + /*00000310*/ "1b 11 1b 22 1b 32 1b 43 1b 53 1b 63 1b 73 1b 83" + + /*00000320*/ "1b 93 1b a2 1b b2 1b c1 1b d1 1b e0 1b ef 1d 5e" + + /*00000330*/ "1d 66 1d 6e 1d 76 1d 7e 1d 85 1d 8c 1d 92 1d 99" + + /*00000340*/ "1d 9f 1d a4 1d a9 1d ae 1d b3 1d b7 1d bb 1d bf" + + /*00000350*/ "1d c2 1d c5 1d c8 1d ca 08 5c 08 83 08 aa 08 d3" + + /*00000360*/ "08 fb 09 25 09 4f 09 79 09 a5 09 d1 09 fe 0a 2b" + + /*00000370*/ "0a 59 0a 88 0a b7 0a e8 0b 19 0b 4b 0b 7d 0b b1" + + /*00000380*/ "0b e5 13 c7 14 18 14 6a 14 be 15 12 15 66 15 bc" + + /*00000390*/ "16 13 16 6a 16 c2 17 1a 17 74 17 ce 18 28 18 84" + + /*000003a0*/ "18 df 19 3b 19 98 19 f5 1a 53 1a b0 00 00 00 00" + + /*000003b0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000003c0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000003d0*/ "00 00 00 c0 00 00 00 00 08 00 08 00 00 00 00 80" + + /*000003e0*/ "00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000003f0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000400*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000410*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000420*/ "d8 f1 d8 f1 d8 f1 03 52 04 3d 01 4e 01 1b 01 0c" + + /*00000430*/ "01 30 01 5f 01 79 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000440*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*00000450*/ "d8 f1 d8 f1 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000460*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000470*/ "00 00 00 00 00 00 00 00 00 00 13 7e 2b fb 27 9c" + + /*00000480*/ "26 0c 21 d3 1e 0a 1e 1d 1f c2 00 00 00 00 00 00" + + /*00000490*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000004a0*/ "00 00 00 00 00 00 00 00 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000004b0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000004c0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 00 02" + + /*000004d0*/ "00 01 00 01 00 01 00 02 00 02 00 02 00 02 d8 f1" + + /*000004e0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1" + + /*000004f0*/ "d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 d8 f1 00 00 00 00" + + /*00000500*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000510*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000520*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000530*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000540*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000550*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000560*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000570*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000580*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*00000590*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005a0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005b0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005c0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005d0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005e0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000005f0*/ "00 00 00 00 00 00 00 00 01 21 00 10 00 30 00 00" + + /*00000600*/ "1a ba 1a cb 1a dc 1a ed 1a fe 1b 0f 1b 20 1b 31" + + /*00000610*/ "1b 41 1b 52 1b 62 1b 73 1b 83 1b 93 1b a3 1b b3" + + /*00000620*/ "1b c2 1b d2 1b e1 1b f0 1c 00 1d 72 1d 7b 1d 83" + + /*00000630*/ "1d 8b 1d 92 1d 9a 1d a1 1d a7 1d ae 1d b4 1d b9" + + /*00000640*/ "1d bf 1d c4 1d c9 1d cd 1d d1 1d d5 1d d8 1d db" + + /*00000650*/ "1d de 1d e0 08 2d 08 54 08 7b 08 a3 08 cc 08 f5" + + /*00000660*/ "09 1f 09 4a 09 75 09 a1 09 ce 09 fb 0a 29 0a 58" + + /*00000670*/ "0a 87 0a b8 0a e9 0b 1b 0b 4e 0b 81 0b b5 13 a5" + + /*00000680*/ "13 f8 14 4b 14 9f 14 f4 15 4a 15 a1 15 f9 16 51" + + /*00000690*/ "16 aa 17 04 17 5f 17 ba 18 16 18 73 18 d0 19 2d" + + /*000006a0*/ "19 8b 19 ea 1a 49 1a a8 00 00 00 00 00 00 00 00" + + /*000006b0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000006c0*/ "00 00 00 00 00 00 00 00 00 00 00 00 00 c0 00 80" + + /*000006d0*/ "00 00 00 00 00 00 08 00 00 00 00 00 00 80 00 80" + + /*000006e0*/ "00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + + /*000006f0*/ "00 00 00 00 00 00 00 00 00 00 00 00 d8 f1 d8 f1" ) + .replaceAll(" ", "") ; + // @formatter:on + +} diff --git a/tests/unit/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoderTest.java b/tests/unit/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoderTest.java new file mode 100644 index 0000000000..11cef2554d --- /dev/null +++ b/tests/unit/gov/noaa/nws/ncep/edex/plugin/ntrans/decoder/NtransDecoderTest.java @@ -0,0 +1,725 @@ +/** + + **/ +package gov.noaa.nws.ncep.edex.plugin.ntrans.decoder; + +import static org.junit.Assert.assertEquals; + +import java.util.Calendar; +import java.util.TimeZone; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.raytheon.uf.common.time.DataTime; + +/** + * Unit Tests for NtransDecoder Class + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 8, 2014            bhebbard     Initial creation
+ * 
+ * 
+ * + * @author bhebbard + * @version 1.0 + */ + +public class NtransDecoderTest { + + private NtransDecoder decoder = null; + + private Calendar decodeTime = null; + + private String frameTimeString = null; + + private String metafileName = null; + + DataTime actual, expected; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + decoder = new NtransDecoder(); + decodeTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + decodeTime.setLenient(false); // no nonsense here + // default simulated decode time: 2014-08-16 23:57:59.327 + decodeTime.set(2014, Calendar.AUGUST, 16, 23, 57, 59); + decodeTime.set(Calendar.MILLISECOND, 327); + // set some other defaults + frameTimeString = ""; + metafileName = "METAFILE_NAME_CONTAINS_NO_TIME_STRING"; + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + decoder = null; + decodeTime = null; + frameTimeString = null; + metafileName = null; + } + + // @formatter:off + /** + * Now, the individual test cases! + * + * In the comments which follow... + * C = cycle (or initial) time + * D = decode (or system) time + * V = valid time + * F = forecast hour (V - C) + * M = month boundary + * + */ + // @formatter:on + + /** + * VALID CASES + */ + + /** + * A "typical" scenario: C < D < V (Here F = 36) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_01_C_D_V_F036_A() { + // default simulated decode time: 2014-08-16 23:57:59.327 + frameTimeString = "18/00V036"; + // + expected = new DataTime("2014-08-16 12:00:00.0 (36)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * C = V < D (F = 0) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_02_C_V_D_F000_A() { + decodeTime.set(2014, Calendar.AUGUST, 18, 04, 22, 13); + frameTimeString = "18/00V000"; + // + expected = new DataTime("2014-08-18 00:00:00.0 (0)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * C < M < V < D (F = 6) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_03_C_M_V_D_F006_A() { + decodeTime.set(2014, Calendar.SEPTEMBER, 01, 04, 22, 13); + frameTimeString = "01/03V006"; + // + expected = new DataTime("2014-08-31 21:00:00.0 (6)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * C < D < M < V (F = 96) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_04_C_D_M_V_F096_A() { + decodeTime.set(2014, Calendar.OCTOBER, 31, 04, 22, 13); + frameTimeString = "03/12V096"; // V = 2014-11-03 12:00:00 + // + expected = new DataTime("2014-10-30 12:00:00.0 (96)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * C < M < D < V (F = 240) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_05_C_M_D_V_F240_A() { + decodeTime.set(2017, Calendar.JULY, 01, 04, 22, 13); + frameTimeString = "02/18V240"; // V = 2017-07-02 18:00:00 + // + expected = new DataTime("2017-06-22 18:00:00.0 (240)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * C < V < M < D (F = 240) + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_06_C_V_M_D_F240_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + frameTimeString = "21/18V240"; // V = 2019-01-21 18:00:00 + // + expected = new DataTime("2019-01-11 18:00:00.0 (240)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: YYYYMMDDHH + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_10_YYYYMMDDHH_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "ecens_prob_2013042712_atl"; + frameTimeString = "07/12V240"; // V = 2013-05-07 12:00:00 + // + expected = new DataTime("2013-04-27 12:00:00.0 (240)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2013, decoder.yearFromFileName); + assertEquals((Integer) 04, decoder.monthFromFileName); + assertEquals((Integer) 27, decoder.dateFromFileName); + assertEquals((Integer) 12, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: YYYYMMDD_HH + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_11_YYYYMMDD_HH_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "cmc_20130429_00_chi_sta"; + frameTimeString = "09/00V240"; // V = 2013-05-09 00:00:00 + // + expected = new DataTime("2013-04-29 00:00:00.0 (240)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2013, decoder.yearFromFileName); + assertEquals((Integer) 04, decoder.monthFromFileName); + assertEquals((Integer) 29, decoder.dateFromFileName); + assertEquals((Integer) 00, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: YYMMDD_HH + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_12_YYMMDD_HH_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "iceaccr_130428_18"; + frameTimeString = "08/18V240"; // V = 2013-05-08 18:00:00 + // + expected = new DataTime("2013-04-28 18:00:00.0 (240)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2013, decoder.yearFromFileName); + assertEquals((Integer) 04, decoder.monthFromFileName); + assertEquals((Integer) 28, decoder.dateFromFileName); + assertEquals((Integer) 18, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: YYYYMMDD + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_13_YYYYMMDD_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "cpc_20130419_ecmwf"; + frameTimeString = "04/18V360"; // V = 2013-05-04 18:00:00 - F = 15 days + // + expected = new DataTime("2013-04-19 18:00:00.0 (360)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2013, decoder.yearFromFileName); + assertEquals((Integer) 04, decoder.monthFromFileName); + assertEquals((Integer) 19, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: YYMMDD + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_14_YYMMDD_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "cpc_130419_ecmwf"; + frameTimeString = "04/18V360"; // V = 2013-05-04 18:00:00 - F = 15 days + // + expected = new DataTime("2013-04-19 18:00:00.0 (360)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2013, decoder.yearFromFileName); + assertEquals((Integer) 04, decoder.monthFromFileName); + assertEquals((Integer) 19, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: Date without hour, followed later by date + * with hour + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_15_YYYYMMDD_YYYYMMDD_HH_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "gfs_gfs.20140829_gfs_20140829_18"; + frameTimeString = "29/18V000"; // V = 2013-05-04 18:00:00 - F = 15 days + // + expected = new DataTime("2014-08-29 18:00:00.0 (0)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2014, decoder.yearFromFileName); + assertEquals((Integer) 8, decoder.monthFromFileName); + assertEquals((Integer) 29, decoder.dateFromFileName); + assertEquals((Integer) 18, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Time spec in metafile name: Date with hour, followed later by date + * without hour + * + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String, java.util.Calendar)} + * . + */ + @Test + public final void testCreateDataTime_16_YYYYMMDD_HH_YYYYMMDD_A() { + decodeTime.set(2019, Calendar.FEBRUARY, 01, 04, 22, 13); + metafileName = "gfs_gfs.20140829_gfs_20140829_18"; + frameTimeString = "29/18V000"; // V = 2013-05-04 18:00:00 - F = 15 days + // + expected = new DataTime("2014-08-29 18:00:00.0 (0)"); + // + actual = decoder.createDataTime(frameTimeString, metafileName, + decodeTime); + // + assertEquals((Integer) 2014, decoder.yearFromFileName); + assertEquals((Integer) 8, decoder.monthFromFileName); + assertEquals((Integer) 29, decoder.dateFromFileName); + assertEquals((Integer) 18, decoder.hourFromFileName); + assertEquals(expected, actual); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testCreateDataTimeStringString1() { + DataTime a = decoder.createDataTime("14/22V036", + "GFS_DUMMY_20140713_10"); + assertEquals((Integer) 2014, decoder.yearFromFileName); + assertEquals((Integer) 07, decoder.monthFromFileName); + assertEquals((Integer) 13, decoder.dateFromFileName); + assertEquals((Integer) 10, decoder.hourFromFileName); + DataTime x = new DataTime("2014-07-13 10:00:00.0 (36)"); + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String)} + * . + */ + @Test + public final void testCreateDataTimeString1() { + DataTime a = decoder.createDataTime("20140714/22V036"); + assertEquals(null, decoder.yearFromFileName); + assertEquals(null, decoder.monthFromFileName); + assertEquals(null, decoder.dateFromFileName); + assertEquals(null, decoder.hourFromFileName); + DataTime x = new DataTime("2014-07-13 10:00:00.0 (36)"); + assertEquals(x, a); + + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName01() { + String a = decoder + .normalizeMetafileName("gfs_gfs.20140901_gfs_20140901_12_ak"); + String x = "gfs_20140901_12_ak"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName02() { + String a = decoder + .normalizeMetafileName("gdas_gdas.20140901_gdas_20140901_12_na"); + String x = "gdas_20140901_12_na"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName03() { + String a = decoder + .normalizeMetafileName("gefs_gefs.20140831_gefs_20140831_18_spag"); + String x = "gefs_20140831_18_spag"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName04() { + String a = decoder + .normalizeMetafileName("gefs_gefs.20140902_gefs_avgspr_20140902_06_natl"); + String x = "gefs_avgspr_20140902_06_natl"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName05() { + String a = decoder + .normalizeMetafileName("gfs_gfs.20140901_gfs_20140901_00_mar_skewt"); + String x = "gfs_20140901_00_mar_skewt"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName06() { + String a = decoder + .normalizeMetafileName("gfs_gfs.20140901_gfsver_20140901_00"); + String x = "gfsver_20140901_00"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName07() { + String a = decoder + .normalizeMetafileName("gfs_gfs.20140901_gfsver_20140901_18_na_mar"); + String x = "gfsver_20140901_18_na_mar"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName08() { + String a = decoder + .normalizeMetafileName("ghm_ghm.20140901_ghm_20140901_00_invest99l"); + String x = "ghm_20140901_00_invest99l"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName09() { + String a = decoder + .normalizeMetafileName("ghm_ghm.20140902_ghm_20140902_06_dolly05l_nest"); + String x = "ghm_20140902_06_dolly05l_nest"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName10() { + String a = decoder + .normalizeMetafileName("hwrf_hwrf.20140901_hwrf_20140901_06_invest99l_nest"); + String x = "hwrf_20140901_06_invest99l_nest"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName11() { + String a = decoder + .normalizeMetafileName("nam_nam.20140901_nam_20140901_00"); + String x = "nam_20140901_00"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName12() { + String a = decoder + .normalizeMetafileName("nam_nam.20140901_nam_20140901_00_bwx"); + String x = "nam_20140901_00_bwx"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName13() { + String a = decoder + .normalizeMetafileName("nam_nam.20140901_nam_20140901_00_mar_ver"); + String x = "nam_20140901_00_mar_ver"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName14() { + String a = decoder + .normalizeMetafileName("rap_rap.20140831_rap_20140831_23_anlloop"); + String x = "rap_20140831_23_anlloop"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName15() { + String a = decoder + .normalizeMetafileName("rap_rap.20140901_rap_20140901_01"); + String x = "rap_20140901_01"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName16() { + String a = decoder + .normalizeMetafileName("ukmet.2014090_ukmet.2014090._ukmetver_20140901_00"); + // now this one is tricky! + String x = "ukmetver_20140901_00"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName17() { + String a = decoder + .normalizeMetafileName("ukmet_ukmet.20140902_ukmet_20140902_00_trop"); + String x = "ukmet_20140902_00_trop"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName18() { + String a = decoder + .normalizeMetafileName("wave_wave.20140901_nww3_20140901_12"); + // yes, "wave" disappears here... + String x = "nww3_20140901_12"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName19() { + String a = decoder + .normalizeMetafileName("wave_wave.20140902_nww3_20140902_00_akw"); + String x = "nww3_20140902_00_akw"; + assertEquals(x, a); + } + + /** + * Test method for + * {@link gov.noaa.nws.ncep.edex.plugin.ntrans.decoder.NtransDecoder#createDataTime(java.lang.String, java.lang.String)} + * . + */ + @Test + public final void testNormalizeFileName20() { + String a = decoder + .normalizeMetafileName("opc_ens_20140901_18_gefs_prob_lo_spd"); + // should leave this one alone! + String x = "opc_ens_20140901_18_gefs_prob_lo_spd"; + assertEquals(x, a); + } + +} From acb128eb7228e1acda957aecd76d4cd88edec5ec Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 1 Dec 2014 17:17:39 -0500 Subject: [PATCH 18/19] VLab Issue #4003 - Mostly PGEN bug fixes minor updates to nsharp, lat/lon overlay, ntrans, and plotdata resource Change-Id: I2a1718ed7674edb786bceec13bcb20c29cc5d616 Former-commit-id: d9b57e6c7a5a4003602d6af1e625f686863a8f61 [formerly d9b57e6c7a5a4003602d6af1e625f686863a8f61 [formerly 8bdc663629050457b23d06c19bd7a925597c1288]] Former-commit-id: 57393984d300532ab07dff3238575e91d0fd1d60 Former-commit-id: dc922d5112b57f9a358a220b4914cf890e25289d --- .../parameters/core/contourinterval/CINT.java | 49 +- .../display/rsc/NsharpResourceHandler.java | 7 +- .../ui/nsharp/view/NsharpPaletteWindow.java | 51 +- .../localization/ncep/pgen/settings_tbl.xml | 2 +- .../pgen/settings_tbl_Surface_Analysis.xml | 2 +- .../pgen/xslt/airmet/get_attention_line.xsl | 5 +- .../ncep/pgen/xslt/airmet/get_status.xsl | 17 +- .../ncep/pgen/xslt/airmet/output_outlook.xsl | 7 +- .../nws/ncep/ui/pgen/attrdialog/AttrDlg.java | 22 +- .../ui/pgen/attrdialog/ContoursAttrDlg.java | 124 +- .../ui/pgen/attrdialog/GfaFormatAttrDlg.java | 16 +- .../ncep/ui/pgen/attrdialog/TrackAttrDlg.java | 2241 ++++++------ .../pgen/display/DefaultElementContainer.java | 21 +- .../pgen/display/DisplayElementFactory.java | 35 +- .../noaa/nws/ncep/ui/pgen/display/ITrack.java | 218 +- .../pgen/display/RasterElementContainer.java | 118 +- .../ui/pgen/display/TextDisplayElement.java | 35 +- .../noaa/nws/ncep/ui/pgen/elements/Track.java | 2300 ++++++------ .../ncep/ui/pgen/file/ProductConverter.java | 13 +- .../gov/noaa/nws/ncep/ui/pgen/file/Track.java | 311 +- .../nws/ncep/ui/pgen/file/TrackConverter.java | 691 ++-- .../noaa/nws/ncep/ui/pgen/file/product.xsd | 49 +- .../nws/ncep/ui/pgen/gfa/GfaGenerate.java | 812 ++--- .../noaa/nws/ncep/ui/pgen/gfa/GfaInfo.java | 715 ++-- .../noaa/nws/ncep/ui/pgen/gfa/GfaRules.java | 3156 +++++++++-------- .../layering/PgenLayeringControlDialog.java | 1218 +++---- .../productmanage/ProductManageDialog.java | 41 +- .../pgen/productmanage/ProductNameDialog.java | 883 ++--- .../nws/ncep/ui/pgen/rsc/PgenResource.java | 11 +- .../ncep/ui/pgen/rsc/PgenResourceGhost.java | 61 +- .../ncep/ui/pgen/tools/PgenContoursTool.java | 1 + .../resources/LatLonOverlayResource.java | 388 +- .../ui/createRbd/NtransSelectionControl.java | 18 + .../attributes/ResourceExtPointMngr.java | 663 ++-- .../ncep/viz/rsc/ncgrid/dgdriv/Dgdriv.java | 94 +- .../nws/ncep/viz/rsc/ntrans/ncgm/README.txt | 28 + .../NcPlotModelHdf5DataRequestor.java | 2 +- 37 files changed, 7515 insertions(+), 6910 deletions(-) create mode 100644 ncep/gov.noaa.nws.ncep.viz.rsc.ntrans/src/gov/noaa/nws/ncep/viz/rsc/ntrans/ncgm/README.txt diff --git a/ncep/gov.noaa.nws.ncep.gempak.parameters.core/src/gov/noaa/nws/ncep/gempak/parameters/core/contourinterval/CINT.java b/ncep/gov.noaa.nws.ncep.gempak.parameters.core/src/gov/noaa/nws/ncep/gempak/parameters/core/contourinterval/CINT.java index 25e950d299..7472b4e3d8 100644 --- a/ncep/gov.noaa.nws.ncep.gempak.parameters.core/src/gov/noaa/nws/ncep/gempak/parameters/core/contourinterval/CINT.java +++ b/ncep/gov.noaa.nws.ncep.gempak.parameters.core/src/gov/noaa/nws/ncep/gempak/parameters/core/contourinterval/CINT.java @@ -47,7 +47,7 @@ import java.util.Set; * 17-May-2011 M. Li Created a parseCINT to simplify CINT parsing. * 07-Apr-2014 TTR-938 D.Sushon Added check for null string to constructor, fixing NullPointerException * thrown when attempting to initialize with null String. - * + * 09-Sep-2014 TTR-852 A.Yuk remove restriction of contour lines =50 and make it unlimited contour lines. * * * @@ -56,7 +56,7 @@ import java.util.Set; * @see $GEMPAK/help/hlx/cint.hl2 */ public class CINT { - + /** The object responsible for parsing the CINT string */ private ContourStringParser cintParser; @@ -396,20 +396,44 @@ public class CINT { if (interval == null || interval.isNaN()) { interval = (cmax - cmin) / 10.0; } - - // Only allow less than 50 contour levels - if ((cmax - cmin) / interval > 50) - interval = (cmax - cmin) / 50; - - // System.out.println(" cmax=="+cmax); + +// Only allow less than 50 contour levels : +// comment out contour restriction. : IT WAs BAD Code to generate decimal point on contour labels. + /* if ((cmax - cmin) / interval > 50) { + interval = (cmax - cmin) / 50; + interval =(double) (int) ((cmax - cmin)/50) ; } + */ contourInfo = new CINT(interval.toString() + "/" + cmin.toString() + "/" + cmax.toString()); cvalues = contourInfo - .getUniqueSortedContourValuesFromAllZoomLevels(); + .getUniqueSortedContourValuesFromAllZoomLevels(); + } + } + +/******************************** + int csize=cvalues.size(); + System.out.println(" ................."); + System.out.println(" ................."); + System.out.println(" Contour level range is from "+cvalues.get(0)+" to "+cvalues.get(csize-1)+"."); + System.out.println(" Contour interval "+interval+"."); + System.out.println(" ................."); + System.out.println(" ................."); +// * capped contour lines to 50 + if (csize > 50) { + System.out.println(" !!! Pay attention to CONTOUR INTERVAL."); + System.out.println(" Contour lines from "+cvalues.get(0)+" to "+cvalues.get(csize-1)+" are eliminated due to maximum contour allowance." ); + while (cvalues.size()>50){cvalues.remove(50);} + System.out.println(" !!! Contours are being plotted to the first 50th lines."); + System.out.println(" Range of contour lines drawn is from "+cvalues.get(0)+" to "+cvalues.get(49)+"."); + System.out.println(" !!! Contour lines are capped due to allowance of maximum contour lines of 50. "); } - } - - return cvalues; + System.out.println(" Contour level = "+cvalues.toString()+"."); +***************************/ + while (cvalues.size()>50){cvalues.remove(50);} + int csize=cvalues.size(); + System.out.println(" Contour lines("+csize+ ") from "+cvalues.get(0)+" to "+cvalues.get(csize-1)); + + return cvalues; } /** @return boolean isCINTStringParsed */ @@ -652,3 +676,4 @@ public class CINT { } } + diff --git a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/display/rsc/NsharpResourceHandler.java b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/display/rsc/NsharpResourceHandler.java index 1b1b867fe4..f9f861282f 100644 --- a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/display/rsc/NsharpResourceHandler.java +++ b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/display/rsc/NsharpResourceHandler.java @@ -1940,9 +1940,10 @@ public class NsharpResourceHandler { return; } if (!fromArchive) { - // start FixMark:nearByStnCompSnd d2dlite - if (!(sndType.contentEquals("NCUAIR") || sndType - .contentEquals("BUFRUA"))) { + // For those sounding report with forecast time, e.g. model/pfc sounding + if (timeLine.contains("V")) { //fix D2D loading issue. 10/8/2014 + // if (!(sndType.contentEquals("NCUAIR") || sndType + // .contentEquals("BUFRUA"))) { // Chin's NOTE: // Can Not use reference time directly from the stnInfo, // Timestamp refTime = stnInfo.getReftime() diff --git a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java index 390883ca95..be2d25a49b 100644 --- a/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java +++ b/ncep/gov.noaa.nws.ncep.ui.nsharp/src/gov/noaa/nws/ncep/ui/nsharp/view/NsharpPaletteWindow.java @@ -16,7 +16,7 @@ * 01/08/2014 Chin Chen Only initializing inventory when in NCP * 01/13/2014 Chin Chen TTR829- when interpolation, edit graph is allowed * 01/22/2014 Chin Chen DR17003 issue: NSHARP sounding display throws errors when swapping into main pane when show text is turned on. - * + * 10/20/2014 Chin Chen DR16864, D2D does not use unload button. Check to make sure not D2D instance before access unload button. * * * @author Chin Chen @@ -150,7 +150,7 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, private boolean spcGpCreated = false; - private boolean awcGpCreated = false; + private boolean imD2d = false; // fixMark:NcInventory public static NsharpPaletteWindow getInstance() { if (VizPerspectiveListener.getCurrentPerspectiveManager() != null) { @@ -220,7 +220,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, interpBtn.setEnabled(false); graphModeBtnIcing.setEnabled(false); graphModeBtnTurb.setEnabled(false); - unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd } else if (compareStnIsOn) { compareStnBtn.setText(COMP_STN_ON); graphEditBtn.setEnabled(false); @@ -231,7 +232,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, interpBtn.setEnabled(false); graphModeBtnIcing.setEnabled(false); graphModeBtnTurb.setEnabled(false); - unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd } else if (compareSndIsOn) { compareSndBtn.setText(COMP_SND_ON); graphEditBtn.setEnabled(false); @@ -242,7 +244,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, interpBtn.setEnabled(false); graphModeBtnIcing.setEnabled(false); graphModeBtnTurb.setEnabled(false); - unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd } else if (compareTmIsOn) { compareTmBtn.setText(COMP_TM_ON); compareSndBtn.setEnabled(false); @@ -253,7 +256,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, interpBtn.setEnabled(false); graphModeBtnIcing.setEnabled(false); graphModeBtnTurb.setEnabled(false); - unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd } else if (editGraphOn) { graphEditBtn.setText(EDIT_GRAPH_ON); dataEditBtn.setEnabled(false); @@ -264,7 +268,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, interpBtn.setEnabled(false); graphModeBtnIcing.setEnabled(false); graphModeBtnTurb.setEnabled(false); - unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false); // FixMark:nearByStnCompSnd } } else if (currentGraphMode == NsharpConstants.GRAPH_TURB) { @@ -377,7 +382,7 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, public NsharpPaletteWindow() { super(); instance = this; - boolean imD2d = false; // fixMark:NcInventory + //boolean imD2d = false; // fixMark:NcInventory if (VizPerspectiveListener.getCurrentPerspectiveManager() != null) { if (VizPerspectiveListener.getCurrentPerspectiveManager() .getPerspectiveId().equals(D2D5Pane.ID_PERSPECTIVE)) { @@ -945,7 +950,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(false); interpBtn.setEnabled(false); cfgBtn.setEnabled(false); - unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd } else { overlayIsOn = false; overlayBtn.setText(OVLY_OFF); @@ -958,7 +964,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(true); interpBtn.setEnabled(true); cfgBtn.setEnabled(true); - unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd } NsharpResourceHandler rsc = getRscHandler(); if (rsc != null) { @@ -1001,7 +1008,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(false); interpBtn.setEnabled(false); cfgBtn.setEnabled(false); - unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd } else { compareStnIsOn = false; compareStnBtn.setText(COMP_STN_OFF); @@ -1014,7 +1022,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(true); interpBtn.setEnabled(true); cfgBtn.setEnabled(true); - unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd } NsharpResourceHandler rsc = getRscHandler(); if (rsc != null) { @@ -1059,7 +1068,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(false); interpBtn.setEnabled(false); cfgBtn.setEnabled(false); - unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd } else { compareTmIsOn = false; compareTmBtn.setText(COMP_TM_OFF); @@ -1072,7 +1082,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(true); interpBtn.setEnabled(true); cfgBtn.setEnabled(true); - unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd } NsharpResourceHandler rsc = getRscHandler(); if (rsc != null) { @@ -1115,7 +1126,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(false); interpBtn.setEnabled(false); cfgBtn.setEnabled(false); - unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd } else { compareSndIsOn = false; compareSndBtn.setText(COMP_SND_OFF); @@ -1128,7 +1140,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, graphModeBtnIcing.setEnabled(true); interpBtn.setEnabled(true); cfgBtn.setEnabled(true); - unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd } NsharpResourceHandler rsc = getRscHandler(); if (rsc != null) { @@ -1187,7 +1200,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, compareSndBtn.setEnabled(true); compareStnBtn.setEnabled(true); overlayBtn.setEnabled(true); - unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(true);// FixMark:nearByStnCompSnd } } else { editGraphOn = true; @@ -1200,7 +1214,8 @@ public class NsharpPaletteWindow extends ViewPart implements SelectionListener, compareSndBtn.setEnabled(false); compareStnBtn.setEnabled(false); overlayBtn.setEnabled(false); - unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd + if (!imD2d) + unloadBtn.setEnabled(false);// FixMark:nearByStnCompSnd } NsharpResourceHandler rsc = getRscHandler(); if (rsc != null) { diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl.xml b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl.xml index d208e7a0c7..691ee0e477 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl.xml +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl.xml @@ -840,7 +840,7 @@ - + diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl_Surface_Analysis.xml b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl_Surface_Analysis.xml index 87b170cdab..6bf8fcd9fb 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl_Surface_Analysis.xml +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/settings_tbl_Surface_Analysis.xml @@ -803,7 +803,7 @@ - + diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_attention_line.xsl b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_attention_line.xsl index e2066390b8..1921311f21 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_attention_line.xsl +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_attention_line.xsl @@ -18,6 +18,7 @@ E. Safford/SAIC 06/07 rm "...UPDT TO CANCEL..." B. Yin/SAIC 02/08 add tag number after cancellation B. Yin 12/11 added new line for 'New' or 'Cor' + J. Wu 09/14 added new line for 'CAN' --> @@ -25,14 +26,16 @@ - + 0 + CANCEL AIRMET. CONDS HV ENDED. + CANCEL OUTLOOK. diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_status.xsl b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_status.xsl index 8b34b9c8d3..4c3756067f 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_status.xsl +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/localization/ncep/pgen/xslt/airmet/get_status.xsl @@ -20,15 +20,19 @@ B. Yin/SAIC 08/06 distinguish smear and outlook B. Yin/Chugach 12/11 changed 'Status' to 'issueType' changed for-each condition for smears - + J. Wu/SGT 10/14 TTR 714 - go through all smears (airmets & outlooks) in + one loop since the input XML format is different from + those in NMAP2 + --> NO HAZARD1 NO HAZARD2 NO HAZARD3 - - + + @@ -46,8 +50,9 @@ - - + + - +--> diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/AttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/AttrDlg.java index 2e3a9c4962..d961f7f897 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/AttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/AttrDlg.java @@ -78,6 +78,7 @@ public abstract class AttrDlg extends Dialog implements IAttribute { public static int ctrlBtnHeight = 28; // public static int ctrlBtnWidth = 90; + // public static int ctrlBtnHeight = 30; /** @@ -128,11 +129,24 @@ public abstract class AttrDlg extends Dialog implements IAttribute { this.getButton(IDialogConstants.CANCEL_ID).setEnabled(false); this.getButton(IDialogConstants.OK_ID).setEnabled(false); - this.getButton(IDialogConstants.CANCEL_ID).setLayoutData( - new GridData(ctrlBtnWidth, ctrlBtnHeight)); - this.getButton(IDialogConstants.OK_ID).setLayoutData( - new GridData(ctrlBtnWidth, ctrlBtnHeight)); + setDefaultControlButtonSize(); + } + /** + * Set default size for control buttons. + */ + public void setDefaultControlButtonSize() { + setButtonSize(ctrlBtnWidth, ctrlBtnHeight); + } + + /** + * Set size for control buttons. + */ + public void setButtonSize(int width, int height) { + this.getButton(IDialogConstants.CANCEL_ID).setLayoutData( + new GridData(width, height)); + this.getButton(IDialogConstants.OK_ID).setLayoutData( + new GridData(width, height)); } @Override diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/ContoursAttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/ContoursAttrDlg.java index ebd338f1d9..18e7a06ccd 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/ContoursAttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/ContoursAttrDlg.java @@ -3169,6 +3169,10 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, private PgenContoursTool tool = null; + private Contours prevCont = null; + + private Contours nowCont = null; + private ContourMinmaxAttrDlg(Shell parShell) throws VizException { super(parShell); @@ -3238,11 +3242,54 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, if (apt instanceof PgenContoursTool) { tool = (PgenContoursTool) apt; } + if (tool != null) { tool.resetUndoRedoCount(); PgenSession.getInstance().getCommandManager() .addStackListener(tool); } + + // set the lat/lon from the current symbol. + DrawableElement de = drawingLayer.getSelectedDE(); + if (de != null && de.getParent() instanceof ContourMinmax + && de instanceof Symbol) { + super.setLatitude(((Symbol) de).getLocation().y); + super.setLongitude(((Symbol) de).getLocation().x); + } + + /* + * Reset the listenser. + */ + for (Listener ls : undoBtn.getListeners(SWT.MouseDown)) { + undoBtn.removeListener(SWT.MouseDown, ls); + } + + undoBtn.addListener(SWT.MouseDown, new Listener() { + + @Override + public void handleEvent(Event event) { + + if (undoBtn.getText().equalsIgnoreCase(UNDO_SYMBOL)) { + undoBtn.setText(REDO_SYMBOL); + drawingLayer.getCommandMgr().undo(); + + } else if (undoBtn.getText().equalsIgnoreCase(REDO_SYMBOL)) { + undoBtn.setText(UNDO_SYMBOL); + drawingLayer.getCommandMgr().redo(); + } + + /* + * Reset the currentContours for the ContoursAttrDlg. + */ + currentContours = prevCont; + prevCont = nowCont; + nowCont = currentContours; + + mapEditor.refresh(); + + } + + }); } @Override @@ -3252,6 +3299,10 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, PgenSession.getInstance().getCommandManager() .removeStackListener(tool); } + + prevCont = null; + nowCont = null; + return super.close(); } @@ -3262,15 +3313,34 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, protected void placeSymbol() { if (tool != null) { + if (tool.getMouseHandler() instanceof PgenContoursHandler) { + /* + * Keep a copy of currentConoturs for "Undo". It chnages + * after call the "tool". + */ + prevCont = currentContours; + ((PgenContoursHandler) tool.getMouseHandler()) + .drawContourMinmax(new Coordinate(Double + .parseDouble(longitudeText.getText()), + Double.parseDouble(latitudeText.getText()))); + placeBtn.setEnabled(false); + nowCont = currentContours; // Keep a copy for "Redo" + undoBtn.setEnabled(true); + undoBtn.setText("Undo Symbol"); - ((PgenContoursHandler) tool.getMouseHandler()) - .drawContourMinmax(new Coordinate(Double - .parseDouble(longitudeText.getText()), Double - .parseDouble(latitudeText.getText()))); - placeBtn.setEnabled(false); - undoBtn.setEnabled(true); - undoBtn.setText("Undo Symbol"); + } else if (tool.getMouseHandler() instanceof PgenSelectHandler) { + minmaxTemplate = (gov.noaa.nws.ncep.ui.pgen.elements.Symbol) new DrawableElementFactory() + .create(DrawableType.SYMBOL, (IAttribute) this, + "Symbol", getActiveSymbolObjType(), + (Coordinate) null, null); + contoursAttrSettings.put(getActiveSymbolObjType(), + minmaxTemplate); + updateMinmaxAttributes(); + + placeBtn.setEnabled(false); + + } } } } @@ -3330,7 +3400,34 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, if (newEl != null && oldAdc.equals(de.getParent())) { newEl.setParent(newAdc); + if (newEl instanceof Symbol) { + + if (minmaxAttrDlg != null + && minmaxAttrDlg.getShell() != null) { + if (minmaxAttrDlg.latitudeText.isEnabled() + && minmaxAttrDlg.longitudeText + .isEnabled()) { + ArrayList loc = new ArrayList(); + double lat = ((Symbol) newEl).getLocation().y; + double lon = ((Symbol) newEl).getLocation().x; + try { + lon = Double + .valueOf(minmaxAttrDlg.longitudeText + .getText()); + lat = Double + .valueOf(minmaxAttrDlg.latitudeText + .getText()); + } catch (Exception e) { + lon = ((Symbol) newEl).getLocation().x; + lat = ((Symbol) newEl).getLocation().y; + } + + loc.add(new Coordinate(lon, lat)); + newEl.setPoints(loc); + } + } + ((DECollection) newAdc) .replace(((ContourMinmax) newAdc) .getSymbol(), newEl); @@ -3338,6 +3435,8 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, ((ContourMinmax) newAdc).getSymbol().update( minmaxTemplate); + + ((ContourMinmax) newAdc).getLabel().setAuto(true); } } @@ -3926,4 +4025,15 @@ public class ContoursAttrDlg extends AttrDlg implements IContours, return typeChanged; } + /** + * Update lat/lon and Undo button on SymbolAttrDlg. + */ + public void updateSymbolAttrOnGUI(Coordinate loc) { + if (minmaxAttrDlg != null && minmaxAttrDlg.getShell() != null) { + minmaxAttrDlg.setLatitude(loc.y); + minmaxAttrDlg.setLongitude(loc.x); + minmaxAttrDlg.enableUndoBtn(true); + } + } + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/GfaFormatAttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/GfaFormatAttrDlg.java index 1baeca0350..1befb3e618 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/GfaFormatAttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/GfaFormatAttrDlg.java @@ -68,9 +68,6 @@ import com.raytheon.uf.viz.core.exception.VizException; */ public class GfaFormatAttrDlg extends AttrDlg { - // private final static Logger logger = - // Logger.getLogger(GfaFormatAttrDlg.class); - private static final String ZULU = "ZULU"; private static final String TANGO = "TANGO"; @@ -151,7 +148,6 @@ public class GfaFormatAttrDlg extends AttrDlg { instance = new GfaFormatAttrDlg(parShell); } catch (VizException e) { - // logger.error(e); e.printStackTrace(); } } @@ -306,12 +302,14 @@ public class GfaFormatAttrDlg extends AttrDlg { @Override public void createButtonsForButtonBar(Composite parent) { - super.createButtonsForButtonBar(parent); - this.getButton( OK_ID ).setText( SAVE_LABEL ); - this.getButton( CANCEL_ID).setText( CANCEL_LABEL ); + super.createButtonsForButtonBar(parent); + this.getButton(OK_ID).setText(SAVE_LABEL); + this.getButton(CANCEL_ID).setText(CANCEL_LABEL); + } - // createButton(parent, OK_ID, SAVE_LABEL, true); - // createButton(parent, CANCEL_ID, CANCEL_LABEL, false); + @Override + public void setDefaultControlButtonSize() { + setButtonSize(ctrlBtnWidth + 50, ctrlBtnHeight); } @Override diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/TrackAttrDlg.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/TrackAttrDlg.java index 6134338ed8..24e5633982 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/TrackAttrDlg.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/attrdialog/TrackAttrDlg.java @@ -8,39 +8,39 @@ package gov.noaa.nws.ncep.ui.pgen.attrdialog; +import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; +import gov.noaa.nws.ncep.ui.pgen.display.IAttribute; +import gov.noaa.nws.ncep.ui.pgen.display.IText.FontStyle; +import gov.noaa.nws.ncep.ui.pgen.display.ITrack; +import gov.noaa.nws.ncep.ui.pgen.display.TrackPoint; +import gov.noaa.nws.ncep.ui.pgen.elements.AbstractDrawableComponent; +import gov.noaa.nws.ncep.ui.pgen.elements.Track; +import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; + +import java.awt.Color; import java.util.ArrayList; import java.util.Calendar; -import java.awt.Color; import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Label; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Label; +import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.raytheon.uf.viz.core.exception.VizException; import com.vividsolutions.jts.geom.Coordinate; -import gov.noaa.nws.ncep.ui.pgen.display.ITrack; -import gov.noaa.nws.ncep.ui.pgen.display.IText.FontStyle; -import gov.noaa.nws.ncep.ui.pgen.display.TrackPoint; -import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; -import gov.noaa.nws.ncep.ui.pgen.elements.AbstractDrawableComponent; -import gov.noaa.nws.ncep.ui.pgen.display.IAttribute; -import gov.noaa.nws.ncep.ui.pgen.elements.Track; -import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; - /** * Singleton attribute dialog for Track. * @@ -61,1319 +61,1306 @@ import gov.noaa.nws.ncep.viz.common.ui.color.ColorButtonSelector; * Added isNewTrack flag to make the FirstTime(/SecondTime) current time when create a Track * 03/13 #928 B. Yin Added a separator above the button bar. * 08/13 #1020 B. Yin Fixed the 'Other' interval problem. + * 09/14 TTR750 J. Wu Use fontStyle for track labels. * * - * @author M. Gao + * @author M. Gao */ -public class TrackAttrDlg extends AttrDlg implements ITrack{ - -// private final static org.apache.log4j.Logger log = -// org.apache.log4j.Logger.getLogger(TrackAttrDlg.class); - - public static enum FontSizeName { TINY, SMALL, MEDIUM, LARGE, HUGE, GIANT }; - public static int[] FontSizeValue = { 10, 12, 14, 18, 24, 34 }; - //public static String[] FontName = new String[]{ "Courier", "Helvetica", "Times" }; - public static String[] FontName = new String[]{ "Courier", "Nimbus Sans L", "Liberation Serif" }; +public class TrackAttrDlg extends AttrDlg implements ITrack { - public static String[] BoxName = new String[]{ "Normal", "Boxed", "Blanked", "Outline" }; - - private final int DEFAULT_NUMBER_OF_TIMES = 5; - private final int DEFAULT_HOUR_SHIFT_FOR_FIRST_TIME = 4; - private final int DEFAULT_HOUR_SHIFT_BEYOND_FIRST_TIME = 1; - - private static String[] IntervalTimeValues = {"00:15", "00:30", "01:00", "02:00", "06:00", - "12:00", "Other"}; - private String previousIntervalTimeValue = ""; + public static enum FontSizeName { + TINY, SMALL, MEDIUM, LARGE, HUGE, GIANT + }; - private static String[] UnitValues = {"kts", "kph", "mph"}; - private static String[] RoundTo = {" ", "5", "10"}; - private static String[] RoundDirTo = {" ", "1", "5"}; - - private Text firstTimeText; - private Text secondTimeText; - private boolean setTimeButtonSelected; - private Button frameTimeButton; - private Button setTimeButton; - - private Text numberOfTimesText; - private Text intervalText; + public static int[] FontSizeValue = { 10, 12, 14, 18, 24, 34 }; - private Text skipFactorText; - private ExtraPointTimeDisplayOption extraPointTimeDisplayOption; - - // private Composite top = null; + public static String[] FontName = new String[] { "Courier", + "Nimbus Sans L", "Liberation Serif" }; + + public static String[] BoxName = new String[] { "Normal", "Boxed", + "Blanked", "Outline" }; + + private final int DEFAULT_NUMBER_OF_TIMES = 5; + + private final int DEFAULT_HOUR_SHIFT_FOR_FIRST_TIME = 4; + + private final int DEFAULT_HOUR_SHIFT_BEYOND_FIRST_TIME = 1; + + private static String[] IntervalTimeValues = { "00:15", "00:30", "01:00", + "02:00", "06:00", "12:00", "Other" }; + + private String previousIntervalTimeValue = ""; + + private static String[] UnitValues = { "kts", "kph", "mph" }; + + private static String[] RoundTo = { " ", "5", "10" }; + + private static String[] RoundDirTo = { " ", "1", "5" }; + + private Text firstTimeText; + + private Text secondTimeText; + + private boolean setTimeButtonSelected; + + private Button frameTimeButton; + + private Button setTimeButton; + + private Text numberOfTimesText; + + private Text intervalText; + + private Text skipFactorText; + + private ExtraPointTimeDisplayOption extraPointTimeDisplayOption; + + // private Composite top = null; private ColorButtonSelector initialCS; + private ColorButtonSelector extrapCS; - + private Text text = null; - private Combo intervalCombo; - - private Combo unitCombo; - private int unitComboSelectedIndex; - private Button roundButton; - private Combo roundCombo; - private int roundComboSelectedIndex; - private Button roundDirButton; - private Combo roundDirCombo; - private int roundDirComboSelectedIndex; - - private Combo fontSizeCombo; - private int fontSizeComboSelectedIndex; - private Combo fontNameCombo; - private int fontNameComboSelectedIndex; - private Combo fontStyleCombo; - private int fontStyleComboSelectedIndex; + private Combo intervalCombo; + + private Combo unitCombo; + + private int unitComboSelectedIndex; + + private Button roundButton; + + private Combo roundCombo; + + private int roundComboSelectedIndex; + + private Button roundDirButton; + + private Combo roundDirCombo; + + private int roundDirComboSelectedIndex; + + private Combo fontSizeCombo; + + private int fontSizeComboSelectedIndex; + + private Combo fontNameCombo; + + private int fontNameComboSelectedIndex; + + private Combo fontStyleCombo; + + private int fontStyleComboSelectedIndex; + + private Button skipFactorButton; + + private Button showFirstLastButton; + + private Button onHourButton; + + private Button onHalfHourButton; + + private Calendar firstTimeCalendar; + + private Calendar secondTimeCalendar; + + private int numberOfTimes = DEFAULT_NUMBER_OF_TIMES; // set the default to 5 + + TrackExtrapPointInfoDlg trackExtrapPointInfoDlg; + + private static TrackAttrDlg INSTANCE = null; + + public boolean isNewTrack = false; - private Button skipFactorButton; - private Button showFirstLastButton; - private Button onHourButton; - private Button onHalfHourButton; - - private Calendar firstTimeCalendar; - private Calendar secondTimeCalendar; - - private int numberOfTimes = DEFAULT_NUMBER_OF_TIMES; //set the default to 5 - - TrackExtrapPointInfoDlg trackExtrapPointInfoDlg; - - private static TrackAttrDlg INSTANCE = null; - - public boolean isNewTrack = false; - /** - * Private constructor - * @param parShell - * @throws VizException - */ - private TrackAttrDlg(Shell parShell) throws VizException { + * Private constructor + * + * @param parShell + * @throws VizException + */ + private TrackAttrDlg(Shell parShell) throws VizException { super(parShell); } - - /** - * Creates a track attribute dialog if the dialog does not exist - * and returns the instance. If the dialog exists, return the instance. - * - * @param parShell - * @return - */ - public static TrackAttrDlg getInstance( Shell parShell){ - if ( INSTANCE == null ){ - try { - INSTANCE = new TrackAttrDlg( parShell ); - } catch (VizException e) { - e.printStackTrace(); - } - } - return INSTANCE; - } - - public void okPressed() { - - ArrayList adcList = null; - ArrayList newList = new ArrayList() ; - //get the list of selected tracks - if ( drawingLayer != null ) { - adcList = (ArrayList) drawingLayer.getAllSelected(); - } - - if ( adcList != null && !adcList.isEmpty() ){ - - Track newEl = null; - //loop through the list and update attributes - for ( AbstractDrawableComponent adc : adcList){ + /** + * Creates a track attribute dialog if the dialog does not exist and returns + * the instance. If the dialog exists, return the instance. + * + * @param parShell + * @return + */ + public static TrackAttrDlg getInstance(Shell parShell) { + if (INSTANCE == null) { + try { + INSTANCE = new TrackAttrDlg(parShell); + } catch (VizException e) { + e.printStackTrace(); + } + } + return INSTANCE; + } - Track el = (Track)adc.getPrimaryDE(); + public void okPressed() { - if ( el != null ){ - // Create a copy of the currently selected element - newEl = (Track)el.copy(); - // Update the new Element with these current attributes - newEl.update(this); - /* - * populate the TrackExtrapPointInofDlg object - */ - populateTrackExtrapPointInfoDlgWithNewTrackData(getTrackExtrapPointInfoDlg(), newEl, - unitComboSelectedIndex, roundComboSelectedIndex, roundDirComboSelectedIndex); - - newList.add(newEl); + ArrayList adcList = null; + ArrayList newList = new ArrayList(); - } - } - - if ( newEl != null ){ - AttrSettings.getInstance().setSettings( newEl ); - } - - ArrayList oldList = new ArrayList(adcList); - drawingLayer.replaceElements(oldList, newList); - } - - // set the new elements as selected. - drawingLayer.removeSelected(); - for ( AbstractDrawableComponent adc : newList ){ - drawingLayer.addSelected(adc); - } - - if ( mapEditor != null ) { - mapEditor.refresh(); - } - } + // get the list of selected tracks + if (drawingLayer != null) { + adcList = (ArrayList) drawingLayer + .getAllSelected(); + } - public void cancelPressed(){ - - if(trackExtrapPointInfoDlg != null) { - trackExtrapPointInfoDlg.close(); - trackExtrapPointInfoDlg = null; - } - super.cancelPressed(); - - } - - /** - * Creates the dialog area - */ - @Override - public Control createDialogArea(Composite parent) { - - Composite top = (Composite) super.createDialogArea(parent); + if (adcList != null && !adcList.isEmpty()) { - // Create the main layout for the shell. - GridLayout mainLayout = new GridLayout(2, false); - mainLayout.marginHeight = 3; - mainLayout.marginWidth = 3; - top.setLayout(mainLayout); + Track newEl = null; + // loop through the list and update attributes + for (AbstractDrawableComponent adc : adcList) { - // Initialize all of the menus, controls, and layouts - initializeComponents(top); + Track el = (Track) adc.getPrimaryDE(); - return top; - - } - - public void initializeTrackAttrDlg(Track track) { - if(track == null) - return; - /* - * 1. restore frameTimeButton and setTimeButton status - */ - if(track.isSetTimeButtonSelected()) { - getSetTimeButton().setSelection(true); - getFrameTimeButton().setSelection(false); - } else { - getFrameTimeButton().setSelection(true); - getSetTimeButton().setSelection(false); - } - /* - * 2. restore first time and second time text values - */ - if (isNewTrack == true) { - String[] firstSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); - getFirstTimeText().setText(firstSecondTimeValueArray[0]); - getSecondTimeText().setText(firstSecondTimeValueArray[1]); - } - else { - - getFirstTimeText().setText(getFirstOrSecondTimeStringValue(track.getFirstTimeCalendar(), true, track.getInitialPoints())); - getSecondTimeText().setText(getFirstOrSecondTimeStringValue(track.getSecondTimeCalendar(), false, track.getInitialPoints())); - } - - //isNewTrack = false; - /* - * 3. restore Number of times value - */ - if(track.getExtrapPoints() != null) - numberOfTimesText.setText(String.valueOf(track.getExtrapPoints().length)); - - /* - * 4. restore interval time settings - */ -// intervalCombo.select(track.getIntervalComboSelectedIndex()); -// int intervalComboItemCount = intervalCombo.getItemCount(); -// if ( (intervalComboItemCount - 1) == track.getIntervalComboSelectedIndex() ) -// intervalText.setText(track.getIntervalTimeString()); - - setIntervalTimeString( track.getIntervalTimeString() ); - -// restoreIntervalTimeSettingByTrack(this, track); - - /* - * 5. restore initial and extrap colors - */ - java.awt.Color initColor = track.getInitialColor(); - initialCS.setColorValue(new RGB(initColor.getRed(), initColor.getGreen(), initColor.getBlue())); - java.awt.Color extrapColor = track.getExtrapColor(); - extrapCS.setColorValue(new RGB(extrapColor.getRed(), extrapColor.getGreen(), extrapColor.getBlue())); - - /* - * 6. restore label option settings - */ - setExtraPointTimeDisplayOption(track.getExtraPointTimeDisplayOption()); - makeTimeDisplayOptionSelected(track.getExtraPointTimeDisplayOption(), track.getSkipFactorTextString()); - - /* - * 7. restore Font, Size, Style combo values - */ - getFontNameCombo().select(track.getFontNameComboSelectedIndex()); - getFontSizeCombo().select(track.getFontSizeComboSelectedIndex()); - getFontStyleCombo().select(track.getFontStyleComboSelectedIndex()); - - /* - * 7. restore Unit combo values - */ - unitComboSelectedIndex = track.getUnitComboSelectedIndex(); - getUnitCombo().select(unitComboSelectedIndex); - - roundComboSelectedIndex = track.getRoundComboSelectedIndex(); - getRoundCombo().select(roundComboSelectedIndex); - if (roundComboSelectedIndex >0) - roundButton.setSelection(true); - else - roundButton.setSelection(false); - - roundDirComboSelectedIndex = track.getRoundDirComboSelectedIndex(); - getRoundDirCombo().select(roundDirComboSelectedIndex); - if (roundDirComboSelectedIndex >0) - roundDirButton.setSelection(true); - else - roundDirButton.setSelection(false); - } - - private void populateTrackExtrapPointInfoDlgWithNewTrackData(TrackExtrapPointInfoDlg trackExtrapPointInfoDlgObject, - Track newTrackObject, int unitComboSelectedIndex, int roundComboSelectedIndex, int roundDirComboSelectedIndex) { - if(trackExtrapPointInfoDlgObject != null && newTrackObject != null) { - trackExtrapPointInfoDlgObject.close(); - - trackExtrapPointInfoDlgObject.setBlockOnOpen( false ); - trackExtrapPointInfoDlgObject.open(); - - trackExtrapPointInfoDlgObject.setTrack(newTrackObject, unitComboSelectedIndex, roundComboSelectedIndex, roundDirComboSelectedIndex); + if (el != null) { + // Create a copy of the currently selected element + newEl = (Track) el.copy(); + // Update the new Element with these current attributes + newEl.update(this); + /* + * populate the TrackExtrapPointInofDlg object + */ + populateTrackExtrapPointInfoDlgWithNewTrackData( + getTrackExtrapPointInfoDlg(), newEl, + unitComboSelectedIndex, roundComboSelectedIndex, + roundDirComboSelectedIndex); - trackExtrapPointInfoDlgObject.setBlockOnOpen( true ); - } - } - -// private void restoreIntervalTimeSettingByTrack(TrackAttrDlg targetTrackAttrDlg, Track track) { -// if(targetTrackAttrDlg == null || track == null) -// return; -// -// targetTrackAttrDlg.getIntervalCombo().select(track.getIntervalComboSelectedIndex()); -// int intervalComboItemCount = targetTrackAttrDlg.getIntervalCombo().getItemCount(); -// if((intervalComboItemCount - 1) == track.getIntervalComboSelectedIndex()) { -// if(track.getIntervalTimeString() != null) -// targetTrackAttrDlg.getIntervalText().setText(track.getIntervalTimeString()); -// } else { -//// targetTrackAttrDlg.getIntervalText().setText(targetTrackAttrDlg.getIntervalCombo().getText()); -// track.setIntervalTimeString(targetTrackAttrDlg.getIntervalCombo().getText()); -// } -// } - - private void makeTimeDisplayOptionSelected(ExtraPointTimeDisplayOption extraPointTimeDisplayOption, String skipFactorTextString) { - getSkipFactorButton().setSelection(false); - skipFactorText.setText(""); - if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR) - getOnHalfHourButton().setSelection(true); - else if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR) - getOnHourButton().setSelection(true); - else if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST) - getShowFirstLastButton().setSelection(true); - else { - getSkipFactorButton().setSelection(true); - skipFactorText.setText(skipFactorTextString); - } - } - - /** - * Creates buttons, menus, and other controls in the dialog area - * @param listener - */ - private void initializeComponents(Composite topComposite) { - isNewTrack = true; - - int textWidth = 120; //160; - int textHeight = 15; //40; + newList.add(newEl); - GridLayout childGridLayout = new GridLayout( 2, false ); + } + } + + if (newEl != null) { + AttrSettings.getInstance().setSettings(newEl); + } + + ArrayList oldList = new ArrayList( + adcList); + drawingLayer.replaceElements(oldList, newList); + } + + // set the new elements as selected. + drawingLayer.removeSelected(); + for (AbstractDrawableComponent adc : newList) { + drawingLayer.addSelected(adc); + } + + if (mapEditor != null) { + mapEditor.refresh(); + } + } + + public void cancelPressed() { + + if (trackExtrapPointInfoDlg != null) { + trackExtrapPointInfoDlg.close(); + trackExtrapPointInfoDlg = null; + } + super.cancelPressed(); + + } + + /** + * Creates the dialog area + */ + @Override + public Control createDialogArea(Composite parent) { + + Composite top = (Composite) super.createDialogArea(parent); + + // Create the main layout for the shell. + GridLayout mainLayout = new GridLayout(2, false); + mainLayout.marginHeight = 3; + mainLayout.marginWidth = 3; + top.setLayout(mainLayout); + + // Initialize all of the menus, controls, and layouts + initializeComponents(top); + + return top; + + } + + public void initializeTrackAttrDlg(Track track) { + if (track == null) + return; + /* + * 1. restore frameTimeButton and setTimeButton status + */ + if (track.isSetTimeButtonSelected()) { + getSetTimeButton().setSelection(true); + getFrameTimeButton().setSelection(false); + } else { + getFrameTimeButton().setSelection(true); + getSetTimeButton().setSelection(false); + } + /* + * 2. restore first time and second time text values + */ + if (isNewTrack == true) { + String[] firstSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); + getFirstTimeText().setText(firstSecondTimeValueArray[0]); + getSecondTimeText().setText(firstSecondTimeValueArray[1]); + } else { + + getFirstTimeText().setText( + getFirstOrSecondTimeStringValue( + track.getFirstTimeCalendar(), true, + track.getInitialPoints())); + getSecondTimeText().setText( + getFirstOrSecondTimeStringValue( + track.getSecondTimeCalendar(), false, + track.getInitialPoints())); + } + + // isNewTrack = false; + /* + * 3. restore Number of times value + */ + if (track.getExtrapPoints() != null) + numberOfTimesText + .setText(String.valueOf(track.getExtrapPoints().length)); + + /* + * 4. restore interval time settings + */ + setIntervalTimeString(track.getIntervalTimeString()); + + /* + * 5. restore initial and extrap colors + */ + java.awt.Color initColor = track.getInitialColor(); + initialCS.setColorValue(new RGB(initColor.getRed(), initColor + .getGreen(), initColor.getBlue())); + java.awt.Color extrapColor = track.getExtrapColor(); + extrapCS.setColorValue(new RGB(extrapColor.getRed(), extrapColor + .getGreen(), extrapColor.getBlue())); + + /* + * 6. restore label option settings + */ + setExtraPointTimeDisplayOption(track.getExtraPointTimeDisplayOption()); + makeTimeDisplayOptionSelected(track.getExtraPointTimeDisplayOption(), + track.getSkipFactorTextString()); + + /* + * 7. restore Font, Size, Style combo values + */ + getFontNameCombo().select(track.getFontNameComboSelectedIndex()); + getFontSizeCombo().select(track.getFontSizeComboSelectedIndex()); + getFontStyleCombo().select(track.getFontStyleComboSelectedIndex()); + + /* + * 7. restore Unit combo values + */ + unitComboSelectedIndex = track.getUnitComboSelectedIndex(); + getUnitCombo().select(unitComboSelectedIndex); + + roundComboSelectedIndex = track.getRoundComboSelectedIndex(); + getRoundCombo().select(roundComboSelectedIndex); + if (roundComboSelectedIndex > 0) + roundButton.setSelection(true); + else + roundButton.setSelection(false); + + roundDirComboSelectedIndex = track.getRoundDirComboSelectedIndex(); + getRoundDirCombo().select(roundDirComboSelectedIndex); + if (roundDirComboSelectedIndex > 0) + roundDirButton.setSelection(true); + else + roundDirButton.setSelection(false); + } + + private void populateTrackExtrapPointInfoDlgWithNewTrackData( + TrackExtrapPointInfoDlg trackExtrapPointInfoDlgObject, + Track newTrackObject, int unitComboSelectedIndex, + int roundComboSelectedIndex, int roundDirComboSelectedIndex) { + if (trackExtrapPointInfoDlgObject != null && newTrackObject != null) { + trackExtrapPointInfoDlgObject.close(); + + trackExtrapPointInfoDlgObject.setBlockOnOpen(false); + trackExtrapPointInfoDlgObject.open(); + + trackExtrapPointInfoDlgObject.setTrack(newTrackObject, + unitComboSelectedIndex, roundComboSelectedIndex, + roundDirComboSelectedIndex); + + trackExtrapPointInfoDlgObject.setBlockOnOpen(true); + } + } + + private void makeTimeDisplayOptionSelected( + ExtraPointTimeDisplayOption extraPointTimeDisplayOption, + String skipFactorTextString) { + getSkipFactorButton().setSelection(false); + skipFactorText.setText(""); + if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR) + getOnHalfHourButton().setSelection(true); + else if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR) + getOnHourButton().setSelection(true); + else if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST) + getShowFirstLastButton().setSelection(true); + else { + getSkipFactorButton().setSelection(true); + skipFactorText.setText(skipFactorTextString); + } + } + + /** + * Creates buttons, menus, and other controls in the dialog area + * + * @param listener + */ + private void initializeComponents(Composite topComposite) { + isNewTrack = true; + + int textWidth = 120; // 160; + int textHeight = 15; // 40; + + GridLayout childGridLayout = new GridLayout(2, false); this.getShell().setText("Track Attributes"); -// log.info("===now it is inside initializeComponents(...)"); /** - * Draw Frame/Set time buttons + * Draw Frame/Set time buttons */ Group timeRadioButtonGroup = new Group(topComposite, SWT.NONE); timeRadioButtonGroup.setLayout(childGridLayout); - - frameTimeButton = new Button(timeRadioButtonGroup, SWT.RADIO); -// Button frameTimeButton = new Button(topComposite, SWT.RADIO); + + frameTimeButton = new Button(timeRadioButtonGroup, SWT.RADIO); frameTimeButton.setText("Frame time"); - -// Button setTimeButton = new Button(topComposite, SWT.RADIO); + setTimeButton = new Button(timeRadioButtonGroup, SWT.RADIO); - setTimeButton.setText( "Set Time" ); -// setTimeButton.setSelection(true); -// timeRadioButtonGroup.h - Label emptyLabel = new Label( topComposite, SWT.LEFT ); + setTimeButton.setText("Set Time"); + Label emptyLabel = new Label(topComposite, SWT.LEFT); emptyLabel.setText(" "); /* * Draw First and Second Time text rows */ - String[] firstSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); - setFirstTimeText(createTextfieldWithLabel(topComposite, "First time:", - SWT.SINGLE | SWT.BORDER, textWidth, textHeight, true)); + String[] firstSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); + setFirstTimeText(createTextfieldWithLabel(topComposite, "First time:", + SWT.SINGLE | SWT.BORDER, textWidth, textHeight, true)); getFirstTimeText().setText(firstSecondTimeValueArray[0]); - getFirstTimeText().addModifyListener( new ModifyListener(){ - public void modifyText(ModifyEvent e) { - Text txt = (Text)e.widget; - Calendar cal = gempakTM2Calendar(txt.getText()); - if ( cal != null ) firstTimeCalendar = cal; - - } + getFirstTimeText().addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + Text txt = (Text) e.widget; + Calendar cal = gempakTM2Calendar(txt.getText()); + if (cal != null) + firstTimeCalendar = cal; + + } }); - - setSecondTimeText(createTextfieldWithLabel(topComposite, "Second time:", - SWT.SINGLE | SWT.BORDER, textWidth, textHeight, true)); + setSecondTimeText(createTextfieldWithLabel(topComposite, + "Second time:", SWT.SINGLE | SWT.BORDER, textWidth, textHeight, + true)); getSecondTimeText().setText(firstSecondTimeValueArray[1]); - - getSecondTimeText().addModifyListener( new ModifyListener(){ - public void modifyText(ModifyEvent e) { - Text txt = (Text)e.widget; - Calendar cal = gempakTM2Calendar(txt.getText()); - if ( cal != null ) secondTimeCalendar = cal; - - } + + getSecondTimeText().addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + Text txt = (Text) e.widget; + Calendar cal = gempakTM2Calendar(txt.getText()); + if (cal != null) + secondTimeCalendar = cal; + + } }); - + setTimeButton.setSelection(true); - setSetTimeButtonSelected(true); - frameAndSetTimeButtonSelectionListenerAction(frameTimeButton, getFirstTimeText(), - getSecondTimeText()); - frameAndSetTimeButtonSelectionListenerAction(setTimeButton, getFirstTimeText(), - getSecondTimeText()); - + setSetTimeButtonSelected(true); + frameAndSetTimeButtonSelectionListenerAction(frameTimeButton, + getFirstTimeText(), getSecondTimeText()); + frameAndSetTimeButtonSelectionListenerAction(setTimeButton, + getFirstTimeText(), getSecondTimeText()); + /* - * Played with NMAP2, it seems directly change first/second time texts do not have any - * impact on the first/second starting points. Thus, now set both text fields are not - * editable + * Played with NMAP2, it seems directly change first/second time texts + * do not have any impact on the first/second starting points. Thus, now + * set both text fields are not editable */ - getFirstTimeText().setEditable(true); - getSecondTimeText().setEditable(true); - + getFirstTimeText().setEditable(true); + getSecondTimeText().setEditable(true); + /* * Draw Number of times text row */ - setNumberOfTimesText(createTextfieldWithLabel(topComposite, "Number of times:", - SWT.SINGLE | SWT.BORDER, textWidth/3, textHeight, true)); + setNumberOfTimesText(createTextfieldWithLabel(topComposite, + "Number of times:", SWT.SINGLE | SWT.BORDER, textWidth / 3, + textHeight, true)); numberOfTimesText.setText(String.valueOf(numberOfTimes)); numberOfTimesText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - try { - numberOfTimes = Integer.parseInt(numberOfTimesText.getText()); - } catch(NumberFormatException nfe) { - numberOfTimes = DEFAULT_NUMBER_OF_TIMES; //use the default value - // log.error("The text value of number of times is invalid, input text=" - // +getNumberOfTimesText().getText()); - } - } - }); - + public void modifyText(ModifyEvent e) { + try { + numberOfTimes = Integer.parseInt(numberOfTimesText + .getText()); + } catch (NumberFormatException nfe) { + numberOfTimes = DEFAULT_NUMBER_OF_TIMES; // use the default + // value + } + } + }); + /* * Draw Interval combo box row */ - Label intervalLabel = new Label(topComposite, SWT.LEFT); - intervalLabel.setText("Interval:"); + Label intervalLabel = new Label(topComposite, SWT.LEFT); + intervalLabel.setText("Interval:"); Group intervalRowGroup = new Group(topComposite, SWT.NONE); intervalRowGroup.setLayout(childGridLayout); - - intervalCombo = new Combo(intervalRowGroup, SWT.DROP_DOWN | SWT.READ_ONLY); - for ( String currentString : IntervalTimeValues ) { - intervalCombo.add(currentString); + + intervalCombo = new Combo(intervalRowGroup, SWT.DROP_DOWN + | SWT.READ_ONLY); + for (String currentString : IntervalTimeValues) { + intervalCombo.add(currentString); } - intervalCombo.select(2); //set default to 01:00 - setPreviousIntervalTimeValue(intervalCombo.getText()); - intervalText = new Text(intervalRowGroup, SWT.SINGLE | SWT.BORDER); + intervalCombo.select(2); // set default to 01:00 + setPreviousIntervalTimeValue(intervalCombo.getText()); + intervalText = new Text(intervalRowGroup, SWT.SINGLE | SWT.BORDER); intervalCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - if(intervalCombo.getText().equalsIgnoreCase("Other")) { - intervalText.setEditable(true); - intervalText.setText(getPreviousIntervalTimeValue()); - } else { - intervalText.setEditable(false); - intervalText.setText(""); - setPreviousIntervalTimeValue(intervalCombo.getText()); - // setIntervalTimeString(intervalCombo.getText()); - } - } - }); + public void widgetSelected(SelectionEvent e) { + if (intervalCombo.getText().equalsIgnoreCase("Other")) { + intervalText.setEditable(true); + intervalText.setText(getPreviousIntervalTimeValue()); + } else { + intervalText.setEditable(false); + intervalText.setText(""); + setPreviousIntervalTimeValue(intervalCombo.getText()); + } + } + }); intervalText.addModifyListener(new ModifyListener() { - public void modifyText(ModifyEvent e) { - if ( !((Text)e.widget).getText().isEmpty()) - ;// setIntervalTimeString(intervalText.getText()); - } - }); - + public void modifyText(ModifyEvent e) { + if (!((Text) e.widget).getText().isEmpty()) + ;// setIntervalTimeString(intervalText.getText()); + } + }); + /* * Draw two color choice options */ - Label colorLabel = new Label(topComposite, SWT.LEFT); - colorLabel.setText("Initial Color:"); - initialCS = new ColorButtonSelector ( topComposite ); - initialCS.setColorValue( new RGB( 0,0,255 ) ); // Blue??? - - colorLabel = new Label(topComposite, SWT.LEFT); - colorLabel.setText("Extra Color:"); - extrapCS = new ColorButtonSelector( topComposite ); - extrapCS.setColorValue( new RGB( 0,192,0 ) ); // Green??? - + Label colorLabel = new Label(topComposite, SWT.LEFT); + colorLabel.setText("Initial Color:"); + initialCS = new ColorButtonSelector(topComposite); + initialCS.setColorValue(new RGB(0, 0, 255)); // Blue??? + + colorLabel = new Label(topComposite, SWT.LEFT); + colorLabel.setText("Extra Color:"); + extrapCS = new ColorButtonSelector(topComposite); + extrapCS.setColorValue(new RGB(0, 192, 0)); // Green??? + /* - * Draw speed unit selection label, checkbox and combo + * Draw speed unit selection label, checkbox and combo */ - Label speedUnitLabel = new Label(topComposite, SWT.LEFT); - speedUnitLabel.setText("Speed Unit:"); - - unitCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + Label speedUnitLabel = new Label(topComposite, SWT.LEFT); + speedUnitLabel.setText("Speed Unit:"); + + unitCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); for (String unit : UnitValues) { - unitCombo.add(unit); + unitCombo.add(unit); } - - unitCombo.select(0); // default to the 1st item of the list. the value is Courier - setUnitComboSelectedIndex(0); + + unitCombo.select(0); // default to the 1st item of the list. the value + // is Courier + setUnitComboSelectedIndex(0); unitCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - setUnitComboSelectedIndex(unitCombo.getSelectionIndex()); - } + public void widgetSelected(SelectionEvent e) { + setUnitComboSelectedIndex(unitCombo.getSelectionIndex()); + } }); /* - * Draw speed Round To selection - */ - roundButton = new Button(topComposite, SWT.CHECK); - String roundTo = "Round speed To:"; - roundButton.setText(roundTo); - roundButton.setSelection(false); + * Draw speed Round To selection + */ + roundButton = new Button(topComposite, SWT.CHECK); + String roundTo = "Round speed To:"; + roundButton.setText(roundTo); + roundButton.setSelection(false); roundButton.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - if (!roundButton.getSelection()) - setRoundComboSelectedIndex(-1); - } + public void widgetSelected(SelectionEvent e) { + if (!roundButton.getSelection()) + setRoundComboSelectedIndex(-1); + } }); - - roundCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + + roundCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); for (String round : RoundTo) { - roundCombo.add(round); - } - roundCombo.select(0); + roundCombo.add(round); + } + roundCombo.select(0); setRoundComboSelectedIndex(0); roundCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - if (roundButton.getSelection()) - setRoundComboSelectedIndex(roundCombo.getSelectionIndex()); - else - setRoundComboSelectedIndex(-1); - } + public void widgetSelected(SelectionEvent e) { + if (roundButton.getSelection()) + setRoundComboSelectedIndex(roundCombo.getSelectionIndex()); + else + setRoundComboSelectedIndex(-1); + } }); - + /* * Draw Direction Round To selection */ - roundDirButton = new Button(topComposite, SWT.CHECK); - String roundDirTo = "Round Direction To:"; - roundDirButton.setText(roundDirTo); - roundDirButton.setSelection(false); - roundDirButton.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - if (!roundDirButton.getSelection()) - setRoundDirComboSelectedIndex(-1); - } - }); - - roundDirCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - for (String round : RoundDirTo) { - roundDirCombo.add(round); - } - roundDirCombo.select(0); - setRoundDirComboSelectedIndex(0); - roundDirCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - if (roundDirButton.getSelection()) - setRoundDirComboSelectedIndex(roundDirCombo.getSelectionIndex()); - else - setRoundDirComboSelectedIndex(-1); - } - }); - + roundDirButton = new Button(topComposite, SWT.CHECK); + String roundDirTo = "Round Direction To:"; + roundDirButton.setText(roundDirTo); + roundDirButton.setSelection(false); + roundDirButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (!roundDirButton.getSelection()) + setRoundDirComboSelectedIndex(-1); + } + }); + + roundDirCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + for (String round : RoundDirTo) { + roundDirCombo.add(round); + } + roundDirCombo.select(0); + setRoundDirComboSelectedIndex(0); + roundDirCombo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (roundDirButton.getSelection()) + setRoundDirComboSelectedIndex(roundDirCombo + .getSelectionIndex()); + else + setRoundDirComboSelectedIndex(-1); + } + }); + /* * Draw a single line Label */ - Label optionLabel = new Label(topComposite, SWT.LEFT); - optionLabel.setText("Label Options:"); - //make the label to fill the two columns - GridData gridData = new GridData(); - gridData.horizontalSpan = 2; - optionLabel.setLayoutData(gridData); + Label optionLabel = new Label(topComposite, SWT.LEFT); + optionLabel.setText("Label Options:"); + + // make the label to fill the two columns + GridData gridData = new GridData(); + gridData.horizontalSpan = 2; + optionLabel.setLayoutData(gridData); /* * Draw the four Buttons of Label Options */ - skipFactorButton = new Button(topComposite, SWT.RADIO); - String skipFactorButtonText = "Skip factor"; - skipFactorButton.setText(skipFactorButtonText); - skipFactorButton.setSelection(true); - skipFactorText = new Text(topComposite, SWT.SINGLE | SWT.BORDER); - skipFactorText.setLayoutData( new GridData( textWidth/4, textHeight ) ); + skipFactorButton = new Button(topComposite, SWT.RADIO); + String skipFactorButtonText = "Skip factor"; + skipFactorButton.setText(skipFactorButtonText); + skipFactorButton.setSelection(true); + skipFactorText = new Text(topComposite, SWT.SINGLE | SWT.BORDER); + skipFactorText.setLayoutData(new GridData(textWidth / 4, textHeight)); - skipFactorText.setText("0"); - labelOptionButtonSelectionListenerAction(skipFactorButton, skipFactorText, true, - skipFactorButtonText, 0); - - showFirstLastButton = createButton(topComposite, "Show first&&last", true, 2); - labelOptionButtonSelectionListenerAction(showFirstLastButton, skipFactorText, false, - skipFactorButtonText, 0); + skipFactorText.setText("0"); + labelOptionButtonSelectionListenerAction(skipFactorButton, + skipFactorText, true, skipFactorButtonText, 0); - onHourButton = createButton(topComposite, "On hour", true, 2); - labelOptionButtonSelectionListenerAction(onHourButton, skipFactorText, false, - skipFactorButtonText, 0); + showFirstLastButton = createButton(topComposite, "Show first&&last", + true, 2); + labelOptionButtonSelectionListenerAction(showFirstLastButton, + skipFactorText, false, skipFactorButtonText, 0); - onHalfHourButton = createButton(topComposite, "On half-hour", true, 2); - labelOptionButtonSelectionListenerAction(onHalfHourButton, skipFactorText, false, - skipFactorButtonText, 0); + onHourButton = createButton(topComposite, "On hour", true, 2); + labelOptionButtonSelectionListenerAction(onHourButton, skipFactorText, + false, skipFactorButtonText, 0); + + onHalfHourButton = createButton(topComposite, "On half-hour", true, 2); + labelOptionButtonSelectionListenerAction(onHalfHourButton, + skipFactorText, false, skipFactorButtonText, 0); /* * Initialize the extra point display option as SKIP_FACTOR */ - setExtraPointTimeDisplayOption(ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR); + setExtraPointTimeDisplayOption(ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR); /* * Draw some Combo drop down lists */ - Label fontLabel = new Label(topComposite, SWT.LEFT); - fontLabel.setText("Font:"); - fontNameCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + Label fontLabel = new Label(topComposite, SWT.LEFT); + fontLabel.setText("Font:"); + fontNameCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); for (String fontName : FontName) { - fontNameCombo.add(fontName); + fontNameCombo.add(fontName); } - fontNameCombo.select(0); // default to the 1st item of the list. the value is Courier - setFontNameComboSelectedIndex(0); + fontNameCombo.select(0); // default to the 1st item of the list. the + // value is Courier + setFontNameComboSelectedIndex(0); fontNameCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - setFontNameComboSelectedIndex(fontNameCombo.getSelectionIndex()); - } - }); - - Label fontSizeLabel = new Label(topComposite, SWT.LEFT); - fontSizeLabel.setText("Size:"); - fontSizeCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - for ( FontSizeName fontSizeName : FontSizeName.values() ) { - fontSizeCombo.add(fontSizeName.name()); + public void widgetSelected(SelectionEvent e) { + setFontNameComboSelectedIndex(fontNameCombo.getSelectionIndex()); + } + }); + + Label fontSizeLabel = new Label(topComposite, SWT.LEFT); + fontSizeLabel.setText("Size:"); + fontSizeCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + for (FontSizeName fontSizeName : FontSizeName.values()) { + fontSizeCombo.add(fontSizeName.name()); } - fontSizeCombo.select(2); // default to the 3rd item of the list. The value is Medium - setFontSizeComboSelectedIndex(2); + fontSizeCombo.select(2); // default to the 3rd item of the list. The + // value is Medium + setFontSizeComboSelectedIndex(2); fontSizeCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - setFontSizeComboSelectedIndex(fontSizeCombo.getSelectionIndex()); - } - }); - - Label fontStyleLabel = new Label(topComposite, SWT.LEFT); - fontStyleLabel.setText("Style:"); - fontStyleCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); - for ( FontStyle fontStyle : FontStyle.values() ) { - fontStyleCombo.add(fontStyle.name()); + public void widgetSelected(SelectionEvent e) { + setFontSizeComboSelectedIndex(fontSizeCombo.getSelectionIndex()); + } + }); + + Label fontStyleLabel = new Label(topComposite, SWT.LEFT); + fontStyleLabel.setText("Style:"); + fontStyleCombo = new Combo(topComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + for (FontStyle fontStyle : FontStyle.values()) { + fontStyleCombo.add(fontStyle.name()); } - fontStyleCombo.select(2); // default to the 3rd item of the list. The value is Bold - setFontStyleComboSelectedIndex(2); + fontStyleCombo.select(2); // default to the 3rd item of the list. The + // value is Bold + setFontStyleComboSelectedIndex(2); fontStyleCombo.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - setFontStyleComboSelectedIndex(fontStyleCombo.getSelectionIndex()); - } - }); - + public void widgetSelected(SelectionEvent e) { + setFontStyleComboSelectedIndex(fontStyleCombo + .getSelectionIndex()); + } + }); + addSeparator(topComposite.getParent()); - } - - private void frameAndSetTimeButtonSelectionListenerAction(final Button button, - final Text firstTimeText, final Text secondTimeText) { - button.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - String[] firstAndSecondTimeValueArray = null; - String buttonText = button.getText(); - if(buttonText.indexOf("Frame") < 0) { - firstAndSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); - setSetTimeButtonSelected(true); - } else { - firstAndSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForFrameTimeButton(); - setSetTimeButtonSelected(false); - } - firstTimeText.setText(firstAndSecondTimeValueArray[0]); - secondTimeText.setText(firstAndSecondTimeValueArray[1]); - } - }); - } - - private String[] getFirstSecondTimeInitialTimeValueForFrameTimeButton() { - return getFirstSecondTimeInitialTimeValueForSetTimeButton(); - } - - private String[] getFirstSecondTimeInitialTimeValueForSetTimeButton() { - String[] timeValueResult = new String[2]; - Calendar calendar = Calendar.getInstance(); - - calendar.add(Calendar.HOUR_OF_DAY, DEFAULT_HOUR_SHIFT_FOR_FIRST_TIME); - setFirstTimeCalendar(calendar); - timeValueResult[0] = getDateTimeStringValue(calendar); - calendar.add(Calendar.HOUR_OF_DAY, DEFAULT_HOUR_SHIFT_BEYOND_FIRST_TIME); - setSecondTimeCalendar(calendar); - timeValueResult[1] = getDateTimeStringValue(calendar); - -// Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); -// //calendar.add(Calendar.HOUR_OF_DAY, DEFAULT_HOUR_SHIFT_FOR_FIRST_TIME); -// setFirstTimeCalendar(calendar); -// timeValueResult[0] = getDateTimeStringValue(calendar); -// -// String intervalStr = getPreviousIntervalTimeValue(); //intervalTimeValue; -// System.out.println("intervalStr "+intervalStr); -// -// if (intervalStr == null || intervalStr.equalsIgnoreCase("")) -// intervalStr = "1:00"; -// String[] intervalString = intervalStr.split(":"); -// -// int day = 0; -// int hr = 0; -// int min = 0; -// if (intervalString.length == 1){ -// try { -// hr = Integer.parseInt(intervalString[0]); -// } -// catch (NumberFormatException e) { -// } -// } -// else if (intervalString.length == 2){ -// try { -// hr = Integer.parseInt(intervalString[0]); -// min = Integer.parseInt(intervalString[1]); -// } -// catch (NumberFormatException e) { -// } -// } -// -// calendar.add(Calendar.HOUR_OF_DAY, hr); -// calendar.add(Calendar.MINUTE, min); -// setSecondTimeCalendar(calendar); -// timeValueResult[1] = getDateTimeStringValue(calendar); - - return timeValueResult; - } + } - private String getFirstOrSecondTimeStringValue(Calendar timeCalendar, boolean isFirstTimeCalendar, TrackPoint[] initTrackPoints) { - String timeStringValue = ""; - if(timeCalendar != null) { - timeStringValue = getDateTimeStringValue(timeCalendar); - } else { - if(initTrackPoints != null && initTrackPoints.length >= 2) { - int trackPointArrayIndex = initTrackPoints.length - 1; - if(isFirstTimeCalendar) - trackPointArrayIndex--; - timeStringValue = getInitialPointsTimeStringValue(initTrackPoints, trackPointArrayIndex); - } - } - return timeStringValue; - } - - private String getInitialPointsTimeStringValue(TrackPoint[] trackPointArray, int pointArrayIndex) { - String timeStringValue = ""; - if(pointArrayIndex < trackPointArray.length) { - TrackPoint targetTrackPoint = trackPointArray[pointArrayIndex]; - if(targetTrackPoint != null && targetTrackPoint.getTime() != null) - timeStringValue = getDateTimeStringValue(targetTrackPoint.getTime()); - } - return timeStringValue; - } - - - private String getDateTimeStringValue(Calendar calendar) { - StringBuilder stringBuilder = new StringBuilder(11); - int year = calendar.get(Calendar.YEAR); - int month = calendar.get(Calendar.MONTH); - int day = calendar.get(Calendar.DAY_OF_MONTH); - int hour = calendar.get(Calendar.HOUR_OF_DAY); - int minute = calendar.get(Calendar.MINUTE); - - String yearString = String.valueOf(year); - stringBuilder.append(yearString.substring(2)); - if((month+1) < 10) - stringBuilder.append(0); - stringBuilder.append((month+1)); - if(day < 10) - stringBuilder.append(0); - stringBuilder.append(day); - stringBuilder.append("/"); - if(hour < 10) - stringBuilder.append(0); - stringBuilder.append(hour); - if(minute < 10) - stringBuilder.append(0); - stringBuilder.append(minute); - - return stringBuilder.toString(); - } - -// private Calendar getCalendarByParsingString(String dateString, String dateFormatPattern) { -// SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormatPattern); //a pattern is something like "yyMMdd/HHmm" -// Calendar cal = null; -// if(dateString == null) -// return cal; -// try { -// Date date = simpleDateFormat.parse(dateString); -// cal = Calendar.getInstance(); -// cal.setTime(date); -// } catch(ParseException pe) { -// log.error("The input of dateString is invalid, parse fails, dateString="+dateString); -// } -// return cal; -// } - - - /** - * a helper method to create an editable text with a text label - * @parentComposite, a parent Composite the text and label are built on - * @textLabel, the value of the labe ltext - * @textStyle, text style value - * @textWidth, text width - * @textHeight, text height - * @isEditable, a boolean to indicate if the text is editable - * @return Text - */ - private Text createTextfieldWithLabel(Composite parentComposite, String textLabel, - int textStyle, int textWidth, int textHeight, boolean isEditable) { + private void frameAndSetTimeButtonSelectionListenerAction( + final Button button, final Text firstTimeText, + final Text secondTimeText) { + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + String[] firstAndSecondTimeValueArray = null; + String buttonText = button.getText(); + if (buttonText.indexOf("Frame") < 0) { + firstAndSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForSetTimeButton(); + setSetTimeButtonSelected(true); + } else { + firstAndSecondTimeValueArray = getFirstSecondTimeInitialTimeValueForFrameTimeButton(); + setSetTimeButtonSelected(false); + } + firstTimeText.setText(firstAndSecondTimeValueArray[0]); + secondTimeText.setText(firstAndSecondTimeValueArray[1]); + } + }); + } + + private String[] getFirstSecondTimeInitialTimeValueForFrameTimeButton() { + return getFirstSecondTimeInitialTimeValueForSetTimeButton(); + } + + private String[] getFirstSecondTimeInitialTimeValueForSetTimeButton() { + String[] timeValueResult = new String[2]; + Calendar calendar = Calendar.getInstance(); + + calendar.add(Calendar.HOUR_OF_DAY, DEFAULT_HOUR_SHIFT_FOR_FIRST_TIME); + setFirstTimeCalendar(calendar); + timeValueResult[0] = getDateTimeStringValue(calendar); + calendar.add(Calendar.HOUR_OF_DAY, DEFAULT_HOUR_SHIFT_BEYOND_FIRST_TIME); + setSecondTimeCalendar(calendar); + timeValueResult[1] = getDateTimeStringValue(calendar); + + return timeValueResult; + } + + private String getFirstOrSecondTimeStringValue(Calendar timeCalendar, + boolean isFirstTimeCalendar, TrackPoint[] initTrackPoints) { + String timeStringValue = ""; + if (timeCalendar != null) { + timeStringValue = getDateTimeStringValue(timeCalendar); + } else { + if (initTrackPoints != null && initTrackPoints.length >= 2) { + int trackPointArrayIndex = initTrackPoints.length - 1; + if (isFirstTimeCalendar) + trackPointArrayIndex--; + timeStringValue = getInitialPointsTimeStringValue( + initTrackPoints, trackPointArrayIndex); + } + } + return timeStringValue; + } + + private String getInitialPointsTimeStringValue( + TrackPoint[] trackPointArray, int pointArrayIndex) { + String timeStringValue = ""; + if (pointArrayIndex < trackPointArray.length) { + TrackPoint targetTrackPoint = trackPointArray[pointArrayIndex]; + if (targetTrackPoint != null && targetTrackPoint.getTime() != null) + timeStringValue = getDateTimeStringValue(targetTrackPoint + .getTime()); + } + return timeStringValue; + } + + private String getDateTimeStringValue(Calendar calendar) { + StringBuilder stringBuilder = new StringBuilder(11); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH); + int day = calendar.get(Calendar.DAY_OF_MONTH); + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + + String yearString = String.valueOf(year); + stringBuilder.append(yearString.substring(2)); + if ((month + 1) < 10) + stringBuilder.append(0); + stringBuilder.append((month + 1)); + if (day < 10) + stringBuilder.append(0); + stringBuilder.append(day); + stringBuilder.append("/"); + if (hour < 10) + stringBuilder.append(0); + stringBuilder.append(hour); + if (minute < 10) + stringBuilder.append(0); + stringBuilder.append(minute); + + return stringBuilder.toString(); + } + + /** + * a helper method to create an editable text with a text label + * + * @parentComposite, a parent Composite the text and label are built on + * @textLabel, the value of the labe ltext + * @textStyle, text style value + * @textWidth, text width + * @textHeight, text height + * @isEditable, a boolean to indicate if the text is editable + * @return Text + */ + private Text createTextfieldWithLabel(Composite parentComposite, + String textLabel, int textStyle, int textWidth, int textHeight, + boolean isEditable) { Label firstTimeLabel = new Label(parentComposite, SWT.NONE); firstTimeLabel.setText(textLabel); - - Text text = new Text(parentComposite, textStyle); - text.setLayoutData( new GridData( textWidth, textHeight ) ); - text.setEditable(isEditable); - return text; - } - - /** - * a helper method to create a button - * @parentComposite, a parent Composite the button is built on - * @buttonText, text value associated with the button - * @isHorizontalSpan, a boolean to indicate if the button should do a span - * @spanValue, this value decides how many columns are spaned - * @return Button - */ - private Button createButton(Composite parentComposite, String buttonText, - boolean isHorizontalSpan, int spanValue) { - Button button = new Button(parentComposite, SWT.RADIO); - button.setText(buttonText); + + Text text = new Text(parentComposite, textStyle); + text.setLayoutData(new GridData(textWidth, textHeight)); + text.setEditable(isEditable); + return text; + } + + /** + * a helper method to create a button + * + * @parentComposite, a parent Composite the button is built on + * @buttonText, text value associated with the button + * @isHorizontalSpan, a boolean to indicate if the button should do a span + * @spanValue, this value decides how many columns are spaned + * @return Button + */ + private Button createButton(Composite parentComposite, String buttonText, + boolean isHorizontalSpan, int spanValue) { + Button button = new Button(parentComposite, SWT.RADIO); + button.setText(buttonText); /* * check to see if the button needs to do horizontal span */ - if(isHorizontalSpan) { - GridData gridData = new GridData(); - gridData.horizontalSpan = spanValue; - button.setLayoutData(gridData); + if (isHorizontalSpan) { + GridData gridData = new GridData(); + gridData.horizontalSpan = spanValue; + button.setLayoutData(gridData); } - return button; - } - - private void labelOptionButtonSelectionListenerAction(final Button button, - final Text targetText, final boolean isTargetTextEditable, - final String skipFactorButtonText, final int defaultSkipFactorValue) { - button.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - targetText.setEditable(isTargetTextEditable); - if(isTargetTextEditable) - targetText.setText(String.valueOf(defaultSkipFactorValue)); - else - targetText.setText(""); - String buttonTextString = button.getText(); - ExtraPointTimeDisplayOption extraPointTimeDisplayOption = - decideExtraPointTimeDisplayOptionByButtonText(buttonTextString); - setExtraPointTimeDisplayOption(extraPointTimeDisplayOption); - } - }); - } - // "Skip factor" "Show first&&last" "On hour" "On half-hour" - private ExtraPointTimeDisplayOption decideExtraPointTimeDisplayOptionByButtonText(String buttonTextString) { -// ITrack.ExtraPointTimeDisplayOption[] testOptions = ITrack.ExtraPointTimeDisplayOption.values(); - - if(buttonTextString.equalsIgnoreCase("Show first&&last")) - return ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST; - else if(buttonTextString.equalsIgnoreCase("On hour")) - return ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR; - else if(buttonTextString.equalsIgnoreCase("On half-hour")) - return ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR; - else - return ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR; - - } - - /** - * Gets the text - */ - public String[] getString(){ + return button; + } - return text.getText().split( "\n" ); + private void labelOptionButtonSelectionListenerAction(final Button button, + final Text targetText, final boolean isTargetTextEditable, + final String skipFactorButtonText, final int defaultSkipFactorValue) { + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + targetText.setEditable(isTargetTextEditable); + if (isTargetTextEditable) + targetText.setText(String.valueOf(defaultSkipFactorValue)); + else + targetText.setText(""); + String buttonTextString = button.getText(); + ExtraPointTimeDisplayOption extraPointTimeDisplayOption = decideExtraPointTimeDisplayOptionByButtonText(buttonTextString); + setExtraPointTimeDisplayOption(extraPointTimeDisplayOption); + } + }); + } - } + // "Skip factor" "Show first&&last" "On hour" "On half-hour" + private ExtraPointTimeDisplayOption decideExtraPointTimeDisplayOptionByButtonText( + String buttonTextString) { - /** - * Return font size from the font size combo - */ - public float getFontSize(){ - return ( FontSizeValue[ fontSizeCombo.getSelectionIndex() ] ); - } + if (buttonTextString.equalsIgnoreCase("Show first&&last")) + return ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST; + else if (buttonTextString.equalsIgnoreCase("On hour")) + return ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR; + else if (buttonTextString.equalsIgnoreCase("On half-hour")) + return ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR; + else + return ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR; - /** - * Return font name from the font combo - */ - public String getFontName(){ - return FontName[fontNameCombo.getSelectionIndex()]; - } - - /** - * Return font style from the style combo - */ - public FontStyle getStyle(){ - return FontStyle.values()[ fontStyleCombo.getSelectionIndex() ]; - } - - /** - * Set font size - */ - public void setFontSize( float size ){ - - int index = 0; - for ( int ii = 0; ii < FontSizeValue.length; ii++ ) { - if ( (int)size == FontSizeValue[ ii ] ) { - index = ii; - break; - } - } + } - fontSizeCombo.select( index ); + /** + * Gets the text + */ + public String[] getString() { - } + return text.getText().split("\n"); - /** - * Set font name - */ - public void setFontName( String name ){ - for ( String st:FontName ) { - if ( st.equalsIgnoreCase( name ) ) { - fontNameCombo.setText( st ); - break; - } - } - } - - /** - * set font style - */ - public void setStyle( FontStyle style ){ - for ( FontStyle fs : FontStyle.values() ) { - if ( fs == style ) { - fontStyleCombo.setText( fs.name() ); - break; + } + + /** + * Return font size from the font size combo + */ + public float getFontSize() { + return (FontSizeValue[fontSizeCombo.getSelectionIndex()]); + } + + /** + * Return font name from the font combo + */ + public String getFontName() { + return FontName[fontNameCombo.getSelectionIndex()]; + } + + /** + * Return font style from the style combo + */ + @Override + public FontStyle getFontStyle() { + return FontStyle.values()[fontStyleCombo.getSelectionIndex()]; + } + + /** + * Set font size + */ + public void setFontSize(float size) { + + int index = 0; + for (int ii = 0; ii < FontSizeValue.length; ii++) { + if ((int) size == FontSizeValue[ii]) { + index = ii; + break; } } - } - - /** - * Sets values of all attributes of the dialog. - */ - public void setAttrForDlg( IAttribute attr ){ - } - @Override - public void setAttr(AbstractDrawableComponent adc){ - if ( adc instanceof Track){ - initializeTrackAttrDlg((Track)adc); - } - } - - /* - * All setters and getters start here - */ + fontSizeCombo.select(index); + + } + + /** + * Set font name + */ + public void setFontName(String name) { + for (String st : FontName) { + if (st.equalsIgnoreCase(name)) { + fontNameCombo.setText(st); + break; + } + } + } + + /** + * set font style + */ + public void setFontStyle(FontStyle style) { + for (FontStyle fs : FontStyle.values()) { + if (fs == style) { + fontStyleCombo.setText(fs.name()); + break; + } + } + } + + /** + * Sets values of all attributes of the dialog. + */ + public void setAttrForDlg(IAttribute attr) { + } + + @Override + public void setAttr(AbstractDrawableComponent adc) { + if (adc instanceof Track) { + initializeTrackAttrDlg((Track) adc); + } + } + + /* + * All setters and getters start here + */ public TrackExtrapPointInfoDlg getTrackExtrapPointInfoDlg() { - return trackExtrapPointInfoDlg; - } + return trackExtrapPointInfoDlg; + } - public void setTrackExtrapPointInfoDlg( - TrackExtrapPointInfoDlg trackExtrapPointInfoDlg) { - this.trackExtrapPointInfoDlg = trackExtrapPointInfoDlg; - } + public void setTrackExtrapPointInfoDlg( + TrackExtrapPointInfoDlg trackExtrapPointInfoDlg) { + this.trackExtrapPointInfoDlg = trackExtrapPointInfoDlg; + } public Button getSkipFactorButton() { - return skipFactorButton; - } + return skipFactorButton; + } - public Button getShowFirstLastButton() { - return showFirstLastButton; - } + public Button getShowFirstLastButton() { + return showFirstLastButton; + } - public Button getOnHourButton() { - return onHourButton; - } + public Button getOnHourButton() { + return onHourButton; + } - public Button getOnHalfHourButton() { - return onHalfHourButton; - } + public Button getOnHalfHourButton() { + return onHalfHourButton; + } - public Combo getFontSizeCombo() { - return fontSizeCombo; - } + public Combo getFontSizeCombo() { + return fontSizeCombo; + } - public Combo getFontNameCombo() { - return fontNameCombo; - } + public Combo getFontNameCombo() { + return fontNameCombo; + } - public Combo getFontStyleCombo() { - return fontStyleCombo; - } + public Combo getFontStyleCombo() { + return fontStyleCombo; + } + public int getFontSizeComboSelectedIndex() { + return fontSizeComboSelectedIndex; + } - public int getFontSizeComboSelectedIndex() { - return fontSizeComboSelectedIndex; - } + public void setFontSizeComboSelectedIndex(int fontSizeComboSelectedIndex) { + this.fontSizeComboSelectedIndex = fontSizeComboSelectedIndex; + } - public void setFontSizeComboSelectedIndex(int fontSizeComboSelectedIndex) { - this.fontSizeComboSelectedIndex = fontSizeComboSelectedIndex; - } + public int getFontNameComboSelectedIndex() { + return fontNameComboSelectedIndex; + } - public int getFontNameComboSelectedIndex() { - return fontNameComboSelectedIndex; - } + public void setFontNameComboSelectedIndex(int fontNameComboSelectedIndex) { + this.fontNameComboSelectedIndex = fontNameComboSelectedIndex; + } - public void setFontNameComboSelectedIndex(int fontNameComboSelectedIndex) { - this.fontNameComboSelectedIndex = fontNameComboSelectedIndex; - } + public int getFontStyleComboSelectedIndex() { + return fontStyleComboSelectedIndex; + } - public int getFontStyleComboSelectedIndex() { - return fontStyleComboSelectedIndex; - } + public void setFontStyleComboSelectedIndex(int fontStyleComboSelectedIndex) { + this.fontStyleComboSelectedIndex = fontStyleComboSelectedIndex; + } - public void setFontStyleComboSelectedIndex(int fontStyleComboSelectedIndex) { - this.fontStyleComboSelectedIndex = fontStyleComboSelectedIndex; - } + public Combo getUnitCombo() { + return unitCombo; + } - public Combo getUnitCombo() { - return unitCombo; - } - - public int getUnitComboSelectedIndex() { - return unitComboSelectedIndex; - } + public int getUnitComboSelectedIndex() { + return unitComboSelectedIndex; + } - public void setUnitComboSelectedIndex(int unitComboSelectedIndex) { - this.unitComboSelectedIndex = unitComboSelectedIndex; - } + public void setUnitComboSelectedIndex(int unitComboSelectedIndex) { + this.unitComboSelectedIndex = unitComboSelectedIndex; + } - public Combo getRoundCombo() { - return roundCombo; - } - - public int getRoundComboSelectedIndex() { - return roundComboSelectedIndex; - } + public Combo getRoundCombo() { + return roundCombo; + } - public void setRoundComboSelectedIndex(int roundComboSelectedIndex) { - this.roundComboSelectedIndex = roundComboSelectedIndex; - } + public int getRoundComboSelectedIndex() { + return roundComboSelectedIndex; + } - public Combo getRoundDirCombo() { - return roundDirCombo; - } - - public int getRoundDirComboSelectedIndex() { - return roundDirComboSelectedIndex; - } + public void setRoundComboSelectedIndex(int roundComboSelectedIndex) { + this.roundComboSelectedIndex = roundComboSelectedIndex; + } - public void setRoundDirComboSelectedIndex(int roundDirComboSelectedIndex) { - this.roundDirComboSelectedIndex = roundDirComboSelectedIndex; - } + public Combo getRoundDirCombo() { + return roundDirCombo; + } + public int getRoundDirComboSelectedIndex() { + return roundDirComboSelectedIndex; + } - public boolean isSetTimeButtonSelected() { - return setTimeButtonSelected; - } + public void setRoundDirComboSelectedIndex(int roundDirComboSelectedIndex) { + this.roundDirComboSelectedIndex = roundDirComboSelectedIndex; + } - public void setSetTimeButtonSelected(boolean setTimeButtonSelected) { - this.setTimeButtonSelected = setTimeButtonSelected; - } - public Button getFrameTimeButton() { - return frameTimeButton; - } + public boolean isSetTimeButtonSelected() { + return setTimeButtonSelected; + } - public void setFrameTimeButton(Button frameTimeButton) { - this.frameTimeButton = frameTimeButton; - } + public void setSetTimeButtonSelected(boolean setTimeButtonSelected) { + this.setTimeButtonSelected = setTimeButtonSelected; + } - public Button getSetTimeButton() { - return setTimeButton; - } + public Button getFrameTimeButton() { + return frameTimeButton; + } - public void setSetTimeButton(Button setTimeButton) { - this.setTimeButton = setTimeButton; - } + public void setFrameTimeButton(Button frameTimeButton) { + this.frameTimeButton = frameTimeButton; + } + public Button getSetTimeButton() { + return setTimeButton; + } - public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption() { - return extraPointTimeDisplayOption; - } + public void setSetTimeButton(Button setTimeButton) { + this.setTimeButton = setTimeButton; + } - public void setExtraPointTimeDisplayOption(ExtraPointTimeDisplayOption extraPointTimeDisplayOption) { - this.extraPointTimeDisplayOption = extraPointTimeDisplayOption; - } + public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption() { + return extraPointTimeDisplayOption; + } - public String getSkipFactorText() { - return skipFactorText.getText(); - } + public void setExtraPointTimeDisplayOption( + ExtraPointTimeDisplayOption extraPointTimeDisplayOption) { + this.extraPointTimeDisplayOption = extraPointTimeDisplayOption; + } - public void setSkipFactorText(String skipFactorText) { - this.skipFactorText.setText(skipFactorText); - } + public String getSkipFactorText() { + return skipFactorText.getText(); + } - public Text getFirstTimeText() { - return firstTimeText; - } + public void setSkipFactorText(String skipFactorText) { + this.skipFactorText.setText(skipFactorText); + } - public void setFirstTimeText(Text firstTimeText) { - this.firstTimeText = firstTimeText; - } + public Text getFirstTimeText() { + return firstTimeText; + } - public Text getSecondTimeText() { - return secondTimeText; - } + public void setFirstTimeText(Text firstTimeText) { + this.firstTimeText = firstTimeText; + } - public void setSecondTimeText(Text secondTimeText) { - this.secondTimeText = secondTimeText; - } + public Text getSecondTimeText() { + return secondTimeText; + } - public int getExtraDrawingPointNumber() { - int ret = 0; - try { - ret = Integer.parseInt(numberOfTimesText.getText()); - } - catch ( Exception e ){ - ret = 0; - } - - return ret ; - } + public void setSecondTimeText(Text secondTimeText) { + this.secondTimeText = secondTimeText; + } - public void setNumberOfTimesText(Text numberOfTimesText) { - this.numberOfTimesText = numberOfTimesText; - } + public int getExtraDrawingPointNumber() { + int ret = 0; + try { + ret = Integer.parseInt(numberOfTimesText.getText()); + } catch (Exception e) { + ret = 0; + } - public String getPreviousIntervalTimeValue() { - return previousIntervalTimeValue; - } + return ret; + } - public void setPreviousIntervalTimeValue(String previousIntervalTimeValue) { - this.previousIntervalTimeValue = previousIntervalTimeValue; - } + public void setNumberOfTimesText(Text numberOfTimesText) { + this.numberOfTimesText = numberOfTimesText; + } + + public String getPreviousIntervalTimeValue() { + return previousIntervalTimeValue; + } + + public void setPreviousIntervalTimeValue(String previousIntervalTimeValue) { + this.previousIntervalTimeValue = previousIntervalTimeValue; + } public Calendar getFirstTimeCalendar() { - return firstTimeCalendar; - } + return firstTimeCalendar; + } - public String getIntervalTimeString() { - if(intervalCombo.getSelectionIndex() == intervalCombo.getItemCount() - 1) { - return intervalText.getText(); - } - else - return intervalCombo.getText(); - } + public String getIntervalTimeString() { + if (intervalCombo.getSelectionIndex() == intervalCombo.getItemCount() - 1) { + return intervalText.getText(); + } else + return intervalCombo.getText(); + } - private void setIntervalTimeString(String intervalTimeString) { - for ( int ii = 0; ii < intervalCombo.getItemCount(); ii++ ){ - if (intervalTimeString.equalsIgnoreCase( intervalCombo.getItem(ii) )){ - intervalCombo.select(ii); - return; - } - } - - //set for 'Other' - intervalCombo.select( intervalCombo.getItemCount() - 1 ); - intervalText.setText(intervalTimeString); + private void setIntervalTimeString(String intervalTimeString) { + for (int ii = 0; ii < intervalCombo.getItemCount(); ii++) { + if (intervalTimeString.equalsIgnoreCase(intervalCombo.getItem(ii))) { + intervalCombo.select(ii); + return; + } + } - } - - public void setFirstTimeCalendar(Calendar firstTimeCalendar) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, firstTimeCalendar.get(Calendar.YEAR)); - cal.set(Calendar.MONTH, firstTimeCalendar.get(Calendar.MONTH)); - cal.set(Calendar.DAY_OF_MONTH, firstTimeCalendar.get(Calendar.DAY_OF_MONTH)); - cal.set(Calendar.HOUR_OF_DAY, firstTimeCalendar.get(Calendar.HOUR_OF_DAY)); - cal.set(Calendar.MINUTE, firstTimeCalendar.get(Calendar.MINUTE)); - this.firstTimeCalendar = cal; - } + // set for 'Other' + intervalCombo.select(intervalCombo.getItemCount() - 1); + intervalText.setText(intervalTimeString); - public Calendar getSecondTimeCalendar() { - return secondTimeCalendar; - } + } - public void setSecondTimeCalendar(Calendar secondTimeCalendar) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, secondTimeCalendar.get(Calendar.YEAR)); - cal.set(Calendar.MONTH, secondTimeCalendar.get(Calendar.MONTH)); - cal.set(Calendar.DAY_OF_MONTH, secondTimeCalendar.get(Calendar.DAY_OF_MONTH)); - cal.set(Calendar.HOUR_OF_DAY, secondTimeCalendar.get(Calendar.HOUR_OF_DAY)); - cal.set(Calendar.MINUTE, secondTimeCalendar.get(Calendar.MINUTE)); - this.secondTimeCalendar = cal; - } + public void setFirstTimeCalendar(Calendar firstTimeCalendar) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, firstTimeCalendar.get(Calendar.YEAR)); + cal.set(Calendar.MONTH, firstTimeCalendar.get(Calendar.MONTH)); + cal.set(Calendar.DAY_OF_MONTH, + firstTimeCalendar.get(Calendar.DAY_OF_MONTH)); + cal.set(Calendar.HOUR_OF_DAY, + firstTimeCalendar.get(Calendar.HOUR_OF_DAY)); + cal.set(Calendar.MINUTE, firstTimeCalendar.get(Calendar.MINUTE)); + this.firstTimeCalendar = cal; + } - @Override - public Color getExtrapColor() { - Color color =new java.awt.Color( extrapCS.getColorValue().red, - extrapCS.getColorValue().green, extrapCS.getColorValue().blue ); + public Calendar getSecondTimeCalendar() { + return secondTimeCalendar; + } + + public void setSecondTimeCalendar(Calendar secondTimeCalendar) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, secondTimeCalendar.get(Calendar.YEAR)); + cal.set(Calendar.MONTH, secondTimeCalendar.get(Calendar.MONTH)); + cal.set(Calendar.DAY_OF_MONTH, + secondTimeCalendar.get(Calendar.DAY_OF_MONTH)); + cal.set(Calendar.HOUR_OF_DAY, + secondTimeCalendar.get(Calendar.HOUR_OF_DAY)); + cal.set(Calendar.MINUTE, secondTimeCalendar.get(Calendar.MINUTE)); + this.secondTimeCalendar = cal; + } + + @Override + public Color getExtrapColor() { + Color color = new java.awt.Color(extrapCS.getColorValue().red, + extrapCS.getColorValue().green, extrapCS.getColorValue().blue); return color; - } + } - @Override - public String getExtrapLinePattern() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getExtrapLinePattern() { + // TODO Auto-generated method stub + return null; + } - @Override - public String getExtrapMarker() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getExtrapMarker() { + // TODO Auto-generated method stub + return null; + } - @Override - public TrackPoint[] getExtrapPoints() { - // TODO Auto-generated method stub - return null; - } + @Override + public TrackPoint[] getExtrapPoints() { + // TODO Auto-generated method stub + return null; + } - @Override - public Color getInitialColor(){ - Color color =new java.awt.Color( initialCS.getColorValue().red, - initialCS.getColorValue().green, initialCS.getColorValue().blue ); + @Override + public Color getInitialColor() { + Color color = new java.awt.Color(initialCS.getColorValue().red, + initialCS.getColorValue().green, initialCS.getColorValue().blue); return color; - } + } - @Override - public String getInitialLinePattern() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getInitialLinePattern() { + // TODO Auto-generated method stub + return null; + } - @Override - public String getInitialMarker() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getInitialMarker() { + // TODO Auto-generated method stub + return null; + } - @Override - public TrackPoint[] getInitialPoints() { - // TODO Auto-generated method stub - return null; - } + @Override + public TrackPoint[] getInitialPoints() { + // TODO Auto-generated method stub + return null; + } - /** - * The following methods are used in DrawableElementFactory class to set up all - * necessary attributes for drawing a line. Since Track element dialogue GUI does - * not supply all of those attributes needed by a line. The methods below provide - * some default values for the attributes - */ - /** - * Update the attributes - */ + /** + * The following methods are used in DrawableElementFactory class to set up + * all necessary attributes for drawing a line. Since Track element dialogue + * GUI does not supply all of those attributes needed by a line. The methods + * below provide some default values for the attributes + */ + /** + * Update the attributes + */ public int getSmoothFactor() { - return 0; + return 0; } - + public String getLinePattern() { - return "Solid Line"; + return "Solid Line"; } - + public FillPattern getFillPattern() { - return FillPattern.FILL_PATTERN_0; + return FillPattern.FILL_PATTERN_0; } - + public Boolean isClosedLine() { - return false; + return false; } - + public Boolean isFilled() { - return false; + return false; } - - public Color[] getColors() { - Color[] colors = new Color[1]; - colors[0] = getInitialColor(); - return colors; - } - + + public Color[] getColors() { + Color[] colors = new Color[1]; + colors[0] = getInitialColor(); + return colors; + } + public float getLineWidth() { - return (float)1.0; + return (float) 1.0; } - + public double getSizeScale() { - return 2; + return 2; } - @Override - public FontStyle getFontStyle() { - // TODO Auto-generated method stub - return null; - } + @Override + public boolean[] getExtraPointTimeTextDisplayIndicator() { + // TODO Auto-generated method stub + return null; + } - @Override - public boolean[] getExtraPointTimeTextDisplayIndicator() { - // TODO Auto-generated method stub - return null; - } + @Override + public Coordinate[] getLinePoints() { + // TODO Auto-generated method stub + return null; + } - @Override - public Coordinate[] getLinePoints() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getPatternName() { + // TODO Auto-generated method stub + return null; + } - @Override - public String getPatternName() { - // TODO Auto-generated method stub - return null; - } + /** + * Convert a String in gempak time format to a calendar. + * + * @param gempakTm + * - String in GEMPAK time format + * @return - Calendar + */ + private Calendar gempakTM2Calendar(String gempakTm) { + Calendar cal = null; + try { + cal = Calendar.getInstance(); + int year = 2000 + Integer.valueOf(gempakTm.substring(0, 2)); + int month = Integer.valueOf(gempakTm.substring(2, 4)) - 1; + int day = Integer.valueOf(gempakTm.substring(4, 6)); + int hour = Integer.valueOf(gempakTm.substring(7, 9)); + int min = Integer.valueOf(gempakTm.substring(9)); + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, month); + cal.set(Calendar.DAY_OF_MONTH, day); + cal.set(Calendar.HOUR_OF_DAY, hour); + cal.set(Calendar.MINUTE, min); + } catch (Exception e) { + cal = null; + } - - /** - * Convert a String in gempak time format to a calendar. - * @param gempakTm - String in GEMPAK time format - * @return - Calendar - */ - private Calendar gempakTM2Calendar( String gempakTm ){ - Calendar cal = null; - try { - cal = Calendar.getInstance(); - int year = 2000 + Integer.valueOf(gempakTm.substring(0, 2)); - int month = Integer.valueOf(gempakTm.substring(2, 4)) - 1; - int day = Integer.valueOf(gempakTm.substring(4, 6)); - int hour = Integer.valueOf(gempakTm.substring(7, 9)); - int min = Integer.valueOf(gempakTm.substring(9)); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - cal.set(Calendar.HOUR_OF_DAY, hour); - cal.set(Calendar.MINUTE, min); - } - catch (Exception e){ - cal = null; - } - - return cal; - } + return cal; + } } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DefaultElementContainer.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DefaultElementContainer.java index efcc35ab85..893c94e71b 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DefaultElementContainer.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DefaultElementContainer.java @@ -69,9 +69,27 @@ public class DefaultElementContainer extends AbstractElementContainer { public void draw(IGraphicsTarget target, PaintProperties paintProps, DisplayProperties dprops, boolean needsCreate) { - if ((displayEls == null) || paintProps.isZooming()) + /* + * For ghost drawing - "needsCreate && dprops == null" - It is always on + * the active layer so DiaplayProperties' "filled" should be true while + * "monoColor" should be false (using the element's color). + */ + if (needsCreate && dprops == null) { + dprops = new DisplayProperties(false, null, true); + } + + // For normal drawing........ + if ((displayEls == null) || paintProps.isZooming()) { needsCreate = true; + /* + * TTR971 - needs to set display properties, otherwise the layer + * color may not take effect (e.g., after switching projection) + */ + def.setLayerDisplayAttr(dprops.getLayerMonoColor(), + dprops.getLayerColor(), dprops.getLayerFilled()); + } + if (paintProps.getZoomLevel() != zoomLevel) { needsCreate = true; zoomLevel = paintProps.getZoomLevel(); @@ -102,5 +120,4 @@ public class DefaultElementContainer extends AbstractElementContainer { } } - } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DisplayElementFactory.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DisplayElementFactory.java index eb752cd01b..07d6b64145 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DisplayElementFactory.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/DisplayElementFactory.java @@ -143,6 +143,9 @@ import com.vividsolutions.jts.operation.distance.DistanceOp; * 05/14 TTR 995 J. Wu Make contour label auto-placement an option. * 07/14 ? B. Yin Added support for dashed-line circle for TCM 12 feet sea. * 08/14 ? B. Yin Fixed world wrap for TCM track and zero circle issues. + * 08/14 TTR972 J. Wu Draw filled object as filled only if either its layer's "filled" flag + * "true" or they are on the active layer, . + * 09/14 TTR750 J. Wu Draw track label with specified font styles. * * * @author sgilbert @@ -524,6 +527,7 @@ public class DisplayElementFactory { if (isFilled) { list.add(createFill(pts)); } + /* * Compile each IWireframeShape, create its LineDisplayElement, and add * to IDisplayable return list @@ -1814,7 +1818,8 @@ public class DisplayElementFactory { double major = Math.sqrt((diff[0] * diff[0]) + (diff[1] * diff[1])); double minor = major * arc.getAxisRatio(); - if (major / this.screenToExtent < 0.000001) { // ignore circles with major = 0 + if (major / this.screenToExtent < 0.000001) { // ignore circles with + // major = 0 return slist; } @@ -2035,8 +2040,9 @@ public class DisplayElementFactory { Text txt = new Text(null, track.getFontName(), track.getFontSize(), TextJustification.LEFT_JUSTIFY, pt.getLocation(), 0.0, TextRotation.SCREEN_RELATIVE, - new String[] { dtime }, FontStyle.BOLD, iniDspClr, 0, - 3, false, DisplayType.NORMAL, "Text", "General Text"); + new String[] { dtime }, track.getFontStyle(), + iniDspClr, 0, 3, false, DisplayType.NORMAL, "Text", + "General Text"); temps = createDisplayElements((IText) txt, paintProps); slist.addAll(temps); } @@ -2093,8 +2099,9 @@ public class DisplayElementFactory { Text txt = new Text(null, track.getFontName(), track.getFontSize(), TextJustification.LEFT_JUSTIFY, pt.getLocation(), 0.0, TextRotation.SCREEN_RELATIVE, - new String[] { dtime }, FontStyle.BOLD, expDspClr, 0, - 3, false, DisplayType.NORMAL, "Text", "General Text"); + new String[] { dtime }, track.getFontStyle(), + expDspClr, 0, 3, false, DisplayType.NORMAL, "Text", + "General Text"); temps = createDisplayElements((IText) txt, paintProps); slist.addAll(temps); } @@ -4814,10 +4821,22 @@ public class DisplayElementFactory { */ private boolean getDisplayFillMode(Boolean filled) { - if (layerFilled) { - return layerFilled; + /* + * if (layerFilled) { return layerFilled; } else { return filled; } + */ + + /* + * TTR 972 - to match NMAP2 behavior, non-filled elements will always be + * drawn as non-filled. Filled objects should be drawn as filled only + * when the "filled" flag for its layer is set to "true" or they are on + * the active layer, so it is necessary to set the "layerFilled" flag to + * true before generating displayables for such objects (see + * PgenResource.drawFilledElement()). + */ + if (filled && layerFilled) { + return true; } else { - return filled; + return false; } } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/ITrack.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/ITrack.java index e82f758c52..e195ede396 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/ITrack.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/ITrack.java @@ -7,118 +7,134 @@ */ package gov.noaa.nws.ncep.ui.pgen.display; +import gov.noaa.nws.ncep.ui.pgen.display.IText.FontStyle; + import java.awt.Color; import java.util.Calendar; -import gov.noaa.nws.ncep.ui.pgen.display.IText.FontStyle; - /** * Interface used to get specific attributes of a PGEN Storm track object. + * * @author sgilbert - * + * */ -public interface ITrack extends ILine{ +public interface ITrack extends ILine { - /** - * this enum stores the time display options for extra points - */ - public static enum ExtraPointTimeDisplayOption { SKIP_FACTOR, SHOW_FIRST_LAST, ON_ONE_HOUR, ON_HALF_HOUR }; + /** + * this enum stores the time display options for extra points + */ + public static enum ExtraPointTimeDisplayOption { + SKIP_FACTOR, SHOW_FIRST_LAST, ON_ONE_HOUR, ON_HALF_HOUR + }; -// /** -// * Defines available font styles -// * @return font style -// */ -// public static enum FontStyle { -// REGULAR, BOLD, ITALIC, BOLD_ITALIC -// } - /** * Gets a font style for text of track points */ - public FontStyle getFontStyle() ; - - /** - * Fets a boolean array that indicates if a time text of a extra point should be skipped - */ - public boolean[] getExtraPointTimeTextDisplayIndicator(); + public FontStyle getFontStyle(); - /** - * Gets extra point time display option - */ - public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption(); - - /** - * Gets color to plot the initial storm points - * @return color - */ - public Color getInitialColor(); - - /** - * Gets the line pattern used to display the initial storm points - * @return line pattern - */ - public String getInitialLinePattern(); - - /** - * Gets the marker used to display the initial storm points - * @return marker type - */ - public String getInitialMarker(); - - /** - * Gets the initial storm points and associated date/times - * @return track points - */ - public TrackPoint[] getInitialPoints(); - - /** - * Gets color to plot the extrapolated storm points - * @return color - */ - public Color getExtrapColor(); - - /** - * Gets the line pattern used to display the extrapolated storm points - * @return line pattern - */ - public String getExtrapLinePattern(); - - /** - * Gets the marker used to display the extrapolated storm points - * @return marker type - */ - public String getExtrapMarker(); - - /** - * Gets the extrapolated storm points and associated date/times - * @return track points - */ - public TrackPoint[] getExtrapPoints(); - - /** - * Gets the font used to display the location times - * @return font name - */ - public String getFontName(); - - /** - * Gets the size of the font - * @return font size - */ - public float getFontSize(); - - public Calendar getFirstTimeCalendar(); - public Calendar getSecondTimeCalendar(); - public boolean isSetTimeButtonSelected(); - public int getExtraDrawingPointNumber(); - public FontStyle getStyle(); - public String getSkipFactorText(); - public int getFontNameComboSelectedIndex(); - public int getFontSizeComboSelectedIndex(); - public int getFontStyleComboSelectedIndex(); - public int getUnitComboSelectedIndex(); - public int getRoundComboSelectedIndex(); - public int getRoundDirComboSelectedIndex(); - public String getIntervalTimeString(); + /** + * Fets a boolean array that indicates if a time text of a extra point + * should be skipped + */ + public boolean[] getExtraPointTimeTextDisplayIndicator(); - } + /** + * Gets extra point time display option + */ + public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption(); + + /** + * Gets color to plot the initial storm points + * + * @return color + */ + public Color getInitialColor(); + + /** + * Gets the line pattern used to display the initial storm points + * + * @return line pattern + */ + public String getInitialLinePattern(); + + /** + * Gets the marker used to display the initial storm points + * + * @return marker type + */ + public String getInitialMarker(); + + /** + * Gets the initial storm points and associated date/times + * + * @return track points + */ + public TrackPoint[] getInitialPoints(); + + /** + * Gets color to plot the extrapolated storm points + * + * @return color + */ + public Color getExtrapColor(); + + /** + * Gets the line pattern used to display the extrapolated storm points + * + * @return line pattern + */ + public String getExtrapLinePattern(); + + /** + * Gets the marker used to display the extrapolated storm points + * + * @return marker type + */ + public String getExtrapMarker(); + + /** + * Gets the extrapolated storm points and associated date/times + * + * @return track points + */ + public TrackPoint[] getExtrapPoints(); + + /** + * Gets the font used to display the location times + * + * @return font name + */ + public String getFontName(); + + /** + * Gets the size of the font + * + * @return font size + */ + public float getFontSize(); + + public Calendar getFirstTimeCalendar(); + + public Calendar getSecondTimeCalendar(); + + public boolean isSetTimeButtonSelected(); + + public int getExtraDrawingPointNumber(); + + public String getSkipFactorText(); + + public int getFontNameComboSelectedIndex(); + + public int getFontSizeComboSelectedIndex(); + + public int getFontStyleComboSelectedIndex(); + + public int getUnitComboSelectedIndex(); + + public int getRoundComboSelectedIndex(); + + public int getRoundDirComboSelectedIndex(); + + public String getIntervalTimeString(); + +} diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/RasterElementContainer.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/RasterElementContainer.java index f441262a09..ba197bf19c 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/RasterElementContainer.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/RasterElementContainer.java @@ -15,59 +15,81 @@ import com.raytheon.uf.viz.core.map.IMapDescriptor; /** * An Element Container that can be used for most Symbol/Marker Elements. - * Recreation of the IDisplayable objects is only done if the layer DisplayProperties change. - * The raster images do not need to be recreated when panning or zooming. + * Recreation of the IDisplayable objects is only done if the layer + * DisplayProperties change. The raster images do not need to be recreated when + * panning or zooming. + * * @author sgilbert - * + * */ public class RasterElementContainer extends AbstractElementContainer { - private DisplayProperties saveProps = null; - - /** - * @param element - * @param mapDescriptor - * @param target - */ - public RasterElementContainer(DrawableElement element, - IMapDescriptor mapDescriptor, IGraphicsTarget target) { - super(element, mapDescriptor, target); - // - } + private DisplayProperties saveProps = null; - /* - * Draws to the given graphics target. Recreates the IDisplayable objects - * if the Layer properties change. - * @see gov.noaa.nws.ncep.ui.pgen.display.AbstractTBNL#draw(com.raytheon.uf.viz.core.IGraphicsTarget, com.raytheon.uf.viz.core.drawables.PaintProperties) - */ - @Override - public void draw(IGraphicsTarget target, PaintProperties paintProps, - DisplayProperties dprops) { - draw(target, paintProps, dprops, false); - } + /** + * @param element + * @param mapDescriptor + * @param target + */ + public RasterElementContainer(DrawableElement element, + IMapDescriptor mapDescriptor, IGraphicsTarget target) { + super(element, mapDescriptor, target); + // + } - /* - * Draws to the given graphics target. Recreates the IDisplayable objects - * if the Layer properties change. - * @see gov.noaa.nws.ncep.ui.pgen.display.AbstractTBNL#draw(com.raytheon.uf.viz.core.IGraphicsTarget, com.raytheon.uf.viz.core.drawables.PaintProperties, boolean) - */ - @Override - public void draw(IGraphicsTarget target, PaintProperties paintProps, - DisplayProperties dprops, boolean needsCreate) { - - if ( displayEls == null ) needsCreate = true; - - if ( (dprops != null) && ! dprops.equals(saveProps) ) { - def.setLayerDisplayAttr(dprops.getLayerMonoColor(), dprops.getLayerColor(), dprops.getLayerFilled()); - needsCreate = true; - } - - if ( needsCreate ) createDisplayables(paintProps); - saveProps = dprops; - - for ( IDisplayable each : displayEls ) { - each.draw(target, paintProps); - } - } + /* + * Draws to the given graphics target. Recreates the IDisplayable objects if + * the Layer properties change. + * + * @see + * gov.noaa.nws.ncep.ui.pgen.display.AbstractTBNL#draw(com.raytheon.uf.viz + * .core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + public void draw(IGraphicsTarget target, PaintProperties paintProps, + DisplayProperties dprops) { + draw(target, paintProps, dprops, false); + } + + /* + * Draws to the given graphics target. Recreates the IDisplayable objects if + * the Layer properties change. + * + * @see + * gov.noaa.nws.ncep.ui.pgen.display.AbstractTBNL#draw(com.raytheon.uf.viz + * .core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties, boolean) + */ + @Override + public void draw(IGraphicsTarget target, PaintProperties paintProps, + DisplayProperties dprops, boolean needsCreate) { + + if (displayEls == null) { + needsCreate = true; + + /* + * TTR971 - needs to set display properties, otherwise the layer + * color may not take effect (e.g., after switching projection) + */ + def.setLayerDisplayAttr(dprops.getLayerMonoColor(), + dprops.getLayerColor(), dprops.getLayerFilled()); + } + + if ((dprops != null) && !dprops.equals(saveProps)) { + def.setLayerDisplayAttr(dprops.getLayerMonoColor(), + dprops.getLayerColor(), dprops.getLayerFilled()); + needsCreate = true; + } + + if (needsCreate) + createDisplayables(paintProps); + + saveProps = dprops; + + for (IDisplayable each : displayEls) { + each.draw(target, paintProps); + } + } } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/TextDisplayElement.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/TextDisplayElement.java index b25ed35510..0fa6ec7103 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/TextDisplayElement.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/display/TextDisplayElement.java @@ -154,6 +154,14 @@ public class TextDisplayElement implements IDisplayable { target.drawShadedRect(box, bg, 1.0, null); } + /* + * TTR 741 (10/2014) - Note, for single-line text, we could match it + * to Raytheon's text style. For multi-line text, we cannot match it + * to Raytheon's since it may add box, overline, underline to each + * line of text, not one single box, overline, or underline - so we + * may need to develop a new drawing method or ask Raytheon to + * provide support in GlTarget. + */ switch (displayType) { case NORMAL: @@ -161,19 +169,40 @@ public class TextDisplayElement implements IDisplayable { break; case BOX: - dstring.textStyle = TextStyle.BOXED; + // dstring.textStyle = TextStyle.BOXED; + if (dstring.getText().length > 1) { + target.drawRect(box, dstring.getColors()[0], 1.0f, 1.0); + } else { + dstring.textStyle = TextStyle.BOXED; + } // target.drawRect(box, dstring.getColors()[0], 1.0f, 1.0); break; case OVERLINE: - dstring.textStyle = TextStyle.OVERLINE; + // dstring.textStyle = TextStyle.OVERLINE; + if (dstring.getText().length > 1) { + target.drawLine(box.getMinX(), box.getMinY(), 0.0, + box.getMaxX(), box.getMinY(), 0.0, + dstring.getColors()[0], 1.0f); + } else { + + dstring.textStyle = TextStyle.OVERLINE; + } // target.drawLine(box.getMinX(), box.getMinY(), 0.0, // box.getMaxX(), box.getMinY(), 0.0, // dstring.getColors()[0], 1.0f); break; case UNDERLINE: - dstring.textStyle = TextStyle.UNDERLINE; + // dstring.textStyle = TextStyle.UNDERLINE; + if (dstring.getText().length > 1) { + target.drawLine(box.getMinX(), box.getMaxY(), 0.0, + box.getMaxX(), box.getMaxY(), 0.0, + dstring.getColors()[0], 1.0f); + + } else { + dstring.textStyle = TextStyle.UNDERLINE; + } // target.drawLine(box.getMinX(), box.getMaxY(), 0.0, // box.getMaxX(), box.getMaxY(), 0.0, // dstring.getColors()[0], 1.0f); diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/elements/Track.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/elements/Track.java index 1e67621d07..dd9f624e75 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/elements/Track.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/elements/Track.java @@ -38,1133 +38,1185 @@ import com.vividsolutions.jts.geom.Coordinate; * 02/12 TTR456 Q.Zhou Added speed knot, mph. Added combos and roundTo indices for speed & dir . * Modified setSpeed * 06/12 #777 Q.Zhou Modified DEFAULT_EXTRA_POINT_NUMBER. - * 08/13 #1020 B. Yin Added a method to get direction 'FROM'. + * 08/13 #1020 B. Yin Added a method to get direction 'FROM'. * * - * @author M. Gao - * @version 0.0.1 + * @author M. Gao + * @version 0.0.1 */ -@ElementOperations ( {Operation.COPY_MOVE, Operation.EXTRAPOLATE} ) +@ElementOperations({ Operation.COPY_MOVE, Operation.EXTRAPOLATE }) public class Track extends Line implements ITrack { -//public class Track extends MultiPointElement implements ITrack { - -// private final static org.apache.log4j.Logger log = -// org.apache.log4j.Logger.getLogger(Track.class); - - - private final static float DEFAULT_FONT_SIZE = 14.0f; - private final static float DEFAULT_LINE_WIDTH = 0.1f; - private final static int DEFAULT_EXTRA_POINT_NUMBER = 5; -// private final static int DEFAULT_INTERVAL_HOUR = 1; - private final static String INTERVAL_TIME_FORMAT_PATTERN = "HH:mm"; - public void setExtrapMarker(String extrapMarker) { - this.extrapMarker = extrapMarker; - } - - public void setExtrapLinePattern(String extrapLinePattern) { - this.extrapLinePattern = extrapLinePattern; - } - - private final static String INITIAL_MARKER = "FILLED_DIAMOND"; - private final static String EXTRAP_MARKER = "FILLED_TRIANGLE"; - private final static String INITIAL_LINE_PATTERN = "LINE_SOLID"; - private final static String EXTRAP_LINE_PATTERN = "LINE_SOLID"; - /* - * This value of DEFAULT_LINE_PATTERN is a temporary solution - * Eventually a decision needs to be done for what a value - * should be used - */ - public final static String TRACK_PGEN_CATEGORY = "Track"; - public final static String TRACK_INFO_DLG_CATEGORY_NAME = "TRACK_EXTRA_POINTS_INFO"; - public final static String TRACK_PGEN_TYPE = "STORM_TRACK"; - - private Color initialColor; - private Color extrapColor; - private String initialMarker; - private String initialLinePattern; - private String extrapMarker; - private String extrapLinePattern; - - private TrackPoint[] initTrackPoints; - private TrackPoint[] extrapPoints; - private String fontName; - private float fontSize; - private FontStyle fontStyle; - - private float lineWidth; - private int extraDrawingPointNumber; - - private boolean setTimeButtonSelected; - - private Calendar firstTimeCalendar; - private Calendar secondTimeCalendar; - private String intervalTimeString; - private int intervalComboSelectedIndex; - - private int fontSizeComboSelectedIndex; - private int fontNameComboSelectedIndex; - private int fontStyleComboSelectedIndex; - - private int elapsedHourForExtraPoint; - private int elapsedMinuteForExtraPoint; - - private ExtraPointTimeDisplayOption extraPointTimeDisplayOption; - private String skipFactorTextString; - private boolean[] extraPointTimeTextDisplayIndicator; - - // direction, speed and unit are not saved to a file - private double directionForExtraPoints; - private boolean roundDirBtnSelected; - private int roundDirComboSelectedIndex; - - private double speed; // speed in meter/millisecond - private double speedInKnotOverHour; - private double speedInKilometerOverHour; - private double speedInMileOverHour; - private boolean roundBtnSelected; - private int unitComboSelectedIndex; - private int roundComboSelectedIndex; - - public Track() {} - - public Track(ArrayList _locations, Calendar _firstTimeCalendar, - Calendar _secondTimeCalendar) { - initializeInitTrackPoints(_locations, - _firstTimeCalendar, _secondTimeCalendar); - } - - - public void initializeInitTrackPoints(ArrayList locations, - Calendar firstTimeCalendar, Calendar secondTimeCalendar) { - initializeInitTrackPoints(locations); - initializeInitFirstTimeCalendar(firstTimeCalendar); - initializeInitSecondTimeCalendar(secondTimeCalendar); - } - - public void initializeTrackByTrackAttrDlgAndLocationList(ITrack trackAttrDlgObject, ArrayList locations) { - initializeInitTrackPoints(locations); - initializeInitFirstTimeCalendar(trackAttrDlgObject.getFirstTimeCalendar()); - initializeInitSecondTimeCalendar(trackAttrDlgObject.getSecondTimeCalendar()); - - this.setInitialMarker(""); - this.setSetTimeButtonSelected(trackAttrDlgObject.isSetTimeButtonSelected()); - this.setExtraDrawingPointNumber(trackAttrDlgObject.getExtraDrawingPointNumber()); - - this.setIntervalTimeString(getIntervalTimeTextStringValue(trackAttrDlgObject)); - - this.setFontName(trackAttrDlgObject.getFontName()); - this.setFontStyle(trackAttrDlgObject.getStyle()); - this.setFontSize(trackAttrDlgObject.getFontSize()); - this.setInitialColor(trackAttrDlgObject.getInitialColor()); - this.setExtrapColor(trackAttrDlgObject.getExtrapColor()); - this.setExtraPointTimeDisplayOption(trackAttrDlgObject.getExtraPointTimeDisplayOption()); - this.setSkipFactorTextString(trackAttrDlgObject.getSkipFactorText()); - this.setFontNameComboSelectedIndex(trackAttrDlgObject.getFontNameComboSelectedIndex()); - this.setFontSizeComboSelectedIndex(trackAttrDlgObject.getFontSizeComboSelectedIndex()); - this.setFontStyleComboSelectedIndex(trackAttrDlgObject.getFontStyleComboSelectedIndex()); - this.setUnitComboSelectedIndex(trackAttrDlgObject.getUnitComboSelectedIndex()); - this.setRoundComboSelectedIndex(trackAttrDlgObject.getRoundComboSelectedIndex()); - if (trackAttrDlgObject.getRoundComboSelectedIndex() >0) - this.setRoundBtnSelected(true); - else - this.setRoundBtnSelected(false); - - this.setRoundDirComboSelectedIndex(trackAttrDlgObject.getRoundDirComboSelectedIndex()); - if (trackAttrDlgObject.getRoundDirComboSelectedIndex() >0) - this.setRoundDirBtnSelected(true); - else - this.setRoundDirBtnSelected(false); - - //This method can be called only after all of the above settings are completed! - this.calculateExtrapTrackPoints(); - /** - * For now, the type is the name of a LinePattern defined in - * "gov.noaa.nws.ncep.ui.pgen.display.LinePatternList" - * However, there is no type has been decided for Track element - * yet. Thus, it is now hard coded. - */ -// this.setType("Solid Lines"); - this.setPgenCategory(Track.TRACK_PGEN_CATEGORY); - this.setPgenType(Track.TRACK_PGEN_TYPE); - } - - public void initializeInitTrackPoints(ArrayList locations) { - TrackPoint[] initTrackPointArray = new TrackPoint[locations.size()]; - int arrayIndex = 0; -// log.info("inside Track.initializeInitTrackPoints, points Number="+locations.size()); - for(Coordinate currentCoordinate : locations) { - TrackPoint eachTrackPoint = new TrackPoint(currentCoordinate, null); - initTrackPointArray[arrayIndex++] = eachTrackPoint; - } - setInitTrackPoints(initTrackPointArray); - } - - public void initializeInitFirstTimeCalendar(Calendar firstCalendar) { - setFirstTimeCalendar(firstCalendar); - if(getInitTrackPoints() != null) { - int initTrackPointLength = getInitTrackPoints().length; - if(initTrackPointLength >= 2) { - getInitTrackPoints()[initTrackPointLength - 2].setTime(firstCalendar); - } - } - } - - public void initializeInitSecondTimeCalendar(Calendar secondCalendar) { - setSecondTimeCalendar(secondCalendar); - if(getInitTrackPoints() != null) { - int initTrackPointLength = getInitTrackPoints().length; - if(initTrackPointLength >= 2) { - getInitTrackPoints()[initTrackPointLength - 1].setTime(secondCalendar); - } - } - } - - public void calculateExtrapTrackPoints() { - extrapPoints = calculateExtrapTrackPoints(getInitialPoints(), getFirstTimeCalendar(), - getSecondTimeCalendar(), getExtraDrawingPointNumber(), - getElapsedHourForExtraPoint(), getElapsedMinuteForExtraPoint(), - getExtraPointTimeDisplayOption(), getSkipFactorTextString()); - - /* - * it is important to override the variable "ArrayList linePoints" with - * initTrackPoints and extrapPoints arrays - */ - setLinePointsValue(getInitialPoints(), getExtrapPoints()); - - /* - * a linePattern needs to be set for PgenSelectingTool to pick up - * the correct dialogue window to popup - */ - setPgenCategory(Track.TRACK_PGEN_CATEGORY); - setPgenType(Track.TRACK_PGEN_TYPE); - } - - public void setLinePointsValue(TrackPoint[] initTrackPoints, TrackPoint[] extrapPoints) { - int listSize = 1; - if(initTrackPoints != null) - listSize += initTrackPoints.length; - if(extrapPoints != null) - listSize += extrapPoints.length; - ArrayList coordinatePointList = new ArrayList(listSize); - addArrayToArrayList(coordinatePointList, initTrackPoints); - addArrayToArrayList(coordinatePointList, extrapPoints); - - /* - * Now use the inherited method setLinePoints to set the linPoints value - */ - setLinePoints(coordinatePointList); - } - - /** - * Creates a copy of this object. This is a deep copy and new objects are - * created so that we are not just copying references of objects - */ -// @Override -// public DrawableElement copy() { - public Track copy() { - - /* - * create a new Track object and initially set its attributes to this one's - */ - Track newTrack = new Track(); - Calendar newFirstTimeCalendar = Calendar.getInstance(); - newFirstTimeCalendar.setTimeInMillis(getFirstTimeCalendar().getTimeInMillis()); - newTrack.setFirstTimeCalendar(newFirstTimeCalendar); -// newTrack.setFirstTimeCalendar(getFirstTimeCalendar()); - - Calendar newSecondTimeCalendar = Calendar.getInstance(); - newSecondTimeCalendar.setTimeInMillis(getSecondTimeCalendar().getTimeInMillis()); - newTrack.setSecondTimeCalendar(newSecondTimeCalendar); -// newTrack.setSecondTimeCalendar(getSecondTimeCalendar()); - - TrackPoint[] newInitTrackPoints = new TrackPoint[getInitTrackPoints().length]; -// log.info("######, before enter the loop for TrackPoint.clone, newInitTrackPoints.length="+newInitTrackPoints.length); - for(int i=0; i0) - this.setRoundBtnSelected(true); - else - this.setRoundBtnSelected(false); - - setRoundDirComboSelectedIndex(trackAttrDlg.getRoundDirComboSelectedIndex()); - if (trackAttrDlg.getRoundDirComboSelectedIndex() >0) - this.setRoundDirBtnSelected(true); - else - this.setRoundDirBtnSelected(false); - - //This method can be called only after all of the above settings are completed! - calculateExtrapTrackPoints(); - /** - * For now, the type is the name of a LinePattern defined in - * "gov.noaa.nws.ncep.ui.pgen.display.LinePatternList" - * However, there is no type has been decided for Track element - * yet. Thus, it is now hard coded. - */ -// setType("Solid Lines"); - setPgenType(Track.TRACK_PGEN_TYPE); - setPgenCategory(Track.TRACK_PGEN_CATEGORY); - } - - public void addPoint(int index, Coordinate point) { - ArrayList allLinePoints = getPoints(); - if(allLinePoints == null) - allLinePoints = new ArrayList(); - - if(allLinePoints.size() <= index) - allLinePoints.add(point); - else - allLinePoints.add(index, point); - - int initialPointSize= getInitialPoints().length; - int extrapPointSize = getExtrapPoints().length; - - if(index < initialPointSize) { - TrackPoint modifiedTrackPoint = getInitialPoints()[index]; - modifiedTrackPoint.setLocation(point); - } else { - int extrapindex = index - initialPointSize; - if(extrapindex >= 0 && extrapindex < extrapPointSize) { - TrackPoint modifiedTrackPoint = getExtrapPoints()[extrapindex]; - modifiedTrackPoint.setLocation(point); - } - } -// linePoints.add(index, point); - } - - public void removePoint(int index ) { - ArrayList allLinePoints = getPoints(); - if(allLinePoints == null) - return; -// if(allLinePoints.size() > index && getInitialPoints().length > index) { - if(allLinePoints.size() > index) { - allLinePoints.remove(index); - } - -// linePoints.remove( index ); - - } - - public void setPoints( ArrayList pts ){ - if(pts == null) - return; - /* - * call MultiPointElement.setPoint(...) - */ - super.setPoints(pts); - /* - * Now initialize initPoint and ExtrapPoint arrays - */ - int allPointsSize = pts.size(); - - int initTrackPointSize = 0; - if(getInitTrackPoints() != null) - initTrackPointSize = getInitTrackPoints().length; - int index = 0; - - /* - * reset coordinate values for initial track points - */ - while(index < initTrackPointSize && index < allPointsSize) { - TrackPoint currentTrackPoint = getInitTrackPoints()[index]; - if(currentTrackPoint != null) - currentTrackPoint.setLocation(pts.get(index)); - index++; - } - - - - - int extrapTrackPointSize = 0; - if(getExtrapPoints() != null) - extrapTrackPointSize = getExtrapPoints().length; - int extrapIndex = 0; - while(extrapIndex < extrapTrackPointSize && - index < allPointsSize) { - TrackPoint currentTrackPoint = getExtrapPoints()[extrapIndex]; - if(currentTrackPoint != null) - currentTrackPoint.setLocation(pts.get(index)); - index++; - extrapIndex++; - } - - -// this.linePoints = pts; - - } - - /* - * All private help methods start here - */ - private String getIntervalTimeTextStringValue(ITrack trackAttrDlg) { - - return trackAttrDlg.getIntervalTimeString(); - } - - private void addArrayToArrayList(ArrayList coordinatePointList, TrackPoint[] trackPoints) { - if(trackPoints == null) - return; - for(TrackPoint trackPoint : trackPoints) { - coordinatePointList.add(trackPoint.getLocation()); - } - } - - private TrackPoint[] calculateExtrapTrackPoints(TrackPoint[] initialPoints, - Calendar initPointBeforeLastInitPointTimeCal, - Calendar lastInitPointTimeCal, - int extraDrawingPointNumber, - int elapsedHourForExtraPointValue, - int elapsedMinuteForExtraPointValue, - ExtraPointTimeDisplayOption extraPointTimeDisplayOption, - String skipFactorTextString) { - if(initialPoints == null || initialPoints.length < 2) { -// log.error("Method:calculateExtrapTrackPoints, the input initialPoints is null or initialPoints.length less than 2"); - return null; - } - - int arrayLength = initialPoints.length; - Coordinate initPointBeforeLastInitPointCoordinate = initialPoints[arrayLength - 2].getLocation(); - Coordinate lastInitPointCoordinate = initialPoints[arrayLength - 1].getLocation(); - if(!isCoordinateValid(initPointBeforeLastInitPointCoordinate) || - !isCoordinateValid(lastInitPointCoordinate) || - initPointBeforeLastInitPointTimeCal == null || - lastInitPointTimeCal == null) { -// log.error("Method: calculateExtrapTrackPoints, find 4 possible invalid input: startPointCoordinate or "+ -// "destPointCoordinate is invalid. firstTimeCal or secondTimeCal is null"); - return null; - } - - GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); - gc.setStartingGeographicPoint(initPointBeforeLastInitPointCoordinate.x, - initPointBeforeLastInitPointCoordinate.y); - gc.setDestinationGeographicPoint(lastInitPointCoordinate.x, - lastInitPointCoordinate.y); - double direction = gc.getAzimuth(); - setDirectionForExtraPoints(direction); - - double distanceInMeter = gc.getOrthodromicDistance(); - long timeDifference = getTimeDifferenceInMillisecond(initPointBeforeLastInitPointTimeCal, - lastInitPointTimeCal); - double speed = distanceInMeter / (double)timeDifference; - setSpeed(speed); - - //Calculate the first extra point time Calendar - Calendar firstExtraPointTimeCal = getTimeElapsedCalendarForFirstExtraPoint(lastInitPointTimeCal, - elapsedHourForExtraPointValue, - elapsedMinuteForExtraPointValue); - - //calculate the distance between the last Initial point and the first extra point - double distanceBetweenLastInitPointAndFirstExtraPoint = calculateDistanceBetweenLastInitPointAndFirstExtraPoint(speed, - lastInitPointTimeCal, firstExtraPointTimeCal); - - //calculate the distance among extra points - double distanceForExtraPoint = calculateDistanceForExtraPoints(speed, - firstExtraPointTimeCal, elapsedHourForExtraPointValue, - elapsedMinuteForExtraPointValue); - - TrackPoint[] extrapTrackPointArray = calculateExtrapTrackPoints(gc, - lastInitPointCoordinate, direction, - distanceBetweenLastInitPointAndFirstExtraPoint, - distanceForExtraPoint, - extraDrawingPointNumber, lastInitPointTimeCal, - firstExtraPointTimeCal, - elapsedHourForExtraPointValue, - elapsedMinuteForExtraPointValue); - disableSomeTimeTagsDisplayBasedOnExtraPointTimeDisplayOption(extrapTrackPointArray, - extraPointTimeDisplayOption, skipFactorTextString); - - return extrapTrackPointArray; - } - - private void disableSomeTimeTagsDisplayBasedOnExtraPointTimeDisplayOption(TrackPoint[] extrapTrackPointArray, - ExtraPointTimeDisplayOption extraPointTimeDisplayOption, String skipFactorTextString) { - if(extrapTrackPointArray == null) - return; - boolean[] extraPointTimeTagFlagArray = new boolean[extrapTrackPointArray.length]; - initializeBooleanArray(extraPointTimeTagFlagArray, true); - - if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR) { - removeTimeTagsBasedOnSkipFactor(extrapTrackPointArray, skipFactorTextString, extraPointTimeTagFlagArray); - } else if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST) { - removeTimeTagsBasedOnShowLastFirstOnly(extrapTrackPointArray, extraPointTimeTagFlagArray); - } else if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR) { - removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, true, extraPointTimeTagFlagArray); - } else if(extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR) { - removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, false, extraPointTimeTagFlagArray); - } - else { - removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, false, extraPointTimeTagFlagArray); - } - - /* - * set the updated boolean array back to the indicator, - * in displayElementFactory, this boolean array will be - * used to indicate if a time text should be skipped - */ - setExtraPointTimeTextDisplayIndicator(extraPointTimeTagFlagArray); - } - - private void removeTimeTagsBasedOnShowLastFirstOnly(TrackPoint[] extrapTrackPointArray, boolean[] timeTagIndicatorArray) { - if(extrapTrackPointArray.length < 3) - return; - for(int i=1; i<(extrapTrackPointArray.length - 1); i++) { - timeTagIndicatorArray[i] = false; - } - } - - private void removeTimeTagsBasedOnSkipFactor(TrackPoint[] extrapTrackPointArray, - String skipFactorTextString, boolean[] timeTagIndicatorArray) { - if(skipFactorTextString == null) - return; - /* - * always show the time tags of the first and last extra points - */ - if(extrapTrackPointArray.length < 3) - return; - - int skipFactorIntValue = 0; - try { - skipFactorIntValue = Integer.parseInt(skipFactorTextString); - } catch(NumberFormatException nfe) { -// log.error("The input of skipFactorTextString is invalid, skipFactorTextString="+ -// skipFactorTextString); - } - - /* - * 1. make sure skipFactorIntValue is a valid value - * 2. since the last and first extra points are always - * displayed, thus do skipFactorIntValue > (extrapTrackPointArray.length - 2) - * check - */ - if(!(skipFactorIntValue > 0) || skipFactorIntValue > (extrapTrackPointArray.length - 2)) - return; - - for(int i=1; i<=skipFactorIntValue; i++) { - timeTagIndicatorArray[i] = false; - } - } - - private void removeTimeTagsBasedOnHourMinuteValue(TrackPoint[] extrapTrackPointArray, - boolean isExactHourDisplayed, boolean[] timeTagIndicatorArray) { - for(int i=0; i<(extrapTrackPointArray.length); i++) { - TrackPoint targetTrackPoint = extrapTrackPointArray[i]; - Calendar targetPointTimeCal = targetTrackPoint.getTime(); - - if(!isTimeTagDisplayable(targetPointTimeCal, isExactHourDisplayed)) { - /* - * mark the flag array index for the time needs to be hided - */ - timeTagIndicatorArray[i] = false; - } - } - } - - private void initializeBooleanArray(boolean[] booleanArray, boolean initValue) { - if(booleanArray == null) - return; - for(int i=0; i 180.0 || coordinate.x < -180.0 || coordinate.y > 90.0 || - coordinate.y < -90.0) - return false; - return true; - } - - private Calendar getIntervalCalendarByParsingString(String dateString, - String formatStringPattern, Calendar secondTimeCal) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStringPattern); - Calendar cal = null; - int elapsedHour = 1; - int elapsedMinute = 0; - if(dateString != null) { - try { - Date date = simpleDateFormat.parse(dateString); - cal = Calendar.getInstance(); - cal.setTime(date); - elapsedHour = cal.get(Calendar.HOUR_OF_DAY); - elapsedMinute = cal.get(Calendar.MINUTE); - } catch(ParseException pe) { -// log.error("The input of dateString is invalid, parse fails, dateString="+dateString); - elapsedHour = 1; - } - } - setElapsedHourForExtraPoint(elapsedHour); - setElapsedMinuteForExtraPoint(elapsedMinute); - cal = getTimeElapsedCalendar(secondTimeCal, elapsedHour, elapsedMinute); - return cal; - } - - private Calendar getTimeElapsedCalendarForFirstExtraPoint(Calendar startCalendar, int elapsedHour, - int elapsedMinute) { - Calendar nextCal = Calendar.getInstance(); - nextCal.setTimeInMillis(startCalendar.getTimeInMillis()); - /* - * played with the nmap2 APP, get confused with the logic behind, right now, calculate - * the first extra point as the logic described below: - * 1. if elapsedHour > 1 hour, set the first extra point time as the next exact hour - * 2. if elapsedHour == 0 and last init. point MINUTE value >= elapsedMinute, - * set the first time extra point as the next exact hour - * 3. if elapsedHour == 0 and last init. point MINUTE value < elapsedMinute, - * set the first time extra point as the exact hour of the last init. point + elapsedMinute - * In the future, this logic may be changed once the real logic is figured. Michael Gao comment. - */ - if(elapsedHour >= 1) { - nextCal.set(Calendar.MINUTE, 0); - nextCal.add(Calendar.HOUR_OF_DAY, 1); - } else { - int currentMinute = nextCal.get(Calendar.MINUTE); - if(currentMinute >= elapsedMinute) { - nextCal.set(Calendar.MINUTE, 0); - nextCal.add(Calendar.HOUR_OF_DAY, 1); - } else { - nextCal.set(Calendar.MINUTE, elapsedMinute); - } - } - return nextCal; - } - - private Calendar getTimeElapsedCalendar(Calendar startCalendar, int elapsedHour, - int elapsedMinute) { - Calendar nextCal = Calendar.getInstance(); - nextCal.setTimeInMillis(startCalendar.getTimeInMillis()); - nextCal.add(Calendar.HOUR_OF_DAY, elapsedHour); - nextCal.add(Calendar.MINUTE, elapsedMinute); - return nextCal; - } - - - /* - * all override setters and getters of the instance variables go here - */ - @Override - public Color getExtrapColor() { - return this.extrapColor; - } - - @Override - public String getExtrapLinePattern() { - return EXTRAP_LINE_PATTERN; - } - - @Override - public String getExtrapMarker() { - return EXTRAP_MARKER; - } - - public TrackPoint[] getInitTrackPoints() { - return initTrackPoints; - } - - public void setInitTrackPoints(TrackPoint[] initTrackPoints) { - this.initTrackPoints = initTrackPoints; - } - - public void setExtrapPoints(TrackPoint[] extrapPoints) { - this.extrapPoints = extrapPoints; - } - - @Override - public TrackPoint[] getExtrapPoints() { - return extrapPoints; - } - - @Override - public Color getInitialColor() { - return this.initialColor; - } - - @Override - public String getInitialLinePattern() { - return INITIAL_LINE_PATTERN; - } - - @Override - public String getInitialMarker() { - return INITIAL_MARKER; - } - - @Override - public TrackPoint[] getInitialPoints() { - return initTrackPoints; - } - - @Override - public String getFontName() { - return this.fontName; - } - - public void setFontName(String _fontName) { - this.fontName = _fontName; - } - - @Override - public float getFontSize() { - if(this.fontSize <= 0.0) - return DEFAULT_FONT_SIZE; - return this.fontSize; - } - - public void setFontSize(float _fontSize) { - this.fontSize = _fontSize; - } - - public FontStyle getFontStyle() { - return fontStyle; - } - - public void setFontStyle(FontStyle fontStyle) { - this.fontStyle = fontStyle; - } - - @Override - public float getLineWidth() { - if(this.lineWidth <= 0.0) - return DEFAULT_LINE_WIDTH; - return this.lineWidth; - } - - /* - * all non-override setters and getters of the instance variables go here - */ - public boolean isSetTimeButtonSelected() { - return setTimeButtonSelected; - } - - public void setSetTimeButtonSelected(boolean setTimeButtonSelected) { - this.setTimeButtonSelected = setTimeButtonSelected; - } - - public int getFontSizeComboSelectedIndex() { - return fontSizeComboSelectedIndex; - } - - public void setFontSizeComboSelectedIndex(int fontSizeComboSelectedIndex) { - this.fontSizeComboSelectedIndex = fontSizeComboSelectedIndex; - } - - public int getFontNameComboSelectedIndex() { - return fontNameComboSelectedIndex; - } - - public void setFontNameComboSelectedIndex(int fontNameComboSelectedIndex) { - this.fontNameComboSelectedIndex = fontNameComboSelectedIndex; - } - - public int getFontStyleComboSelectedIndex() { - return fontStyleComboSelectedIndex; - } - - public void setFontStyleComboSelectedIndex(int fontStyleComboSelectedIndex) { - this.fontStyleComboSelectedIndex = fontStyleComboSelectedIndex; - } - - public int getIntervalComboSelectedIndex() { - return intervalComboSelectedIndex; - } - - public void setIntervalComboSelectedIndex(int intervalComboSelectedIndex) { - this.intervalComboSelectedIndex = intervalComboSelectedIndex; - } - - public int getUnitComboSelectedIndex() { - return unitComboSelectedIndex; - } - - public void setUnitComboSelectedIndex(int unitComboSelectedIndex) { - this.unitComboSelectedIndex = unitComboSelectedIndex; - } - - public int getRoundComboSelectedIndex() { - return roundComboSelectedIndex; - } - - public void setRoundComboSelectedIndex(int roundComboSelectedIndex) { - this.roundComboSelectedIndex = roundComboSelectedIndex; - } - - public boolean getRoundBtnSelected() { - return roundBtnSelected; - } - - public void setRoundBtnSelected(boolean roundBtnSelected) { - this.roundBtnSelected = roundBtnSelected; - } - - public int getRoundDirComboSelectedIndex() { - return roundDirComboSelectedIndex; - } - - public void setRoundDirComboSelectedIndex(int roundDirComboSelectedIndex) { - this.roundDirComboSelectedIndex = roundDirComboSelectedIndex; - } - - public boolean getRoundDirBtnSelected() { - return roundDirBtnSelected; - } - - public void setRoundDirBtnSelected(boolean roundDirBtnSelected) { - this.roundDirBtnSelected = roundDirBtnSelected; - } - - public double getDirectionForExtraPoints() { - return directionForExtraPoints; - } - - public double getFromdirection(){ - - Coordinate initPointBeforeLastInitPointCoordinate = initTrackPoints[initTrackPoints.length - 2].getLocation(); - Coordinate lastInitPointCoordinate = initTrackPoints[initTrackPoints.length - 1].getLocation(); - - GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); - gc.setStartingGeographicPoint(lastInitPointCoordinate.x, - lastInitPointCoordinate.y); - gc.setDestinationGeographicPoint(initPointBeforeLastInitPointCoordinate.x, - initPointBeforeLastInitPointCoordinate.y); - double dir = gc.getAzimuth(); - if ( dir < 0 ) dir += 360; - return dir; - } - - public void setDirectionForExtraPoints(double directionForExtraPoints) { - this.directionForExtraPoints = directionForExtraPoints; - } - - public double getSpeed() { - return speed; - } - - public void setSpeed(double speed) { - this.speed = speed; - /* - * The original speed is meters / millisecond, now it needs - * to be converted to following units - */ - this.speedInKnotOverHour = speed * 1944; - this.speedInKilometerOverHour = speed * 3600; - this.speedInMileOverHour = speed * 2237; - } - - public double getSpeedInKnotOverHour() { - return speedInKnotOverHour; - } - public double getSpeedInKilometerOverHour() { - return speedInKilometerOverHour; - } - public double getSpeedInMileOverHour() { - return speedInMileOverHour; - } - - - public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption() { - return extraPointTimeDisplayOption; - } - - public void setExtraPointTimeDisplayOption(ExtraPointTimeDisplayOption extraPointTimeDisplayOption) { - this.extraPointTimeDisplayOption = extraPointTimeDisplayOption; - } - - public String getSkipFactorTextString() { - return skipFactorTextString; - } - - public void setSkipFactorTextString(String skipFactorTextString) { - this.skipFactorTextString = skipFactorTextString; - } - - public boolean[] getExtraPointTimeTextDisplayIndicator() { - return extraPointTimeTextDisplayIndicator; - } - - public void setExtraPointTimeTextDisplayIndicator( - boolean[] extraPointTimeTextDisplayIndicator) { - this.extraPointTimeTextDisplayIndicator = extraPointTimeTextDisplayIndicator; - } - - public void setInitialColor(Color initialColor) { - this.initialColor = initialColor; - } - - public void setExtrapColor(Color extrapColor) { - this.extrapColor = extrapColor; - } - - public void setInitialMarker(String initialMarker) { - this.initialMarker = initialMarker; - } - - public void setInitialLinePattern(String initialLinePattern) { - this.initialLinePattern = initialLinePattern; - } - - public void setLineWidth(float lineWidth) { - this.lineWidth = lineWidth; - } - - public int getExtraDrawingPointNumber() { - if(!(this.extraDrawingPointNumber > 0)) - return DEFAULT_EXTRA_POINT_NUMBER; - return this.extraDrawingPointNumber; - } - - public void setExtraDrawingPointNumber(int extraDrawingPointNumber) { - this.extraDrawingPointNumber = extraDrawingPointNumber; - } - - public Calendar getFirstTimeCalendar() { - return firstTimeCalendar; - } - - public void setFirstTimeCalendar(Calendar firstTimeCalendar) { - this.firstTimeCalendar = firstTimeCalendar; - } - - public Calendar getSecondTimeCalendar() { - return secondTimeCalendar; - } - - public void setSecondTimeCalendar(Calendar secondTimeCalendar) { - this.secondTimeCalendar = secondTimeCalendar; - } - - public String getIntervalTimeString() { - return intervalTimeString; - } - - public void setIntervalTimeString(String _intervalTimeString) { - /* - * intervalTimeString == null is allowed - */ - this.intervalTimeString = _intervalTimeString; - - Calendar intervalTimeCal = getIntervalCalendarByParsingString(_intervalTimeString, - INTERVAL_TIME_FORMAT_PATTERN, getSecondTimeCalendar()); - //setIntervalTimeCalendar(intervalTimeCal); - } - - public int getElapsedHourForExtraPoint() { - return elapsedHourForExtraPoint; - } - - private void setElapsedHourForExtraPoint(int elapsedHourForExtraPoint) { - this.elapsedHourForExtraPoint = elapsedHourForExtraPoint; - } - - public int getElapsedMinuteForExtraPoint() { - return elapsedMinuteForExtraPoint; - } - - private void setElapsedMinuteForExtraPoint(int elapsedMinuteForExtraPoint) { - this.elapsedMinuteForExtraPoint = elapsedMinuteForExtraPoint; - } - - @Override - public String getSkipFactorText() { - return skipFactorTextString; - } - - @Override - public FontStyle getStyle() { - // TODO Auto-generated method stub - return null; - } + private final static float DEFAULT_FONT_SIZE = 14.0f; + + private final static float DEFAULT_LINE_WIDTH = 0.1f; + + private final static int DEFAULT_EXTRA_POINT_NUMBER = 5; + + // private final static int DEFAULT_INTERVAL_HOUR = 1; + private final static String INTERVAL_TIME_FORMAT_PATTERN = "HH:mm"; + + public void setExtrapMarker(String extrapMarker) { + this.extrapMarker = extrapMarker; + } + + public void setExtrapLinePattern(String extrapLinePattern) { + this.extrapLinePattern = extrapLinePattern; + } + + private final static String INITIAL_MARKER = "FILLED_DIAMOND"; + + private final static String EXTRAP_MARKER = "FILLED_TRIANGLE"; + + private final static String INITIAL_LINE_PATTERN = "LINE_SOLID"; + + private final static String EXTRAP_LINE_PATTERN = "LINE_SOLID"; + + /* + * This value of DEFAULT_LINE_PATTERN is a temporary solution Eventually a + * decision needs to be done for what a value should be used + */ + public final static String TRACK_PGEN_CATEGORY = "Track"; + + public final static String TRACK_INFO_DLG_CATEGORY_NAME = "TRACK_EXTRA_POINTS_INFO"; + + public final static String TRACK_PGEN_TYPE = "STORM_TRACK"; + + private Color initialColor; + + private Color extrapColor; + + private String initialMarker; + + private String initialLinePattern; + + private String extrapMarker; + + private String extrapLinePattern; + + private TrackPoint[] initTrackPoints; + + private TrackPoint[] extrapPoints; + + private String fontName; + + private float fontSize; + + private FontStyle fontStyle; + + private float lineWidth; + + private int extraDrawingPointNumber; + + private boolean setTimeButtonSelected; + + private Calendar firstTimeCalendar; + + private Calendar secondTimeCalendar; + + private String intervalTimeString; + + private int intervalComboSelectedIndex; + + private int fontSizeComboSelectedIndex; + + private int fontNameComboSelectedIndex; + + private int fontStyleComboSelectedIndex; + + private int elapsedHourForExtraPoint; + + private int elapsedMinuteForExtraPoint; + + private ExtraPointTimeDisplayOption extraPointTimeDisplayOption; + + private String skipFactorTextString; + + private boolean[] extraPointTimeTextDisplayIndicator; + + // direction, speed and unit are not saved to a file + private double directionForExtraPoints; + + private boolean roundDirBtnSelected; + + private int roundDirComboSelectedIndex; + + private double speed; // speed in meter/millisecond + + private double speedInKnotOverHour; + + private double speedInKilometerOverHour; + + private double speedInMileOverHour; + + private boolean roundBtnSelected; + + private int unitComboSelectedIndex; + + private int roundComboSelectedIndex; + + public Track() { + } + + public Track(ArrayList _locations, Calendar _firstTimeCalendar, + Calendar _secondTimeCalendar) { + initializeInitTrackPoints(_locations, _firstTimeCalendar, + _secondTimeCalendar); + } + + public void initializeInitTrackPoints(ArrayList locations, + Calendar firstTimeCalendar, Calendar secondTimeCalendar) { + initializeInitTrackPoints(locations); + initializeInitFirstTimeCalendar(firstTimeCalendar); + initializeInitSecondTimeCalendar(secondTimeCalendar); + } + + public void initializeTrackByTrackAttrDlgAndLocationList( + ITrack trackAttrDlgObject, ArrayList locations) { + initializeInitTrackPoints(locations); + initializeInitFirstTimeCalendar(trackAttrDlgObject + .getFirstTimeCalendar()); + initializeInitSecondTimeCalendar(trackAttrDlgObject + .getSecondTimeCalendar()); + + this.setInitialMarker(""); + this.setSetTimeButtonSelected(trackAttrDlgObject + .isSetTimeButtonSelected()); + this.setExtraDrawingPointNumber(trackAttrDlgObject + .getExtraDrawingPointNumber()); + + this.setIntervalTimeString(getIntervalTimeTextStringValue(trackAttrDlgObject)); + + this.setFontName(trackAttrDlgObject.getFontName()); + this.setFontStyle(trackAttrDlgObject.getFontStyle()); + this.setFontSize(trackAttrDlgObject.getFontSize()); + this.setInitialColor(trackAttrDlgObject.getInitialColor()); + this.setExtrapColor(trackAttrDlgObject.getExtrapColor()); + this.setExtraPointTimeDisplayOption(trackAttrDlgObject + .getExtraPointTimeDisplayOption()); + this.setSkipFactorTextString(trackAttrDlgObject.getSkipFactorText()); + this.setFontNameComboSelectedIndex(trackAttrDlgObject + .getFontNameComboSelectedIndex()); + this.setFontSizeComboSelectedIndex(trackAttrDlgObject + .getFontSizeComboSelectedIndex()); + this.setFontStyleComboSelectedIndex(trackAttrDlgObject + .getFontStyleComboSelectedIndex()); + this.setUnitComboSelectedIndex(trackAttrDlgObject + .getUnitComboSelectedIndex()); + this.setRoundComboSelectedIndex(trackAttrDlgObject + .getRoundComboSelectedIndex()); + if (trackAttrDlgObject.getRoundComboSelectedIndex() > 0) + this.setRoundBtnSelected(true); + else + this.setRoundBtnSelected(false); + + this.setRoundDirComboSelectedIndex(trackAttrDlgObject + .getRoundDirComboSelectedIndex()); + if (trackAttrDlgObject.getRoundDirComboSelectedIndex() > 0) + this.setRoundDirBtnSelected(true); + else + this.setRoundDirBtnSelected(false); + + // This method can be called only after all of the above settings are + // completed! + this.calculateExtrapTrackPoints(); + /** + * For now, the type is the name of a LinePattern defined in + * "gov.noaa.nws.ncep.ui.pgen.display.LinePatternList" However, there is + * no type has been decided for Track element yet. Thus, it is now hard + * coded. + */ + this.setPgenCategory(Track.TRACK_PGEN_CATEGORY); + this.setPgenType(Track.TRACK_PGEN_TYPE); + } + + public void initializeInitTrackPoints(ArrayList locations) { + TrackPoint[] initTrackPointArray = new TrackPoint[locations.size()]; + int arrayIndex = 0; + + for (Coordinate currentCoordinate : locations) { + TrackPoint eachTrackPoint = new TrackPoint(currentCoordinate, null); + initTrackPointArray[arrayIndex++] = eachTrackPoint; + } + setInitTrackPoints(initTrackPointArray); + } + + public void initializeInitFirstTimeCalendar(Calendar firstCalendar) { + setFirstTimeCalendar(firstCalendar); + if (getInitTrackPoints() != null) { + int initTrackPointLength = getInitTrackPoints().length; + if (initTrackPointLength >= 2) { + getInitTrackPoints()[initTrackPointLength - 2] + .setTime(firstCalendar); + } + } + } + + public void initializeInitSecondTimeCalendar(Calendar secondCalendar) { + setSecondTimeCalendar(secondCalendar); + if (getInitTrackPoints() != null) { + int initTrackPointLength = getInitTrackPoints().length; + if (initTrackPointLength >= 2) { + getInitTrackPoints()[initTrackPointLength - 1] + .setTime(secondCalendar); + } + } + } + + public void calculateExtrapTrackPoints() { + extrapPoints = calculateExtrapTrackPoints(getInitialPoints(), + getFirstTimeCalendar(), getSecondTimeCalendar(), + getExtraDrawingPointNumber(), getElapsedHourForExtraPoint(), + getElapsedMinuteForExtraPoint(), + getExtraPointTimeDisplayOption(), getSkipFactorTextString()); + + /* + * it is important to override the variable + * "ArrayList linePoints" with initTrackPoints and + * extrapPoints arrays + */ + setLinePointsValue(getInitialPoints(), getExtrapPoints()); + + /* + * a linePattern needs to be set for PgenSelectingTool to pick up the + * correct dialogue window to popup + */ + setPgenCategory(Track.TRACK_PGEN_CATEGORY); + setPgenType(Track.TRACK_PGEN_TYPE); + } + + public void setLinePointsValue(TrackPoint[] initTrackPoints, + TrackPoint[] extrapPoints) { + int listSize = 1; + if (initTrackPoints != null) + listSize += initTrackPoints.length; + if (extrapPoints != null) + listSize += extrapPoints.length; + ArrayList coordinatePointList = new ArrayList( + listSize); + addArrayToArrayList(coordinatePointList, initTrackPoints); + addArrayToArrayList(coordinatePointList, extrapPoints); + + /* + * Now use the inherited method setLinePoints to set the linPoints value + */ + setLinePoints(coordinatePointList); + } + + /** + * Creates a copy of this object. This is a deep copy and new objects are + * created so that we are not just copying references of objects + */ + // @Override + // public DrawableElement copy() { + public Track copy() { + + /* + * create a new Track object and initially set its attributes to this + * one's + */ + Track newTrack = new Track(); + Calendar newFirstTimeCalendar = Calendar.getInstance(); + newFirstTimeCalendar.setTimeInMillis(getFirstTimeCalendar() + .getTimeInMillis()); + newTrack.setFirstTimeCalendar(newFirstTimeCalendar); + + Calendar newSecondTimeCalendar = Calendar.getInstance(); + newSecondTimeCalendar.setTimeInMillis(getSecondTimeCalendar() + .getTimeInMillis()); + newTrack.setSecondTimeCalendar(newSecondTimeCalendar); + + TrackPoint[] newInitTrackPoints = new TrackPoint[getInitTrackPoints().length]; + + for (int i = 0; i < newInitTrackPoints.length; i++) { + + newInitTrackPoints[i] = TrackPoint.clone( + getInitTrackPoints()[i].getLocation(), + getInitTrackPoints()[i].getTime()); + } + newTrack.setInitTrackPoints(newInitTrackPoints); + + newTrack.setFontStyle(getFontStyle()); + newTrack.setFontSize(getFontSize()); + newTrack.setFontName(new String(getFontName())); + newTrack.setExtraPointTimeDisplayOption(getExtraPointTimeDisplayOption()); + + boolean[] newExtraPointTimeTextDisplayIndicator = new boolean[getExtraPointTimeTextDisplayIndicator().length]; + for (int i = 0; i < getExtraPointTimeTextDisplayIndicator().length; i++) { + newExtraPointTimeTextDisplayIndicator[i] = getExtraPointTimeTextDisplayIndicator()[i]; + } + newTrack.setExtraPointTimeTextDisplayIndicator(newExtraPointTimeTextDisplayIndicator); + + newTrack.setSkipFactorTextString(new String(getSkipFactorTextString())); + newTrack.setInitialColor(new Color(getInitialColor().getRed(), + getInitialColor().getGreen(), getInitialColor().getBlue())); + newTrack.setExtrapColor(new Color(getExtrapColor().getRed(), + getExtrapColor().getGreen(), getExtrapColor().getBlue())); + + newTrack.setIntervalTimeString(new String(getIntervalTimeString())); + + /* + * Under some scenarios, e.g. marshall/unmarshall procees, the + * ExtraDrawingPointNumber is not serialized. Thus, first try to use the + * length of ExtrapPoints array + */ + if (getExtrapPoints() != null) + newTrack.setExtraDrawingPointNumber(getExtrapPoints().length); + else + newTrack.setExtraDrawingPointNumber(getExtraDrawingPointNumber()); + + newTrack.setExtrapLinePattern(new String(getExtrapLinePattern())); + newTrack.setExtrapMarker(new String(getExtrapMarker())); + + newTrack.setInitialLinePattern(new String(getInitialLinePattern())); + newTrack.setInitialMarker(new String(getInitialMarker())); + + if (getPgenCategory() != null) + newTrack.setPgenCategory(new String(getPgenCategory())); + if (getPgenType() != null) + newTrack.setPgenType(new String(getPgenType())); + + newTrack.calculateExtrapTrackPoints(); + + /* + * Now copy some important attributes that make a Line or multi-points + * element can be displayed + */ + newTrack.setClosed(isClosedLine()); + newTrack.setFilled(isFilled()); + + /* + * colors value in Track will only be used in dragging initial points. + * Thus, here the color of the initial points is used + */ + Color[] initColors = new Color[1]; + initColors[0] = getInitialColor(); + newTrack.setColors(initColors); + newTrack.setLineWidth(getLineWidth()); + newTrack.setSizeScale(getSizeScale()); + + newTrack.setSmoothFactor(2); + newTrack.setFillPattern(getFillPattern()); + + newTrack.setParent(this.getParent()); + + return newTrack; + } + + public void update(ITrack trackAttrDlg) { + + initializeInitFirstTimeCalendar(trackAttrDlg.getFirstTimeCalendar()); + initializeInitSecondTimeCalendar(trackAttrDlg.getSecondTimeCalendar()); + + setInitialMarker(INITIAL_MARKER); + setSetTimeButtonSelected(trackAttrDlg.isSetTimeButtonSelected()); + setExtraDrawingPointNumber(trackAttrDlg.getExtraDrawingPointNumber()); + setIntervalTimeString(trackAttrDlg.getIntervalTimeString()); + setFontName(trackAttrDlg.getFontName()); + setFontStyle(trackAttrDlg.getFontStyle()); + setFontSize(trackAttrDlg.getFontSize()); + setInitialColor(trackAttrDlg.getInitialColor()); + setExtrapColor(trackAttrDlg.getExtrapColor()); + setExtraPointTimeDisplayOption(trackAttrDlg + .getExtraPointTimeDisplayOption()); + setSkipFactorTextString(trackAttrDlg.getSkipFactorText()); + setFontNameComboSelectedIndex(trackAttrDlg + .getFontNameComboSelectedIndex()); + setFontSizeComboSelectedIndex(trackAttrDlg + .getFontSizeComboSelectedIndex()); + setFontStyleComboSelectedIndex(trackAttrDlg + .getFontStyleComboSelectedIndex()); + setUnitComboSelectedIndex(trackAttrDlg.getUnitComboSelectedIndex()); + setRoundComboSelectedIndex(trackAttrDlg.getRoundComboSelectedIndex()); + if (trackAttrDlg.getRoundComboSelectedIndex() > 0) + this.setRoundBtnSelected(true); + else + this.setRoundBtnSelected(false); + + setRoundDirComboSelectedIndex(trackAttrDlg + .getRoundDirComboSelectedIndex()); + if (trackAttrDlg.getRoundDirComboSelectedIndex() > 0) + this.setRoundDirBtnSelected(true); + else + this.setRoundDirBtnSelected(false); + + // This method can be called only after all of the above settings are + // completed! + calculateExtrapTrackPoints(); + + /** + * For now, the type is the name of a LinePattern defined in + * "gov.noaa.nws.ncep.ui.pgen.display.LinePatternList" However, there is + * no type has been decided for Track element yet. Thus, it is now hard + * coded. + */ + setPgenType(Track.TRACK_PGEN_TYPE); + setPgenCategory(Track.TRACK_PGEN_CATEGORY); + } + + public void addPoint(int index, Coordinate point) { + ArrayList allLinePoints = getPoints(); + if (allLinePoints == null) + allLinePoints = new ArrayList(); + + if (allLinePoints.size() <= index) + allLinePoints.add(point); + else + allLinePoints.add(index, point); + + int initialPointSize = getInitialPoints().length; + int extrapPointSize = getExtrapPoints().length; + + if (index < initialPointSize) { + TrackPoint modifiedTrackPoint = getInitialPoints()[index]; + modifiedTrackPoint.setLocation(point); + } else { + int extrapindex = index - initialPointSize; + if (extrapindex >= 0 && extrapindex < extrapPointSize) { + TrackPoint modifiedTrackPoint = getExtrapPoints()[extrapindex]; + modifiedTrackPoint.setLocation(point); + } + } + + } + + public void removePoint(int index) { + ArrayList allLinePoints = getPoints(); + if (allLinePoints == null) + return; + + if (allLinePoints.size() > index) { + allLinePoints.remove(index); + } + + } + + public void setPoints(ArrayList pts) { + if (pts == null) + return; + /* + * call MultiPointElement.setPoint(...) + */ + super.setPoints(pts); + + /* + * Now initialize initPoint and ExtrapPoint arrays + */ + int allPointsSize = pts.size(); + + int initTrackPointSize = 0; + if (getInitTrackPoints() != null) + initTrackPointSize = getInitTrackPoints().length; + int index = 0; + + /* + * reset coordinate values for initial track points + */ + while (index < initTrackPointSize && index < allPointsSize) { + TrackPoint currentTrackPoint = getInitTrackPoints()[index]; + if (currentTrackPoint != null) + currentTrackPoint.setLocation(pts.get(index)); + index++; + } + + int extrapTrackPointSize = 0; + if (getExtrapPoints() != null) + extrapTrackPointSize = getExtrapPoints().length; + int extrapIndex = 0; + while (extrapIndex < extrapTrackPointSize && index < allPointsSize) { + TrackPoint currentTrackPoint = getExtrapPoints()[extrapIndex]; + if (currentTrackPoint != null) + currentTrackPoint.setLocation(pts.get(index)); + index++; + extrapIndex++; + } + + } + + /* + * All private help methods start here + */ + private String getIntervalTimeTextStringValue(ITrack trackAttrDlg) { + + return trackAttrDlg.getIntervalTimeString(); + } + + private void addArrayToArrayList(ArrayList coordinatePointList, + TrackPoint[] trackPoints) { + if (trackPoints == null) + return; + for (TrackPoint trackPoint : trackPoints) { + coordinatePointList.add(trackPoint.getLocation()); + } + } + + private TrackPoint[] calculateExtrapTrackPoints(TrackPoint[] initialPoints, + Calendar initPointBeforeLastInitPointTimeCal, + Calendar lastInitPointTimeCal, int extraDrawingPointNumber, + int elapsedHourForExtraPointValue, + int elapsedMinuteForExtraPointValue, + ExtraPointTimeDisplayOption extraPointTimeDisplayOption, + String skipFactorTextString) { + if (initialPoints == null || initialPoints.length < 2) { + // log.error("Method:calculateExtrapTrackPoints, the input initialPoints is null or initialPoints.length less than 2"); + return null; + } + + int arrayLength = initialPoints.length; + Coordinate initPointBeforeLastInitPointCoordinate = initialPoints[arrayLength - 2] + .getLocation(); + Coordinate lastInitPointCoordinate = initialPoints[arrayLength - 1] + .getLocation(); + if (!isCoordinateValid(initPointBeforeLastInitPointCoordinate) + || !isCoordinateValid(lastInitPointCoordinate) + || initPointBeforeLastInitPointTimeCal == null + || lastInitPointTimeCal == null) { + + return null; + } + + GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); + gc.setStartingGeographicPoint(initPointBeforeLastInitPointCoordinate.x, + initPointBeforeLastInitPointCoordinate.y); + gc.setDestinationGeographicPoint(lastInitPointCoordinate.x, + lastInitPointCoordinate.y); + double direction = gc.getAzimuth(); + setDirectionForExtraPoints(direction); + + double distanceInMeter = gc.getOrthodromicDistance(); + long timeDifference = getTimeDifferenceInMillisecond( + initPointBeforeLastInitPointTimeCal, lastInitPointTimeCal); + double speed = distanceInMeter / (double) timeDifference; + setSpeed(speed); + + // Calculate the first extra point time Calendar + Calendar firstExtraPointTimeCal = getTimeElapsedCalendarForFirstExtraPoint( + lastInitPointTimeCal, elapsedHourForExtraPointValue, + elapsedMinuteForExtraPointValue); + + // calculate the distance between the last Initial point and the first + // extra point + double distanceBetweenLastInitPointAndFirstExtraPoint = calculateDistanceBetweenLastInitPointAndFirstExtraPoint( + speed, lastInitPointTimeCal, firstExtraPointTimeCal); + + // calculate the distance among extra points + double distanceForExtraPoint = calculateDistanceForExtraPoints(speed, + firstExtraPointTimeCal, elapsedHourForExtraPointValue, + elapsedMinuteForExtraPointValue); + + TrackPoint[] extrapTrackPointArray = calculateExtrapTrackPoints(gc, + lastInitPointCoordinate, direction, + distanceBetweenLastInitPointAndFirstExtraPoint, + distanceForExtraPoint, extraDrawingPointNumber, + lastInitPointTimeCal, firstExtraPointTimeCal, + elapsedHourForExtraPointValue, elapsedMinuteForExtraPointValue); + disableSomeTimeTagsDisplayBasedOnExtraPointTimeDisplayOption( + extrapTrackPointArray, extraPointTimeDisplayOption, + skipFactorTextString); + + return extrapTrackPointArray; + } + + private void disableSomeTimeTagsDisplayBasedOnExtraPointTimeDisplayOption( + TrackPoint[] extrapTrackPointArray, + ExtraPointTimeDisplayOption extraPointTimeDisplayOption, + String skipFactorTextString) { + if (extrapTrackPointArray == null) + return; + boolean[] extraPointTimeTagFlagArray = new boolean[extrapTrackPointArray.length]; + initializeBooleanArray(extraPointTimeTagFlagArray, true); + + if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR) { + removeTimeTagsBasedOnSkipFactor(extrapTrackPointArray, + skipFactorTextString, extraPointTimeTagFlagArray); + } else if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.SHOW_FIRST_LAST) { + removeTimeTagsBasedOnShowLastFirstOnly(extrapTrackPointArray, + extraPointTimeTagFlagArray); + } else if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_ONE_HOUR) { + removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, true, + extraPointTimeTagFlagArray); + } else if (extraPointTimeDisplayOption == ITrack.ExtraPointTimeDisplayOption.ON_HALF_HOUR) { + removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, false, + extraPointTimeTagFlagArray); + } else { + removeTimeTagsBasedOnHourMinuteValue(extrapTrackPointArray, false, + extraPointTimeTagFlagArray); + } + + /* + * set the updated boolean array back to the indicator, in + * displayElementFactory, this boolean array will be used to indicate if + * a time text should be skipped + */ + setExtraPointTimeTextDisplayIndicator(extraPointTimeTagFlagArray); + } + + private void removeTimeTagsBasedOnShowLastFirstOnly( + TrackPoint[] extrapTrackPointArray, boolean[] timeTagIndicatorArray) { + if (extrapTrackPointArray.length < 3) + return; + for (int i = 1; i < (extrapTrackPointArray.length - 1); i++) { + timeTagIndicatorArray[i] = false; + } + } + + private void removeTimeTagsBasedOnSkipFactor( + TrackPoint[] extrapTrackPointArray, String skipFactorTextString, + boolean[] timeTagIndicatorArray) { + if (skipFactorTextString == null) + return; + /* + * always show the time tags of the first and last extra points + */ + if (extrapTrackPointArray.length < 3) + return; + + int skipFactorIntValue = 0; + try { + skipFactorIntValue = Integer.parseInt(skipFactorTextString); + } catch (NumberFormatException nfe) { + } + + /* + * 1. make sure skipFactorIntValue is a valid value 2. since the last + * and first extra points are always displayed, thus do + * skipFactorIntValue > (extrapTrackPointArray.length - 2) check + */ + if (!(skipFactorIntValue > 0) + || skipFactorIntValue > (extrapTrackPointArray.length - 2)) + return; + + for (int i = 1; i <= skipFactorIntValue; i++) { + timeTagIndicatorArray[i] = false; + } + } + + private void removeTimeTagsBasedOnHourMinuteValue( + TrackPoint[] extrapTrackPointArray, boolean isExactHourDisplayed, + boolean[] timeTagIndicatorArray) { + for (int i = 0; i < (extrapTrackPointArray.length); i++) { + TrackPoint targetTrackPoint = extrapTrackPointArray[i]; + Calendar targetPointTimeCal = targetTrackPoint.getTime(); + + if (!isTimeTagDisplayable(targetPointTimeCal, isExactHourDisplayed)) { + /* + * mark the flag array index for the time needs to be hided + */ + timeTagIndicatorArray[i] = false; + } + } + } + + private void initializeBooleanArray(boolean[] booleanArray, + boolean initValue) { + if (booleanArray == null) + return; + for (int i = 0; i < booleanArray.length; i++) + booleanArray[i] = initValue; + } + + private boolean isTimeTagDisplayable(Calendar targetPointTimeCal, + boolean isExactHourDisplayed) { + boolean isDisplayable = false; + if (targetPointTimeCal == null) + return isDisplayable; + + int minuteIntValue = targetPointTimeCal.get(Calendar.MINUTE); + if (isExactHourDisplayed) { + if (minuteIntValue == 0) + isDisplayable = true; + } else { + if (minuteIntValue == 0 || minuteIntValue == 30) + isDisplayable = true; + } + return isDisplayable; + } + + private double calculateDistanceBetweenLastInitPointAndFirstExtraPoint( + double speed, Calendar lastInitPointCal, Calendar firstExtraPointCal) { + long timeDifferenceBetweenExtraPoints = getTimeDifferenceInMillisecond( + lastInitPointCal, firstExtraPointCal); + double distanceBetweenLastInitPointAndFirstExtraPoint = speed + * timeDifferenceBetweenExtraPoints; + return distanceBetweenLastInitPointAndFirstExtraPoint; + } + + private double calculateDistanceForExtraPoints(double speed, + Calendar firstExtraPointCal, int elapsedHourForExtraPoint, + int elapsedMinuteForExtraPoint) { + Calendar nextExtraPointTimeCal = getTimeElapsedCalendar( + firstExtraPointCal, elapsedHourForExtraPoint, + elapsedMinuteForExtraPoint); + long timeDifferenceBetweenExtraPoints = getTimeDifferenceInMillisecond( + firstExtraPointCal, nextExtraPointTimeCal); + double distanceForExtraPoint = speed * timeDifferenceBetweenExtraPoints; + return distanceForExtraPoint; + } + + private TrackPoint[] calculateExtrapTrackPoints(GeodeticCalculator gc, + Coordinate lastInitPointCoordinate, double direction, + double distanceBetweenLastInitPointAndFirstExtraPoint, + double distanceBetweenExtraPoint, int extraPointNumber, + Calendar lastInitPointTimeCal, Calendar firstExtraPointTimeCal, + int elapsedHourForExtraPoint, int elapsedMinuteForExtraPoint) { + double startLongitude = lastInitPointCoordinate.x; + double startLatitude = lastInitPointCoordinate.y; + TrackPoint[] trackPointArray = new TrackPoint[extraPointNumber]; + + /* + * Add the first extra point + */ + java.awt.geom.Point2D firstExtraPointPoint2dValue = getNextPoint2DValue( + gc, startLongitude, startLatitude, direction, + distanceBetweenLastInitPointAndFirstExtraPoint); + startLongitude = firstExtraPointPoint2dValue.getX(); + startLatitude = firstExtraPointPoint2dValue.getY(); + Coordinate firstExtraPointCoordinate = new Coordinate(startLongitude, + startLatitude); + TrackPoint firstExtraTrackPoint = new TrackPoint( + firstExtraPointCoordinate, firstExtraPointTimeCal); + trackPointArray[0] = firstExtraTrackPoint; + + Calendar newPointCal = firstExtraPointTimeCal; + for (int i = 1; i < (extraPointNumber); i++) { + java.awt.geom.Point2D pt = getNextPoint2DValue(gc, startLongitude, + startLatitude, direction, distanceBetweenExtraPoint); + startLongitude = pt.getX(); + startLatitude = pt.getY(); + Coordinate nextCoordinate = new Coordinate(startLongitude, + startLatitude); + newPointCal = getTimeElapsedCalendar(newPointCal, + elapsedHourForExtraPoint, elapsedMinuteForExtraPoint); + TrackPoint eachTrackPoint = new TrackPoint(nextCoordinate, + newPointCal); + trackPointArray[i] = eachTrackPoint; + } + return trackPointArray; + } + + private java.awt.geom.Point2D getNextPoint2DValue(GeodeticCalculator gc, + double startingPointLongitude, double startIngPointLatitude, + double direction, double distanceBetweenTwoPoints) { + gc.setStartingGeographicPoint(startingPointLongitude, + startIngPointLatitude); + gc.setDirection(direction, distanceBetweenTwoPoints); + java.awt.geom.Point2D pt = gc.getDestinationGeographicPoint(); + return pt; + } + + private long getTimeDifferenceInMillisecond(Calendar startTimeCal, + Calendar endTimeCal) { + long startTimeInMillisecond = startTimeCal.getTimeInMillis(); + long endTimeInMillisecond = endTimeCal.getTimeInMillis(); + + long timeDiffInMillisecond = endTimeInMillisecond + - startTimeInMillisecond; + return timeDiffInMillisecond; + } + + private boolean isCoordinateValid(Coordinate coordinate) { + if (coordinate.x > 180.0 || coordinate.x < -180.0 + || coordinate.y > 90.0 || coordinate.y < -90.0) + return false; + return true; + } + + private Calendar getIntervalCalendarByParsingString(String dateString, + String formatStringPattern, Calendar secondTimeCal) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat( + formatStringPattern); + Calendar cal = null; + int elapsedHour = 1; + int elapsedMinute = 0; + if (dateString != null) { + try { + Date date = simpleDateFormat.parse(dateString); + cal = Calendar.getInstance(); + cal.setTime(date); + elapsedHour = cal.get(Calendar.HOUR_OF_DAY); + elapsedMinute = cal.get(Calendar.MINUTE); + } catch (ParseException pe) { + elapsedHour = 1; + } + } + setElapsedHourForExtraPoint(elapsedHour); + setElapsedMinuteForExtraPoint(elapsedMinute); + cal = getTimeElapsedCalendar(secondTimeCal, elapsedHour, elapsedMinute); + return cal; + } + + private Calendar getTimeElapsedCalendarForFirstExtraPoint( + Calendar startCalendar, int elapsedHour, int elapsedMinute) { + Calendar nextCal = Calendar.getInstance(); + nextCal.setTimeInMillis(startCalendar.getTimeInMillis()); + /* + * played with the nmap2 APP, get confused with the logic behind, right + * now, calculate the first extra point as the logic described below: 1. + * if elapsedHour > 1 hour, set the first extra point time as the next + * exact hour 2. if elapsedHour == 0 and last init. point MINUTE value + * >= elapsedMinute, set the first time extra point as the next exact + * hour 3. if elapsedHour == 0 and last init. point MINUTE value < + * elapsedMinute, set the first time extra point as the exact hour of + * the last init. point + elapsedMinute In the future, this logic may be + * changed once the real logic is figured. Michael Gao comment. + */ + if (elapsedHour >= 1) { + nextCal.set(Calendar.MINUTE, 0); + nextCal.add(Calendar.HOUR_OF_DAY, 1); + } else { + int currentMinute = nextCal.get(Calendar.MINUTE); + if (currentMinute >= elapsedMinute) { + nextCal.set(Calendar.MINUTE, 0); + nextCal.add(Calendar.HOUR_OF_DAY, 1); + } else { + nextCal.set(Calendar.MINUTE, elapsedMinute); + } + } + return nextCal; + } + + private Calendar getTimeElapsedCalendar(Calendar startCalendar, + int elapsedHour, int elapsedMinute) { + Calendar nextCal = Calendar.getInstance(); + nextCal.setTimeInMillis(startCalendar.getTimeInMillis()); + nextCal.add(Calendar.HOUR_OF_DAY, elapsedHour); + nextCal.add(Calendar.MINUTE, elapsedMinute); + return nextCal; + } + + /* + * all override setters and getters of the instance variables go here + */ + @Override + public Color getExtrapColor() { + return this.extrapColor; + } + + @Override + public String getExtrapLinePattern() { + return EXTRAP_LINE_PATTERN; + } + + @Override + public String getExtrapMarker() { + return EXTRAP_MARKER; + } + + public TrackPoint[] getInitTrackPoints() { + return initTrackPoints; + } + + public void setInitTrackPoints(TrackPoint[] initTrackPoints) { + this.initTrackPoints = initTrackPoints; + } + + public void setExtrapPoints(TrackPoint[] extrapPoints) { + this.extrapPoints = extrapPoints; + } + + @Override + public TrackPoint[] getExtrapPoints() { + return extrapPoints; + } + + @Override + public Color getInitialColor() { + return this.initialColor; + } + + @Override + public String getInitialLinePattern() { + return INITIAL_LINE_PATTERN; + } + + @Override + public String getInitialMarker() { + return INITIAL_MARKER; + } + + @Override + public TrackPoint[] getInitialPoints() { + return initTrackPoints; + } + + @Override + public String getFontName() { + return this.fontName; + } + + public void setFontName(String _fontName) { + this.fontName = _fontName; + } + + @Override + public float getFontSize() { + if (this.fontSize <= 0.0) + return DEFAULT_FONT_SIZE; + return this.fontSize; + } + + public void setFontSize(float _fontSize) { + this.fontSize = _fontSize; + } + + public FontStyle getFontStyle() { + return fontStyle; + } + + public void setFontStyle(FontStyle fontStyle) { + this.fontStyle = fontStyle; + } + + @Override + public float getLineWidth() { + if (this.lineWidth <= 0.0) + return DEFAULT_LINE_WIDTH; + return this.lineWidth; + } + + /* + * all non-override setters and getters of the instance variables go here + */ + public boolean isSetTimeButtonSelected() { + return setTimeButtonSelected; + } + + public void setSetTimeButtonSelected(boolean setTimeButtonSelected) { + this.setTimeButtonSelected = setTimeButtonSelected; + } + + public int getFontSizeComboSelectedIndex() { + return fontSizeComboSelectedIndex; + } + + public void setFontSizeComboSelectedIndex(int fontSizeComboSelectedIndex) { + this.fontSizeComboSelectedIndex = fontSizeComboSelectedIndex; + } + + public int getFontNameComboSelectedIndex() { + return fontNameComboSelectedIndex; + } + + public void setFontNameComboSelectedIndex(int fontNameComboSelectedIndex) { + this.fontNameComboSelectedIndex = fontNameComboSelectedIndex; + } + + public int getFontStyleComboSelectedIndex() { + return fontStyleComboSelectedIndex; + } + + public void setFontStyleComboSelectedIndex(int fontStyleComboSelectedIndex) { + this.fontStyleComboSelectedIndex = fontStyleComboSelectedIndex; + } + + public int getIntervalComboSelectedIndex() { + return intervalComboSelectedIndex; + } + + public void setIntervalComboSelectedIndex(int intervalComboSelectedIndex) { + this.intervalComboSelectedIndex = intervalComboSelectedIndex; + } + + public int getUnitComboSelectedIndex() { + return unitComboSelectedIndex; + } + + public void setUnitComboSelectedIndex(int unitComboSelectedIndex) { + this.unitComboSelectedIndex = unitComboSelectedIndex; + } + + public int getRoundComboSelectedIndex() { + return roundComboSelectedIndex; + } + + public void setRoundComboSelectedIndex(int roundComboSelectedIndex) { + this.roundComboSelectedIndex = roundComboSelectedIndex; + } + + public boolean getRoundBtnSelected() { + return roundBtnSelected; + } + + public void setRoundBtnSelected(boolean roundBtnSelected) { + this.roundBtnSelected = roundBtnSelected; + } + + public int getRoundDirComboSelectedIndex() { + return roundDirComboSelectedIndex; + } + + public void setRoundDirComboSelectedIndex(int roundDirComboSelectedIndex) { + this.roundDirComboSelectedIndex = roundDirComboSelectedIndex; + } + + public boolean getRoundDirBtnSelected() { + return roundDirBtnSelected; + } + + public void setRoundDirBtnSelected(boolean roundDirBtnSelected) { + this.roundDirBtnSelected = roundDirBtnSelected; + } + + public double getDirectionForExtraPoints() { + return directionForExtraPoints; + } + + public double getFromdirection() { + + Coordinate initPointBeforeLastInitPointCoordinate = initTrackPoints[initTrackPoints.length - 2] + .getLocation(); + Coordinate lastInitPointCoordinate = initTrackPoints[initTrackPoints.length - 1] + .getLocation(); + + GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); + gc.setStartingGeographicPoint(lastInitPointCoordinate.x, + lastInitPointCoordinate.y); + gc.setDestinationGeographicPoint( + initPointBeforeLastInitPointCoordinate.x, + initPointBeforeLastInitPointCoordinate.y); + double dir = gc.getAzimuth(); + if (dir < 0) + dir += 360; + return dir; + } + + public void setDirectionForExtraPoints(double directionForExtraPoints) { + this.directionForExtraPoints = directionForExtraPoints; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + /* + * The original speed is meters / millisecond, now it needs to be + * converted to following units + */ + this.speedInKnotOverHour = speed * 1944; + this.speedInKilometerOverHour = speed * 3600; + this.speedInMileOverHour = speed * 2237; + } + + public double getSpeedInKnotOverHour() { + return speedInKnotOverHour; + } + + public double getSpeedInKilometerOverHour() { + return speedInKilometerOverHour; + } + + public double getSpeedInMileOverHour() { + return speedInMileOverHour; + } + + public ExtraPointTimeDisplayOption getExtraPointTimeDisplayOption() { + return extraPointTimeDisplayOption; + } + + public void setExtraPointTimeDisplayOption( + ExtraPointTimeDisplayOption extraPointTimeDisplayOption) { + this.extraPointTimeDisplayOption = extraPointTimeDisplayOption; + } + + public String getSkipFactorTextString() { + return skipFactorTextString; + } + + public void setSkipFactorTextString(String skipFactorTextString) { + this.skipFactorTextString = skipFactorTextString; + } + + public boolean[] getExtraPointTimeTextDisplayIndicator() { + return extraPointTimeTextDisplayIndicator; + } + + public void setExtraPointTimeTextDisplayIndicator( + boolean[] extraPointTimeTextDisplayIndicator) { + this.extraPointTimeTextDisplayIndicator = extraPointTimeTextDisplayIndicator; + } + + public void setInitialColor(Color initialColor) { + this.initialColor = initialColor; + } + + public void setExtrapColor(Color extrapColor) { + this.extrapColor = extrapColor; + } + + public void setInitialMarker(String initialMarker) { + this.initialMarker = initialMarker; + } + + public void setInitialLinePattern(String initialLinePattern) { + this.initialLinePattern = initialLinePattern; + } + + public void setLineWidth(float lineWidth) { + this.lineWidth = lineWidth; + } + + public int getExtraDrawingPointNumber() { + if (!(this.extraDrawingPointNumber > 0)) + return DEFAULT_EXTRA_POINT_NUMBER; + return this.extraDrawingPointNumber; + } + + public void setExtraDrawingPointNumber(int extraDrawingPointNumber) { + this.extraDrawingPointNumber = extraDrawingPointNumber; + } + + public Calendar getFirstTimeCalendar() { + return firstTimeCalendar; + } + + public void setFirstTimeCalendar(Calendar firstTimeCalendar) { + this.firstTimeCalendar = firstTimeCalendar; + } + + public Calendar getSecondTimeCalendar() { + return secondTimeCalendar; + } + + public void setSecondTimeCalendar(Calendar secondTimeCalendar) { + this.secondTimeCalendar = secondTimeCalendar; + } + + public String getIntervalTimeString() { + return intervalTimeString; + } + + public void setIntervalTimeString(String _intervalTimeString) { + /* + * intervalTimeString == null is allowed + */ + this.intervalTimeString = _intervalTimeString; + + Calendar intervalTimeCal = getIntervalCalendarByParsingString( + _intervalTimeString, INTERVAL_TIME_FORMAT_PATTERN, + getSecondTimeCalendar()); + // setIntervalTimeCalendar(intervalTimeCal); + } + + public int getElapsedHourForExtraPoint() { + return elapsedHourForExtraPoint; + } + + private void setElapsedHourForExtraPoint(int elapsedHourForExtraPoint) { + this.elapsedHourForExtraPoint = elapsedHourForExtraPoint; + } + + public int getElapsedMinuteForExtraPoint() { + return elapsedMinuteForExtraPoint; + } + + private void setElapsedMinuteForExtraPoint(int elapsedMinuteForExtraPoint) { + this.elapsedMinuteForExtraPoint = elapsedMinuteForExtraPoint; + } + + @Override + public String getSkipFactorText() { + return skipFactorTextString; + } } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/ProductConverter.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/ProductConverter.java index 4c2fb4e4a8..9886d020af 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/ProductConverter.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/ProductConverter.java @@ -134,6 +134,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 12/13 TTR904 B. Yin Added back the water zone string for Watch county list * 11/13 #1065 J. Wu Added Kink lines. * 05/14 TTR995 J. Wu Set Text's 'auto" flag to false. + * 09/14 TTR716 J. Wu Use "-" for GFA Outlook's Vor text. * * * @@ -735,6 +736,12 @@ public class ProductConverter { gfa.setGfaValue("Type", fgfa.getType()); } + // textVOR + String vorStr = fgfa.getTextVor(); + if (vorStr != null) { + gfa.setGfaVorText(nvl(vorStr)); + } + String cig = fgfa.getCig(); if (cig != null) { gfa.setGfaValue(Gfa.CIG, fgfa.getCig()); @@ -1098,7 +1105,11 @@ public class ProductConverter { } // textVOR - fgfa.setTextVor(nvl(((Gfa) de).getGfaVorText())); + String vorStr = ((Gfa) de).getGfaVorText(); + if (vorStr != null && ((Gfa) de).isOutlook()) { + vorStr = vorStr.replaceAll(" TO ", "-"); + } + fgfa.setTextVor(nvl(vorStr)); fgfa.setFillPattern(nvl(((Gfa) de).getFillPattern() .name())); diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/Track.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/Track.java index 02cce275df..0ab12d7884 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/Track.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/Track.java @@ -5,11 +5,11 @@ // Generated on: 2009.05.28 at 02:35:15 PM EDT // - package gov.noaa.nws.ncep.ui.pgen.file; import java.util.ArrayList; import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -17,11 +17,13 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; - /** - *

Java class for anonymous complex type. + *

+ * Java class for anonymous complex type. * - *

The following schema fragment specifies the expected content contained within this class. + *

+ * The following schema fragment specifies the expected content contained within + * this class. * *

  * <complexType>
@@ -38,6 +40,7 @@ import javax.xml.bind.annotation.XmlType;
  *       <attribute name="extrapLinePattern" type="{http://www.w3.org/2001/XMLSchema}string" />
  *       <attribute name="extrapMarker" type="{http://www.w3.org/2001/XMLSchema}string" />
  *       <attribute name="fontName" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="fontStyle" type="{http://www.w3.org/2001/XMLSchema}string" />
  *       <attribute name="fontNameComboSelectedIndex" type="{http://www.w3.org/2001/XMLSchema}int" />
  *       <attribute name="fontSize" type="{http://www.w3.org/2001/XMLSchema}float" />
  *       <attribute name="fontSizeComboSelectedIndex" type="{http://www.w3.org/2001/XMLSchema}int" />
@@ -60,68 +63,85 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "initialColor",
-    "extrapColor",
-    "initialPoints",
-    "extrapPoints",
-    "extraPointTimeTextDisplayIndicator"
-})
+@XmlType(name = "", propOrder = { "initialColor", "extrapColor",
+        "initialPoints", "extrapPoints", "extraPointTimeTextDisplayIndicator" })
 @XmlRootElement(name = "Track")
 public class Track {
 
     @XmlElement(required = true)
     protected ColorType initialColor;
+
     @XmlElement(required = true)
     protected ColorType extrapColor;
+
     @XmlElement(required = true)
     protected List initialPoints;
+
     @XmlElement(required = true)
     protected List extrapPoints;
+
     @XmlElement(type = Boolean.class)
     protected List extraPointTimeTextDisplayIndicator;
+
     @XmlAttribute
     protected String extraPointTimeDisplayOptionName;
+
     @XmlAttribute
     protected String extrapLinePattern;
+
     @XmlAttribute
     protected String extrapMarker;
+
     @XmlAttribute
     protected String fontName;
+
+    @XmlAttribute
+    protected String fontStyle;
+
     @XmlAttribute
     protected Integer fontNameComboSelectedIndex;
+
     @XmlAttribute
     protected Float fontSize;
+
     @XmlAttribute
     protected Integer fontSizeComboSelectedIndex;
+
     @XmlAttribute
     protected Integer fontStyleComboSelectedIndex;
+
     @XmlAttribute
     protected String initialLinePattern;
+
     @XmlAttribute
     protected String initialMarker;
+
     @XmlAttribute
     protected Integer intervalComboSelectedIndex;
+
     @XmlAttribute
     protected String intervalTimeTextString;
+
     @XmlAttribute
     protected Float lineWidth;
+
     @XmlAttribute
     protected String pgenCategory;
+
     @XmlAttribute
     protected String pgenType;
+
     @XmlAttribute
     protected Boolean setTimeButtonSelected;
+
     @XmlAttribute
     protected String skipFactorTextString;
 
     /**
      * Gets the value of the initialColor property.
      * 
-     * @return
-     *     possible object is
-     *     {@link ColorType }
-     *     
+     * @return possible object is {@link ColorType }
+     * 
      */
     public ColorType getInitialColor() {
         return initialColor;
@@ -131,9 +151,8 @@ public class Track {
      * Sets the value of the initialColor property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link ColorType }
-     *     
+     *            allowed object is {@link ColorType }
+     * 
      */
     public void setInitialColor(ColorType value) {
         this.initialColor = value;
@@ -142,10 +161,8 @@ public class Track {
     /**
      * Gets the value of the extrapColor property.
      * 
-     * @return
-     *     possible object is
-     *     {@link ColorType }
-     *     
+     * @return possible object is {@link ColorType }
+     * 
      */
     public ColorType getExtrapColor() {
         return extrapColor;
@@ -155,9 +172,8 @@ public class Track {
      * Sets the value of the extrapColor property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link ColorType }
-     *     
+     *            allowed object is {@link ColorType }
+     * 
      */
     public void setExtrapColor(ColorType value) {
         this.extrapColor = value;
@@ -167,15 +183,16 @@ public class Track {
      * Gets the value of the initialPoints property.
      * 
      * 

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the initialPoints property. + * This accessor method returns a reference to the live list, not a + * snapshot. Therefore any modification you make to the returned list will + * be present inside the JAXB object. This is why there is not a + * set method for the initialPoints property. * *

* For example, to add a new item, do as follows: + * *

-     *    getInitialPoints().add(newItem);
+     * getInitialPoints().add(newItem);
      * 
* * @@ -196,15 +213,16 @@ public class Track { * Gets the value of the extrapPoints property. * *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the extrapPoints property. + * This accessor method returns a reference to the live list, not a + * snapshot. Therefore any modification you make to the returned list will + * be present inside the JAXB object. This is why there is not a + * set method for the extrapPoints property. * *

* For example, to add a new item, do as follows: + * *

-     *    getExtrapPoints().add(newItem);
+     * getExtrapPoints().add(newItem);
      * 
* * @@ -225,21 +243,22 @@ public class Track { * Gets the value of the extraPointTimeTextDisplayIndicator property. * *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the extraPointTimeTextDisplayIndicator property. + * This accessor method returns a reference to the live list, not a + * snapshot. Therefore any modification you make to the returned list will + * be present inside the JAXB object. This is why there is not a + * set method for the extraPointTimeTextDisplayIndicator + * property. * *

* For example, to add a new item, do as follows: + * *

-     *    getExtraPointTimeTextDisplayIndicator().add(newItem);
+     * getExtraPointTimeTextDisplayIndicator().add(newItem);
      * 
* * *

- * Objects of the following type(s) are allowed in the list - * {@link Boolean } + * Objects of the following type(s) are allowed in the list {@link Boolean } * * */ @@ -253,10 +272,8 @@ public class Track { /** * Gets the value of the extraPointTimeDisplayOptionName property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getExtraPointTimeDisplayOptionName() { return extraPointTimeDisplayOptionName; @@ -266,9 +283,8 @@ public class Track { * Sets the value of the extraPointTimeDisplayOptionName property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setExtraPointTimeDisplayOptionName(String value) { this.extraPointTimeDisplayOptionName = value; @@ -277,10 +293,8 @@ public class Track { /** * Gets the value of the extrapLinePattern property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getExtrapLinePattern() { return extrapLinePattern; @@ -290,9 +304,8 @@ public class Track { * Sets the value of the extrapLinePattern property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setExtrapLinePattern(String value) { this.extrapLinePattern = value; @@ -301,10 +314,8 @@ public class Track { /** * Gets the value of the extrapMarker property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getExtrapMarker() { return extrapMarker; @@ -314,9 +325,8 @@ public class Track { * Sets the value of the extrapMarker property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setExtrapMarker(String value) { this.extrapMarker = value; @@ -325,10 +335,8 @@ public class Track { /** * Gets the value of the fontName property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getFontName() { return fontName; @@ -338,21 +346,39 @@ public class Track { * Sets the value of the fontName property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setFontName(String value) { this.fontName = value; } + /** + * Gets the value of the fontStyle property. + * + * @return possible object is {@link String } + * + */ + public String getFontStyle() { + return fontStyle; + } + + /** + * Sets the value of the fontStyle property. + * + * @param value + * allowed object is {@link String } + * + */ + public void setFontStyle(String value) { + this.fontStyle = value; + } + /** * Gets the value of the fontNameComboSelectedIndex property. * - * @return - * possible object is - * {@link Integer } - * + * @return possible object is {@link Integer } + * */ public Integer getFontNameComboSelectedIndex() { return fontNameComboSelectedIndex; @@ -362,9 +388,8 @@ public class Track { * Sets the value of the fontNameComboSelectedIndex property. * * @param value - * allowed object is - * {@link Integer } - * + * allowed object is {@link Integer } + * */ public void setFontNameComboSelectedIndex(Integer value) { this.fontNameComboSelectedIndex = value; @@ -373,10 +398,8 @@ public class Track { /** * Gets the value of the fontSize property. * - * @return - * possible object is - * {@link Float } - * + * @return possible object is {@link Float } + * */ public Float getFontSize() { return fontSize; @@ -386,9 +409,8 @@ public class Track { * Sets the value of the fontSize property. * * @param value - * allowed object is - * {@link Float } - * + * allowed object is {@link Float } + * */ public void setFontSize(Float value) { this.fontSize = value; @@ -397,10 +419,8 @@ public class Track { /** * Gets the value of the fontSizeComboSelectedIndex property. * - * @return - * possible object is - * {@link Integer } - * + * @return possible object is {@link Integer } + * */ public Integer getFontSizeComboSelectedIndex() { return fontSizeComboSelectedIndex; @@ -410,9 +430,8 @@ public class Track { * Sets the value of the fontSizeComboSelectedIndex property. * * @param value - * allowed object is - * {@link Integer } - * + * allowed object is {@link Integer } + * */ public void setFontSizeComboSelectedIndex(Integer value) { this.fontSizeComboSelectedIndex = value; @@ -421,10 +440,8 @@ public class Track { /** * Gets the value of the fontStyleComboSelectedIndex property. * - * @return - * possible object is - * {@link Integer } - * + * @return possible object is {@link Integer } + * */ public Integer getFontStyleComboSelectedIndex() { return fontStyleComboSelectedIndex; @@ -434,9 +451,8 @@ public class Track { * Sets the value of the fontStyleComboSelectedIndex property. * * @param value - * allowed object is - * {@link Integer } - * + * allowed object is {@link Integer } + * */ public void setFontStyleComboSelectedIndex(Integer value) { this.fontStyleComboSelectedIndex = value; @@ -445,10 +461,8 @@ public class Track { /** * Gets the value of the initialLinePattern property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getInitialLinePattern() { return initialLinePattern; @@ -458,9 +472,8 @@ public class Track { * Sets the value of the initialLinePattern property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setInitialLinePattern(String value) { this.initialLinePattern = value; @@ -469,10 +482,8 @@ public class Track { /** * Gets the value of the initialMarker property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getInitialMarker() { return initialMarker; @@ -482,9 +493,8 @@ public class Track { * Sets the value of the initialMarker property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setInitialMarker(String value) { this.initialMarker = value; @@ -493,10 +503,8 @@ public class Track { /** * Gets the value of the intervalComboSelectedIndex property. * - * @return - * possible object is - * {@link Integer } - * + * @return possible object is {@link Integer } + * */ public Integer getIntervalComboSelectedIndex() { return intervalComboSelectedIndex; @@ -506,9 +514,8 @@ public class Track { * Sets the value of the intervalComboSelectedIndex property. * * @param value - * allowed object is - * {@link Integer } - * + * allowed object is {@link Integer } + * */ public void setIntervalComboSelectedIndex(Integer value) { this.intervalComboSelectedIndex = value; @@ -517,10 +524,8 @@ public class Track { /** * Gets the value of the intervalTimeTextString property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getIntervalTimeTextString() { return intervalTimeTextString; @@ -530,9 +535,8 @@ public class Track { * Sets the value of the intervalTimeTextString property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setIntervalTimeTextString(String value) { this.intervalTimeTextString = value; @@ -541,10 +545,8 @@ public class Track { /** * Gets the value of the lineWidth property. * - * @return - * possible object is - * {@link Float } - * + * @return possible object is {@link Float } + * */ public Float getLineWidth() { return lineWidth; @@ -554,9 +556,8 @@ public class Track { * Sets the value of the lineWidth property. * * @param value - * allowed object is - * {@link Float } - * + * allowed object is {@link Float } + * */ public void setLineWidth(Float value) { this.lineWidth = value; @@ -565,10 +566,8 @@ public class Track { /** * Gets the value of the pgenCategory property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getPgenCategory() { return pgenCategory; @@ -578,9 +577,8 @@ public class Track { * Sets the value of the pgenCategory property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setPgenCategory(String value) { this.pgenCategory = value; @@ -589,10 +587,8 @@ public class Track { /** * Gets the value of the pgenType property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getPgenType() { return pgenType; @@ -602,9 +598,8 @@ public class Track { * Sets the value of the pgenType property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setPgenType(String value) { this.pgenType = value; @@ -613,10 +608,8 @@ public class Track { /** * Gets the value of the setTimeButtonSelected property. * - * @return - * possible object is - * {@link Boolean } - * + * @return possible object is {@link Boolean } + * */ public Boolean isSetTimeButtonSelected() { return setTimeButtonSelected; @@ -626,9 +619,8 @@ public class Track { * Sets the value of the setTimeButtonSelected property. * * @param value - * allowed object is - * {@link Boolean } - * + * allowed object is {@link Boolean } + * */ public void setSetTimeButtonSelected(Boolean value) { this.setTimeButtonSelected = value; @@ -637,10 +629,8 @@ public class Track { /** * Gets the value of the skipFactorTextString property. * - * @return - * possible object is - * {@link String } - * + * @return possible object is {@link String } + * */ public String getSkipFactorTextString() { return skipFactorTextString; @@ -650,9 +640,8 @@ public class Track { * Sets the value of the skipFactorTextString property. * * @param value - * allowed object is - * {@link String } - * + * allowed object is {@link String } + * */ public void setSkipFactorTextString(String value) { this.skipFactorTextString = value; diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/TrackConverter.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/TrackConverter.java index 940cec1409..02e50623d6 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/TrackConverter.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/TrackConverter.java @@ -7,11 +7,17 @@ */ package gov.noaa.nws.ncep.ui.pgen.file; +import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; +import gov.noaa.nws.ncep.ui.pgen.display.IText.FontStyle; +import gov.noaa.nws.ncep.ui.pgen.display.ITrack; +import gov.noaa.nws.ncep.ui.pgen.display.TrackPoint; +import gov.noaa.nws.ncep.ui.pgen.elements.Track; + +import java.awt.Color; +import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; -import java.util.ArrayList; -import java.awt.Color; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; @@ -22,318 +28,423 @@ import org.geotools.referencing.datum.DefaultEllipsoid; import com.vividsolutions.jts.geom.Coordinate; -import gov.noaa.nws.ncep.ui.pgen.elements.Track; -import gov.noaa.nws.ncep.ui.pgen.display.ITrack; -import gov.noaa.nws.ncep.ui.pgen.display.TrackPoint; -import gov.noaa.nws.ncep.ui.pgen.display.FillPatternList.FillPattern; - /** - * Define a ProductConverter Class - some methods to convert the products between XML format - * and the actual in-memory PGEN products. + * Define a ProductConverter Class - some methods to convert the products + * between XML format and the actual in-memory PGEN products. * *

  * SOFTWARE HISTORY
  * Date       	Ticket#		Engineer	Description
  * ------------	----------	-----------	--------------------------
- * 02/2012		TTR456			Q. Zhou   	Added speed, dir. Default to kts, no round
+ * 02/2012		TTR456		Q. Zhou   	Added speed, dir. Default to kts, no round
+ * 09/2014      TTR750      J. Wu       Use FontStyle instead of "index".
  * 
* */ public class TrackConverter { -// private final static org.apache.log4j.Logger log = -// org.apache.log4j.Logger.getLogger(TrackConverter.class); - - /* - * Convert a XML file DrawableElement object to a list of PGEN in-memory - * DrawableElement objects - */ - public static List getTrackElementListByTrackBeanList ( - List trackBeanList) { - List trackElementList = new ArrayList(trackBeanList.size()); - - for(gov.noaa.nws.ncep.ui.pgen.file.Track trackBean : trackBeanList) { - Track trackElement = new Track(); - - trackElement.setInitialColor(getColorByColorTypeBean(trackBean.initialColor, true)); - trackElement.setExtrapColor(getColorByColorTypeBean(trackBean.extrapColor, false)); - - trackElement.setInitTrackPoints(getTrackPointElementListByTrackPointBeanList(trackBean.getInitialPoints()).toArray(new TrackPoint[trackBean.getInitialPoints().size()])); - trackElement.setExtrapPoints(getTrackPointElementListByTrackPointBeanList(trackBean.getExtrapPoints()).toArray(new TrackPoint[trackBean.getExtrapPoints().size()])); - - /* - * Now initialize track's firstTimeCalendar and secondTimeCalendar using initTrackPoints - */ - trackElement.setFirstTimeCalendar(getFirstOrSecondTimeCalendarByTrackBean(trackBean, true)); - trackElement.setSecondTimeCalendar(getFirstOrSecondTimeCalendarByTrackBean(trackBean, false)); - - /* - * Important note: the following two method calls are necessary. - * 1. combine init and extrap points to allow PgenSource to go over every point for drawing - * 2. setLinePattern is from the parent class of Track, the name is kind of misleading - * It is hard coded now, for future, a new field is needed to the XSD file. - */ - trackElement.setLinePointsValue(trackElement.getInitialPoints(), trackElement.getExtrapPoints()); - - trackElement.setExtraPointTimeTextDisplayIndicator(getBooleanArrayByBooleanList(trackBean.extraPointTimeTextDisplayIndicator)); - - trackElement.setInitialLinePattern(trackBean.getInitialLinePattern()); - trackElement.setExtrapLinePattern(trackBean.getExtrapLinePattern()); - trackElement.setInitialMarker(trackBean.getInitialMarker()); - trackElement.setExtrapMarker(trackBean.getExtrapMarker()); - trackElement.setFontName(trackBean.getFontName()); - if(trackBean.getLineWidth() != null) - trackElement.setLineWidth(trackBean.getLineWidth().floatValue()); - else - trackElement.setLineWidth((float)1.0); //set a 1.0 as the default value - if(trackBean.getFontSize() != null) - trackElement.setFontSize(trackBean.getFontSize().floatValue()); - else - trackElement.setFontSize((float)2.0); //set a 2.0 as the default value - - if(trackBean.getPgenCategory() == null) - trackElement.setPgenCategory(Track.TRACK_PGEN_CATEGORY); - else - trackElement.setPgenCategory(trackBean.getPgenCategory()); - - if(trackBean.getPgenType() == null) - trackElement.setPgenType(Track.TRACK_PGEN_TYPE); - else - trackElement.setPgenType(trackBean.getPgenType()); - - /* - * add speed, dir. Default to kts, no round --Quan - */ - TrackPoint[] initPts = trackElement.getInitTrackPoints(); - int initPtsLength = initPts.length; - Coordinate initPointBeforeLastInitPointCoordinate = initPts[initPtsLength - 2].getLocation(); - Coordinate lastInitPointCoordinate = initPts[initPtsLength - 1].getLocation(); - - GeodeticCalculator gc = new GeodeticCalculator(DefaultEllipsoid.WGS84); - gc.setStartingGeographicPoint(initPointBeforeLastInitPointCoordinate.x, - initPointBeforeLastInitPointCoordinate.y); - gc.setDestinationGeographicPoint(lastInitPointCoordinate.x, - lastInitPointCoordinate.y); - double direction = gc.getAzimuth(); - - double distanceInMeter = gc.getOrthodromicDistance(); - long timeDifference = initPts[initPtsLength - 1].getTime().getTimeInMillis() - - initPts[initPtsLength - 2].getTime().getTimeInMillis(); - double speed = distanceInMeter / (double)timeDifference; - - trackElement.setDirectionForExtraPoints(direction); - trackElement.setSpeed(speed); - - /* - * add something related to line drawing - */ - trackElement.setSizeScale((double) 1.0); - trackElement.setSmoothFactor(0); - trackElement.setClosed(false); - trackElement.setFilled(false); - trackElement.setFillPattern(FillPattern.FILL_PATTERN_0); - - /* - * The following attributes are necessary to fill values for the pop-up - * TrackAttiDlg window from the restored line images. - */ - boolean setTimeButtonSelectedFlag = true; // set the default value as TRUE - if(trackBean.isSetTimeButtonSelected() != null) - setTimeButtonSelectedFlag = trackBean.isSetTimeButtonSelected().booleanValue(); - trackElement.setSetTimeButtonSelected(setTimeButtonSelectedFlag); - - int intervalComboSelectedIndexValue = 0; //set the default value - if(trackBean.getIntervalComboSelectedIndex() != null) - intervalComboSelectedIndexValue = trackBean.getIntervalComboSelectedIndex().intValue(); - trackElement.setIntervalComboSelectedIndex(intervalComboSelectedIndexValue); - - trackElement.setIntervalTimeString(trackBean.getIntervalTimeTextString()); - - String extraPointTimeDisplayOptionName = ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR.name(); // set the default value - if(trackBean.getExtraPointTimeDisplayOptionName() != null) - extraPointTimeDisplayOptionName = trackBean.getExtraPointTimeDisplayOptionName(); - trackElement.setExtraPointTimeDisplayOption(ITrack.ExtraPointTimeDisplayOption.valueOf(extraPointTimeDisplayOptionName)); - - String skipFactorTextString = "0"; //set the default value - if(trackBean.getSkipFactorTextString() != null) - skipFactorTextString = trackBean.getSkipFactorTextString(); - trackElement.setSkipFactorTextString(skipFactorTextString); - - int fontNameComboSelectedIndex = 0; //set the default value - if(trackBean.getFontNameComboSelectedIndex() != null) - fontNameComboSelectedIndex = trackBean.getFontNameComboSelectedIndex().intValue(); - trackElement.setFontNameComboSelectedIndex(fontNameComboSelectedIndex); - - int fontSizeComboSelectedIndex = 0; //set the default value - if(trackBean.getFontSizeComboSelectedIndex() != null) - fontSizeComboSelectedIndex = trackBean.getFontSizeComboSelectedIndex().intValue(); - trackElement.setFontSizeComboSelectedIndex(fontSizeComboSelectedIndex); - - int fontStyleComboSelectedIndex = 0; //set the default value - if(trackBean.getFontStyleComboSelectedIndex() != null) - fontStyleComboSelectedIndex = trackBean.getFontStyleComboSelectedIndex().intValue(); - trackElement.setFontStyleComboSelectedIndex(fontStyleComboSelectedIndex); - - trackElementList.add(trackElement); - } - + // private final static org.apache.log4j.Logger log = + // org.apache.log4j.Logger.getLogger(TrackConverter.class); + + /* + * Convert a XML file DrawableElement object to a list of PGEN in-memory + * DrawableElement objects + */ + public static List getTrackElementListByTrackBeanList( + List trackBeanList) { + List trackElementList = new ArrayList( + trackBeanList.size()); + + for (gov.noaa.nws.ncep.ui.pgen.file.Track trackBean : trackBeanList) { + Track trackElement = new Track(); + + trackElement.setInitialColor(getColorByColorTypeBean( + trackBean.initialColor, true)); + trackElement.setExtrapColor(getColorByColorTypeBean( + trackBean.extrapColor, false)); + + trackElement + .setInitTrackPoints(getTrackPointElementListByTrackPointBeanList( + trackBean.getInitialPoints()) + .toArray( + new TrackPoint[trackBean.getInitialPoints() + .size()])); + trackElement + .setExtrapPoints(getTrackPointElementListByTrackPointBeanList( + trackBean.getExtrapPoints()).toArray( + new TrackPoint[trackBean.getExtrapPoints().size()])); + + /* + * Now initialize track's firstTimeCalendar and secondTimeCalendar + * using initTrackPoints + */ + trackElement + .setFirstTimeCalendar(getFirstOrSecondTimeCalendarByTrackBean( + trackBean, true)); + trackElement + .setSecondTimeCalendar(getFirstOrSecondTimeCalendarByTrackBean( + trackBean, false)); + + /* + * Important note: the following two method calls are necessary. 1. + * combine init and extrap points to allow PgenSource to go over + * every point for drawing 2. setLinePattern is from the parent + * class of Track, the name is kind of misleading It is hard coded + * now, for future, a new field is needed to the XSD file. + */ + trackElement.setLinePointsValue(trackElement.getInitialPoints(), + trackElement.getExtrapPoints()); + + trackElement + .setExtraPointTimeTextDisplayIndicator(getBooleanArrayByBooleanList(trackBean.extraPointTimeTextDisplayIndicator)); + + trackElement.setInitialLinePattern(trackBean + .getInitialLinePattern()); + trackElement.setExtrapLinePattern(trackBean.getExtrapLinePattern()); + trackElement.setInitialMarker(trackBean.getInitialMarker()); + trackElement.setExtrapMarker(trackBean.getExtrapMarker()); + trackElement.setFontName(trackBean.getFontName()); + + // TTR 950 - Font Style + int styleInd = 0; + FontStyle dstyle = FontStyle.BOLD; + if (trackBean.getFontStyle() != null) { + int jj = 0; + for (FontStyle ft : FontStyle.values()) { + if (ft == FontStyle.valueOf(trackBean.getFontStyle() + .toUpperCase())) { + styleInd = jj; + dstyle = ft; + break; + } + + jj++; + } + } + + trackElement.setFontStyle(dstyle); + trackElement.setFontStyleComboSelectedIndex(styleInd); + + if (trackBean.getLineWidth() != null) + trackElement + .setLineWidth(trackBean.getLineWidth().floatValue()); + else + trackElement.setLineWidth((float) 1.0); // set a 1.0 as the + // default value + if (trackBean.getFontSize() != null) + trackElement.setFontSize(trackBean.getFontSize().floatValue()); + else + trackElement.setFontSize((float) 2.0); // set a 2.0 as the + // default value + + if (trackBean.getPgenCategory() == null) + trackElement.setPgenCategory(Track.TRACK_PGEN_CATEGORY); + else + trackElement.setPgenCategory(trackBean.getPgenCategory()); + + if (trackBean.getPgenType() == null) + trackElement.setPgenType(Track.TRACK_PGEN_TYPE); + else + trackElement.setPgenType(trackBean.getPgenType()); + + /* + * add speed, dir. Default to kts, no round --Quan + */ + TrackPoint[] initPts = trackElement.getInitTrackPoints(); + int initPtsLength = initPts.length; + Coordinate initPointBeforeLastInitPointCoordinate = initPts[initPtsLength - 2] + .getLocation(); + Coordinate lastInitPointCoordinate = initPts[initPtsLength - 1] + .getLocation(); + + GeodeticCalculator gc = new GeodeticCalculator( + DefaultEllipsoid.WGS84); + gc.setStartingGeographicPoint( + initPointBeforeLastInitPointCoordinate.x, + initPointBeforeLastInitPointCoordinate.y); + gc.setDestinationGeographicPoint(lastInitPointCoordinate.x, + lastInitPointCoordinate.y); + double direction = gc.getAzimuth(); + + double distanceInMeter = gc.getOrthodromicDistance(); + long timeDifference = initPts[initPtsLength - 1].getTime() + .getTimeInMillis() + - initPts[initPtsLength - 2].getTime().getTimeInMillis(); + double speed = distanceInMeter / (double) timeDifference; + + trackElement.setDirectionForExtraPoints(direction); + trackElement.setSpeed(speed); + + /* + * add something related to line drawing + */ + trackElement.setSizeScale((double) 1.0); + trackElement.setSmoothFactor(0); + trackElement.setClosed(false); + trackElement.setFilled(false); + trackElement.setFillPattern(FillPattern.FILL_PATTERN_0); + + /* + * The following attributes are necessary to fill values for the + * pop-up TrackAttiDlg window from the restored line images. + */ + boolean setTimeButtonSelectedFlag = true; // set the default value + // as TRUE + if (trackBean.isSetTimeButtonSelected() != null) + setTimeButtonSelectedFlag = trackBean.isSetTimeButtonSelected() + .booleanValue(); + trackElement.setSetTimeButtonSelected(setTimeButtonSelectedFlag); + + int intervalComboSelectedIndexValue = 0; // set the default value + if (trackBean.getIntervalComboSelectedIndex() != null) + intervalComboSelectedIndexValue = trackBean + .getIntervalComboSelectedIndex().intValue(); + trackElement + .setIntervalComboSelectedIndex(intervalComboSelectedIndexValue); + + trackElement.setIntervalTimeString(trackBean + .getIntervalTimeTextString()); + + String extraPointTimeDisplayOptionName = ITrack.ExtraPointTimeDisplayOption.SKIP_FACTOR + .name(); // set the default value + if (trackBean.getExtraPointTimeDisplayOptionName() != null) + extraPointTimeDisplayOptionName = trackBean + .getExtraPointTimeDisplayOptionName(); + trackElement + .setExtraPointTimeDisplayOption(ITrack.ExtraPointTimeDisplayOption + .valueOf(extraPointTimeDisplayOptionName)); + + String skipFactorTextString = "0"; // set the default value + if (trackBean.getSkipFactorTextString() != null) + skipFactorTextString = trackBean.getSkipFactorTextString(); + trackElement.setSkipFactorTextString(skipFactorTextString); + + int fontNameComboSelectedIndex = 0; // set the default value + if (trackBean.getFontNameComboSelectedIndex() != null) + fontNameComboSelectedIndex = trackBean + .getFontNameComboSelectedIndex().intValue(); + trackElement + .setFontNameComboSelectedIndex(fontNameComboSelectedIndex); + + int fontSizeComboSelectedIndex = 0; // set the default value + if (trackBean.getFontSizeComboSelectedIndex() != null) + fontSizeComboSelectedIndex = trackBean + .getFontSizeComboSelectedIndex().intValue(); + trackElement + .setFontSizeComboSelectedIndex(fontSizeComboSelectedIndex); + + trackElementList.add(trackElement); + } + return trackElementList; } - public static gov.noaa.nws.ncep.ui.pgen.file.Track getTrackBeanByTrackElement( + public static gov.noaa.nws.ncep.ui.pgen.file.Track getTrackBeanByTrackElement( Track trackElement) { - gov.noaa.nws.ncep.ui.pgen.file.Track trackBean = new gov.noaa.nws.ncep.ui.pgen.file.Track(); + gov.noaa.nws.ncep.ui.pgen.file.Track trackBean = new gov.noaa.nws.ncep.ui.pgen.file.Track(); - trackBean.setInitialColor(getColorTypeBeanByColorElement(trackElement.getInitialColor())); - trackBean.setExtrapColor(getColorTypeBeanByColorElement(trackElement.getExtrapColor())); - - if(trackElement.getInitialPoints() != null) { - for(TrackPoint currentTrackPoint : trackElement.getInitialPoints()) { - trackBean.getInitialPoints().add(getTrackPointBeanByTrackPointElement(currentTrackPoint)); - } - } - if(trackElement.getExtrapPoints() != null) { - for(TrackPoint currentTrackPoint : trackElement.getExtrapPoints()) { - trackBean.getExtrapPoints().add(getTrackPointBeanByTrackPointElement(currentTrackPoint)); - } - } - - trackBean.getExtraPointTimeTextDisplayIndicator().addAll(getBooleanObjectList(trackElement.getExtraPointTimeTextDisplayIndicator())); + trackBean.setInitialColor(getColorTypeBeanByColorElement(trackElement + .getInitialColor())); + trackBean.setExtrapColor(getColorTypeBeanByColorElement(trackElement + .getExtrapColor())); - trackBean.setInitialLinePattern(trackElement.getInitialLinePattern()); - trackBean.setExtrapLinePattern(trackElement.getExtrapLinePattern()); - trackBean.setInitialMarker(trackElement.getInitialMarker()); - trackBean.setExtrapMarker(trackElement.getExtrapMarker()); - trackBean.setFontName(trackElement.getFontName()); - trackBean.setFontSize(new Float(trackElement.getFontSize())); - trackBean.setLineWidth(new Float(trackElement.getLineWidth())); - - trackBean.setPgenCategory(trackElement.getPgenCategory()); - trackBean.setPgenType(trackElement.getPgenType()); - - /* - * The following attributes are not necessary to save the line images - * and late to restore them back on the map. However, they are necessary - * values to pop-up and set up the correct attributes of the TrackAttrDlg - */ - trackBean.setSetTimeButtonSelected(new Boolean(trackElement.isSetTimeButtonSelected())); - trackBean.setIntervalComboSelectedIndex(new Integer(trackElement.getIntervalComboSelectedIndex())); - trackBean.setIntervalTimeTextString(trackElement.getIntervalTimeString()); - trackBean.setExtraPointTimeDisplayOptionName(trackElement.getExtraPointTimeDisplayOption().name()); - trackBean.setSkipFactorTextString(trackElement.getSkipFactorTextString()); - trackBean.setFontNameComboSelectedIndex(new Integer(trackElement.getFontNameComboSelectedIndex())); - trackBean.setFontSizeComboSelectedIndex(new Integer(trackElement.getFontSizeComboSelectedIndex())); - trackBean.setFontStyleComboSelectedIndex(new Integer(trackElement.getFontStyleComboSelectedIndex())); - - return trackBean; + if (trackElement.getInitialPoints() != null) { + for (TrackPoint currentTrackPoint : trackElement.getInitialPoints()) { + trackBean + .getInitialPoints() + .add(getTrackPointBeanByTrackPointElement(currentTrackPoint)); + } + } + if (trackElement.getExtrapPoints() != null) { + for (TrackPoint currentTrackPoint : trackElement.getExtrapPoints()) { + trackBean + .getExtrapPoints() + .add(getTrackPointBeanByTrackPointElement(currentTrackPoint)); + } + } + + trackBean.getExtraPointTimeTextDisplayIndicator().addAll( + getBooleanObjectList(trackElement + .getExtraPointTimeTextDisplayIndicator())); + + trackBean.setInitialLinePattern(trackElement.getInitialLinePattern()); + trackBean.setExtrapLinePattern(trackElement.getExtrapLinePattern()); + trackBean.setInitialMarker(trackElement.getInitialMarker()); + trackBean.setExtrapMarker(trackElement.getExtrapMarker()); + trackBean.setFontName(trackElement.getFontName()); + + // Font style + int styleInd = 0; + FontStyle dstyle = FontStyle.BOLD; + if (trackElement.getFontStyle() != null) { + int jj = 0; + for (FontStyle ft : FontStyle.values()) { + if (ft == trackElement.getFontStyle()) { + styleInd = jj; + dstyle = ft; + break; + } + + jj++; + } + } + + trackBean.setFontStyle(dstyle.toString()); + trackBean.setFontStyleComboSelectedIndex(styleInd); + + trackBean.setFontSize(new Float(trackElement.getFontSize())); + trackBean.setLineWidth(new Float(trackElement.getLineWidth())); + + trackBean.setPgenCategory(trackElement.getPgenCategory()); + trackBean.setPgenType(trackElement.getPgenType()); + + /* + * The following attributes are not necessary to save the line images + * and late to restore them back on the map. However, they are necessary + * values to pop-up and set up the correct attributes of the + * TrackAttrDlg + */ + trackBean.setSetTimeButtonSelected(new Boolean(trackElement + .isSetTimeButtonSelected())); + trackBean.setIntervalComboSelectedIndex(new Integer(trackElement + .getIntervalComboSelectedIndex())); + trackBean.setIntervalTimeTextString(trackElement + .getIntervalTimeString()); + trackBean.setExtraPointTimeDisplayOptionName(trackElement + .getExtraPointTimeDisplayOption().name()); + trackBean.setSkipFactorTextString(trackElement + .getSkipFactorTextString()); + trackBean.setFontNameComboSelectedIndex(new Integer(trackElement + .getFontNameComboSelectedIndex())); + trackBean.setFontSizeComboSelectedIndex(new Integer(trackElement + .getFontSizeComboSelectedIndex())); + + return trackBean; } - + /* - * help methods for transferring objects back and forth between class objects and JAXB beans + * help methods for transferring objects back and forth between class + * objects and JAXB beans */ - private static Calendar getFirstOrSecondTimeCalendarByTrackBean(gov.noaa.nws.ncep.ui.pgen.file.Track trackBean, boolean isFirstTimeCalendar) { - int indexOffSet = 1; - if(isFirstTimeCalendar) - indexOffSet++; - List trackPointElementList = getTrackPointElementListByTrackPointBeanList(trackBean.getInitialPoints()); - if(trackPointElementList == null || trackPointElementList.size() < 2) { -// log.error("Retrieved List trackPointElementList is NULL or the initial points are less than 2 points"); - return null; - } - int listSize = trackPointElementList.size(); - return trackPointElementList.get(listSize - indexOffSet).getTime(); - } - - private static java.awt.Color getColorByColorTypeBean(gov.noaa.nws.ncep.ui.pgen.file.ColorType colorTypeBean, - boolean isInitColor) { - if(colorTypeBean == null || colorTypeBean.getColor() == null) { - if(isInitColor) - return new Color(0, 0, 255); //return a default color as Blue - else - return new Color(0, 192, 0); //return a green color as the default color for extrapPoint - } - gov.noaa.nws.ncep.ui.pgen.file.Color colorBean = colorTypeBean.getColor(); - return new Color(colorBean.getRed(), colorBean.getGreen(), colorBean.getBlue(), - colorBean.getAlpha()); - } - - private static List getTrackPointElementListByTrackPointBeanList(List trackPointBeanList) { - List trackPointElementList = new ArrayList(trackPointBeanList.size()); - for(gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean : trackPointBeanList) { - java.util.Calendar currentCalendar = null; - if(trackPointBean.getTime() != null) { - currentCalendar = trackPointBean.getTime().toGregorianCalendar(); - } - Coordinate currentCoordinate = getCoordinateByTrackPointBean(trackPointBean); - TrackPoint currentTrackPointElement = new TrackPoint(currentCoordinate, currentCalendar); - trackPointElementList.add(currentTrackPointElement); - } - return trackPointElementList; - } - - private static Coordinate getCoordinateByTrackPointBean(gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean) { - Coordinate coordinate = new Coordinate(); - if(trackPointBean.getLocation() != null) { - coordinate.x = trackPointBean.getLocation().getLongitude(); - coordinate.y = trackPointBean.getLocation().getLatitude(); - } - return coordinate; - } - - private static boolean[] getBooleanArrayByBooleanList(List booleanList) { - boolean[] booleanArray = new boolean[booleanList.size()]; - int arrayIndex = 0; - for(Boolean currentBoolean : booleanList) { - booleanArray[arrayIndex++] = currentBoolean.booleanValue(); - } - return booleanArray; + private static Calendar getFirstOrSecondTimeCalendarByTrackBean( + gov.noaa.nws.ncep.ui.pgen.file.Track trackBean, + boolean isFirstTimeCalendar) { + int indexOffSet = 1; + if (isFirstTimeCalendar) + indexOffSet++; + List trackPointElementList = getTrackPointElementListByTrackPointBeanList(trackBean + .getInitialPoints()); + if (trackPointElementList == null || trackPointElementList.size() < 2) { + // log.error("Retrieved List trackPointElementList is NULL or the initial points are less than 2 points"); + return null; + } + int listSize = trackPointElementList.size(); + return trackPointElementList.get(listSize - indexOffSet).getTime(); } - - private static gov.noaa.nws.ncep.ui.pgen.file.ColorType getColorTypeBeanByColorElement(java.awt.Color colorElement) { - gov.noaa.nws.ncep.ui.pgen.file.ColorType colorTypeBean = new gov.noaa.nws.ncep.ui.pgen.file.ColorType(); - gov.noaa.nws.ncep.ui.pgen.file.Color colorBean = new gov.noaa.nws.ncep.ui.pgen.file.Color(); - colorBean.setAlpha(colorElement.getAlpha()); - colorBean.setBlue(colorElement.getBlue()); - colorBean.setRed(colorElement.getRed()); - colorBean.setGreen(colorElement.getGreen()); - colorTypeBean.setColor(colorBean); - return colorTypeBean; + private static java.awt.Color getColorByColorTypeBean( + gov.noaa.nws.ncep.ui.pgen.file.ColorType colorTypeBean, + boolean isInitColor) { + if (colorTypeBean == null || colorTypeBean.getColor() == null) { + if (isInitColor) + return new Color(0, 0, 255); // return a default color as Blue + else + return new Color(0, 192, 0); // return a green color as the + // default color for extrapPoint + } + gov.noaa.nws.ncep.ui.pgen.file.Color colorBean = colorTypeBean + .getColor(); + return new Color(colorBean.getRed(), colorBean.getGreen(), + colorBean.getBlue(), colorBean.getAlpha()); } - - private static gov.noaa.nws.ncep.ui.pgen.file.TrackPoint getTrackPointBeanByTrackPointElement(TrackPoint trackPointElement) { - gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean = new gov.noaa.nws.ncep.ui.pgen.file.TrackPoint(); - if(trackPointElement.getTime() != null) { - GregorianCalendar gregorianCalendar = new GregorianCalendar(); - gregorianCalendar.setTimeInMillis(trackPointElement.getTime().getTimeInMillis()); - try { - XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar); - trackPointBean.setTime(xmlGregorianCalendar); - } catch(DatatypeConfigurationException dce) { -// log.error("Error, instantiating XMLGregorianCalendar failed, error="+dce.getMessage()); - } - } - if(trackPointElement.getLocation() != null) { - trackPointBean.location = new gov.noaa.nws.ncep.ui.pgen.file.TrackPoint.Location(); - trackPointBean.getLocation().setLongitude(trackPointElement.getLocation().x); - trackPointBean.getLocation().setLatitude(trackPointElement.getLocation().y); - } - return trackPointBean; + private static List getTrackPointElementListByTrackPointBeanList( + List trackPointBeanList) { + List trackPointElementList = new ArrayList( + trackPointBeanList.size()); + for (gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean : trackPointBeanList) { + java.util.Calendar currentCalendar = null; + if (trackPointBean.getTime() != null) { + currentCalendar = trackPointBean.getTime() + .toGregorianCalendar(); + } + Coordinate currentCoordinate = getCoordinateByTrackPointBean(trackPointBean); + TrackPoint currentTrackPointElement = new TrackPoint( + currentCoordinate, currentCalendar); + trackPointElementList.add(currentTrackPointElement); + } + return trackPointElementList; } - + + private static Coordinate getCoordinateByTrackPointBean( + gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean) { + Coordinate coordinate = new Coordinate(); + if (trackPointBean.getLocation() != null) { + coordinate.x = trackPointBean.getLocation().getLongitude(); + coordinate.y = trackPointBean.getLocation().getLatitude(); + } + return coordinate; + } + + private static boolean[] getBooleanArrayByBooleanList( + List booleanList) { + boolean[] booleanArray = new boolean[booleanList.size()]; + int arrayIndex = 0; + for (Boolean currentBoolean : booleanList) { + booleanArray[arrayIndex++] = currentBoolean.booleanValue(); + } + return booleanArray; + } + + private static gov.noaa.nws.ncep.ui.pgen.file.ColorType getColorTypeBeanByColorElement( + java.awt.Color colorElement) { + gov.noaa.nws.ncep.ui.pgen.file.ColorType colorTypeBean = new gov.noaa.nws.ncep.ui.pgen.file.ColorType(); + gov.noaa.nws.ncep.ui.pgen.file.Color colorBean = new gov.noaa.nws.ncep.ui.pgen.file.Color(); + colorBean.setAlpha(colorElement.getAlpha()); + colorBean.setBlue(colorElement.getBlue()); + colorBean.setRed(colorElement.getRed()); + colorBean.setGreen(colorElement.getGreen()); + colorTypeBean.setColor(colorBean); + return colorTypeBean; + } + + private static gov.noaa.nws.ncep.ui.pgen.file.TrackPoint getTrackPointBeanByTrackPointElement( + TrackPoint trackPointElement) { + gov.noaa.nws.ncep.ui.pgen.file.TrackPoint trackPointBean = new gov.noaa.nws.ncep.ui.pgen.file.TrackPoint(); + + if (trackPointElement.getTime() != null) { + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTimeInMillis(trackPointElement.getTime() + .getTimeInMillis()); + try { + XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory + .newInstance().newXMLGregorianCalendar( + gregorianCalendar); + trackPointBean.setTime(xmlGregorianCalendar); + } catch (DatatypeConfigurationException dce) { + // log.error("Error, instantiating XMLGregorianCalendar failed, error="+dce.getMessage()); + } + } + if (trackPointElement.getLocation() != null) { + trackPointBean.location = new gov.noaa.nws.ncep.ui.pgen.file.TrackPoint.Location(); + trackPointBean.getLocation().setLongitude( + trackPointElement.getLocation().x); + trackPointBean.getLocation().setLatitude( + trackPointElement.getLocation().y); + } + return trackPointBean; + } + private static List getBooleanObjectList(boolean[] booleanArray) { - List booleanList = null; - if(booleanArray == null) - booleanList = new ArrayList(); - else - booleanList = new ArrayList(booleanArray.length); - for(boolean booleanValue : booleanArray) { - Boolean booleanObject = new Boolean(booleanValue); - booleanList.add(booleanObject); - } - return booleanList; + List booleanList = null; + if (booleanArray == null) + booleanList = new ArrayList(); + else + booleanList = new ArrayList(booleanArray.length); + for (boolean booleanValue : booleanArray) { + Boolean booleanObject = new Boolean(booleanValue); + booleanList.add(booleanObject); + } + return booleanList; } - - -} +} diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/product.xsd b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/product.xsd index 7b56012fba..6aed5f6601 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/product.xsd +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/file/product.xsd @@ -411,27 +411,52 @@ - - - + + + + + + - + + + - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaGenerate.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaGenerate.java index e54fc3f253..e34d8f932d 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaGenerate.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaGenerate.java @@ -14,10 +14,10 @@ import gov.noaa.nws.ncep.ui.pgen.elements.Product; import gov.noaa.nws.ncep.ui.pgen.file.FileTools; import gov.noaa.nws.ncep.ui.pgen.file.ProductConverter; import gov.noaa.nws.ncep.ui.pgen.file.Products; +import gov.noaa.nws.ncep.ui.pgen.rsc.PgenResource; import gov.noaa.nws.ncep.ui.pgen.store.PgenStorageException; import gov.noaa.nws.ncep.ui.pgen.store.StorageUtils; import gov.noaa.nws.ncep.ui.pgen.tools.PgenCycleTool; -import gov.noaa.nws.ncep.ui.pgen.rsc.PgenResource; import java.io.File; import java.io.IOException; @@ -61,6 +61,7 @@ import com.vividsolutions.jts.geom.GeometryFactory; * 05/13 #610 J. Wu Implemented FZLVL range (TTR425) * 07/13 ? J. Wu Move state list ordering to GfaRules. * 08/13 TTR714/715 J. Wu Fixed issue type and times. + * 10/14 TTR714 J. Wu Check issue type in get_status.xml. * *
* @@ -70,7 +71,9 @@ import com.vividsolutions.jts.geom.GeometryFactory; public class GfaGenerate { private static final String TEXT_TYPE = "TEXT"; - private GeometryFactory gf = new GeometryFactory(); + + private GeometryFactory gf = new GeometryFactory(); + private static final String ISSUE_TYPE_FROM_OUTLOOK = "ISSUE_TYPE_FROM_OUTLOOK"; // private final static Logger logger = Logger.getLogger(GfaGenerate.class); @@ -109,20 +112,22 @@ public class GfaGenerate { /* * Create an additional smear for the adjacent area. */ - for ( Gfa g : all) { - Gfa sg = createAdjacentGfa( g ); + for (Gfa g : all) { + Gfa sg = createAdjacentGfa(g); - adjusted.add( g ); + adjusted.add(g); - if ( sg != null ) { - adjusted.add( sg ); + if (sg != null) { + adjusted.add(sg); } } /* - * Find issue type for an Airmet's associated Outlook + * Find issue type for an Airmet's associated Outlook. Note: TTR 714 - + * J. Wu: this may cause other issues. Instead, we should check the + * issue types in "get_status.xsl". */ - trackOtlkIssueTypeToAirmet( adjusted ); + // trackOtlkIssueTypeToAirmet(adjusted); /* * Find GFA smears in each area and hazard category, generate xml, and @@ -130,14 +135,14 @@ public class GfaGenerate { */ for (String category : categories) { for (String area : areas) { - - List ret = filterSelected( adjusted, area, category ); + + List ret = filterSelected(adjusted, area, category); // If no issue/until times, assign them. for (Gfa de : ret) { if (!de.isSnapshot() && de.getAttribute(Gfa.ISSUE_TIME) == null) { - GfaRules.assignIssueTime( de ); + GfaRules.assignIssueTime(de); } } @@ -154,24 +159,25 @@ public class GfaGenerate { /* * Find freezing range for this area! */ - String fzlvlRange = findFreezingRange( all, ret, area, category ); + String fzlvlRange = findFreezingRange(all, ret, area, category); /* * Note - needs to use a copy so it won't change the parent of * the original G-Airmets, e.g. l.add( de ) will set the parent * of the 'de" to be "l"! */ - for ( Gfa gss : ret) { - Gfa gfaCopy = gss.copy(); - String otlkIssueType = nvl( gfaCopy.getGfaValue( ISSUE_TYPE_FROM_OUTLOOK ) ); - if ( !otlkIssueType.equals( "NRML" ) ) { - gfaCopy.setGfaIssueType( otlkIssueType ); - } - - if ( fzlvlRange != null ) { - gfaCopy.setGfaValue( Gfa.FZL_RANGE, fzlvlRange ); - } - l.add( gfaCopy ); + for (Gfa gss : ret) { + Gfa gfaCopy = gss.copy(); + /* + * String otlkIssueType = nvl(gfaCopy + * .getGfaValue(ISSUE_TYPE_FROM_OUTLOOK)); if + * (!otlkIssueType.equals("NRML")) { + * gfaCopy.setGfaIssueType( otlkIssueType ); } + */ + if (fzlvlRange != null) { + gfaCopy.setGfaValue(Gfa.FZL_RANGE, fzlvlRange); + } + l.add(gfaCopy); } // l.add( ret ); @@ -183,7 +189,7 @@ public class GfaGenerate { // Needs to add an empty Gfa to carry the issue/until for proper // formatting. if (ret.size() == 0) { - addNullGfa( products, category, fzlvlRange ); + addNullGfa(products, category, fzlvlRange); } String xml = SerializationUtil.marshalToXml(products); @@ -191,7 +197,7 @@ public class GfaGenerate { if (sb.length() > 0 && !sb.toString().endsWith("\n\n")) { sb.append("\n\n"); } - + String prdXml = generateProduct(xml, category, area).trim(); temp.append(prdXml); @@ -233,7 +239,8 @@ public class GfaGenerate { * @param cats * @return */ - private static List filterSelected( List all, String area, String category) { + private static List filterSelected(List all, String area, + String category) { ArrayList ret = new ArrayList(); @@ -258,6 +265,7 @@ public class GfaGenerate { } public String generateProduct(String prdxml, String category, String area) { + System.out.println("\nprdxml is:\n" + prdxml + "\n"); String xml1 = prdxml.replaceAll("TURB-HI", "TURB"); String xml = xml1.replaceAll("TURB-LO", "TURB"); @@ -279,6 +287,7 @@ public class GfaGenerate { transformer.transform(xmlSource, result); res = result.getWriter().toString().trim(); + System.out.println("\nres is:\n" + res + "\n"); } catch (Exception e) { // logger.error( "", e ); @@ -295,11 +304,13 @@ public class GfaGenerate { } /** - * Create a new smear for smears with two FA areas and re-order the state list. + * Create a new smear for smears with two FA areas and re-order the state + * list. * - * The States in the primary area precede states in the adjacent area. + * The States in the primary area precede states in the adjacent area. * - * @param g Gfa to be processed + * @param g + * Gfa to be processed * * @return */ @@ -310,12 +321,12 @@ public class GfaGenerate { String[] s = nvl(g.getGfaArea()).split("-"); if (s.length > 1) { - String sname = new String( s[1].trim() + "-" + s[0].trim() ); + String sname = new String(s[1].trim() + "-" + s[0].trim()); // create an additional smear and re-order state list. - secondg = g.copy(); - secondg.setGfaArea( sname ); - GfaRules.reorderStateList( secondg ); + secondg = g.copy(); + secondg.setGfaArea(sname); + GfaRules.reorderStateList(secondg); } return secondg; @@ -362,12 +373,12 @@ public class GfaGenerate { /* * Adds an empty Gfa to the product so it can pass issue/until time for - * correct formatting. Freezing range should be set if provided. + * correct formatting. Freezing range should be set if provided. * * Note - this should be called only when there is no Gfa smears in the * "prds". */ - private void addNullGfa(Products prds, String category, String fzlRange ) { + private void addNullGfa(Products prds, String category, String fzlRange) { gov.noaa.nws.ncep.ui.pgen.file.Gfa fgfa = new gov.noaa.nws.ncep.ui.pgen.file.Gfa(); @@ -380,9 +391,9 @@ public class GfaGenerate { fgfa.setFcstHr("0-6"); // If freezing range is provided, set it and set hazard type as "FZLVL". - if ( fzlRange != null ) { - fgfa.setHazard( "FZLVL" ); - fgfa.setFzlRange( fzlRange ); + if (fzlRange != null) { + fgfa.setHazard("FZLVL"); + fgfa.setFzlRange(fzlRange); } // @@ -429,398 +440,395 @@ public class GfaGenerate { } /* - * Find the freezing range from FZLVL/M_FZLVL airmets. + * Find the freezing range from FZLVL/M_FZLVL airmets. */ - private String findFreezingRange( List all, List selected, - String area, String cat ) { - - if ( !cat.equalsIgnoreCase( "ZULU" ) ) { - return null; - } - - - String fzlRange = null; - String topStr = null; - String botStr = null; - - /* - * If no FZLVL/M_FZLVL in this area, find range using those outside of - * this area, if any. - */ - if ( selected == null || selected.size() == 0 ) { - int[] extRange = findExernalFzlvlRange( all, area ); - if ( extRange[0] != -1 ) { - topStr = padding( extRange[0] ); - botStr = padding( extRange[1] ); - } - } - else { - /* - * First - find the worst range from existing FZL_RANGE in FZLVL airmets. - * If no existing range found, then find the worst top/bottom from - * FZLVLs' levels ( top = level + 40 and bottom = level - 40) - * Second - find the worst top/bottom from M_FZLVLs - * - * Third - find the worst case range using info from step 1 and 2. - * - */ - int[] existingRange = findExistingFzlRange( all, selected, area ); - int[] mfzlRange = findMfzlvlRange( all, selected, area ); + private String findFreezingRange(List all, List selected, + String area, String cat) { - if ( existingRange[0] == -1 ) { - existingRange = findFzlvlLevelRange( all, selected, area ); - } + if (!cat.equalsIgnoreCase("ZULU")) { + return null; + } - if ( existingRange[0] != -1 || mfzlRange[0] != -1 ) { - topStr = padding( Math.max( existingRange[0], mfzlRange[0] ) ); - } + String fzlRange = null; + String topStr = null; + String botStr = null; - if ( existingRange[1] != 9999 || mfzlRange[1] != 9999 ){ - botStr = padding( Math.min( existingRange[1], mfzlRange[1] ) ); - } - } - - // Now create a range string. - if ( topStr != null && botStr != null ) { - fzlRange = area + ";" + topStr + ";" + botStr; - } - - return fzlRange; - - } - - - /* - * Retrieve the worst FZLVL range from ranges existing in FZLVL airmet/outlook. - * Such existing range should be in the form as "MIA;160;40", retrievable as - * gfa.getGfaValue( Gfa.FZL_RANGE ). - */ - private int[] findExistingFzlRange( List all, List selected, String area ) { - - int[] topBot = { -1, 9999 }; - - for ( Gfa elem : selected ) { - - String gtype = elem.getGfaHazard(); - - if ( !gtype.equalsIgnoreCase("FZLVL") || elem.isSnapshot() ) { - continue; - } - - String range1 = elem.getGfaValue( Gfa.FZL_RANGE ); - if ( range1 != null ) { - String[] rangeInfo = range1.split(";"); - if ( rangeInfo.length >= 3 && rangeInfo[0].equalsIgnoreCase( area ) ) { - int top1 = -1; - int bot1 = -1; - - try { - top1 = Integer.parseInt( rangeInfo[1] ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - - if ( rangeInfo[2].equalsIgnoreCase("SFC") ) { - bot1 = 0; - } - else { - try { - bot1 = Integer.parseInt( rangeInfo[2] ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - } - - if ( top1 >= 0 && bot1 >= 0 ) { - topBot[0] = Math.max( topBot[0], top1 ); - topBot[1] = Math.min( topBot[1], bot1 ); - } - } - } - } - - return topBot; - } - - /* - * Retrieve the worst range from existing top/bottom of M_FZLVL airmet/outlook. - * Such top/bottom are retrievable as gfa.getGfaTop() & gfa.getGfaBottom(). - */ - private int[] findMfzlvlRange( List all, List selected, String area ) { - - int[] topBot = { -1, 9999 }; - - for ( Gfa elem : selected ) { - - String gtype = elem.getGfaHazard(); - - if ( !gtype.equalsIgnoreCase("M_FZLVL") || elem.isSnapshot() ) { - continue; - } - - int top2 = -1; - int bot2 = -1; - - if ( elem.getGfaTop() != null ) { - try { - top2 = Integer.parseInt( elem.getGfaTop() ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - } - - String botStr = elem.getGfaBottom(); - if ( botStr != null ) { - if ( botStr.equalsIgnoreCase( "SFC") ) { - bot2 = 0; - } - else { - try { - bot2 = Integer.parseInt( elem.getGfaBottom() ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - } - } - - if ( top2 >= 0 && bot2 >= 0 ) { - topBot[0] = Math.max( topBot[0], top2 ); - topBot[1] = Math.min( topBot[1], bot2 ); - } - - } - - return topBot; - - } - - /* - * Retrieve the worst range from existing levels of FZLVL airmet/outlook. - * Such levels are retrievable as gfa.getGfaValue( Gfa.LEVEL ). - */ - private int[] findFzlvlLevelRange( List all, List selected, String area ) { - - int[] topBot = { -1, 9999 }; - for ( Gfa elem : selected ) { - - String gtype = elem.getGfaHazard(); - - if ( !gtype.equalsIgnoreCase("FZLVL") || elem.isSnapshot() ) { - continue; - } - - int top2 = -1; - int bot2 = -1; - - String levelStr = elem.getGfaValue( Gfa.LEVEL ); - int lvl = -1; - - if ( levelStr != null ) { - - if ( levelStr.equalsIgnoreCase( "SFC" ) ) { - top2 = 40; - bot2 = 0; - } - else { - try { - lvl = Integer.parseInt( levelStr ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - - if ( lvl >= 0 && lvl <= 40 ) { - top2 = 40; - bot2 = 0; - } - else { - top2 = lvl + 40; - bot2 = lvl - 40; - } - } - } - - - if ( top2 >= 0 && bot2 >= 0 ) { - topBot[0] = Math.max( topBot[0], top2 ); - topBot[1] = Math.min( topBot[1], bot2 ); - } - - } - - return topBot; - - } - - /* - * Find the top and base levels for a FA area that is not intersected by any FZLVL - * contours. It sorts all external fzlvls by distance from the area centroid, then - * uses the level from that contour. If the contour is to the left of the area then - * the answer is base = contour level, top = base + 040. If the contour is to the - * right of the area then the answer top = contour level, base = top - 040. - * - * See legacy af_getExternalFzlvlRng() in af_getAirmetXml.c. - * - * Note (1) only FZLVLs are used, not M_FZLVLs. - * (2) All FZLVLs are used, including snapshots. - * - */ - private int[] findExernalFzlvlRange( List all, String area ) { - - int[] topBot = { -1, 9999 }; - - HashMap areaBnds = GfaClip.getInstance().getFaAreaBounds(); - - Coordinate center = gf.createLinearRing( areaBnds.get(area ).getCoordinates() ).getCentroid().getCoordinate(); - - Gfa closestGfa = null; - double minDist = Double.MAX_VALUE; - - for ( Gfa elem : all ) { - - String gtype = elem.getGfaHazard(); - - if ( !gtype.equalsIgnoreCase("FZLVL") ) { - continue; - } - - // Find distance from the FA Area's centroid to this FZLVL. - double dist = distance( elem, center ); - if ( dist < minDist ) { - minDist = dist; - closestGfa = elem; + /* + * If no FZLVL/M_FZLVL in this area, find range using those outside of + * this area, if any. + */ + if (selected == null || selected.size() == 0) { + int[] extRange = findExernalFzlvlRange(all, area); + if (extRange[0] != -1) { + topStr = padding(extRange[0]); + botStr = padding(extRange[1]); } - - } - - if ( closestGfa != null ) { - boolean isLeft = GfaSnap.getInstance().atLeft( center, closestGfa.getLinePoints(), - closestGfa.isClosedLine(), 0.0 ); - - String levelStr = closestGfa.getGfaValue( Gfa.LEVEL ); - int lvl = -1; - - if ( levelStr != null ) { - - if ( levelStr.equalsIgnoreCase( "SFC" ) ) { + } else { + /* + * First - find the worst range from existing FZL_RANGE in FZLVL + * airmets. If no existing range found, then find the worst + * top/bottom from FZLVLs' levels ( top = level + 40 and bottom = + * level - 40) Second - find the worst top/bottom from M_FZLVLs + * + * Third - find the worst case range using info from step 1 and 2. + */ + int[] existingRange = findExistingFzlRange(all, selected, area); + int[] mfzlRange = findMfzlvlRange(all, selected, area); + + if (existingRange[0] == -1) { + existingRange = findFzlvlLevelRange(all, selected, area); + } + + if (existingRange[0] != -1 || mfzlRange[0] != -1) { + topStr = padding(Math.max(existingRange[0], mfzlRange[0])); + } + + if (existingRange[1] != 9999 || mfzlRange[1] != 9999) { + botStr = padding(Math.min(existingRange[1], mfzlRange[1])); + } + } + + // Now create a range string. + if (topStr != null && botStr != null) { + fzlRange = area + ";" + topStr + ";" + botStr; + } + + return fzlRange; + + } + + /* + * Retrieve the worst FZLVL range from ranges existing in FZLVL + * airmet/outlook. Such existing range should be in the form as + * "MIA;160;40", retrievable as gfa.getGfaValue( Gfa.FZL_RANGE ). + */ + private int[] findExistingFzlRange(List all, List selected, + String area) { + + int[] topBot = { -1, 9999 }; + + for (Gfa elem : selected) { + + String gtype = elem.getGfaHazard(); + + if (!gtype.equalsIgnoreCase("FZLVL") || elem.isSnapshot()) { + continue; + } + + String range1 = elem.getGfaValue(Gfa.FZL_RANGE); + if (range1 != null) { + String[] rangeInfo = range1.split(";"); + if (rangeInfo.length >= 3 + && rangeInfo[0].equalsIgnoreCase(area)) { + int top1 = -1; + int bot1 = -1; + + try { + top1 = Integer.parseInt(rangeInfo[1]); + } catch (Exception e) { + e.printStackTrace(); + } + + if (rangeInfo[2].equalsIgnoreCase("SFC")) { + bot1 = 0; + } else { + try { + bot1 = Integer.parseInt(rangeInfo[2]); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (top1 >= 0 && bot1 >= 0) { + topBot[0] = Math.max(topBot[0], top1); + topBot[1] = Math.min(topBot[1], bot1); + } + } + } + } + + return topBot; + } + + /* + * Retrieve the worst range from existing top/bottom of M_FZLVL + * airmet/outlook. Such top/bottom are retrievable as gfa.getGfaTop() & + * gfa.getGfaBottom(). + */ + private int[] findMfzlvlRange(List all, List selected, String area) { + + int[] topBot = { -1, 9999 }; + + for (Gfa elem : selected) { + + String gtype = elem.getGfaHazard(); + + if (!gtype.equalsIgnoreCase("M_FZLVL") || elem.isSnapshot()) { + continue; + } + + int top2 = -1; + int bot2 = -1; + + if (elem.getGfaTop() != null) { + try { + top2 = Integer.parseInt(elem.getGfaTop()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + String botStr = elem.getGfaBottom(); + if (botStr != null) { + if (botStr.equalsIgnoreCase("SFC")) { + bot2 = 0; + } else { + try { + bot2 = Integer.parseInt(elem.getGfaBottom()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + if (top2 >= 0 && bot2 >= 0) { + topBot[0] = Math.max(topBot[0], top2); + topBot[1] = Math.min(topBot[1], bot2); + } + + } + + return topBot; + + } + + /* + * Retrieve the worst range from existing levels of FZLVL airmet/outlook. + * Such levels are retrievable as gfa.getGfaValue( Gfa.LEVEL ). + */ + private int[] findFzlvlLevelRange(List all, List selected, + String area) { + + int[] topBot = { -1, 9999 }; + for (Gfa elem : selected) { + + String gtype = elem.getGfaHazard(); + + if (!gtype.equalsIgnoreCase("FZLVL") || elem.isSnapshot()) { + continue; + } + + int top2 = -1; + int bot2 = -1; + + String levelStr = elem.getGfaValue(Gfa.LEVEL); + int lvl = -1; + + if (levelStr != null) { + + if (levelStr.equalsIgnoreCase("SFC")) { + top2 = 40; + bot2 = 0; + } else { + try { + lvl = Integer.parseInt(levelStr); + } catch (Exception e) { + e.printStackTrace(); + } + + if (lvl >= 0 && lvl <= 40) { + top2 = 40; + bot2 = 0; + } else { + top2 = lvl + 40; + bot2 = lvl - 40; + } + } + } + + if (top2 >= 0 && bot2 >= 0) { + topBot[0] = Math.max(topBot[0], top2); + topBot[1] = Math.min(topBot[1], bot2); + } + + } + + return topBot; + + } + + /* + * Find the top and base levels for a FA area that is not intersected by any + * FZLVL contours. It sorts all external fzlvls by distance from the area + * centroid, then uses the level from that contour. If the contour is to the + * left of the area then the answer is base = contour level, top = base + + * 040. If the contour is to the right of the area then the answer top = + * contour level, base = top - 040. + * + * See legacy af_getExternalFzlvlRng() in af_getAirmetXml.c. + * + * Note (1) only FZLVLs are used, not M_FZLVLs. (2) All FZLVLs are used, + * including snapshots. + */ + private int[] findExernalFzlvlRange(List all, String area) { + + int[] topBot = { -1, 9999 }; + + HashMap areaBnds = GfaClip.getInstance() + .getFaAreaBounds(); + + Coordinate center = gf + .createLinearRing(areaBnds.get(area).getCoordinates()) + .getCentroid().getCoordinate(); + + Gfa closestGfa = null; + double minDist = Double.MAX_VALUE; + + for (Gfa elem : all) { + + String gtype = elem.getGfaHazard(); + + if (!gtype.equalsIgnoreCase("FZLVL")) { + continue; + } + + // Find distance from the FA Area's centroid to this FZLVL. + double dist = distance(elem, center); + if (dist < minDist) { + minDist = dist; + closestGfa = elem; + } + + } + + if (closestGfa != null) { + boolean isLeft = GfaSnap.getInstance().atLeft(center, + closestGfa.getLinePoints(), closestGfa.isClosedLine(), 0.0); + + String levelStr = closestGfa.getGfaValue(Gfa.LEVEL); + int lvl = -1; + + if (levelStr != null) { + + if (levelStr.equalsIgnoreCase("SFC")) { lvl = 0; - } - else { - try { - lvl = Integer.parseInt( levelStr ); - } - catch ( Exception e ) { - e.printStackTrace(); - } - } - } - - if ( lvl >= 0 ) { - if ( !isLeft ) { // FZLVL is at right of FA area - topBot[0] = lvl + 40; - topBot[1] = lvl; - } - else { // FZLVL is at left of FA area - topBot[0] = lvl; - topBot[1] = lvl - 40; - if ( topBot[1] < 0 ) topBot[1] = 0; - } - } - } - - return topBot; - + } else { + try { + lvl = Integer.parseInt(levelStr); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + if (lvl >= 0) { + if (!isLeft) { // FZLVL is at right of FA area + topBot[0] = lvl + 40; + topBot[1] = lvl; + } else { // FZLVL is at left of FA area + topBot[0] = lvl; + topBot[1] = lvl - 40; + if (topBot[1] < 0) + topBot[1] = 0; + } + } + } + + return topBot; + } - + /* - * Pad a value between 0 to 100 in format of "0xx". - */ - private String padding( int value ) { - - StringBuilder str = new StringBuilder(); - if ( value <= 0 ) { - str.append( "SFC" ); - } - else { - if ( value < 100 ) { - str.append( "0" + value ); - } - else { - str.append( value ); - } - } - - return str.toString(); - + * Pad a value between 0 to 100 in format of "0xx". + */ + private String padding(int value) { + + StringBuilder str = new StringBuilder(); + if (value <= 0) { + str.append("SFC"); + } else { + if (value < 100) { + str.append("0" + value); + } else { + str.append(value); + } + } + + return str.toString(); + } - + /* - * Find the distance from a given point to a Gfa line or polygon. - */ - private double distance( Gfa gfa, Coordinate loc ) { - + * Find the distance from a given point to a Gfa line or polygon. + */ + private double distance(Gfa gfa, Coordinate loc) { + double dist = Double.MAX_VALUE; double minDist = Double.MAX_VALUE; - + Object pts[] = gfa.getPoints().toArray(); - for ( int ii = 0; ii < pts.length; ii++ ) { + for (int ii = 0; ii < pts.length; ii++) { - if ( ii == pts.length - 1 ) { - if ( gfa.isClosedLine() ) { - dist = PgenResource.distanceFromLineSegment( loc, + if (ii == pts.length - 1) { + if (gfa.isClosedLine()) { + dist = PgenResource.distanceFromLineSegment(loc, (Coordinate) pts[ii], (Coordinate) pts[0]); - } - else { + } else { break; } - } - else { - dist = PgenResource.distanceFromLineSegment( loc, (Coordinate) pts[ii], - (Coordinate) pts[ii + 1]); + } else { + dist = PgenResource.distanceFromLineSegment(loc, + (Coordinate) pts[ii], (Coordinate) pts[ii + 1]); } - if ( dist < minDist ) { + if (dist < minDist) { minDist = dist; - } - } - - return minDist; - + } + } + + return minDist; + } - + /** - * Find if a smear has an associated outlook that are generated from the same series of - * snapshots (with same hazard type, tag and desk. + * Find if a smear has an associated outlook that are generated from the + * same series of snapshots (with same hazard type, tag and desk. * - * This is used to get around the issue when a pair of airmet and outlook is generated from - * the same series of snapshots, and the airmet's issue tyep is "NRML" while outlook's issue - * type is not "NRML". In this case, the formatted header should show the outlook's issue type. + * This is used to get around the issue when a pair of airmet and outlook is + * generated from the same series of snapshots, and the airmet's issue type + * is "NRML" while outlook's issue type is not "NRML". In this case, the + * formatted header should show the outlook's issue type. + * + * Note: TTR 714 - 10/2014: for the above case, we should modify + * "get_status.xsl" to get the formatted header by looping through all + * airmets and outlooks instead of modifying it here. * * @param all * @return */ - private static void trackOtlkIssueTypeToAirmet( List all ) { + private static void trackOtlkIssueTypeToAirmet(List all) { - for ( Gfa gg : all) { - gg.setGfaValue( ISSUE_TYPE_FROM_OUTLOOK, "NRML" ); - if ( gg.isAirmet() && "NRML".equalsIgnoreCase( gg.getGfaIssueType() ) ) { - String akey = gg.getGfaHazard() + gg.getGfaTag() + gg.getGfaDesk(); - for ( Gfa gotlk : all) { - if ( gotlk.isOutlook() && !("NRML".equalsIgnoreCase( gotlk.getGfaIssueType() ) ) ) { - String okey = gotlk.getGfaHazard() + gotlk.getGfaTag() + gotlk.getGfaDesk(); - if ( okey.equals( akey ) ) { - gg.setGfaValue( ISSUE_TYPE_FROM_OUTLOOK, gotlk.getGfaIssueType() ); - break; - } - } - } - } + for (Gfa gg : all) { + gg.setGfaValue(ISSUE_TYPE_FROM_OUTLOOK, "NRML"); + if (gg.isAirmet() && "NRML".equalsIgnoreCase(gg.getGfaIssueType())) { + String akey = gg.getGfaHazard() + gg.getGfaTag() + + gg.getGfaDesk(); + for (Gfa gotlk : all) { + if (gotlk.isOutlook() + && !("NRML".equalsIgnoreCase(gotlk + .getGfaIssueType()))) { + String okey = gotlk.getGfaHazard() + gotlk.getGfaTag() + + gotlk.getGfaDesk(); + if (okey.equals(akey)) { + gg.setGfaValue(ISSUE_TYPE_FROM_OUTLOOK, + gotlk.getGfaIssueType()); + break; + } + } + } + } } } - + } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaInfo.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaInfo.java index 3693d2745e..2cac8c7acc 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaInfo.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaInfo.java @@ -7,6 +7,12 @@ */ package gov.noaa.nws.ncep.ui.pgen.gfa; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.BOS; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.CHI; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.DFW; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.MIA; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.SFO; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.SLC; import gov.noaa.nws.ncep.ui.pgen.PgenStaticDataProvider; import java.awt.Color; @@ -20,8 +26,6 @@ import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.eclipse.swt.graphics.RGB; -import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.*; - /** * Helper class to read the GFA configuration. * @@ -41,379 +45,390 @@ import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.*; */ public class GfaInfo { - // gui settings - private static Document doc; + // gui settings + private static Document doc; - public static final String HAZARD_XPATH = "/root/hazard"; - public static final String FCSTHR_XPATH = "/root/fcstHr"; - public static final String TAG_XPATH = "/root/tag"; - public static final String DESK_XPATH = "/root/desk"; - public static final String ISSUE_TYPE_XPATH = "/root/issueType"; - public static final String GFA_OTLKGEN_RATIO_XPATH = "/root/gfaOtlkgenRatio"; - - public static final String AIRMET_ELEMENT_XPATH = "/airmetcycle/element"; - - public static final String GFA_SNAPSHOT = "snapshot"; - public static final String GFA_SMEAR = "smear"; - public static final String GFA_OUTLOOK = "outlook"; + public static final String HAZARD_XPATH = "/root/hazard"; - public static final int GFA_SMEAR_LINEWIDTH = 3; - public static final int GFA_OUTLOOK_LINEWIDTH = 4; - public static final int GFA_OTHER_LINEWIDTH = 2; - + public static final String FCSTHR_XPATH = "/root/fcstHr"; - /** - * Hazard type vs color array (index means the same as the position - * in fcstHr combo box) - */ - private static HashMap rgbMap; + public static final String TAG_XPATH = "/root/tag"; - /** - * Pairs like ("red", new RGB(255, 0, 0)) read from gfa.xml - */ - private static HashMap definedColors; - - /** - * Hazard categories - */ - private static HashMap hazardCategories; - - public enum HazardCategory{ - SIERRA, TANGO, ZULU, NONE; - } + public static final String DESK_XPATH = "/root/desk"; - /** - * State orders in each FA area. - */ - private static HashMap > stateOrderByArea; - - /** - * Pairs like ("red", new RGB(255, 0, 0)) read from gfa.xml - */ - private static HashMap fzlvlSfcColors; - - /** - * Getter for the document. - * - * @return - */ - public static Document getDocument() { - if (doc == null) { - readOptions(); - } - return doc; - } + public static final String ISSUE_TYPE_XPATH = "/root/issueType"; - /** - * Read the menu configuration from gfa.xml file - */ - private static void readOptions() { - File gfainfoFile = PgenStaticDataProvider.getProvider().getStaticFile( - PgenStaticDataProvider.getProvider().getPgenLocalizationRoot() + "gfa.xml"); + public static final String GFA_OTLKGEN_RATIO_XPATH = "/root/gfaOtlkgenRatio"; - try { - SAXReader reader = new SAXReader(); - doc = reader.read(gfainfoFile.getAbsoluteFile()); - } catch (Exception e) { - e.printStackTrace(); - } - } + public static final String AIRMET_ELEMENT_XPATH = "/airmetcycle/element"; - /* - * This method is just to suppress warning - */ - @SuppressWarnings("unchecked") - public static List selectNodes(String xPath) { - return (List) GfaInfo.getDocument().selectNodes(xPath); - } + public static final String GFA_SNAPSHOT = "snapshot"; - /** - * Creates an rgb map for hazard types and returns the corresponding color. - * - * @param hazard - * @return - */ - public static RGB getRGB(String hazard, int fcstHrIndex) { - if (rgbMap == null) { - loadColors(); - } + public static final String GFA_SMEAR = "smear"; - if (fcstHrIndex < 0 || fcstHrIndex >= rgbMap.get(hazard).length) { - // take last as default if parameter is out of range (fcstHr=Other) - fcstHrIndex = rgbMap.get(hazard).length-1; - } + public static final String GFA_OUTLOOK = "outlook"; - return rgbMap.get(hazard)[fcstHrIndex]; - } - - /** - * Load colors. - */ - private static void loadColors() { - List colorNodes = selectNodes("/root/color/value"); + public static final int GFA_SMEAR_LINEWIDTH = 3; - definedColors = new HashMap(); - for (Node n : colorNodes) { - int r = Integer.parseInt(n.valueOf("@r")); - int g = Integer.parseInt(n.valueOf("@g")); - int b = Integer.parseInt(n.valueOf("@b")); - // for example, <"red", (255,0,0)> - definedColors.put(n.valueOf("@name"), new RGB(r, g, b)); - } + public static final int GFA_OUTLOOK_LINEWIDTH = 4; - List hazardNodes = selectNodes(HAZARD_XPATH); - List fcstHrNodes = selectNodes(FCSTHR_XPATH); + public static final int GFA_OTHER_LINEWIDTH = 2; - // hazard type vs. color array (index means the same as the position - // in fcstHr combo box) - rgbMap = new HashMap(); + /** + * Hazard type vs color array (index means the same as the position in + * fcstHr combo box) + */ + private static HashMap rgbMap; - for (Node n : hazardNodes) { - RGB[] colors = new RGB[fcstHrNodes.size()]; - int i = 0; - for (Node f : fcstHrNodes) { - String type = f.valueOf("@type"); // for example, "smear" - String colorStr = n.valueOf("@" + type); // for example, - // "blue" - colors[i++] = definedColors.get(colorStr); - } - rgbMap.put(n.valueOf("@name"), colors); - } - } + /** + * Pairs like ("red", new RGB(255, 0, 0)) read from gfa.xml + */ + private static HashMap definedColors; - /** - * Returns the default colors for the hazard and forecast hour pair. - * - * @param hazard - * @param fcstHr - * @return Color[] - */ - public static Color[] getDefaultColors(String hazard, String fcstHr) { - RGB rgb = getDefaultRGB( hazard, fcstHr ); - - Color color = new Color(rgb.red, rgb.green, rgb.blue); - return new Color[]{color, color}; - } + /** + * Hazard categories + */ + private static HashMap hazardCategories; - /** - * Returns the default color's RGB for the hazard and forecast hour pair. - * - * @param hazard - * @param fcstHr - * @return RGB - */ - public static RGB getDefaultRGB(String hazard, String fcstHr) { - if (definedColors == null) { - loadColors(); - } - - String xPath = HAZARD_XPATH + "[@name='" + hazard + "']"; - List hazardNodes = selectNodes(xPath); - - xPath = FCSTHR_XPATH + "[@name='" + fcstHr + "']"; - List fcsthrNodes = selectNodes(xPath); - - if (fcsthrNodes.size() != 1) { - try{ - if(fcstHr.indexOf("-") == -1) { // snapshot - xPath = FCSTHR_XPATH + "[@name='0 Z']"; - } else { - String second= fcstHr.split("-")[1]; - String hour = second.split(":")[0]; - if(Integer.parseInt(hour) <=6){ // smear - xPath = FCSTHR_XPATH + "[@name='0-6']"; - } else { // outlook - xPath = FCSTHR_XPATH + "[@name='6-9']"; - } - } - } catch (Exception e){ - xPath = FCSTHR_XPATH + "[@name='Other']"; - } - fcsthrNodes = selectNodes(xPath); - } - - String gfaType = GFA_SNAPSHOT; - if ( fcsthrNodes.size() != 1 ) { //hard-coded - if ( fcstHr.indexOf("-") >= 0 ) { - String second= fcstHr.split("-")[1]; - String hour = second.split(":")[0]; - if(Integer.parseInt(hour) <=6) { - gfaType = GFA_SMEAR; - } else { - gfaType = GFA_OUTLOOK; - } - } - } - else { - gfaType = fcsthrNodes.get(0).valueOf("@type"); // from table - } - - if (hazardNodes.size() != 1 ) { - throw new IllegalArgumentException("Please check hazard name"); - } - - String colorStr = hazardNodes.get(0).valueOf("@" + gfaType ); - - RGB rgb = definedColors.get(colorStr); - - return rgb; - } - - /** - * Returns the default line width for the forecast hour. - * - * @param fcstHr - * @return - */ - public static int getLineWidth(String fcstHr) { - String xPath = FCSTHR_XPATH + "[@name='" + fcstHr + "']"; - List fcsthrNodes = selectNodes(xPath); - - int lineWidth = GFA_OTHER_LINEWIDTH; - if ( fcsthrNodes.size() > 0 ) { - lineWidth = Integer.parseInt( fcsthrNodes.get(0).valueOf("@linewidth") ); - } - else { - if ( fcstHr.indexOf("-") >= 0 ) { - String second= fcstHr.split("-")[1]; - String hour = second.split(":")[0]; - if( Integer.parseInt(hour) <= 6 ) { - lineWidth = GFA_SMEAR_LINEWIDTH; - } else { - lineWidth = GFA_OUTLOOK_LINEWIDTH; - } - } - - } + public enum HazardCategory { + SIERRA, TANGO, ZULU, NONE; + } - return lineWidth; - } - - public static boolean isFormat(String hazard){ - if (definedColors == null) { - loadColors(); - } - - String xPath = HAZARD_XPATH + "[@name='" + hazard + "']"; - List hazardNodes = selectNodes(xPath); - if (hazardNodes.size() != 1) { - throw new IllegalArgumentException("Please check hazard name"); - } - String format = hazardNodes.get(0).valueOf("@format"); - return !"false".equals(format); - } + /** + * State orders in each FA area. + */ + private static HashMap> stateOrderByArea; - private static HashMap getHazardCategories() { - if(hazardCategories == null) { - hazardCategories = new HashMap(); - List nodes = selectNodes(HAZARD_XPATH); - for(Node n: nodes){ - String key = n.valueOf("@name"); - String category = n.valueOf("@category"); - HazardCategory cat = HazardCategory.valueOf(HazardCategory.class, category); - if(cat == null) cat = HazardCategory.NONE; - hazardCategories.put(key, cat); - } - } - return hazardCategories; - } - - public static HazardCategory getHazardCategory(String hazard){ - return getHazardCategories().get(hazard); - } - - public static double getGfaOtlkgenRatio(){ - List nodes = selectNodes(GFA_OTLKGEN_RATIO_XPATH); - Node n = nodes.get(0); - String rationStr = n.getStringValue(); - return Double.parseDouble(rationStr); - } + /** + * Pairs like ("red", new RGB(255, 0, 0)) read from gfa.xml + */ + private static HashMap fzlvlSfcColors; + + /** + * Getter for the document. + * + * @return + */ + public static Document getDocument() { + if (doc == null) { + readOptions(); + } + return doc; + } + + /** + * Read the menu configuration from gfa.xml file + */ + private static void readOptions() { + File gfainfoFile = PgenStaticDataProvider.getProvider().getStaticFile( + PgenStaticDataProvider.getProvider().getPgenLocalizationRoot() + + "gfa.xml"); + + try { + SAXReader reader = new SAXReader(); + doc = reader.read(gfainfoFile.getAbsoluteFile()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /* + * This method is just to suppress warning + */ + @SuppressWarnings("unchecked") + public static List selectNodes(String xPath) { + return (List) GfaInfo.getDocument().selectNodes(xPath); + } + + /** + * Creates an rgb map for hazard types and returns the corresponding color. + * + * @param hazard + * @return + */ + public static RGB getRGB(String hazard, int fcstHrIndex) { + if (rgbMap == null) { + loadColors(); + } + + if (fcstHrIndex < 0 || fcstHrIndex >= rgbMap.get(hazard).length) { + // take last as default if parameter is out of range (fcstHr=Other) + fcstHrIndex = rgbMap.get(hazard).length - 1; + } + + return rgbMap.get(hazard)[fcstHrIndex]; + } + + /** + * Load colors. + */ + private static void loadColors() { + List colorNodes = selectNodes("/root/color/value"); + + definedColors = new HashMap(); + for (Node n : colorNodes) { + int r = Integer.parseInt(n.valueOf("@r")); + int g = Integer.parseInt(n.valueOf("@g")); + int b = Integer.parseInt(n.valueOf("@b")); + // for example, <"red", (255,0,0)> + definedColors.put(n.valueOf("@name"), new RGB(r, g, b)); + } + + List hazardNodes = selectNodes(HAZARD_XPATH); + List fcstHrNodes = selectNodes(FCSTHR_XPATH); + + // hazard type vs. color array (index means the same as the position + // in fcstHr combo box) + rgbMap = new HashMap(); + + for (Node n : hazardNodes) { + RGB[] colors = new RGB[fcstHrNodes.size()]; + int i = 0; + for (Node f : fcstHrNodes) { + String type = f.valueOf("@type"); // for example, "smear" + String colorStr = n.valueOf("@" + type); // for example, + // "blue" + colors[i++] = definedColors.get(colorStr); + } + rgbMap.put(n.valueOf("@name"), colors); + } + } + + /** + * Returns the default colors for the hazard and forecast hour pair. + * + * @param hazard + * @param fcstHr + * @return Color[] + */ + public static Color[] getDefaultColors(String hazard, String fcstHr) { + RGB rgb = getDefaultRGB(hazard, fcstHr); + + Color color = new Color(rgb.red, rgb.green, rgb.blue); + return new Color[] { color, color }; + } + + /** + * Returns the default color's RGB for the hazard and forecast hour pair. + * + * @param hazard + * @param fcstHr + * @return RGB + */ + public static RGB getDefaultRGB(String hazard, String fcstHr) { + if (definedColors == null) { + loadColors(); + } + + String xPath = HAZARD_XPATH + "[@name='" + hazard + "']"; + List hazardNodes = selectNodes(xPath); + + xPath = FCSTHR_XPATH + "[@name='" + fcstHr + "']"; + List fcsthrNodes = selectNodes(xPath); + + if (fcsthrNodes.size() != 1) { + try { + if (fcstHr.indexOf("-") == -1) { // snapshot + xPath = FCSTHR_XPATH + "[@name='0 Z']"; + } else { + String second = fcstHr.split("-")[1]; + String hour = second.split(":")[0]; + if (Integer.parseInt(hour) <= 6) { // smear + xPath = FCSTHR_XPATH + "[@name='0-6']"; + } else { // outlook + xPath = FCSTHR_XPATH + "[@name='6-9']"; + } + } + } catch (Exception e) { + xPath = FCSTHR_XPATH + "[@name='Other']"; + } + fcsthrNodes = selectNodes(xPath); + } + + String gfaType = GFA_SNAPSHOT; + if (fcsthrNodes.size() != 1) { // hard-coded + if (fcstHr.indexOf("-") >= 0) { + String second = fcstHr.split("-")[1]; + String hour = second.split(":")[0]; + if (Integer.parseInt(hour) <= 6) { + gfaType = GFA_SMEAR; + } else { + gfaType = GFA_OUTLOOK; + } + } + } else { + gfaType = fcsthrNodes.get(0).valueOf("@type"); // from table + } + + if (hazardNodes.size() != 1) { + throw new IllegalArgumentException("Please check hazard name"); + } + + String colorStr = hazardNodes.get(0).valueOf("@" + gfaType); + + RGB rgb = definedColors.get(colorStr); + + return rgb; + } + + /** + * Returns the default line width for the forecast hour. + * + * @param fcstHr + * @return + */ + public static int getLineWidth(String fcstHr) { + String xPath = FCSTHR_XPATH + "[@name='" + fcstHr + "']"; + List fcsthrNodes = selectNodes(xPath); + + int lineWidth = GFA_OTHER_LINEWIDTH; + if (fcsthrNodes.size() > 0) { + lineWidth = Integer.parseInt(fcsthrNodes.get(0).valueOf( + "@linewidth")); + } else { + if (fcstHr.indexOf("-") >= 0) { + String second = fcstHr.split("-")[1]; + String hour = second.split(":")[0]; + if (Integer.parseInt(hour) <= 6) { + lineWidth = GFA_SMEAR_LINEWIDTH; + } else { + lineWidth = GFA_OUTLOOK_LINEWIDTH; + } + } + + } + + return lineWidth; + } + + public static boolean isFormat(String hazard) { + if (definedColors == null) { + loadColors(); + } + + String xPath = HAZARD_XPATH + "[@name='" + hazard + "']"; + List hazardNodes = selectNodes(xPath); + if (hazardNodes.size() != 1) { + throw new IllegalArgumentException("Please check hazard name"); + } + String format = hazardNodes.get(0).valueOf("@format"); + return !"false".equals(format); + } + + private static HashMap getHazardCategories() { + if (hazardCategories == null) { + hazardCategories = new HashMap(); + List nodes = selectNodes(HAZARD_XPATH); + for (Node n : nodes) { + String key = n.valueOf("@name"); + String category = n.valueOf("@category"); + HazardCategory cat = HazardCategory.valueOf( + HazardCategory.class, category); + if (cat == null) + cat = HazardCategory.NONE; + hazardCategories.put(key, cat); + } + } + return hazardCategories; + } + + public static HazardCategory getHazardCategory(String hazard) { + return getHazardCategories().get(hazard); + } + + public static double getGfaOtlkgenRatio() { + List nodes = selectNodes(GFA_OTLKGEN_RATIO_XPATH); + Node n = nodes.get(0); + String rationStr = n.getStringValue(); + return Double.parseDouble(rationStr); + } /** * Return the fixed ordered state list in each FA area. */ - public static HashMap > getStateOrderByArea() { - - if ( stateOrderByArea == null ) { - stateOrderByArea = new HashMap >(); - ArrayList bos = new ArrayList(); - String[] bosStr = new String[]{"ME","NH","VT","MA","RI","CT","NY", - "LO","PA","NJ","OH","LE","WV","MD", - "DC", "DE", "VA", "CSTL WTRS"}; - for ( String st : bosStr ) { - bos.add( st ); - } - stateOrderByArea.put( BOS, bos); - - ArrayList mia = new ArrayList(); - String[] miaStr = new String[]{"NC", "SC", "GA", "FL" , "CSTL WTRS"}; - for ( String st : miaStr ) { - mia.add( st ); - } - stateOrderByArea.put( MIA, mia ); + public static HashMap> getStateOrderByArea() { - ArrayList chi = new ArrayList(); - String[] chiStr = new String[]{"ND", "SD", "NE", "KS", "MN", "IA", - "MO", "WI", "LM", "LS", "MI", "LH", - "IL", "IN", "KY"}; - for ( String st : chiStr ) { - chi.add( st ); - } - stateOrderByArea.put( CHI, chi ); + if (stateOrderByArea == null) { + stateOrderByArea = new HashMap>(); + ArrayList bos = new ArrayList(); + String[] bosStr = new String[] { "ME", "NH", "VT", "MA", "RI", + "CT", "NY", "LO", "NJ", "PA", "OH", "LE", "WV", "MD", "DC", + "DE", "VA", "CSTL WTRS" }; + for (String st : bosStr) { + bos.add(st); + } + stateOrderByArea.put(BOS, bos); - ArrayList dfw = new ArrayList(); - String[] dfwStr = new String[]{"OK", "TX", "AR", "TN", "LA", "MS", - "AL", "CSTL WTRS"}; - for ( String st : dfwStr ) { - dfw.add( st ); - } - stateOrderByArea.put( DFW, dfw ); - - ArrayList slc = new ArrayList(); - String[] slcStr = new String[]{"ID", "MT", "WY", "NV", "UT", "CO", - "AZ", "NM"} ; - for ( String st : slcStr ) { - slc.add( st ); - } - stateOrderByArea.put( SLC, slc ); - - ArrayList sfo = new ArrayList(); - String[] sfoStr = new String[]{"WA", "OR", "CA", "CSTL WTRS"}; - for ( String st : sfoStr ) { - sfo.add( st ); - } - stateOrderByArea.put( SFO, sfo ); - - } - - return stateOrderByArea; - } - - /** - * Get colors for FZLVL SFC snapshot, smear, or outlook. - * Default is "sky". - */ - public static RGB getFzlvlSfcColor( String name ) { + ArrayList mia = new ArrayList(); + String[] miaStr = new String[] { "NC", "SC", "GA", "FL", + "CSTL WTRS" }; + for (String st : miaStr) { + mia.add(st); + } + stateOrderByArea.put(MIA, mia); - if ( definedColors == null ) { - loadColors(); - } - - List colorNodes = selectNodes("/root/fzlvlSFC/value"); - - if ( fzlvlSfcColors == null ) { - fzlvlSfcColors = new HashMap(); - for ( Node nd : colorNodes ) { - fzlvlSfcColors.put( nd.valueOf("@name"), definedColors.get( nd.valueOf("@nmapcolor") ) ); - } - } - - RGB clr = fzlvlSfcColors.get( name ); - - if ( clr == null ) clr = definedColors.get( "sky" ); - - return clr; + ArrayList chi = new ArrayList(); + String[] chiStr = new String[] { "ND", "SD", "NE", "KS", "MN", + "IA", "MO", "WI", "LM", "LS", "MI", "LH", "IL", "IN", "KY" }; + for (String st : chiStr) { + chi.add(st); + } + stateOrderByArea.put(CHI, chi); + + ArrayList dfw = new ArrayList(); + String[] dfwStr = new String[] { "OK", "TX", "AR", "TN", "LA", + "MS", "AL", "CSTL WTRS" }; + for (String st : dfwStr) { + dfw.add(st); + } + stateOrderByArea.put(DFW, dfw); + + ArrayList slc = new ArrayList(); + String[] slcStr = new String[] { "ID", "MT", "WY", "NV", "UT", + "CO", "AZ", "NM" }; + for (String st : slcStr) { + slc.add(st); + } + stateOrderByArea.put(SLC, slc); + + ArrayList sfo = new ArrayList(); + String[] sfoStr = new String[] { "WA", "OR", "CA", "CSTL WTRS" }; + for (String st : sfoStr) { + sfo.add(st); + } + stateOrderByArea.put(SFO, sfo); + + } + + return stateOrderByArea; + } + + /** + * Get colors for FZLVL SFC snapshot, smear, or outlook. Default is "sky". + */ + public static RGB getFzlvlSfcColor(String name) { + + if (definedColors == null) { + loadColors(); + } + + List colorNodes = selectNodes("/root/fzlvlSFC/value"); + + if (fzlvlSfcColors == null) { + fzlvlSfcColors = new HashMap(); + for (Node nd : colorNodes) { + fzlvlSfcColors.put(nd.valueOf("@name"), + definedColors.get(nd.valueOf("@nmapcolor"))); + } + } + + RGB clr = fzlvlSfcColors.get(name); + + if (clr == null) + clr = definedColors.get("sky"); + + return clr; + + } - } - } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaRules.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaRules.java index e1640eac65..e79b4aa90a 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaRules.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/gfa/GfaRules.java @@ -7,7 +7,18 @@ */ package gov.noaa.nws.ncep.ui.pgen.gfa; -import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.*; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.BOS; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.CHI; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.DFW; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.DVLPG_HR; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.ENDG_HR; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.ISSUE_TIME; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.MIA; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.OUTLOOK_END_TIME; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.SFO; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.SLC; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.SNAPSHOT_TYPE; +import static gov.noaa.nws.ncep.ui.pgen.gfa.Gfa.UNTIL_TIME; import static gov.noaa.nws.ncep.ui.pgen.tools.PgenCycleTool.pad; import static java.lang.Math.abs; import static java.lang.Math.ceil; @@ -23,14 +34,11 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.TreeSet; -//import org.apache.log4j.Logger; - import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; - /** * GFA rules functionality. * @@ -61,1591 +69,1649 @@ import com.vividsolutions.jts.geom.Polygon; */ public class GfaRules { + public static final String WORDING = "WORDING"; - public static final String WORDING = "WORDING"; + /** Area limit in square nautical miles */ + public static final double AREA_LIMIT = 3000.0; - /** Logger */ -// private final static Logger logger = Logger.getLogger(GfaRules.class); + /** Tolerance for coordinates to be treated as the same /close points. */ + private static final double PRECISION = 0.000000001; - /** Area limit in square nautical miles */ - public static final double AREA_LIMIT = 3000.0; + public enum SnapshotType { + /* Snapshot intersects FROM/BOUNDED BY line. */ + X, + /* Snapshot does not intersect FROM/BOUNDED BY line. */ + O + }; - /** Tolerance for coordinates to be treated as the same /close points. */ - private static final double PRECISION = 0.000000001; + /** XPATH for states in document */ + public static String MTOBSC_XPATH = "/MT_OBSC"; - - public enum SnapshotType { - /* Snapshot intersects FROM/BOUNDED BY line. */ - X, - /* Snapshot does not intersect FROM/BOUNDED BY line. */ - O - }; - - /** XPATH for states in document */ - public static String MTOBSC_XPATH = "/MT_OBSC"; - - - /** - * Applies all the rules one by one by calling the corresponding method of this class. - * - * @param smear Original smear before clipped - Airmet or Outlook - * @param list List of GFAs from clipping - * @param snapshots List of original snapshots which were used to create the smear - */ - public static void applyRules( Gfa smear, ArrayList clipped, ArrayList snapshots ) { - - /* - * Pass GFA format structures through area rules to set up area/adjarea info. - */ - areaRules( smear, clipped, snapshots ); - - /* - * Removes outlooks which cover only "6"-hour snapshots. - */ - removeOutlooks( clipped, snapshots ); + /** + * Applies all the rules one by one by calling the corresponding method of + * this class. + * + * @param smear + * Original smear before clipped - Airmet or Outlook + * @param list + * List of GFAs from clipping + * @param snapshots + * List of original snapshots which were used to create the smear + */ + public static void applyRules(Gfa smear, ArrayList clipped, + ArrayList snapshots) { - /* - * Reduce points to desired threshold set in prefs.tbl. Check the flag - * before doing the above. - */ - GfaReducePoint.getInstance().reducePoints( clipped, snapshots ); - - /* - * Set wording, area, region, and state list for each format structure. - */ - setWording( clipped, snapshots ); - - } - - /** - * This routine clips the GFA smears against two FA areas in a FA region (the input GFA - * smear is assumed to have been clipped against FA regions) and checks the size of the - * clipped parts in each FA area to determine the primary area and the possible adjacent - * area they belong to, if the smear intersects both FA areas with an area >= 3K square - * nautical miles. - * - * @param original Original smear before clipped - Airmet or Outlook - * @param clippedList List of GFAs from clipping - * @param clippedList List of original snapshots - */ - private static void areaRules( Gfa original, ArrayList clippedList, - ArrayList snapshots ) { - - /* - * Toss out all freezing level contours. The area rules are - * applied to them within af_fzlvl2fmt(). - */ - if ( original.getGfaHazard().equals( "FZLVL") ) { - return; - } - - /* - * Clipped against FA areas to update area info - */ - for ( Gfa g : clippedList ) { - findGfaAreaInGrid( g, snapshots ); - } - - } - - /** - * Removes outlooks which cover only "6"-hour snapshots. - * - * @param original - * @param list - */ - private static void removeOutlooks(ArrayList clipped, ArrayList original) { - - ArrayList toRemove = new ArrayList(); - for(Gfa g: clipped) { - if (!g.isOutlook()) continue; - boolean intersectsWithAtLeastOneOriginal = false; - for(Gfa o : original) { - if("6".equals(o.getGfaFcstHr())) continue; // ignore 6 (see tests 49-50) - // if g covers o, leave it - Polygon gP = GfaClip.getInstance().gfaToPolygonInGrid(g); - Polygon oP = GfaClip.getInstance().gfaToPolygonInGrid(o); - Geometry intersection = gP.intersection(oP); - if (intersection instanceof Polygon || intersection instanceof MultiPolygon) { - intersectsWithAtLeastOneOriginal = true; - } - } - if(!intersectsWithAtLeastOneOriginal) toRemove.add(g); - } - clipped.removeAll(toRemove); - } - - - /** - * Compares two Coordinate objects by comparing x and y coordinates. If the coordinates are - * close within a precision, returns true, otherwise false. - * - * @param c1 - * - * @param c2 - * - * @return true is c1 and c2 are very close, false otherwise - */ - public static boolean compareCoordinates(Coordinate c1, Coordinate c2) { - if (abs(c1.x - c2.x) < PRECISION && abs(c1.y - c2.y) < PRECISION) { - return true; - } - return false; - } - - /** - * This routine sets the beginning/ending wording, area, region, and state list for all VALID - * GFA format structures. Invalid structures are marked "delete", including those polygons - * having less than 3 points (closed) or 2 points (open), and those having no state list. - * Outlooks for LLWS, M_FZLVLS, and FZLVL are deleted as well. - * - * @param clipped - * @param originalSS - */ - private static void setWording(ArrayList clipped, ArrayList originalSS ) { - - ArrayList checkStates= new ArrayList(); - for ( Gfa smear : clipped ) { - - // Create state list - updateGfaStates( smear ); - - // If state is empty, remove this Gfa! - String stList = smear.getGfaStates(); - if ( stList != null && stList.trim().length() > 1 ) { - checkStates.add( smear ); - } - - } - - /* - * Now do conditional wording. - */ - ArrayList invalidOtlk = new ArrayList(); - for ( Gfa smear : checkStates ) { - - /* see corresponding method af_getSSAttr in the legacy code - * /nawips/gempak/source/textlib/airmet/afutils.c * - * / - - /* - * Find the type of each snapshot and assign to SNAPSHOT_TYPE attribute. - * - * X_SNAPSHOTS - SS intersects with the clipped polygon with an area > 3K. - * O_SNAPSHOTS - SS do not intersect with the clipped polygon - */ - assignXorO( originalSS, smear ); - - /* - * Retrieve each snapshot's forecast time. - * - * Round UP - X_SNAPSHOTS for development wording or O_SNAPSHOTS for ending wording - * Round Down - X_SNAPSHOTS for ending wording or O_SNAPSHOTS for development wording - */ - assignSSForecastTime( originalSS ); - - assignIssueTime( smear ); - - /* - * Assign "airmetTag". - */ - assignAirmetTag( smear ); - - /* - * Do wording - */ - GfaWording wording = new GfaWording(); - - // wording. - wording.fromCondsDvlpg = fromCondsDvlpg( smear, originalSS ); - - // wording. - wording.fromCondsEndg = fromCondsEndg( smear, originalSS ); - - int[] olkSeq = findOtlkSeq(originalSS); - - // GEN_OLK wording - wording.genOlk = otlkGenWording( originalSS, olkSeq ); - if("MAYBE".equals( wording.genOlk ) ) { - wording.genOlk = processMAYBE( smear, originalSS ); - } - - /* - * Outlooks should be removed if "genOlk" is "NO". - */ - if ( smear.isOutlook() && !("YES".equalsIgnoreCase(wording.genOlk)) ) { - invalidOtlk.add( smear ); - } - - // OTLK CONDS CONTG BYD wording - // since "smear" element can be either Smear or Outlook, we need an if statement - if (smear.isAirmet()) { // not for outlooks - wording.condsContg = contgBydWording( originalSS, olkSeq, smear ); - } - - // OTLK CONDS DVLPG wording - if ("YES".equalsIgnoreCase(wording.genOlk)) { - wording.otlkCondsDvlpg = otlkDvlpgWording( originalSS, olkSeq ); - } - - // OTLK CONDS ENDG wording - if ("YES".equalsIgnoreCase(wording.genOlk)) { - wording.otlkCondsEndg = otlkEndgWording( originalSS, olkSeq ); - } - smear.addAttribute( WORDING, wording ); - -// logger.trace( smear.toString() ); -// logger.debug( "\n" + wording ); - - // create beginning and ending - parseWording( smear, wording ); - - clearAttributes( originalSS ); - - } - - // Return valid Gfa - those with at least one state in it and outlooks with GenOlk is "YES" - clipped.clear(); - if ( invalidOtlk.size() > 0 ) checkStates.removeAll( invalidOtlk ); - clipped.addAll( checkStates ); - } - - - /** - * Generate the state list for a smear. - * - * Note: 1. The state list is not sorted. - * 2. If a smear has two FA areas, the state list is generated but not - * in final order (states in primary FA area precede states in adjacent - * area). This will be done in GfaGeneate.java instead. - * Warning: the validity check of the state bounds should be done when pre-loading - * them (if necessary), not here - since geometry().isValid() is a quite - * expensive call. - * - * @param smear - */ - private static void updateGfaStates( Gfa smear ) { - - HashMap states = GfaClip.getInstance().getStateBoundsInGrid(); - HashMap greatLakes = GfaClip.getInstance().getGreatLakesBoundsInGrid(); - HashMap coastalWater = GfaClip.getInstance().getCoastalWaterBoundsInGrid(); - LinkedHashMap stateMaps = new LinkedHashMap(); // keep insertion order - stateMaps.putAll( states ); - - /* - * Find all states that touches the smear. - * - * If this is a MT_OBSC, only those MT_OBSC states will be - * tested and added to the state list. - * - */ - List mtobscsts = GfaClip.getInstance().getMtObscStates(); - Polygon smearP = GfaClip.getInstance().gfaToPolygonInGrid( smear ); - boolean is_MTOBSC = false; - if ( smear.getGfaHazard().equalsIgnoreCase( "MT_OBSC" ) ) { - is_MTOBSC = true; - } - - int nState = 0; - for ( String key : stateMaps.keySet() ) { - Geometry g = stateMaps.get( key) ; - - if ( is_MTOBSC && !mtobscsts.contains( key ) ) continue; - - if ( smearP.intersects( g ) ) { - nState++; - updateGfaStatesField( smear, key ); - } - - } - - - /** - * Check for the airmet over Great Lakes and coastal waters. - * - * If the state to which those waters belong is not already - * in the stList, then add it. - * - * MT_OBSC hazards can never include any Great Lakes & coastal waters. - */ - int nWaters = 0; - if ( !is_MTOBSC ) { - - for ( String key : greatLakes.keySet() ) { - Geometry g = greatLakes.get( key ); - - if ( !g.intersects( smearP ) ) continue; - updateGfaStatesField( smear, key ); - - } - - for ( String key : coastalWater.keySet() ) { - Geometry g = coastalWater.get( key ); - - if ( !g.intersects( smearP ) ) continue; - - nWaters++; - updateGfaStatesField( smear, key ); - } - - } - - - /** - * If the airmet covers land and water then append "AND CSTL WTRS" - * to the state list. If only water then use just "CSTL WTRS" (no AND). - */ - if ( nWaters > 0 ) { - - StringBuilder s = new StringBuilder ( nvl( smear.getGfaStates() ) ); - - /* - * Note - nState should be states on land, not including states from - * Great Lakes and Coastal Waters. - */ - if ( nState > 0 ) { - s.append( " AND" ); - } - - s.append( " CSTL WTRS" ); - - smear.setGfaStates( s.toString() ); - } - - /* - * Re-order the state list in the specified FA-Area based order. - */ - reorderStateList( smear ); - - } - - - /** - * Updates the states field. - * - * @param gfa - * @param state - * @param polygon - */ - private static boolean updateGfaStatesField( Gfa gfa, String state ) { - boolean added = false; - String s = nvl( gfa.getGfaStates() ); - if( !s.contains( state ) ) { - if ( !s.isEmpty() ) s += " "; - s += state; - gfa.setGfaStates( s ); - added = true; - } - - return added; - } - - - /** - * Find the type of each snapshot and assign to SNAPSHOT_TYPE attribute. - * - *
-	 * X_SNAPSHOTS - SS intersects with the clipped polygon with an area > 3K. 
-	 * O_SNAPSHOTS - SS do not intersect with the clipped polygon
-	 * 
- * - * @param originalSS - * @param smear - */ - private static void assignXorO(ArrayList originalSS, Gfa smear) { -// Polygon smearP = GfaClip.getInstance().gfaToPolygon(smear); - Polygon smearP = GfaClip.getInstance().gfaToPolygonInGrid( smear ); - boolean allOutlook = true; - for(Gfa ss: originalSS){ // snapshots - assignSnapshotType(smearP, ss); - String fcstHr = ss.getGfaFcstHr(); - if(! ("9".equals(fcstHr) || "12".equals(fcstHr)) ) { - allOutlook = false; - } - } - - Gfa first = originalSS.get(0); - ArrayList outlooks = first.getAttribute("OUTLOOKS", ArrayList.class); - - // SMEAR or OUTLOKOS - list of created clipped smears - // OTLK_LIST - original list of outlook gfa elements (6,9,12) - if("6".equals(first.getGfaFcstHr()) && !allOutlook - && outlooks != null) { - // only for smears which have "6" hour snapshots - ArrayList otkl = first.getAttribute("OTLK_LIST", ArrayList.class); - if (otkl == null || otkl.isEmpty()) return; - smearP = findTheSmear(smearP, outlooks); - //smearP = GfaClip.gfaToPolygon((Gfa)otkl.get(0).getAttribute("AIRMETS")); - for(Gfa g: otkl) { - if(g == originalSS.get(0)) continue; - assignSnapshotType(smearP, g); - } - } - } - - /** - *
-	 * X snapshots - SS intersects with the clipped polygon smearP with an area > 3K. 
-	 * O snapshots - SS do not intersect with the clipped polygon
-	 * 
- * - * - * @param smearP Polygon - * @param ss - */ - private static void assignSnapshotType(Polygon smearP, Gfa ss) { - - Polygon ssP = GfaClip.getInstance().gfaToPolygonInGrid(ss); - Geometry intersection = ssP.intersection(smearP); - - ss.addAttribute(SNAPSHOT_TYPE, SnapshotType.O); - - if( PgenUtil.getSphPolyAreaInGrid( intersection ) > AREA_LIMIT) { - ss.addAttribute(SNAPSHOT_TYPE, SnapshotType.X); - } - - } - - private static Polygon findTheSmear(Polygon smearP, ArrayList outlooks) { - for(Gfa g: outlooks) { - - Polygon p = GfaClip.getInstance().gfaToPolygonInGrid(g); - - Geometry intersection = p.intersection(smearP); - - double area = PgenUtil.getSphPolyAreaInGrid ( intersection ); - - if( area > AREA_LIMIT ) { - return p; - } - } - return smearP; - } - - /** - * Retrieve each snapshot's forecast time. - * - *
-	 * Round UP - X_SNAPSHOTS for development wording or O_SNAPSHOTS for ending wording. 
-	 * Round Down - X_SNAPSHOTS for ending wording or O_SNAPSHOTS for development wording
-	 * 
- * - * @param originalSS - */ - private static void assignSSForecastTime(ArrayList originalSS) { - for(Gfa ss: originalSS) { - String fcstHr = ss.getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(nvl(fcstHr)); - ss.addAttribute("HOUR_INT", hm[0]); - ss.addAttribute("MIN_INT", hm[1]); - double hmD = hm[0] + hm[1] / 60.0; - SnapshotType type = ss.getAttribute(SNAPSHOT_TYPE, SnapshotType.class); - if(type == SnapshotType.X){ - ss.addAttribute(DVLPG_HR, (int)ceil(hmD)); - ss.addAttribute(ENDG_HR, (int)floor(hmD)); - } else if (type == SnapshotType.O){ - ss.addAttribute(DVLPG_HR, (int)floor(hmD)); - ss.addAttribute(ENDG_HR, (int)ceil(hmD)); - } else { - // sanity check - should never reach this place - // check asssignXorO if this happens - String err = "Snapshot type must be assigned by this time"; -// logger.error(err); - throw new IllegalArgumentException(err); - } - } - } - - /** - * Assigns issue time to the smear. - * - * @param smear - */ - static void assignIssueTime(Gfa smear) { - /* - * First determine if the standard issue time should be overridden. An issue time is - * overridden if any of the hazards (smears) are of an issuance type that is CAN, COR, NEW, - * or AMD. - */ - boolean overrideIssueTime = !"NRML".equalsIgnoreCase(smear.getGfaIssueType()); - - Calendar localTimeCal = Calendar.getInstance(); - - String timeStr = AirmetCycleInfo.getIssueTime(); - Calendar issueTimeCal = Calendar.getInstance(); - int hour = Integer.parseInt(timeStr.substring(0, 2)); - int min = Integer.parseInt(timeStr.substring(2)); - issueTimeCal.set(Calendar.HOUR_OF_DAY, hour); - issueTimeCal.set(Calendar.MINUTE, min); - issueTimeCal.set(Calendar.SECOND, 0); - - if (overrideIssueTime) { - // Compare the local time to the issue time if overrideIssueTm flag is TRUE. - if (issueTimeCal.before(localTimeCal)) { - issueTimeCal = localTimeCal; - } else { - // set issue time = issue time + 1 min - issueTimeCal.add(Calendar.MINUTE, 1); - } - } - - smear.addAttribute(ISSUE_TIME, issueTimeCal); - - Calendar untilTimeCal = AirmetCycleInfo.getUntilTime(); - smear.addAttribute(UNTIL_TIME, untilTimeCal ); - - Calendar otlkEndTime = Calendar.getInstance(); - otlkEndTime.set(Calendar.DAY_OF_MONTH, untilTimeCal.get(Calendar.DAY_OF_MONTH)); - otlkEndTime.set(Calendar.HOUR_OF_DAY, untilTimeCal.get(Calendar.HOUR_OF_DAY) + 6 ); - otlkEndTime.set(Calendar.MINUTE, untilTimeCal.get(Calendar.MINUTE) ); - otlkEndTime.set(Calendar.SECOND, untilTimeCal.get(Calendar.SECOND) ); - - smear.addAttribute( OUTLOOK_END_TIME, otlkEndTime ); - - } - - /** - * Generates "" wording. - * - * @param smear - * @param originalSS - * @return - */ - private static String fromCondsDvlpg(Gfa smear, ArrayList originalSS) { - - int endHour = 6; - /* - * from the legacy system (af_condsWording method in source/textlib/airmet/afconditions.c): - * - * Wording rules: - * If the first ss in the sequence is an 'X_SNAPSHOTS' { - * If the first ss time is 00, there is no wording. - * If the first ss time is 03 or less, wording is "+00-+TTZ", - * where 'TT' is the ss time. - * If the first ss time is 06 or less (on-time cycles only), - * wording is "+03-+TTZ", where 'TT' is the ss time. - * } - * - * If the first ss is an 'O_SNAPSHOTS' { - * Scan the sequence forward from the first ss to find the - * last 'O' before encountering an 'X' ss. - * The wording is "AFT +TTZ" where 'TT' is this 'O' ss time. - * } - */ - String wording = ""; - int xx = 0; - int yy = 0; - Gfa ss = originalSS.get(0); - int dvlpgHr = ss.getAttribute(DVLPG_HR, Integer.class); - if (ss.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - if (dvlpgHr == 0) { - // no wording - } else if (dvlpgHr <= 3) { - wording = "CONDS DVLPG +00-+" + pad(dvlpgHr) + "Z"; - yy = dvlpgHr; - } else if (dvlpgHr <= 6) { - wording = "CONDS DVLPG +03-+" + pad(dvlpgHr) + "Z"; - xx = 3; - yy = dvlpgHr; - } - } else { - int lastO = 0; - for (int i = 1; i < originalSS.size(); i++) { - Gfa g = originalSS.get(i); - dvlpgHr = ss.getAttribute(DVLPG_HR, Integer.class); - if (g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X && dvlpgHr <= endHour) { - lastO = i - 1; - break; - } - } - dvlpgHr = originalSS.get(lastO).getAttribute(DVLPG_HR, Integer.class); - wording = "CONDS DVLPG AFT +" + pad(dvlpgHr) + "Z"; - xx = dvlpgHr; - yy = -1; - } - - if(!PgenCycleTool.isRoutine() && !wording.isEmpty() && xx >= 0 && yy >= 0) { - - Calendar cal = smear.getAttribute(ISSUE_TIME, Calendar.class); - int issueHrMin = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE); - - int basetime = PgenCycleTool.getCycleHour(); - - if ((yy + basetime) * 100 <= issueHrMin) { /* yy in past */ - wording = ""; - } else { /* yy in future */ - if ((xx + basetime) * 100 <= issueHrMin) {/* xx in past */ - wording = "CONDS DVLPG BY +" + pad(yy) + "Z"; // BY +23Z - } else { - wording = "CONDS DVLPG +" + pad(xx) + "-+" + pad(yy) + "Z"; // +03-+06Z - } - } - } - - return wording; - } - - /** - * Generates "" wording. - * - * @param smear - * @param originalSS - * @return - */ - private static String fromCondsEndg(Gfa smear, ArrayList originalSS) { - - int endHour = 6; - /* - * from the legacy system (af_fromEndgWording) - * - * Wording Rules: - * - * If last ss in the sequence is an 'X_SNAPSHOTS' { - * If the last ss time is the last possible time (06 for on-time cycles - * or 03 for off-time cycles), wording is determined by the outlook - * component snapshots rules. See the 'Outlook BOUNDED BY lines' - * section below for "CONDS CONTG BYD +06Z" wording - * (or "CONDS CONTG BYD +03Z" for cycles 00, 06, 12 and 18). - * If the last ss time is less than 03, wording is "+TT-+03Z", - * where 'TT' is the ss time. - * If the last ss time is less than 06 (on-time cycles only), - * wording is "+TT-+06Z", where 'TT' is the ss time. - * } - * - * If last ss is an 'O_SNAPSHOT' { - * Scan the sequence backward from the last ss to find the first 'O' - * after encountering an 'X' ss. The wording is "BY +TTZ" where 'TT' - * is this 'O' ss time. - * } - * - */ - String wording = ""; - int xx = -1; - int yy = -1; - int lastSSIndex = originalSS.size() - 1; - for (int i = originalSS.size() - 1; i >= 0; i--) { - lastSSIndex = i; - int hr = originalSS.get(lastSSIndex).getAttribute(ENDG_HR, Integer.class); - if(hr <= endHour) break; - } - Gfa lastSS = originalSS.get(lastSSIndex); - int lastEndgHr = lastSS.getAttribute(ENDG_HR, Integer.class); - String lastFcstHr = lastSS.getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(lastFcstHr); - - if (lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - - if(hm[0] == endHour && hm[1] == 0) { - /* Handled separately by af_contgBydWording() */ - } else if(lastEndgHr < 3){ - // sprintf(wording, "CONDS ENDG +0%d-+03Z", last_ss_hr) - wording = "CONDS ENDG +" + pad(lastEndgHr) + "-+03Z"; - xx = lastEndgHr; - yy=3; - } else if (lastEndgHr <= 6) { - // sprintf(wording, "CONDS ENDG +0%d-+06Z", last_ss_hr); - wording = "CONDS ENDG +" + pad(lastEndgHr) + "-+06Z"; - xx = lastEndgHr; - yy = 6; - } - } else { - int firstO = lastSSIndex; - - ArrayList otlkList = lastSS.getAttribute("OTLK_LIST", ArrayList.class); - if("6".equals(originalSS.get(originalSS.size()-1).getGfaFcstHr()) && otlkList != null) { - lastSSIndex = otlkList.size()-1; - lastSS = otlkList.get(lastSSIndex); - for (int jj = otlkList.size() - 2; jj >= 0; jj--) { - lastSS = otlkList.get(jj); - if(lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - firstO = jj + 1; - break; - } - } - lastEndgHr = Integer.parseInt(otlkList.get(firstO).getGfaFcstHr()); - } else { - for (int jj = lastSSIndex-1; jj >= 0; jj--) { - lastSS = originalSS.get(jj); - if(lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - firstO = jj + 1; - break; - } - } - lastEndgHr = originalSS.get(firstO).getAttribute(ENDG_HR, Integer.class); - } - wording = "CONDS ENDG BY +" + pad(lastEndgHr) + "Z"; - } - - - if (!PgenCycleTool.isRoutine() && !wording.isEmpty() && xx >= 0 && yy >= 0) { - - Calendar cal = smear.getAttribute(ISSUE_TIME, Calendar.class); - int issueHrMin = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE); - - int basetime = PgenCycleTool.getCycleHour(); - - if ((yy + basetime) * 100 <= issueHrMin) { /* yy in past */ - wording = "CONDS HV ENDED"; - } else { /* yy in future */ - if ((xx + basetime) * 100 <= issueHrMin) {/* xx in past */ - wording = "CONDS ENDG BY +" + pad(yy) + "Z"; // BY +23Z - } else { - wording = "CONDS ENDG +" + pad(xx) + "-+" + pad(yy) + "Z"; // +03-+06Z - } - } - } - - return wording; - } - - private static int[] findOtlkSeq(ArrayList originalSS) { - int startHour = 6; // ontime - - int[] olkSeq = new int[3]; - for(int i=0; i<3; i++) { - olkSeq[i] = -1; - } - - for(int ii=0; ii< originalSS.size(); ii++) { - String fcstHr = originalSS.get(ii).getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(nvl(fcstHr)); - if (hm[1] != 0) continue; - - if (hm[0] == startHour) { - olkSeq[0] = ii; - } else if (hm[0] == (startHour + 3)) { - olkSeq[1] = ii; - } else if (hm[0] == (startHour + 6)) { - olkSeq[2] = ii; - } - } - return olkSeq; - } - - /** - * Generates wording - * - * @param smear - * @param originalSS - * @return - */ - private static String otlkGenWording(ArrayList originalSS, int[] olkSeq) { -// af_otlkGenWording(ss_attr, olk_seq, tmpstr); - - /* - * Wording Rules: - * Assume there is at least one SS in the sequence. - * 1SS - 06 ss (03 for off-time cycles) - * 2SS - 09 ss (06 for off-time cycles) - * 3SS - 12 ss (09 for off-time cycles) - * - * If 1SS does not exist or exists as an O_SNAPSHOTS { - * is "YES" - * } - * - * If both 1SS and 2SS exist as X_SNAPSHOTSs { - * is "MAYBE" - * } - * - * If 1SS & 3SS exist X_SNAPSHOTSs { - * is "MAYBE" (X-O-X case and X---X case) - * } - * - * All other cases - is "NO" - */ - - String genOlk = "NO"; - if (olkSeq[0] >= 0 || olkSeq[1] >= 0 || olkSeq[2] >= 0) { - if (olkSeq[0] < 0 - || (olkSeq[0] >= 0 && originalSS.get(olkSeq[0]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.O)) { - genOlk = "YES"; - } else if ((olkSeq[1] >= 0 && originalSS.get(olkSeq[1]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) || - (olkSeq[2] >= 0 && originalSS.get(olkSeq[2]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X)) { - genOlk = "MAYBE"; - } - } - - return genOlk; - } - - private static String processMAYBE(Gfa outlook, ArrayList originalSS) { - // corresponds to afconditions.af_processMAYBE - - Polygon outlookP = GfaClip.getInstance().gfaToPolygon(outlook); - HashMap states = GfaClip.getInstance().getStateBounds(); - - Gfa g6 = null; - for(Gfa g: originalSS) { - updateGfaStates(g); - if("6".equals(g.getGfaFcstHr())) g6 = g; - } - - // smears list is not null here, because MAYBE can only be called - // for outlooks containing "6" and "9" hour snapshots. - // and at least one "6-6" airmet exists, g6 is not be null - ArrayList airmets = g6.getAttribute("AIRMETS", ArrayList.class); // from 0 to 6 hours - - // loop through airmets and find the one which overlaps with the outlook we process - // then the overlapping one is the one we will use to apply rules. - TreeSet statesInAirmet = new TreeSet(); - Gfa airmet = null; - for(Gfa g: airmets){ - Polygon gP = GfaClip.getInstance().gfaToPolygon(g); - Geometry intersection = outlookP.intersection(gP); - if (intersection instanceof Polygon || intersection instanceof MultiPolygon) { - // states - String [] statesArray = nvl(g.getGfaStates()).split(" "); - for(String s: statesArray) { - statesInAirmet.add(s.trim()); - } - airmet = g; - break; - } - } - - /* - * Rule 1: For states in the outlook's state list but not listed in the - * airmet's state list, check the sizes of the intersection areas - * between the outlook with those states. If there is at least - * one of them is greater than or equal to 3K, set the flag to True - * to issue the outlook. - * - * Rule 2: For states both in the outlook's state list and the airmet's state - * list, check the in-state outlook generation ratio with the threshold - * set in the prefs.tbl. If it's greater than the threshold, issue the - * outlook. - * - * Both checks should be done for the state bound, the Great Lakes - * bound, and the coastal water bound. - */ - String[] statesInOutlook = nvl(outlook.getGfaStates()).split(" "); - double gfaOtlkgenRatio = GfaInfo.getGfaOtlkgenRatio(); - Polygon airmetP = GfaClip.getInstance().gfaToPolygon(airmet); - for(String stateStr: statesInOutlook) { - if(stateStr.isEmpty()) continue; - Geometry stateP = states.get(stateStr); - - if(stateP == null) continue; - - if(statesInAirmet.contains(stateStr)) { - // rule 2 - // - // the formula from tt 8.106 takes precedence over the earlier one - // - // ratio = (Outlook Area - Intersect Area)/ State Area - // - // June, 2012 - adjust algorithm to find the ratio due to high-resolution state bounds. - // - // Prevoius - Intersection Area = (A^S) ^ (O^S) - // Now - Intersection Area = (A^O)^S - // - // - Geometry a = airmetP.intersection( outlookP ); - if ( a == null ) continue; - - Geometry o = outlookP.intersection(stateP); - - Geometry i = a.intersection( stateP ); - if ( i == null ) continue; - - double oArea = PgenUtil.getSphPolyArea(o); - double iArea = PgenUtil.getSphPolyArea(i); - - double ratio = 0.0; - if ( (oArea - iArea) > 0.0 ) { - double sArea = PgenUtil.getSphPolyArea(stateP); - ratio = (oArea - iArea)/sArea; - } - - if (ratio >= gfaOtlkgenRatio) return "YES"; - - } else { - // rule 1 - Geometry intersection = outlookP.intersection(stateP); - double area = PgenUtil.getSphPolyArea(intersection ); - if(area > AREA_LIMIT) { - // stop here, yes we need to issue the outlook - return "YES"; - } - } - } - - return "NO"; - } - - /** - * OTLK CONDS CONTG BYD wording - * - * @param origSS - * @param olkSeq - * @param smr - * @return - */ - private static String contgBydWording(ArrayList origSS, int[] olkSeqIn, Gfa smr ) { - - /* - * Wording Rules: - * - * Proceed only if the 06 ss exists ( 03 ss for off-time cycles ) - * as an "X_SNAPSHOTS". - * - * If the last ss in the sequence is an 'X' { - * If its time is 12, wording - "CONDS CONTG BYD +0NZ THRU +12Z". - * If its time is 09, wording - "CONDS CONTG BYD +0NZ ENDG +09-+12Z". - * If its time is 06, wording - "CONDS CONTG BYD +0NZ ENDG +06-+09Z". - * If its time is 03, wording - "CONDS CONTG BYD +0NZ ENDG +03-+06Z". - * } - * - * If the last ss in the sequence is an 'O' { - * Scan the sequence backward from the last ss to find the first 'O' - * after encountering an 'X' ss. - * - * If this 'O' ss time is 12, wording - "CONDS CONTG BYD +0NZ ENDG BY +12Z". - * If this 'O' ss time is 09, wording - "CONDS CONTG BYD +0NZ ENDG BY +09Z". - * } - * - * Where "N" is "6" for on-time cycle and "3" for off-time cycle. - * - */ - - // Proceed only if the 06 ss exists as an "X_SNAPSHOTS" - boolean ss06Exists = false; - for (Gfa g : origSS) { - int[] hm = Gfa.getHourMinInt(g.getGfaFcstHr()); - if (hm[0] == 6 && hm[1] == 0 && g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - ss06Exists = true; - break; - } - } - if (!ss06Exists) return ""; - - // Make a copy, since we need to adjust it here. - int[] olkSeq = new int[ olkSeqIn.length ]; - for ( int ii = 0; ii < olkSeqIn.length; ii++ ) { - olkSeq[ ii ] = olkSeqIn[ ii ]; - } - - String wording = ""; - int lastSS; - if (olkSeq[2] >= 0) - lastSS = 2; - else if (olkSeq[1] >= 0) - lastSS = 1; - else - lastSS = 0; - - ArrayList originalSS = new ArrayList(); - originalSS.addAll( origSS ); - - boolean isX = originalSS.get(olkSeq[lastSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X; - ArrayList otlkList = originalSS.get(olkSeq[lastSS]).getAttribute("OTLK_LIST", ArrayList.class); - - // now test if OTLK_LIST list has - if(lastSS == 0 && otlkList != null) { - for(Gfa g: otlkList) { - if(g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.O && !"6".equals(g.getGfaFcstHr())) { - isX = false; - break; - } - } - } - /* - * Find the types of outlook snapshots embedded in the airmet and adjust the - * type of outlook snapshots - */ - boolean adjEmbedOtlk = false; - ArrayList embedOtlks = originalSS.get(olkSeq[lastSS]).getAttribute( "OUTLOOKS", ArrayList.class); - if ( embedOtlks != null && embedOtlks.size() > 0 ) { - - /* - * Find the outlook originated from the same snapshots and clipped to - * the same region - */ - Gfa otlkInSameRegion = null; - for ( Gfa gg : embedOtlks ) { - if ( gg.getAttribute( "FA_REGION").equals( smr.getAttribute( "FA_REGION") ) ) { - otlkInSameRegion = gg; - break; - } - } - - //Adjust the type - FcstHrListPair p = embedOtlks.get(0).getAttribute( "PAIR", FcstHrListPair.class ); - for ( Gfa gg : p.getOriginal() ) { - if ( !originalSS.contains( gg ) ) { - Gfa temp = gg.copy(); - temp.addAttribute( SNAPSHOT_TYPE, SnapshotType.O ); - - if ( otlkInSameRegion != null ) { - Polygon otlkPoly = GfaClip.getInstance().gfaToPolygonInGrid( otlkInSameRegion ); - assignSnapshotType( otlkPoly, temp ); - } + * Pass GFA format structures through area rules to set up area/adjarea + * info. + */ + areaRules(smear, clipped, snapshots); - originalSS.add( temp ); - } - } - - adjEmbedOtlk = true; - } - - if ( adjEmbedOtlk ) { - olkSeq = findOtlkSeq( originalSS ); - if (olkSeq[2] >= 0) - lastSS = 2; - else if (olkSeq[1] >= 0) - lastSS = 1; - else - lastSS = 0; - - isX = originalSS.get( olkSeq[lastSS] ).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X; - } - - /* - * wording.... - */ - if ( isX ) { + /* + * Removes outlooks which cover only "6"-hour snapshots. + */ + removeOutlooks(clipped, snapshots); - String hourMinStr = originalSS.get(olkSeq[lastSS]).getGfaFcstHr(); - int [] hm = Gfa.getHourMinInt(hourMinStr); - String lastXinOtlk= ""; - if(otlkList != null && !otlkList.isEmpty() - && otlkList.get(otlkList.size() -1).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - lastXinOtlk = otlkList.get(otlkList.size()-1).getGfaFcstHr(); - } - - if(hm[0] == 12 || "12".equals(lastXinOtlk)) { - wording = "CONDS CONTG BYD +06Z THRU +12Z"; - } else if (hm[0] == 9 || "9".equals(lastXinOtlk)) { - wording = "CONDS CONTG BYD +06Z ENDG +09-+12Z"; - } else if (hm[0] == 6 ) { - wording = "CONDS CONTG BYD +06Z ENDG +06-+09Z"; - } - } - else { - int firstO = lastSS; - int firstX = -1; + /* + * Reduce points to desired threshold set in prefs.tbl. Check the flag + * before doing the above. + */ + GfaReducePoint.getInstance().reducePoints(clipped, snapshots); - for (int ii = lastSS; ii >= 0; ii--) { - if (olkSeq[ii] >= 0 - && originalSS.get(olkSeq[ii]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - firstX = ii; - break; - } - } + /* + * Set wording, area, region, and state list for each format structure. + */ + setWording(clipped, snapshots); - if (firstX >= 0) { - for (int ii = firstX + 1; ii <= lastSS; ii++) { - if (olkSeq[ii] >= 0 - && originalSS.get(olkSeq[ii]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.O) { - firstO = ii; - break; - } - } - } + } - String hourMinStr = originalSS.get(olkSeq[firstO]).getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(hourMinStr); - String firstOinOtlk= ""; - if(otlkList != null && !otlkList.isEmpty()) { - for(Gfa el: otlkList) { - if(el.getAttribute(SNAPSHOT_TYPE) == SnapshotType.O) { - firstOinOtlk = el.getGfaFcstHr(); - break; - } - } - } + /** + * This routine clips the GFA smears against two FA areas in a FA region + * (the input GFA smear is assumed to have been clipped against FA regions) + * and checks the size of the clipped parts in each FA area to determine the + * primary area and the possible adjacent area they belong to, if the smear + * intersects both FA areas with an area >= 3K square nautical miles. + * + * @param original + * Original smear before clipped - Airmet or Outlook + * @param clippedList + * List of GFAs from clipping + * @param clippedList + * List of original snapshots + */ + private static void areaRules(Gfa original, ArrayList clippedList, + ArrayList snapshots) { - if (hm[0] == 12 || "12".equals(firstOinOtlk)) { - wording = "CONDS CONTG BYD +06Z ENDG BY +12Z"; - } else if (hm[0] == 9 || "9".equals(firstOinOtlk)) { - wording = "CONDS CONTG BYD +06Z ENDG BY +09Z"; - } else if (hm[0] == 6) { - wording = "CONDS CONTG BYD +03Z ENDG BY +06Z"; - } - } + /* + * Toss out all freezing level contours. The area rules are applied to + * them within af_fzlvl2fmt(). + */ + if (original.getGfaHazard().equals("FZLVL")) { + return; + } - return wording; - } - - /** - * OTLK CONDS DVLPG wording - * - * @param smear - * @param originalSS - * @param olkSeq - * @return - */ - private static String otlkDvlpgWording(ArrayList originalSS, int[] olkSeq) { - // afconditions.af_otlkDvlpgWording - - /* - * Wording Rules: - * - * If the first ss in the sequence is an 'X' { - * If first ss time is 06, there is no wording. - * If first ss time is 09, wording is "+06-+09Z". - * If first ss time is 12, wording is "+09-+12Z". - * } - * If the first ss is an 'O' { - * Scan the sequence forward from the first ss to find the last 'O' - * before encountering an 'X' ss. The wording is "AFT +TTZ" where 'TT' - * is this 'O' ss time. - * } - * - */ - int firstSS = -1; - for (int ii = 0; ii < 3; ii++) { - if (olkSeq[ii] >= 0) { - firstSS = ii; - break; - } - } - - String hourMinStr = originalSS.get(olkSeq[firstSS]).getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(hourMinStr); - - String wording = ""; + /* + * Clipped against FA areas to update area info + */ + for (Gfa g : clippedList) { + findGfaAreaInGrid(g, snapshots); + } - if (originalSS.get(olkSeq[firstSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + } - if (firstSS == olkSeq[0]) { - /* No wording */ - } else if (hm[0] == 6) { - wording = "CONDS DVLPG +03-+06Z"; - } else if (hm[0] == 9) { - wording = "CONDS DVLPG +06-+09Z"; - } else if (hm[0] == 12) { - wording = "CONDS DVLPG +09-+12Z"; - } - } else { - int lastO = firstSS; - for (int ii = 0; ii < 2; ii++) { - if (lastO == olkSeq[ii] - && olkSeq[ii + 1] >= 0 - && originalSS.get(olkSeq[ii + 1]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.O) { - lastO = olkSeq[ii + 1]; - } - } - hourMinStr = originalSS.get(olkSeq[lastO]).getGfaFcstHr(); - hm = Gfa.getHourMinInt(hourMinStr); + /** + * Removes outlooks which cover only "6"-hour snapshots. + * + * @param original + * @param list + */ + private static void removeOutlooks(ArrayList clipped, + ArrayList original) { - wording = "CONDS DVLPG AFT +" + pad(hm[0]) + "Z"; - } - return wording; - } - - /** - * OTLK CONDS ENDG wording - * @param originalSS - * @param olkSeq - * @return - */ - private static String otlkEndgWording(ArrayList originalSS, int[] olkSeq) { - // afconditions.af_otlkEndgWording - - /* - * Wording Rules: - * - * If last ss in the sequence is an 'X' { - * If its time is 12 (09 for off-time), wording is "CONTG THRU +12Z" - * ("CONTG THRU +09Z" for off-time cycle). - * If its time is 09, wording is "ENDG +09-+12Z" for on-time cycle and - * "CONTG THRU +09Z" for off-time cycle. - * If its time is 06, wording is "ENDG +03-+06Z" for off-time cycle. - * } - * - * If last ss is an 'O' { - * Scan the sequence backward from the last ss to find the first 'O' - * after encountering an 'X' ss. The wording is "ENDG BY +TTZ" - * where 'TT' is this ss time. - * - * If this time is 12 (09 for off-time cycle). - * If this time is 09 (06 for off-time cycle), no wording. - * } - * - */ - int lastSS; - if (olkSeq[2] >= 0) - lastSS = 2; - else if (olkSeq[1] >= 0) - lastSS = 1; - else - lastSS = 0; + ArrayList toRemove = new ArrayList(); + for (Gfa g : clipped) { + if (!g.isOutlook()) + continue; + boolean intersectsWithAtLeastOneOriginal = false; + for (Gfa o : original) { + if ("6".equals(o.getGfaFcstHr())) + continue; // ignore 6 (see tests 49-50) + // if g covers o, leave it + Polygon gP = GfaClip.getInstance().gfaToPolygonInGrid(g); + Polygon oP = GfaClip.getInstance().gfaToPolygonInGrid(o); + Geometry intersection = gP.intersection(oP); + if (intersection instanceof Polygon + || intersection instanceof MultiPolygon) { + intersectsWithAtLeastOneOriginal = true; + } + } + if (!intersectsWithAtLeastOneOriginal) + toRemove.add(g); + } + clipped.removeAll(toRemove); + } - String hourMinStr = originalSS.get(olkSeq[lastSS]).getGfaFcstHr(); - int[] hm = Gfa.getHourMinInt(hourMinStr); + /** + * Compares two Coordinate objects by comparing x and y coordinates. If the + * coordinates are close within a precision, returns true, otherwise false. + * + * @param c1 + * + * @param c2 + * + * @return true is c1 and c2 are very close, false otherwise + */ + public static boolean compareCoordinates(Coordinate c1, Coordinate c2) { + if (abs(c1.x - c2.x) < PRECISION && abs(c1.y - c2.y) < PRECISION) { + return true; + } + return false; + } - String wording = ""; + /** + * This routine sets the beginning/ending wording, area, region, and state + * list for all VALID GFA format structures. Invalid structures are marked + * "delete", including those polygons having less than 3 points (closed) or + * 2 points (open), and those having no state list. Outlooks for LLWS, + * M_FZLVLS, and FZLVL are deleted as well. + * + * @param clipped + * @param originalSS + */ + private static void setWording(ArrayList clipped, + ArrayList originalSS) { - if (originalSS.get(olkSeq[lastSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + ArrayList checkStates = new ArrayList(); + for (Gfa smear : clipped) { - if (hm[0] == 12) { - wording = "CONDS CONTG THRU +12Z"; - } else if (hm[0] == 9) { - wording = "CONDS ENDG +09-+12Z"; - } else if (hm[0] == 6) { - // no wording for on-time - } - } else { - int firstO = lastSS; - int firstX = -1; + // Create state list + updateGfaStates(smear); - for (int ii = lastSS; ii >= 0; ii--) { - if (olkSeq[ii] >= 0 - && originalSS.get(olkSeq[ii]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { - firstX = ii; - break; - } - } + // If state is empty, remove this Gfa! + String stList = smear.getGfaStates(); + if (stList != null && stList.trim().length() > 1) { + checkStates.add(smear); + } - if (firstX >= 0) { - for (int ii = firstX + 1; ii <= lastSS; ii++) { - if (olkSeq[ii] >= 0 - && originalSS.get(olkSeq[ii]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.O) { - firstO = ii; - break; - } - } - } + } - hourMinStr = originalSS.get(olkSeq[firstO]).getGfaFcstHr(); - hm = Gfa.getHourMinInt(hourMinStr); + /* + * Now do conditional wording. + */ + ArrayList invalidOtlk = new ArrayList(); + for (Gfa smear : checkStates) { - if (hm[0] == 12) { - wording = "CONDS ENDG BY +12Z"; - } else if (hm[0] == 9) { - // no wording for on-time - } - } + /* + * see corresponding method af_getSSAttr in the legacy code + * /nawips/gempak/source/textlib/airmet/afutils.c * / + * + * /* Find the type of each snapshot and assign to SNAPSHOT_TYPE + * attribute. + * + * X_SNAPSHOTS - SS intersects with the clipped polygon with an area + * > 3K. O_SNAPSHOTS - SS do not intersect with the clipped polygon + */ + assignXorO(originalSS, smear); - return wording; - } - - /** - * This routine gets the starting and ending wordings from the format string. - * - * @param smear - * @param wording - */ - private static void parseWording(Gfa smear, GfaWording wording) { - - String beginWording = ""; - String endWording = ""; - // For smear wording - if (smear.isAirmet()) { - //Get developing wording - - beginWording = wording.fromCondsDvlpg; - - if(!wording.condsContg.isEmpty()) { - if(beginWording.isEmpty()) { - beginWording += wording.condsContg; - } else { - beginWording += ". " + wording.condsContg; - } - } - endWording = wording.fromCondsEndg; + /* + * Retrieve each snapshot's forecast time. + * + * Round UP - X_SNAPSHOTS for development wording or O_SNAPSHOTS for + * ending wording Round Down - X_SNAPSHOTS for ending wording or + * O_SNAPSHOTS for development wording + */ + assignSSForecastTime(originalSS); - } else { //For outlook wording - - beginWording = wording.otlkCondsDvlpg; - - if(!wording.condsContg.isEmpty()){ - if(beginWording.isEmpty()) { - beginWording += wording.condsContg; - } else { - beginWording += ". " + wording.condsContg; - } - } - - if(!wording.otlkCondsEndg.isEmpty()) { - endWording = wording.otlkCondsEndg; - } - } - - smear.setGfaBeginning(beginWording); - smear.setGfaEnding(endWording); + assignIssueTime(smear); - replacePlusWithCycle(smear); - } + /* + * Assign "airmetTag". + */ + assignAirmetTag(smear); - /** - * Replaces all occurrences of substrings like +ii in beginning and ending words with the - * strings calculated as a sum of ii and a cycle. For example, "CONDS ENDG +09-+12Z" becomes - * "CONDS ENDG 05-08Z" if the gfa cycle is 20. - * - * @param gfa - */ - public static void replacePlusWithCycle(Gfa gfa) { - int cycle = gfa.getGfaCycleHour(); + /* + * Do wording + */ + GfaWording wording = new GfaWording(); - String b = gfa.getGfaBeginning(); - b = replacePlusWithCycle(b, cycle); - gfa.setGfaBeginning(b); + // wording. + wording.fromCondsDvlpg = fromCondsDvlpg(smear, originalSS); - String e = gfa.getGfaEnding(); - e = replacePlusWithCycle(e, cycle); - gfa.setGfaEnding(e); - } + // wording. + wording.fromCondsEndg = fromCondsEndg(smear, originalSS); - /** - * Replaces all occurrences of substrings like +ii with the string calculated as a sum of ii + - * cycle. For example, CONDS ENDG +09-+12Z becomes CONDS ENDG 05-08Z if cycle is 20. - * - * @param b - * @param cycle - * @return - */ - public static String replacePlusWithCycle(String b, int cycle) { - int i; - while ((i = b.indexOf("+")) > -1) { - String toReplace = b.substring(i, i + 3); - String hour = toReplace.substring(1); - int h = Integer.parseInt(hour); - hour = pad((h + cycle) % 24); - b = b.replace(toReplace, hour); - } - return b; - } + int[] olkSeq = findOtlkSeq(originalSS); - /** - * Deletes all the parameters added in this class to avoid confusion in the future. - * - * @param originalSS - */ - private static void clearAttributes(ArrayList originalSS) { - for (Gfa ss : originalSS) { - ss.removeAttribute(SNAPSHOT_TYPE); - ss.removeAttribute(DVLPG_HR); - ss.removeAttribute(ENDG_HR); - } - } - - private static String nvl(String value) { - return value == null ? "" : value; - } - - - /** - * This routine clips ONE GFA smear against two FA areas in a FA region (the input GFA - * smear is assumed to have been clipped against FA regions) and checks the size of the - * clipped parts in each FA area to determine the primary area and the possible adjacent - * area they belong to. Additional Airmet/Outlook may need to be created when generating - * text product for such an smear (see GfaGenerate.java) - * - * @param current GFA to be processed - * @param clippedlist List of GFA snapshots from clipping - */ - private static void findGfaAreaInGrid( Gfa current, ArrayList snapShots ) { - - /* - * Clip against the FA areas - * - * 1. Clip against the FA areas and compute the size of the intersection - * in each FA area. - * 2. Find the area that the smear has the largest intersection - * 3. Find the area that the smear has the second largest intersection, if any. - * 4. Apply the area rules: - * a. The primary "area" is the area that the smear intersects with a larger size. - * b. When both areas >= 3K, both areas are considered as primary areas and - * one additional AIRMET should be created (in GfaGenerate.java) - * c. the part in an FA area must also intersect with one of the snapshots - * with an area >= 3K, if there are associated snapshots. - */ - HashMap areaBnds = GfaClip.getInstance().getFaAreaBoundsInGrid(); - HashMap interSizes = new HashMap(); - HashMap interWithSS = new HashMap(); - - Polygon clipPoly = GfaClip.getInstance().gfaToPolygonInGrid( current ); + // GEN_OLK wording + wording.genOlk = otlkGenWording(originalSS, olkSeq); + if ("MAYBE".equals(wording.genOlk)) { + wording.genOlk = processMAYBE(smear, originalSS); + } - for ( String areaName : areaBnds.keySet() ) { - - Geometry g = areaBnds.get( areaName ); + /* + * Outlooks should be removed if "genOlk" is "NO". + */ + if (smear.isOutlook() && !("YES".equalsIgnoreCase(wording.genOlk))) { + invalidOtlk.add(smear); + } - if ( clipPoly.intersects( g ) ) { + // OTLK CONDS CONTG BYD wording + // since "smear" element can be either Smear or Outlook, we need an + // if statement + if (smear.isAirmet()) { // not for outlooks + wording.condsContg = contgBydWording(originalSS, olkSeq, smear); + } - Geometry interAA = clipPoly.intersection( g ); - - double ss = PgenUtil.getSphPolyAreaInGrid( interAA ); - - interSizes.put( areaName, ss ); - - boolean interSSBig = false; - if ( snapShots == null || snapShots.size() <= 0 ) { - interSSBig = true; - } - else { - for ( Gfa gfa : snapShots ) { + // OTLK CONDS DVLPG wording + if ("YES".equalsIgnoreCase(wording.genOlk)) { + wording.otlkCondsDvlpg = otlkDvlpgWording(originalSS, olkSeq); + } - Polygon p = GfaClip.getInstance().gfaToPolygonInGrid( gfa ); - //Note: interAA might be an GeometryCollection and thus - // will be illegal parameter for intersects(). - - double narea = 0.0; - for ( int nn = 0; nn < interAA.getNumGeometries(); nn++ ) { - if ( p.intersects( interAA.getGeometryN( nn ) ) ) { - Geometry in_1 = p.intersection( interAA.getGeometryN( nn ) ); - narea += PgenUtil.getSphPolyAreaInGrid( in_1 ); - } - } - - if ( narea >= AREA_LIMIT ) { - interSSBig = true; - break; - } - } - } - - interWithSS.put( areaName, interSSBig ); - } - } - - // Find the primary and the secondary area - String primaryArea = null; - double biggest = 0.0; - for ( String areaName : interSizes.keySet() ) { - if ( interSizes.get( areaName ) > biggest ) { - primaryArea = new String( areaName ); - biggest = interSizes.get( areaName ); - } - } - - String secondArea = null; - double second = 0.0; - for ( String areaName : interSizes.keySet() ) { - if ( !areaName.equals( primaryArea ) && - interSizes.get( areaName ) > second ) { - - secondArea = areaName; - second = interSizes.get( areaName ); - } - } - - // Set up "area" info in the smear. - StringBuilder gfaArea = new StringBuilder(); - if ( primaryArea != null && interWithSS.get( primaryArea ) ) { - - gfaArea.append( primaryArea ); - - if ( secondArea != null && interSizes.get( secondArea ) >= AREA_LIMIT && - interWithSS.get( secondArea ) ) { + // OTLK CONDS ENDG wording + if ("YES".equalsIgnoreCase(wording.genOlk)) { + wording.otlkCondsEndg = otlkEndgWording(originalSS, olkSeq); + } + smear.addAttribute(WORDING, wording); - gfaArea.append( "-" + secondArea ); - } - } - - current.setGfaArea( gfaArea.toString() ); - - } - - /** - * Assigns airmetTag to the smear. - * - * @param smear - */ - static void assignAirmetTag(Gfa smear) { - - /* - * Note, if necessary, this could be controlled as a preference? - */ - boolean addAirmetTag = true; - String haz = smear.getGfaHazard(); - if ( addAirmetTag && !("FZLVL".equals( haz ) ) && !("M_FZLVL".equals( haz ) )) { - String prefix = ""; - if ( haz.equals( "TURB-HI") ) { - prefix = "H"; - } - else if ( haz.equals( "TURB-LO") ) { - prefix = "L"; - } - - String airmetTag = new String ( prefix + smear.getGfaTag()+smear.getGfaDesk() ); - smear.setGfaValue( Gfa.AIRMET_TAG, airmetTag ); - - } + // logger.trace( smear.toString() ); + // logger.debug( "\n" + wording ); - } - - /** - * Re-order the state list in a GFA. - * - * 1. If there are two FA areas, the state in the primary area go first. - * 2. For each FA area, the states in that area should follow the given order. - * 3. "CSTL WATERS" goes last, if exists. - * - */ - public static void reorderStateList( Gfa gg ) { - - String area = gg.getGfaArea(); + // create beginning and ending + parseWording(smear, wording); - if ( area == null || !isValidGfaArea( area ) || gg.getGfaStates() == null || - gg.getGfaStates().trim().length() == 0 ) { - return; - } + clearAttributes(originalSS); - ArrayList oldStates = new ArrayList(); - ArrayList oldStatesNoWater = new ArrayList(); - for ( String ss : gg.getGfaStates().split(" ") ) { - oldStates.add( ss ); - if ( ss.length() == 2 ) - oldStatesNoWater.add(ss); - } + } - String[] s = area.split( "-" ); + // Return valid Gfa - those with at least one state in it and outlooks + // with GenOlk is "YES" + clipped.clear(); + if (invalidOtlk.size() > 0) + checkStates.removeAll(invalidOtlk); + clipped.addAll(checkStates); + } - ArrayList statesInArea1 = GfaInfo.getStateOrderByArea().get( s[0] ); - ArrayList statesInArea2 = null; - if ( s.length > 1 ) { - statesInArea2 = GfaInfo.getStateOrderByArea().get( s[1] ); - } + /** + * Generate the state list for a smear. + * + * Note: 1. The state list is not sorted. 2. If a smear has two FA areas, + * the state list is generated but not in final order (states in primary FA + * area precede states in adjacent area). This will be done in + * GfaGeneate.java instead. Warning: the validity check of the state bounds + * should be done when pre-loading them (if necessary), not here - since + * geometry().isValid() is a quite expensive call. + * + * @param smear + */ + private static void updateGfaStates(Gfa smear) { - // Sort states in primary FA area - StringBuilder newStates = new StringBuilder(); - for (String st : statesInArea1) { - if ( st.length() == 2 && oldStatesNoWater.contains( st ) ) { - newStates.append( st ); - newStates.append(" "); - } - } + HashMap states = GfaClip.getInstance() + .getStateBoundsInGrid(); + HashMap greatLakes = GfaClip.getInstance() + .getGreatLakesBoundsInGrid(); + HashMap coastalWater = GfaClip.getInstance() + .getCoastalWaterBoundsInGrid(); + LinkedHashMap stateMaps = new LinkedHashMap(); // keep + // insertion + // order + stateMaps.putAll(states); - // Sort and add states in second FA area, if any. - if ( statesInArea2 != null ) { - for ( String st : statesInArea2 ) { - if ( st.length() == 2 && oldStatesNoWater.contains( st ) ) { - newStates.append( st ); - newStates.append(" "); - } - } - } + /* + * Find all states that touches the smear. + * + * If this is a MT_OBSC, only those MT_OBSC states will be tested and + * added to the state list. + */ + List mtobscsts = GfaClip.getInstance().getMtObscStates(); + Polygon smearP = GfaClip.getInstance().gfaToPolygonInGrid(smear); + boolean is_MTOBSC = false; + if (smear.getGfaHazard().equalsIgnoreCase("MT_OBSC")) { + is_MTOBSC = true; + } + + int nState = 0; + for (String key : stateMaps.keySet()) { + Geometry g = stateMaps.get(key); + + if (is_MTOBSC && !mtobscsts.contains(key)) + continue; + + if (smearP.intersects(g)) { + nState++; + updateGfaStatesField(smear, key); + } + + } + + /** + * Check for the airmet over Great Lakes and coastal waters. + * + * If the state to which those waters belong is not already in the + * stList, then add it. + * + * MT_OBSC hazards can never include any Great Lakes & coastal waters. + */ + int nWaters = 0; + if (!is_MTOBSC) { + + for (String key : greatLakes.keySet()) { + Geometry g = greatLakes.get(key); + + if (!g.intersects(smearP)) + continue; + updateGfaStatesField(smear, key); + + } + + for (String key : coastalWater.keySet()) { + Geometry g = coastalWater.get(key); + + if (!g.intersects(smearP)) + continue; + + nWaters++; + updateGfaStatesField(smear, key); + } + + } + + /** + * If the airmet covers land and water then append "AND CSTL WTRS" to + * the state list. If only water then use just "CSTL WTRS" (no AND). + */ + if (nWaters > 0) { + + StringBuilder s = new StringBuilder(nvl(smear.getGfaStates())); + + /* + * Note - nState should be states on land, not including states from + * Great Lakes and Coastal Waters. + */ + if (nState > 0) { + s.append(" AND"); + } + + s.append(" CSTL WTRS"); + + smear.setGfaStates(s.toString()); + } + + /* + * Re-order the state list in the specified FA-Area based order. + */ + reorderStateList(smear); + + } + + /** + * Updates the states field. + * + * @param gfa + * @param state + * @param polygon + */ + private static boolean updateGfaStatesField(Gfa gfa, String state) { + boolean added = false; + String s = nvl(gfa.getGfaStates()); + if (!s.contains(state)) { + if (!s.isEmpty()) + s += " "; + s += state; + gfa.setGfaStates(s); + added = true; + } + + return added; + } + + /** + * Find the type of each snapshot and assign to SNAPSHOT_TYPE attribute. + * + *
+     * X_SNAPSHOTS - SS intersects with the clipped polygon with an area > 3K. 
+     * O_SNAPSHOTS - SS do not intersect with the clipped polygon
+     * 
+ * + * @param originalSS + * @param smear + */ + private static void assignXorO(ArrayList originalSS, Gfa smear) { + // Polygon smearP = GfaClip.getInstance().gfaToPolygon(smear); + Polygon smearP = GfaClip.getInstance().gfaToPolygonInGrid(smear); + boolean allOutlook = true; + for (Gfa ss : originalSS) { // snapshots + assignSnapshotType(smearP, ss); + String fcstHr = ss.getGfaFcstHr(); + if (!("9".equals(fcstHr) || "12".equals(fcstHr))) { + allOutlook = false; + } + } + + Gfa first = originalSS.get(0); + ArrayList outlooks = first.getAttribute("OUTLOOKS", + ArrayList.class); + + // SMEAR or OUTLOKOS - list of created clipped smears + // OTLK_LIST - original list of outlook gfa elements (6,9,12) + if ("6".equals(first.getGfaFcstHr()) && !allOutlook && outlooks != null) { + // only for smears which have "6" hour snapshots + ArrayList otkl = first.getAttribute("OTLK_LIST", + ArrayList.class); + if (otkl == null || otkl.isEmpty()) + return; + smearP = findTheSmear(smearP, outlooks); + // smearP = + // GfaClip.gfaToPolygon((Gfa)otkl.get(0).getAttribute("AIRMETS")); + for (Gfa g : otkl) { + if (g == originalSS.get(0)) + continue; + assignSnapshotType(smearP, g); + } + } + } + + /** + *
+     * X snapshots - SS intersects with the clipped polygon smearP with an area > 3K. 
+     * O snapshots - SS do not intersect with the clipped polygon
+     * 
+ * + * + * @param smearP + * Polygon + * @param ss + */ + private static void assignSnapshotType(Polygon smearP, Gfa ss) { + + Polygon ssP = GfaClip.getInstance().gfaToPolygonInGrid(ss); + Geometry intersection = ssP.intersection(smearP); + + ss.addAttribute(SNAPSHOT_TYPE, SnapshotType.O); + + if (PgenUtil.getSphPolyAreaInGrid(intersection) > AREA_LIMIT) { + ss.addAttribute(SNAPSHOT_TYPE, SnapshotType.X); + } + + } + + private static Polygon findTheSmear(Polygon smearP, ArrayList outlooks) { + for (Gfa g : outlooks) { + + Polygon p = GfaClip.getInstance().gfaToPolygonInGrid(g); + + Geometry intersection = p.intersection(smearP); + + double area = PgenUtil.getSphPolyAreaInGrid(intersection); + + if (area > AREA_LIMIT) { + return p; + } + } + return smearP; + } + + /** + * Retrieve each snapshot's forecast time. + * + *
+     * Round UP - X_SNAPSHOTS for development wording or O_SNAPSHOTS for ending wording. 
+     * Round Down - X_SNAPSHOTS for ending wording or O_SNAPSHOTS for development wording
+     * 
+ * + * @param originalSS + */ + private static void assignSSForecastTime(ArrayList originalSS) { + for (Gfa ss : originalSS) { + String fcstHr = ss.getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(nvl(fcstHr)); + ss.addAttribute("HOUR_INT", hm[0]); + ss.addAttribute("MIN_INT", hm[1]); + double hmD = hm[0] + hm[1] / 60.0; + SnapshotType type = ss.getAttribute(SNAPSHOT_TYPE, + SnapshotType.class); + if (type == SnapshotType.X) { + ss.addAttribute(DVLPG_HR, (int) ceil(hmD)); + ss.addAttribute(ENDG_HR, (int) floor(hmD)); + } else if (type == SnapshotType.O) { + ss.addAttribute(DVLPG_HR, (int) floor(hmD)); + ss.addAttribute(ENDG_HR, (int) ceil(hmD)); + } else { + // sanity check - should never reach this place + // check asssignXorO if this happens + String err = "Snapshot type must be assigned by this time"; + // logger.error(err); + throw new IllegalArgumentException(err); + } + } + } + + /** + * Assigns issue time to the smear. + * + * @param smear + */ + static void assignIssueTime(Gfa smear) { + /* + * First determine if the standard issue time should be overridden. An + * issue time is overridden if any of the hazards (smears) are of an + * issuance type that is CAN, COR, NEW, or AMD. + */ + boolean overrideIssueTime = !"NRML".equalsIgnoreCase(smear + .getGfaIssueType()); + + Calendar localTimeCal = Calendar.getInstance(); + + String timeStr = AirmetCycleInfo.getIssueTime(); + Calendar issueTimeCal = Calendar.getInstance(); + int hour = Integer.parseInt(timeStr.substring(0, 2)); + int min = Integer.parseInt(timeStr.substring(2)); + issueTimeCal.set(Calendar.HOUR_OF_DAY, hour); + issueTimeCal.set(Calendar.MINUTE, min); + issueTimeCal.set(Calendar.SECOND, 0); + + if (overrideIssueTime) { + // Compare the local time to the issue time if overrideIssueTm flag + // is TRUE. + if (issueTimeCal.before(localTimeCal)) { + issueTimeCal = localTimeCal; + } else { + // set issue time = issue time + 1 min + issueTimeCal.add(Calendar.MINUTE, 1); + } + } + + smear.addAttribute(ISSUE_TIME, issueTimeCal); + + Calendar untilTimeCal = AirmetCycleInfo.getUntilTime(); + smear.addAttribute(UNTIL_TIME, untilTimeCal); + + Calendar otlkEndTime = Calendar.getInstance(); + otlkEndTime.set(Calendar.DAY_OF_MONTH, + untilTimeCal.get(Calendar.DAY_OF_MONTH)); + otlkEndTime.set(Calendar.HOUR_OF_DAY, + untilTimeCal.get(Calendar.HOUR_OF_DAY) + 6); + otlkEndTime.set(Calendar.MINUTE, untilTimeCal.get(Calendar.MINUTE)); + otlkEndTime.set(Calendar.SECOND, untilTimeCal.get(Calendar.SECOND)); + + smear.addAttribute(OUTLOOK_END_TIME, otlkEndTime); + + } + + /** + * Generates "" wording. + * + * @param smear + * @param originalSS + * @return + */ + private static String fromCondsDvlpg(Gfa smear, ArrayList originalSS) { + + int endHour = 6; + /* + * from the legacy system (af_condsWording method in + * source/textlib/airmet/afconditions.c): + * + * Wording rules: If the first ss in the sequence is an 'X_SNAPSHOTS' { + * If the first ss time is 00, there is no wording. If the first ss time + * is 03 or less, wording is "+00-+TTZ", where 'TT' is the ss time. If + * the first ss time is 06 or less (on-time cycles only), wording is + * "+03-+TTZ", where 'TT' is the ss time. } + * + * If the first ss is an 'O_SNAPSHOTS' { Scan the sequence forward from + * the first ss to find the last 'O' before encountering an 'X' ss. The + * wording is "AFT +TTZ" where 'TT' is this 'O' ss time. } + */ + String wording = ""; + int xx = 0; + int yy = 0; + Gfa ss = originalSS.get(0); + int dvlpgHr = ss.getAttribute(DVLPG_HR, Integer.class); + if (ss.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + if (dvlpgHr == 0) { + // no wording + } else if (dvlpgHr <= 3) { + wording = "CONDS DVLPG +00-+" + pad(dvlpgHr) + "Z"; + yy = dvlpgHr; + } else if (dvlpgHr <= 6) { + wording = "CONDS DVLPG +03-+" + pad(dvlpgHr) + "Z"; + xx = 3; + yy = dvlpgHr; + } + } else { + int lastO = 0; + for (int i = 1; i < originalSS.size(); i++) { + Gfa g = originalSS.get(i); + dvlpgHr = ss.getAttribute(DVLPG_HR, Integer.class); + if (g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X + && dvlpgHr <= endHour) { + lastO = i - 1; + break; + } + } + dvlpgHr = originalSS.get(lastO).getAttribute(DVLPG_HR, + Integer.class); + wording = "CONDS DVLPG AFT +" + pad(dvlpgHr) + "Z"; + xx = dvlpgHr; + yy = -1; + } + + if (!PgenCycleTool.isRoutine() && !wording.isEmpty() && xx >= 0 + && yy >= 0) { + + Calendar cal = smear.getAttribute(ISSUE_TIME, Calendar.class); + int issueHrMin = cal.get(Calendar.HOUR_OF_DAY) * 100 + + cal.get(Calendar.MINUTE); + + int basetime = PgenCycleTool.getCycleHour(); + + if ((yy + basetime) * 100 <= issueHrMin) { /* yy in past */ + wording = ""; + } else { /* yy in future */ + if ((xx + basetime) * 100 <= issueHrMin) {/* xx in past */ + wording = "CONDS DVLPG BY +" + pad(yy) + "Z"; // BY +23Z + } else { + wording = "CONDS DVLPG +" + pad(xx) + "-+" + pad(yy) + "Z"; // +03-+06Z + } + } + } + + return wording; + } + + /** + * Generates "" wording. + * + * @param smear + * @param originalSS + * @return + */ + private static String fromCondsEndg(Gfa smear, ArrayList originalSS) { + + int endHour = 6; + /* + * from the legacy system (af_fromEndgWording) + * + * Wording Rules: + * + * If last ss in the sequence is an 'X_SNAPSHOTS' { If the last ss time + * is the last possible time (06 for on-time cycles or 03 for off-time + * cycles), wording is determined by the outlook component snapshots + * rules. See the 'Outlook BOUNDED BY lines' section below for + * "CONDS CONTG BYD +06Z" wording (or "CONDS CONTG BYD +03Z" for cycles + * 00, 06, 12 and 18). If the last ss time is less than 03, wording is + * "+TT-+03Z", where 'TT' is the ss time. If the last ss time is less + * than 06 (on-time cycles only), wording is "+TT-+06Z", where 'TT' is + * the ss time. } + * + * If last ss is an 'O_SNAPSHOT' { Scan the sequence backward from the + * last ss to find the first 'O' after encountering an 'X' ss. The + * wording is "BY +TTZ" where 'TT' is this 'O' ss time. } + */ + String wording = ""; + int xx = -1; + int yy = -1; + int lastSSIndex = originalSS.size() - 1; + for (int i = originalSS.size() - 1; i >= 0; i--) { + lastSSIndex = i; + int hr = originalSS.get(lastSSIndex).getAttribute(ENDG_HR, + Integer.class); + if (hr <= endHour) + break; + } + Gfa lastSS = originalSS.get(lastSSIndex); + int lastEndgHr = lastSS.getAttribute(ENDG_HR, Integer.class); + String lastFcstHr = lastSS.getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(lastFcstHr); + + if (lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + + if (hm[0] == endHour && hm[1] == 0) { + /* Handled separately by af_contgBydWording() */ + } else if (lastEndgHr < 3) { + // sprintf(wording, "CONDS ENDG +0%d-+03Z", last_ss_hr) + wording = "CONDS ENDG +" + pad(lastEndgHr) + "-+03Z"; + xx = lastEndgHr; + yy = 3; + } else if (lastEndgHr <= 6) { + // sprintf(wording, "CONDS ENDG +0%d-+06Z", last_ss_hr); + wording = "CONDS ENDG +" + pad(lastEndgHr) + "-+06Z"; + xx = lastEndgHr; + yy = 6; + } + } else { + int firstO = lastSSIndex; + + ArrayList otlkList = lastSS.getAttribute("OTLK_LIST", + ArrayList.class); + if ("6".equals(originalSS.get(originalSS.size() - 1).getGfaFcstHr()) + && otlkList != null) { + lastSSIndex = otlkList.size() - 1; + lastSS = otlkList.get(lastSSIndex); + for (int jj = otlkList.size() - 2; jj >= 0; jj--) { + lastSS = otlkList.get(jj); + if (lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + firstO = jj + 1; + break; + } + } + lastEndgHr = Integer.parseInt(otlkList.get(firstO) + .getGfaFcstHr()); + } else { + for (int jj = lastSSIndex - 1; jj >= 0; jj--) { + lastSS = originalSS.get(jj); + if (lastSS.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + firstO = jj + 1; + break; + } + } + lastEndgHr = originalSS.get(firstO).getAttribute(ENDG_HR, + Integer.class); + } + wording = "CONDS ENDG BY +" + pad(lastEndgHr) + "Z"; + } + + if (!PgenCycleTool.isRoutine() && !wording.isEmpty() && xx >= 0 + && yy >= 0) { + + Calendar cal = smear.getAttribute(ISSUE_TIME, Calendar.class); + int issueHrMin = cal.get(Calendar.HOUR_OF_DAY) * 100 + + cal.get(Calendar.MINUTE); + + int basetime = PgenCycleTool.getCycleHour(); + + if ((yy + basetime) * 100 <= issueHrMin) { /* yy in past */ + wording = "CONDS HV ENDED"; + } else { /* yy in future */ + if ((xx + basetime) * 100 <= issueHrMin) {/* xx in past */ + wording = "CONDS ENDG BY +" + pad(yy) + "Z"; // BY +23Z + } else { + wording = "CONDS ENDG +" + pad(xx) + "-+" + pad(yy) + "Z"; // +03-+06Z + } + } + } + + return wording; + } + + private static int[] findOtlkSeq(ArrayList originalSS) { + int startHour = 6; // ontime + + int[] olkSeq = new int[3]; + for (int i = 0; i < 3; i++) { + olkSeq[i] = -1; + } + + for (int ii = 0; ii < originalSS.size(); ii++) { + String fcstHr = originalSS.get(ii).getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(nvl(fcstHr)); + if (hm[1] != 0) + continue; + + if (hm[0] == startHour) { + olkSeq[0] = ii; + } else if (hm[0] == (startHour + 3)) { + olkSeq[1] = ii; + } else if (hm[0] == (startHour + 6)) { + olkSeq[2] = ii; + } + } + return olkSeq; + } + + /** + * Generates wording + * + * @param smear + * @param originalSS + * @return + */ + private static String otlkGenWording(ArrayList originalSS, int[] olkSeq) { + // af_otlkGenWording(ss_attr, olk_seq, tmpstr); + + /* + * Wording Rules: Assume there is at least one SS in the sequence. 1SS - + * 06 ss (03 for off-time cycles) 2SS - 09 ss (06 for off-time cycles) + * 3SS - 12 ss (09 for off-time cycles) + * + * If 1SS does not exist or exists as an O_SNAPSHOTS { is + * "YES" } + * + * If both 1SS and 2SS exist as X_SNAPSHOTSs { is "MAYBE" } + * + * If 1SS & 3SS exist X_SNAPSHOTSs { is "MAYBE" (X-O-X case + * and X---X case) } + * + * All other cases - is "NO" + */ + + String genOlk = "NO"; + if (olkSeq[0] >= 0 || olkSeq[1] >= 0 || olkSeq[2] >= 0) { + if (olkSeq[0] < 0 + || (olkSeq[0] >= 0 && originalSS.get(olkSeq[0]) + .getAttribute(SNAPSHOT_TYPE) == SnapshotType.O)) { + genOlk = "YES"; + } else if ((olkSeq[1] >= 0 && originalSS.get(olkSeq[1]) + .getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) + || (olkSeq[2] >= 0 && originalSS.get(olkSeq[2]) + .getAttribute(SNAPSHOT_TYPE) == SnapshotType.X)) { + genOlk = "MAYBE"; + } + } + + return genOlk; + } + + private static String processMAYBE(Gfa outlook, ArrayList originalSS) { + // corresponds to afconditions.af_processMAYBE + + Polygon outlookP = GfaClip.getInstance().gfaToPolygon(outlook); + HashMap states = GfaClip.getInstance() + .getStateBounds(); + + Gfa g6 = null; + for (Gfa g : originalSS) { + updateGfaStates(g); + if ("6".equals(g.getGfaFcstHr())) + g6 = g; + } + + // smears list is not null here, because MAYBE can only be called + // for outlooks containing "6" and "9" hour snapshots. + // and at least one "6-6" airmet exists, g6 is not be null + ArrayList airmets = g6.getAttribute("AIRMETS", ArrayList.class); // from + // 0 + // to + // 6 + // hours + + // loop through airmets and find the one which overlaps with the outlook + // we process + // then the overlapping one is the one we will use to apply rules. + TreeSet statesInAirmet = new TreeSet(); + Gfa airmet = null; + for (Gfa g : airmets) { + Polygon gP = GfaClip.getInstance().gfaToPolygon(g); + Geometry intersection = outlookP.intersection(gP); + if (intersection instanceof Polygon + || intersection instanceof MultiPolygon) { + // states + String[] statesArray = nvl(g.getGfaStates()).split(" "); + for (String s : statesArray) { + statesInAirmet.add(s.trim()); + } + airmet = g; + break; + } + } + + /* + * Rule 1: For states in the outlook's state list but not listed in the + * airmet's state list, check the sizes of the intersection areas + * between the outlook with those states. If there is at least one of + * them is greater than or equal to 3K, set the flag to True to issue + * the outlook. + * + * Rule 2: For states both in the outlook's state list and the airmet's + * state list, check the in-state outlook generation ratio with the + * threshold set in the prefs.tbl. If it's greater than the threshold, + * issue the outlook. + * + * Both checks should be done for the state bound, the Great Lakes + * bound, and the coastal water bound. + */ + String[] statesInOutlook = nvl(outlook.getGfaStates()).split(" "); + double gfaOtlkgenRatio = GfaInfo.getGfaOtlkgenRatio(); + Polygon airmetP = GfaClip.getInstance().gfaToPolygon(airmet); + for (String stateStr : statesInOutlook) { + if (stateStr.isEmpty()) + continue; + Geometry stateP = states.get(stateStr); + + if (stateP == null) + continue; + + if (statesInAirmet.contains(stateStr)) { + // rule 2 + // + // the formula from tt 8.106 takes precedence over the earlier + // one + // + // ratio = (Outlook Area - Intersect Area)/ State Area + // + // June, 2012 - adjust algorithm to find the ratio due to + // high-resolution state bounds. + // + // Prevoius - Intersection Area = (A^S) ^ (O^S) + // Now - Intersection Area = (A^O)^S + // + // + Geometry a = airmetP.intersection(outlookP); + if (a == null) + continue; + + Geometry o = outlookP.intersection(stateP); + + Geometry i = a.intersection(stateP); + if (i == null) + continue; + + double oArea = PgenUtil.getSphPolyArea(o); + double iArea = PgenUtil.getSphPolyArea(i); + + double ratio = 0.0; + if ((oArea - iArea) > 0.0) { + double sArea = PgenUtil.getSphPolyArea(stateP); + ratio = (oArea - iArea) / sArea; + } + + if (ratio >= gfaOtlkgenRatio) + return "YES"; + + } else { + // rule 1 + Geometry intersection = outlookP.intersection(stateP); + double area = PgenUtil.getSphPolyArea(intersection); + if (area > AREA_LIMIT) { + // stop here, yes we need to issue the outlook + return "YES"; + } + } + } + + return "NO"; + } + + /** + * OTLK CONDS CONTG BYD wording + * + * @param origSS + * @param olkSeq + * @param smr + * @return + */ + private static String contgBydWording(ArrayList origSS, + int[] olkSeqIn, Gfa smr) { + + /* + * Wording Rules: + * + * Proceed only if the 06 ss exists ( 03 ss for off-time cycles ) as an + * "X_SNAPSHOTS". + * + * If the last ss in the sequence is an 'X' { If its time is 12, wording + * - "CONDS CONTG BYD +0NZ THRU +12Z". If its time is 09, wording - + * "CONDS CONTG BYD +0NZ ENDG +09-+12Z". If its time is 06, wording - + * "CONDS CONTG BYD +0NZ ENDG +06-+09Z". If its time is 03, wording - + * "CONDS CONTG BYD +0NZ ENDG +03-+06Z". } + * + * If the last ss in the sequence is an 'O' { Scan the sequence backward + * from the last ss to find the first 'O' after encountering an 'X' ss. + * + * If this 'O' ss time is 12, wording - + * "CONDS CONTG BYD +0NZ ENDG BY +12Z". If this 'O' ss time is 09, + * wording - "CONDS CONTG BYD +0NZ ENDG BY +09Z". } + * + * Where "N" is "6" for on-time cycle and "3" for off-time cycle. + */ + + // Proceed only if the 06 ss exists as an "X_SNAPSHOTS" + boolean ss06Exists = false; + for (Gfa g : origSS) { + int[] hm = Gfa.getHourMinInt(g.getGfaFcstHr()); + if (hm[0] == 6 && hm[1] == 0 + && g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + ss06Exists = true; + break; + } + } + if (!ss06Exists) + return ""; + + // Make a copy, since we need to adjust it here. + int[] olkSeq = new int[olkSeqIn.length]; + for (int ii = 0; ii < olkSeqIn.length; ii++) { + olkSeq[ii] = olkSeqIn[ii]; + } + + String wording = ""; + int lastSS; + if (olkSeq[2] >= 0) + lastSS = 2; + else if (olkSeq[1] >= 0) + lastSS = 1; + else + lastSS = 0; + + ArrayList originalSS = new ArrayList(); + originalSS.addAll(origSS); + + boolean isX = originalSS.get(olkSeq[lastSS]) + .getAttribute(SNAPSHOT_TYPE) == SnapshotType.X; + ArrayList otlkList = originalSS.get(olkSeq[lastSS]).getAttribute( + "OTLK_LIST", ArrayList.class); + + // now test if OTLK_LIST list has + if (lastSS == 0 && otlkList != null) { + for (Gfa g : otlkList) { + if (g.getAttribute(SNAPSHOT_TYPE) == SnapshotType.O + && !"6".equals(g.getGfaFcstHr())) { + isX = false; + break; + } + } + } + + /* + * Find the types of outlook snapshots embedded in the airmet and adjust + * the type of outlook snapshots + */ + boolean adjEmbedOtlk = false; + ArrayList embedOtlks = originalSS.get(olkSeq[lastSS]) + .getAttribute("OUTLOOKS", ArrayList.class); + if (embedOtlks != null && embedOtlks.size() > 0) { + + /* + * Find the outlook originated from the same snapshots and clipped + * to the same region + */ + Gfa otlkInSameRegion = null; + for (Gfa gg : embedOtlks) { + if (gg.getAttribute("FA_REGION").equals( + smr.getAttribute("FA_REGION"))) { + otlkInSameRegion = gg; + break; + } + } + + // Adjust the type + FcstHrListPair p = embedOtlks.get(0).getAttribute("PAIR", + FcstHrListPair.class); + for (Gfa gg : p.getOriginal()) { + if (!originalSS.contains(gg)) { + Gfa temp = gg.copy(); + temp.addAttribute(SNAPSHOT_TYPE, SnapshotType.O); + + if (otlkInSameRegion != null) { + Polygon otlkPoly = GfaClip.getInstance() + .gfaToPolygonInGrid(otlkInSameRegion); + assignSnapshotType(otlkPoly, temp); + } + + originalSS.add(temp); + } + } + + adjEmbedOtlk = true; + } + + if (adjEmbedOtlk) { + olkSeq = findOtlkSeq(originalSS); + if (olkSeq[2] >= 0) + lastSS = 2; + else if (olkSeq[1] >= 0) + lastSS = 1; + else + lastSS = 0; + + isX = originalSS.get(olkSeq[lastSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X; + } + + /* + * wording.... + */ + if (isX) { + + String hourMinStr = originalSS.get(olkSeq[lastSS]).getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(hourMinStr); + String lastXinOtlk = ""; + if (otlkList != null + && !otlkList.isEmpty() + && otlkList.get(otlkList.size() - 1).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.X) { + lastXinOtlk = otlkList.get(otlkList.size() - 1).getGfaFcstHr(); + } + + if (hm[0] == 12 || "12".equals(lastXinOtlk)) { + wording = "CONDS CONTG BYD +06Z THRU +12Z"; + } else if (hm[0] == 9 || "9".equals(lastXinOtlk)) { + wording = "CONDS CONTG BYD +06Z ENDG +09-+12Z"; + } else if (hm[0] == 6) { + wording = "CONDS CONTG BYD +06Z ENDG +06-+09Z"; + } + } else { + int firstO = lastSS; + int firstX = -1; + + for (int ii = lastSS; ii >= 0; ii--) { + if (olkSeq[ii] >= 0 + && originalSS.get(olkSeq[ii]).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.X) { + firstX = ii; + break; + } + } + + if (firstX >= 0) { + for (int ii = firstX + 1; ii <= lastSS; ii++) { + if (olkSeq[ii] >= 0 + && originalSS.get(olkSeq[ii]).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.O) { + firstO = ii; + break; + } + } + } + + String hourMinStr = originalSS.get(olkSeq[firstO]).getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(hourMinStr); + String firstOinOtlk = ""; + if (otlkList != null && !otlkList.isEmpty()) { + for (Gfa el : otlkList) { + if (el.getAttribute(SNAPSHOT_TYPE) == SnapshotType.O) { + firstOinOtlk = el.getGfaFcstHr(); + break; + } + } + } + + if (hm[0] == 12 || "12".equals(firstOinOtlk)) { + wording = "CONDS CONTG BYD +06Z ENDG BY +12Z"; + } else if (hm[0] == 9 || "9".equals(firstOinOtlk)) { + wording = "CONDS CONTG BYD +06Z ENDG BY +09Z"; + } else if (hm[0] == 6) { + wording = "CONDS CONTG BYD +03Z ENDG BY +06Z"; + } + } + + return wording; + } + + /** + * OTLK CONDS DVLPG wording + * + * @param smear + * @param originalSS + * @param olkSeq + * @return + */ + private static String otlkDvlpgWording(ArrayList originalSS, + int[] olkSeq) { + // afconditions.af_otlkDvlpgWording + + /* + * Wording Rules: + * + * If the first ss in the sequence is an 'X' { If first ss time is 06, + * there is no wording. If first ss time is 09, wording is "+06-+09Z". + * If first ss time is 12, wording is "+09-+12Z". } If the first ss is + * an 'O' { Scan the sequence forward from the first ss to find the last + * 'O' before encountering an 'X' ss. The wording is "AFT +TTZ" where + * 'TT' is this 'O' ss time. } + */ + int firstSS = -1; + for (int ii = 0; ii < 3; ii++) { + if (olkSeq[ii] >= 0) { + firstSS = ii; + break; + } + } + + String hourMinStr = originalSS.get(olkSeq[firstSS]).getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(hourMinStr); + + String wording = ""; + + if (originalSS.get(olkSeq[firstSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + + if (firstSS == olkSeq[0]) { + /* No wording */ + } else if (hm[0] == 6) { + wording = "CONDS DVLPG +03-+06Z"; + } else if (hm[0] == 9) { + wording = "CONDS DVLPG +06-+09Z"; + } else if (hm[0] == 12) { + wording = "CONDS DVLPG +09-+12Z"; + } + } else { + int lastO = firstSS; + for (int ii = 0; ii < 2; ii++) { + if (lastO == olkSeq[ii] + && olkSeq[ii + 1] >= 0 + && originalSS.get(olkSeq[ii + 1]).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.O) { + lastO = olkSeq[ii + 1]; + } + } + hourMinStr = originalSS.get(olkSeq[lastO]).getGfaFcstHr(); + hm = Gfa.getHourMinInt(hourMinStr); + + wording = "CONDS DVLPG AFT +" + pad(hm[0]) + "Z"; + } + return wording; + } + + /** + * OTLK CONDS ENDG wording + * + * @param originalSS + * @param olkSeq + * @return + */ + private static String otlkEndgWording(ArrayList originalSS, + int[] olkSeq) { + // afconditions.af_otlkEndgWording + + /* + * Wording Rules: + * + * If last ss in the sequence is an 'X' { If its time is 12 (09 for + * off-time), wording is "CONTG THRU +12Z" ("CONTG THRU +09Z" for + * off-time cycle). If its time is 09, wording is "ENDG +09-+12Z" for + * on-time cycle and "CONTG THRU +09Z" for off-time cycle. If its time + * is 06, wording is "ENDG +03-+06Z" for off-time cycle. } + * + * If last ss is an 'O' { Scan the sequence backward from the last ss to + * find the first 'O' after encountering an 'X' ss. The wording is + * "ENDG BY +TTZ" where 'TT' is this ss time. + * + * If this time is 12 (09 for off-time cycle). If this time is 09 (06 + * for off-time cycle), no wording. } + */ + int lastSS; + if (olkSeq[2] >= 0) + lastSS = 2; + else if (olkSeq[1] >= 0) + lastSS = 1; + else + lastSS = 0; + + String hourMinStr = originalSS.get(olkSeq[lastSS]).getGfaFcstHr(); + int[] hm = Gfa.getHourMinInt(hourMinStr); + + String wording = ""; + + if (originalSS.get(olkSeq[lastSS]).getAttribute(SNAPSHOT_TYPE) == SnapshotType.X) { + + if (hm[0] == 12) { + wording = "CONDS CONTG THRU +12Z"; + } else if (hm[0] == 9) { + wording = "CONDS ENDG +09-+12Z"; + } else if (hm[0] == 6) { + // no wording for on-time + } + } else { + int firstO = lastSS; + int firstX = -1; + + for (int ii = lastSS; ii >= 0; ii--) { + if (olkSeq[ii] >= 0 + && originalSS.get(olkSeq[ii]).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.X) { + firstX = ii; + break; + } + } + + if (firstX >= 0) { + for (int ii = firstX + 1; ii <= lastSS; ii++) { + if (olkSeq[ii] >= 0 + && originalSS.get(olkSeq[ii]).getAttribute( + SNAPSHOT_TYPE) == SnapshotType.O) { + firstO = ii; + break; + } + } + } + + hourMinStr = originalSS.get(olkSeq[firstO]).getGfaFcstHr(); + hm = Gfa.getHourMinInt(hourMinStr); + + if (hm[0] == 12) { + wording = "CONDS ENDG BY +12Z"; + } else if (hm[0] == 9) { + // no wording for on-time + } + } + + return wording; + } + + /** + * This routine gets the starting and ending wordings from the format + * string. + * + * @param smear + * @param wording + */ + private static void parseWording(Gfa smear, GfaWording wording) { + + String beginWording = ""; + String endWording = ""; + // For smear wording + if (smear.isAirmet()) { + // Get developing wording + + beginWording = wording.fromCondsDvlpg; + + if (!wording.condsContg.isEmpty()) { + if (beginWording.isEmpty()) { + beginWording += wording.condsContg; + } else { + beginWording += ". " + wording.condsContg; + } + } + endWording = wording.fromCondsEndg; + + } else { // For outlook wording + + beginWording = wording.otlkCondsDvlpg; + + if (!wording.condsContg.isEmpty()) { + if (beginWording.isEmpty()) { + beginWording += wording.condsContg; + } else { + beginWording += ". " + wording.condsContg; + } + } + + if (!wording.otlkCondsEndg.isEmpty()) { + endWording = wording.otlkCondsEndg; + } + } + + smear.setGfaBeginning(beginWording); + smear.setGfaEnding(endWording); + + replacePlusWithCycle(smear); + } + + /** + * Replaces all occurrences of substrings like +ii in beginning and ending + * words with the strings calculated as a sum of ii and a cycle. For + * example, "CONDS ENDG +09-+12Z" becomes "CONDS ENDG 05-08Z" if the gfa + * cycle is 20. + * + * @param gfa + */ + public static void replacePlusWithCycle(Gfa gfa) { + int cycle = gfa.getGfaCycleHour(); + + String b = gfa.getGfaBeginning(); + b = replacePlusWithCycle(b, cycle); + gfa.setGfaBeginning(b); + + String e = gfa.getGfaEnding(); + e = replacePlusWithCycle(e, cycle); + gfa.setGfaEnding(e); + } + + /** + * Replaces all occurrences of substrings like +ii with the string + * calculated as a sum of ii + cycle. For example, CONDS ENDG +09-+12Z + * becomes CONDS ENDG 05-08Z if cycle is 20. + * + * @param b + * @param cycle + * @return + */ + public static String replacePlusWithCycle(String b, int cycle) { + int i; + while ((i = b.indexOf("+")) > -1) { + String toReplace = b.substring(i, i + 3); + String hour = toReplace.substring(1); + int h = Integer.parseInt(hour); + hour = pad((h + cycle) % 24); + b = b.replace(toReplace, hour); + } + return b; + } + + /** + * Deletes all the parameters added in this class to avoid confusion in the + * future. + * + * @param originalSS + */ + private static void clearAttributes(ArrayList originalSS) { + for (Gfa ss : originalSS) { + ss.removeAttribute(SNAPSHOT_TYPE); + ss.removeAttribute(DVLPG_HR); + ss.removeAttribute(ENDG_HR); + } + } + + private static String nvl(String value) { + return value == null ? "" : value; + } + + /** + * This routine clips ONE GFA smear against two FA areas in a FA region (the + * input GFA smear is assumed to have been clipped against FA regions) and + * checks the size of the clipped parts in each FA area to determine the + * primary area and the possible adjacent area they belong to. Additional + * Airmet/Outlook may need to be created when generating text product for + * such an smear (see GfaGenerate.java) + * + * @param current + * GFA to be processed + * @param clippedlist + * List of GFA snapshots from clipping + */ + private static void findGfaAreaInGrid(Gfa current, ArrayList snapShots) { + + /* + * Clip against the FA areas + * + * 1. Clip against the FA areas and compute the size of the intersection + * in each FA area. 2. Find the area that the smear has the largest + * intersection 3. Find the area that the smear has the second largest + * intersection, if any. 4. Apply the area rules: a. The primary "area" + * is the area that the smear intersects with a larger size. b. When + * both areas >= 3K, both areas are considered as primary areas and one + * additional AIRMET should be created (in GfaGenerate.java) c. the part + * in an FA area must also intersect with one of the snapshots with an + * area >= 3K, if there are associated snapshots. + */ + HashMap areaBnds = GfaClip.getInstance() + .getFaAreaBoundsInGrid(); + HashMap interSizes = new HashMap(); + HashMap interWithSS = new HashMap(); + + Polygon clipPoly = GfaClip.getInstance().gfaToPolygonInGrid(current); + + for (String areaName : areaBnds.keySet()) { + + Geometry g = areaBnds.get(areaName); + + if (clipPoly.intersects(g)) { + + Geometry interAA = clipPoly.intersection(g); + + double ss = PgenUtil.getSphPolyAreaInGrid(interAA); + + interSizes.put(areaName, ss); + + boolean interSSBig = false; + if (snapShots == null || snapShots.size() <= 0) { + interSSBig = true; + } else { + for (Gfa gfa : snapShots) { + + Polygon p = GfaClip.getInstance().gfaToPolygonInGrid( + gfa); + // Note: interAA might be an GeometryCollection and thus + // will be illegal parameter for intersects(). + + double narea = 0.0; + for (int nn = 0; nn < interAA.getNumGeometries(); nn++) { + if (p.intersects(interAA.getGeometryN(nn))) { + Geometry in_1 = p.intersection(interAA + .getGeometryN(nn)); + narea += PgenUtil.getSphPolyAreaInGrid(in_1); + } + } + + if (narea >= AREA_LIMIT) { + interSSBig = true; + break; + } + } + } + + interWithSS.put(areaName, interSSBig); + } + } + + // Find the primary and the secondary area + String primaryArea = null; + double biggest = 0.0; + for (String areaName : interSizes.keySet()) { + if (interSizes.get(areaName) > biggest) { + primaryArea = new String(areaName); + biggest = interSizes.get(areaName); + } + } + + String secondArea = null; + double second = 0.0; + for (String areaName : interSizes.keySet()) { + if (!areaName.equals(primaryArea) + && interSizes.get(areaName) > second) { + + secondArea = areaName; + second = interSizes.get(areaName); + } + } + + // Set up "area" info in the smear. + StringBuilder gfaArea = new StringBuilder(); + if (primaryArea != null && interWithSS.get(primaryArea)) { + + gfaArea.append(primaryArea); + + if (secondArea != null && interSizes.get(secondArea) >= AREA_LIMIT + && interWithSS.get(secondArea)) { + + gfaArea.append("-" + secondArea); + } + } + + current.setGfaArea(gfaArea.toString()); + + } + + /** + * Assigns airmetTag to the smear. + * + * @param smear + */ + static void assignAirmetTag(Gfa smear) { + + /* + * Note, if necessary, this could be controlled as a preference? + */ + boolean addAirmetTag = true; + String haz = smear.getGfaHazard(); + if (addAirmetTag && !("FZLVL".equals(haz)) && !("M_FZLVL".equals(haz))) { + String prefix = ""; + if (haz.equals("TURB-HI")) { + prefix = "H"; + } else if (haz.equals("TURB-LO")) { + prefix = "L"; + } + + String airmetTag = new String(prefix + smear.getGfaTag() + + smear.getGfaDesk()); + smear.setGfaValue(Gfa.AIRMET_TAG, airmetTag); + + } + + } + + /** + * Re-order the state list in a GFA. + * + * 1. If there are two FA areas, the state in the primary area go first. 2. + * For each FA area, the states in that area should follow the given order. + * 3. "CSTL WATERS" goes last, if exists. + * + */ + public static void reorderStateList(Gfa gg) { + + String area = gg.getGfaArea(); + + if (area == null || !isValidGfaArea(area) || gg.getGfaStates() == null + || gg.getGfaStates().trim().length() == 0) { + return; + } + + ArrayList oldStates = new ArrayList(); + ArrayList oldStatesNoWater = new ArrayList(); + for (String ss : gg.getGfaStates().split(" ")) { + oldStates.add(ss); + if (ss.length() == 2) + oldStatesNoWater.add(ss); + } + + String[] s = area.split("-"); + + ArrayList statesInArea1 = GfaInfo.getStateOrderByArea().get( + s[0]); + ArrayList statesInArea2 = null; + if (s.length > 1) { + statesInArea2 = GfaInfo.getStateOrderByArea().get(s[1]); + } + + // Sort states in primary FA area + StringBuilder newStates = new StringBuilder(); + for (String st : statesInArea1) { + if (st.length() == 2 && oldStatesNoWater.contains(st)) { + newStates.append(st); + newStates.append(" "); + } + } + + // Sort and add states in second FA area, if any. + if (statesInArea2 != null) { + for (String st : statesInArea2) { + if (st.length() == 2 && oldStatesNoWater.contains(st)) { + newStates.append(st); + newStates.append(" "); + } + } + } + + // Add back "CSTL WTRS" or "AND CSTL WTRS". + for (String st : oldStates) { + if (st.length() > 2) { + newStates.append(st); + newStates.append(" "); + } + } + + // Set the state list to the re-ordered one. + gg.setGfaStates(newStates.toString().trim()); + + } + + /* + * Check if the input is a valid FA area name. + * + * Note: A combination of two or more FA area names with "-" is valid. + */ + private static boolean isValidGfaArea(String gfaArea) { + boolean validArea = false; + + for (String area : gfaArea.split("-")) + if (area.equalsIgnoreCase(BOS) || area.equalsIgnoreCase(MIA) + || area.equalsIgnoreCase(CHI) || area.equalsIgnoreCase(DFW) + || area.equalsIgnoreCase(SLC) || area.equalsIgnoreCase(SFO)) { + + validArea = true; + break; + } + + return validArea; + } - // Add back "CSTL WTRS" or "AND CSTL WTRS". - for ( String st : oldStates ) { - if ( st.length() > 2 ) { - newStates.append( st ); - newStates.append(" "); - } - } - - // Set the state list to the re-ordered one. - gg.setGfaStates( newStates.toString().trim() ); - - } - - /* - * Check if the input is a valid FA area name. - */ - private static boolean isValidGfaArea( String area ) { - boolean validArea = false; - - if ( area.equalsIgnoreCase( BOS ) || area.equalsIgnoreCase( MIA ) || - area.equalsIgnoreCase( CHI ) || area.equalsIgnoreCase( DFW ) || - area.equalsIgnoreCase( SLC ) || area.equalsIgnoreCase( SFO ) ) { - - validArea = true; - } - - return validArea; - } - } diff --git a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/layering/PgenLayeringControlDialog.java b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/layering/PgenLayeringControlDialog.java index cb1805bc7e..654f7ca675 100644 --- a/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/layering/PgenLayeringControlDialog.java +++ b/ncep/gov.noaa.nws.ncep.ui.pgen/src/gov/noaa/nws/ncep/ui/pgen/layering/PgenLayeringControlDialog.java @@ -27,11 +27,9 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; - import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; - /** * This class controls PGEN layering in National Centers perspective. * @@ -39,7 +37,7 @@ import org.eclipse.ui.PlatformUI; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * 07/09 #131 J. Wu Initial creation. + * 07/09 #131 J. Wu Initial creation. * * * @@ -50,738 +48,754 @@ import org.eclipse.ui.PlatformUI; public class PgenLayeringControlDialog extends PgenLayeringDialog { - /** + /** * Default color for the active layer name button. */ private final Color defaultLayerButtonColor = Color.lightGray; + private final Color activeLayerButtonColor = Color.green; - + /** * Layer name edit dialog. */ - protected PgenLayeringNameDialog layerNameDlg = null; - protected PgenLayeringDisplayDialog displayDlg = null; - - - /** + protected PgenLayeringNameDialog layerNameDlg = null; + + protected PgenLayeringDisplayDialog displayDlg = null; + + /** * List of layers and buttons. */ - private ArrayList layerList = null; - private ArrayList