NSHARP Load (Re)-Implementation and a few NCEP edex plugins
-Added back in the NSHARP button and icon -Re-implemented Unidata's v18 NSHARP load functionality (instead of loading a file, it queuries the database and provides a map of available soundings at differnt times) -Had to add the com.raytheon.uf.edex.ncep.nco.feature to the list of uframe features so that a few ncep edex plugins would start up with ingest
This commit is contained in:
parent
fc0e7d5e1b
commit
aee55a7e74
12 changed files with 1635 additions and 5 deletions
|
@ -75,6 +75,10 @@
|
|||
</and>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<handler
|
||||
class="com.raytheon.uf.viz.d2d.nsharp.D2DNsharpViewAction"
|
||||
commandId="com.raytheon.uf.viz.d2d.nsharp.dialog">
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="com.raytheon.uf.viz.core.classContext">
|
||||
|
@ -92,5 +96,11 @@
|
|||
resourceType="sounding">
|
||||
</productCreator>
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
id="com.raytheon.uf.viz.d2d.nsharp.dialog"
|
||||
name="D2DNsharp">
|
||||
</command>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* gov.noaa.nws.ncep.ui.nsharp.palette.NsharpViewAction
|
||||
*
|
||||
*
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 06/25/2012 229 Chin Chen Initial coding
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.raytheon.uf.viz.d2d.nsharp;
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
public class D2DNsharpViewAction extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public Object execute(ExecutionEvent arg0) throws ExecutionException {
|
||||
/*
|
||||
* The viewID string is in the XML file for NSHARP extension point.
|
||||
*/
|
||||
String viewid = "com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpPaletteWindow";
|
||||
IWorkbenchPage wpage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
IViewPart vpart = wpage.findView( viewid);
|
||||
try {
|
||||
if ( vpart == null ){
|
||||
vpart = wpage.showView(viewid );
|
||||
} else {
|
||||
if ( ! wpage.isPartVisible(vpart) ) vpart = wpage.showView( viewid );
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,9 @@ import org.eclipse.swt.SWT;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.IViewSite;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
import com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager;
|
||||
|
@ -47,6 +49,7 @@ import gov.noaa.nws.ncep.ui.nsharp.view.NsharpPaletteWindow;
|
|||
* ------------- -------- --------- ------------------------------------------
|
||||
* May 12, 2011 9249 bsteffen Initial creation
|
||||
* Apr 29, 2016 5607 bsteffen Fix modal tool manipulation in eclipse 4.
|
||||
* Jun 15, 2023 tiffanym@ucar reimplement NSHARP load functionality
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -58,6 +61,11 @@ public class D2DNSharpPaletteWindow extends NsharpPaletteWindow {
|
|||
|
||||
private AbstractModalTool lastTool = null;
|
||||
|
||||
Shell shell = PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getShell();
|
||||
|
||||
D2DNsharpLoadDialog loadDia = D2DNsharpLoadDialog.getInstance(shell);
|
||||
|
||||
@Override
|
||||
public void init(IViewSite site) {
|
||||
super.init(site);
|
||||
|
@ -104,8 +112,9 @@ public class D2DNSharpPaletteWindow extends NsharpPaletteWindow {
|
|||
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
D2DNsharpHandleArchiveFile.openArchiveFile(getViewSite()
|
||||
.getShell());
|
||||
if (loadDia != null) {
|
||||
loadDia.open();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
/**
|
||||
*
|
||||
* com.raytheon.uf.viz.d2d.nsharp.view.D2DNsharpLoadDialog
|
||||
*
|
||||
* This java class performs the NSHARP D2DNsharpLoadDialog functions.
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 03/23/2010 229 Chin Chen Initial coding
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.raytheon.uf.viz.d2d.nsharp.display;
|
||||
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpConstants;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
|
||||
|
||||
import com.raytheon.uf.viz.d2d.nsharp.display.map.D2DNsharpMapResource;
|
||||
import com.raytheon.uf.viz.d2d.nsharp.display.D2DNsharpHandleArchiveFile;
|
||||
import com.raytheon.uf.viz.d2d.nsharp.display.D2DNsharpObservedSoundingDialogContents;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Cursor;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
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.MessageBox;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
public class D2DNsharpLoadDialog extends Dialog {
|
||||
|
||||
private final static int DIALOG_WIDTH = 300;
|
||||
|
||||
private final static int DIALOG_HEIGHT = 700;
|
||||
|
||||
protected Composite top;
|
||||
|
||||
private static Composite dialogParent;
|
||||
|
||||
private static D2DNsharpLoadDialog INSTANCE = null;
|
||||
|
||||
private static Shell shell;
|
||||
|
||||
public static final String soundingTypeString = "Observed Soundings";
|
||||
|
||||
public static final int OBSER_SND = 0;
|
||||
|
||||
public static final int ARCHIVE = 3; // TBDGPD 5;
|
||||
|
||||
private D2DNsharpObservedSoundingDialogContents obsDialog;
|
||||
|
||||
private Group soundingTypeGp;
|
||||
|
||||
private int activeLoadSoundingType;
|
||||
|
||||
private NcSoundingProfile.ObsSndType activeObsSndType = NcSoundingProfile.ObsSndType.BUFRUA;
|
||||
|
||||
private ArrayList<String> obsSelectedTimeList = new ArrayList<String>();
|
||||
|
||||
private String activeGpdProdName = "";
|
||||
|
||||
private ArrayList<String> gpdSelectedTimeList = new ArrayList<String>();
|
||||
|
||||
private Text text1;
|
||||
|
||||
private MessageBox mb;
|
||||
|
||||
private Cursor waitCursor = null;
|
||||
|
||||
private Font newFont;
|
||||
|
||||
public Font getNewFont() {
|
||||
return newFont;
|
||||
}
|
||||
|
||||
public D2DNsharpObservedSoundingDialogContents getObsDialog() {
|
||||
return obsDialog;
|
||||
}
|
||||
|
||||
public void setAndOpenMb(String msg) {
|
||||
if (mb != null) {
|
||||
mb.setMessage(msg);
|
||||
try {
|
||||
mb.open();
|
||||
} catch (Exception e) {
|
||||
mb = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
|
||||
mb.setMessage(msg);
|
||||
mb.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanSelf() {
|
||||
|
||||
if (text1 != null) {
|
||||
text1.dispose();
|
||||
text1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanupDialog(int activeLoadType) {
|
||||
switch (activeLoadType) {
|
||||
case OBSER_SND:
|
||||
obsDialog.cleanup();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setActiveLoadSoundingType(int activeLoadSoundingType) {
|
||||
this.activeLoadSoundingType = activeLoadSoundingType;
|
||||
}
|
||||
|
||||
public int getActiveLoadSoundingType() {
|
||||
return activeLoadSoundingType;
|
||||
}
|
||||
|
||||
public ArrayList<String> getObsSelectedTimeList() {
|
||||
return obsSelectedTimeList;
|
||||
}
|
||||
|
||||
public void setObsSelectedTimeList(ArrayList<String> obsSelectedTimeList) {
|
||||
this.obsSelectedTimeList = obsSelectedTimeList;
|
||||
}
|
||||
|
||||
public ArrayList<String> getGpdSelectedTimeList() {
|
||||
return gpdSelectedTimeList;
|
||||
}
|
||||
|
||||
public void setGpdSelectedTimeList(ArrayList<String> gpdSelectedTimeList) {
|
||||
this.gpdSelectedTimeList = gpdSelectedTimeList;
|
||||
}
|
||||
|
||||
public NcSoundingProfile.ObsSndType getActiveObsSndType() {
|
||||
return activeObsSndType;
|
||||
}
|
||||
|
||||
public void setActiveObsSndType(
|
||||
NcSoundingProfile.ObsSndType activeObsSndType) {
|
||||
this.activeObsSndType = activeObsSndType;
|
||||
}
|
||||
|
||||
public String getActiveGpdProdName() {
|
||||
return activeGpdProdName;
|
||||
}
|
||||
|
||||
public void setActiveGpdProdName(String activeGpdProdName) {
|
||||
this.activeGpdProdName = activeGpdProdName;
|
||||
}
|
||||
|
||||
static int count = 0;
|
||||
|
||||
public static D2DNsharpLoadDialog getAccess() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public D2DNsharpLoadDialog(Shell parentShell) throws VizException {
|
||||
super(parentShell);
|
||||
this.setShellStyle(SWT.TITLE | SWT.MODELESS | SWT.CLOSE
|
||||
| SWT.SHELL_TRIM);
|
||||
activeLoadSoundingType = OBSER_SND;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
|
||||
* .Shell)
|
||||
*/
|
||||
@Override
|
||||
protected void configureShell(Shell shell) {
|
||||
super.configureShell(shell);
|
||||
D2DNsharpLoadDialog.shell = shell;
|
||||
shell.setSize(getDialogWidth(), DIALOG_HEIGHT);
|
||||
shell.setText("Load Data");
|
||||
mb = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
|
||||
|
||||
mb.setMessage("User Input Error!");
|
||||
Font font = shell.getFont();
|
||||
FontData[] fontData = font.getFontData();
|
||||
for (int i = 0; i < fontData.length; i++) {
|
||||
fontData[i].setHeight(7);
|
||||
}
|
||||
newFont = new Font(font.getDevice(), fontData);
|
||||
shell.setFont(newFont);
|
||||
}
|
||||
|
||||
private void createLoadContents(Composite parent) {
|
||||
dialogParent = parent;
|
||||
obsDialog = new D2DNsharpObservedSoundingDialogContents(dialogParent);
|
||||
obsDialog.createObsvdDialogContents();
|
||||
activeLoadSoundingType = OBSER_SND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dialog area
|
||||
*/
|
||||
@Override
|
||||
public Control createDialogArea(Composite parent) {
|
||||
top = (Composite) super.createDialogArea(parent);
|
||||
GridLayout mainLayout = new GridLayout(1, false);
|
||||
mainLayout.marginHeight = 3;
|
||||
mainLayout.marginWidth = 3;
|
||||
createLoadContents(top);
|
||||
if (waitCursor == null)
|
||||
waitCursor = new Cursor(top.getDisplay(), SWT.CURSOR_WAIT);
|
||||
return top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int open() {
|
||||
if (this.getShell() == null) {
|
||||
this.create();
|
||||
}
|
||||
this.getShell().setLocation(
|
||||
this.getShell().getParent().getLocation().x + 1100,
|
||||
this.getShell().getParent().getLocation().y + 200);
|
||||
D2DNsharpMapResource.bringMapEditorToTop();
|
||||
return super.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean close() {
|
||||
cleanSelf();
|
||||
cleanupDialog(activeLoadSoundingType);
|
||||
if (waitCursor != null)
|
||||
waitCursor.dispose();
|
||||
waitCursor = null;
|
||||
newFont.dispose();
|
||||
return (super.close());
|
||||
}
|
||||
|
||||
public boolean closeDiaOnly() {
|
||||
cleanSelf();
|
||||
return (super.close());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createButtonsForButtonBar(Composite parent) {
|
||||
createButton(parent, IDialogConstants.CANCEL_ID,
|
||||
IDialogConstants.CLOSE_LABEL, false);
|
||||
}
|
||||
|
||||
public static D2DNsharpLoadDialog getInstance(Shell parShell) {
|
||||
if (INSTANCE == null) {
|
||||
try {
|
||||
INSTANCE = new D2DNsharpLoadDialog(parShell);
|
||||
} catch (VizException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void startWaitCursor() {
|
||||
if (waitCursor != null)
|
||||
top.setCursor(waitCursor);
|
||||
}
|
||||
|
||||
public void stopWaitCursor() {
|
||||
top.setCursor(null);
|
||||
}
|
||||
|
||||
public static int getDialogWidth() {
|
||||
return DIALOG_WIDTH;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,369 @@
|
|||
/**
|
||||
*
|
||||
* gov.noaa.nws.ncep.ui.nsharp.view.ObservedSoundingDialogContents
|
||||
*
|
||||
* This java class performs the NSHARP D2DNsharpLoadDialog functions.
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 01/2011 229 Chin Chen Initial coding
|
||||
* 09/14/2011 457 S. Gurung Renamed H5UAIR to NCUAIR
|
||||
* 07202015 RM#9173 Chin Chen use NcSoundingQuery.genericSoundingDataQuery() to query grid model sounding data
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.raytheon.uf.viz.d2d.nsharp.display;
|
||||
|
||||
import gov.noaa.nws.ncep.viz.soundingrequest.NcSoundingQuery;
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile;
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfo;
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection;
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingTimeLines;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpConstants;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
|
||||
import com.raytheon.uf.viz.d2d.nsharp.display.map.D2DNsharpMapResource;
|
||||
|
||||
import java.text.DateFormatSymbols;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
|
||||
public class D2DNsharpObservedSoundingDialogContents {
|
||||
private Composite parent;
|
||||
|
||||
private org.eclipse.swt.widgets.List sndTimeList;
|
||||
|
||||
private Group sndTimeListGp, topGp;
|
||||
|
||||
private boolean timeLimit = false;
|
||||
|
||||
private boolean rawData = false;
|
||||
|
||||
private Button timeBtn, bufruaBtn, uairBtn, rawBtn;
|
||||
|
||||
private String FILE_UAIR = "UAIR";
|
||||
|
||||
private String FILE_BUFRUA = "BUFRUA";
|
||||
|
||||
// private String FILE_DROP = "DROP";
|
||||
private NcSoundingProfile.ObsSndType currentSndType = NcSoundingProfile.ObsSndType.NONE;
|
||||
|
||||
private D2DNsharpLoadDialog ldDia;
|
||||
|
||||
private ArrayList<String> selectedTimeList = new ArrayList<String>();
|
||||
|
||||
private Font newFont;
|
||||
|
||||
public boolean isRawData() {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
public NcSoundingProfile.ObsSndType getCurrentSndType() {
|
||||
return currentSndType;
|
||||
}
|
||||
|
||||
public D2DNsharpObservedSoundingDialogContents(Composite parent) {
|
||||
this.parent = parent;
|
||||
ldDia = D2DNsharpLoadDialog.getAccess();
|
||||
newFont = ldDia.getNewFont();
|
||||
}
|
||||
|
||||
private void createObsvdSndUairList() {
|
||||
sndTimeList.removeAll();
|
||||
|
||||
// use NcSoundingQuery to query
|
||||
NcSoundingTimeLines timeLines = NcSoundingQuery
|
||||
.soundingTimeLineQuery(currentSndType.toString());
|
||||
|
||||
if (timeLines != null && timeLines.getTimeLines() != null) {
|
||||
DateFormatSymbols dfs = new DateFormatSymbols();
|
||||
String[] defaultDays = dfs.getShortWeekdays();
|
||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||
ldDia.startWaitCursor();
|
||||
for (Object timeLine : timeLines.getTimeLines()) {
|
||||
Date synoptictime = (Date) timeLine;
|
||||
if (synoptictime != null) {
|
||||
// need to format synoptictime to GMT time string.
|
||||
// Date.toString produce a local time Not GMT time
|
||||
cal.setTimeInMillis(synoptictime.getTime());
|
||||
String dayOfWeek = defaultDays[cal
|
||||
.get(Calendar.DAY_OF_WEEK)];
|
||||
// String gmtTimeStr =
|
||||
// String.format("%1$ty%1$tm%1$td/%1$tH%1$tM %2$s", cal,
|
||||
// currentSndType.toString());
|
||||
String gmtTimeStr = String.format(
|
||||
"%1$ty%1$tm%1$td/%1$tH(%3$s) %2$s", cal,
|
||||
currentSndType.toString(), dayOfWeek);
|
||||
if (!timeLimit) {
|
||||
// System.out.println("not 00z and 12z only");
|
||||
sndTimeList.add(gmtTimeStr);
|
||||
} else {
|
||||
int hour = cal.get(Calendar.HOUR_OF_DAY);
|
||||
// System.out.println("00z and 12z only hour = "+ hour);
|
||||
if ((hour == 0) || (hour == 12))
|
||||
sndTimeList.add(gmtTimeStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
ldDia.stopWaitCursor();
|
||||
} else
|
||||
System.out.println("EDEX timeline query return null");
|
||||
|
||||
}
|
||||
|
||||
private void queryAndMarkStn(String selectedSndTime) {
|
||||
String selectTimetr = NcSoundingQuery
|
||||
.convertSoundTimeDispStringToRangeStartTimeFormat(selectedSndTime);
|
||||
D2DNsharpMapResource nsharpMapResource = D2DNsharpMapResource
|
||||
.getOrCreateNsharpMapResource();
|
||||
// Chin float lat, lon;
|
||||
double lat, lon;
|
||||
String stnInfoStr;
|
||||
|
||||
// use NcSoundingQuery to query stn info
|
||||
NcSoundingStnInfoCollection sndStnInfoCol = NcSoundingQuery.genericSoundingStnInfoQuery(currentSndType.toString(),null, selectTimetr) ;
|
||||
// .soundingStnInfoQuery(currentSndType.toString(), selectTimetr);
|
||||
if (sndStnInfoCol != null && sndStnInfoCol.getStationInfo() != null) {
|
||||
|
||||
NcSoundingStnInfo[] stnInfoAry = sndStnInfoCol.getStationInfo();
|
||||
// System.out.println("obs station number = "+ stnInfoAry.length );
|
||||
// Note: A same station may have many reports
|
||||
for (int i = 0; i < stnInfoAry.length; i++) {
|
||||
NcSoundingStnInfo stnInfo = stnInfoAry[i];
|
||||
Date synoptictime = null;
|
||||
stnInfoStr = stnInfo.getStnId();
|
||||
if (stnInfoStr == null || stnInfoStr.length() < 1)
|
||||
stnInfoStr = "*";
|
||||
lat = stnInfo.getStationLatitude();
|
||||
lon = stnInfo.getStationLongitude();
|
||||
// elv = stnInfo.getStationElevation();
|
||||
synoptictime = (Date) stnInfo.getSynopTime();
|
||||
|
||||
// convert to Nsharp's own station info struct
|
||||
NsharpStationInfo stn = new NsharpStationInfo();
|
||||
String packedStnInfoStr = stnInfoStr.replace(" ", "_");
|
||||
stn.setStnDisplayInfo(packedStnInfoStr + " " + selectedSndTime
|
||||
+ " " + currentSndType.toString());
|
||||
stn.setLongitude(lon);
|
||||
stn.setLatitude(lat);
|
||||
stn.setStnId(stnInfoStr);
|
||||
stn.setReftime(synoptictime);
|
||||
stn.setRangestarttime(synoptictime);
|
||||
stn.setSndType(currentSndType.toString());
|
||||
// System.out.println("sndType= "+currentSndType);
|
||||
// System.out.println("stn lat ="+stn.getLatitude() +
|
||||
// " lon="+stn.getLongitude());
|
||||
nsharpMapResource.addPoint(stn);
|
||||
}
|
||||
|
||||
D2DNsharpMapResource.bringMapEditorToTop();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSndTimeSelection() {
|
||||
String selectedSndTime = null;
|
||||
if (sndTimeList.getSelectionCount() > 0) {
|
||||
D2DNsharpMapResource nsharpMapResource = D2DNsharpMapResource
|
||||
.getOrCreateNsharpMapResource();// D2DNsharpLoadDialog.getAccess().getD2DNsharpMapResource();
|
||||
nsharpMapResource.setPoints(null);
|
||||
selectedTimeList.clear();
|
||||
ldDia.startWaitCursor();
|
||||
for (int i = 0; i < sndTimeList.getSelectionCount(); i++) {
|
||||
selectedSndTime = sndTimeList.getSelection()[i];
|
||||
selectedTimeList.add(selectedSndTime);
|
||||
int endIndex = selectedSndTime.indexOf(" ");
|
||||
String queryingSndTime = selectedSndTime.substring(0, endIndex);
|
||||
queryAndMarkStn(queryingSndTime);
|
||||
|
||||
}
|
||||
ldDia.setObsSelectedTimeList(selectedTimeList);
|
||||
ldDia.stopWaitCursor();
|
||||
}
|
||||
}
|
||||
|
||||
public void createObsvdDialogContents() {
|
||||
currentSndType = ldDia.getActiveObsSndType();
|
||||
timeLimit = false;
|
||||
rawData = false;
|
||||
topGp = new Group(parent, SWT.SHADOW_ETCHED_IN);
|
||||
topGp.setLayout(new GridLayout(2, false));
|
||||
|
||||
bufruaBtn = new Button(topGp, SWT.RADIO | SWT.BORDER);
|
||||
bufruaBtn.setText(FILE_BUFRUA);
|
||||
bufruaBtn.setEnabled(true);
|
||||
bufruaBtn.setBounds(topGp.getBounds().x + NsharpConstants.btnGapX,
|
||||
topGp.getBounds().y + NsharpConstants.labelGap,
|
||||
NsharpConstants.btnWidth, NsharpConstants.btnHeight);
|
||||
bufruaBtn.setFont(newFont);
|
||||
bufruaBtn.addListener(SWT.MouseUp, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
sndTimeList.removeAll();
|
||||
currentSndType = NcSoundingProfile.ObsSndType.BUFRUA;
|
||||
ldDia.setActiveObsSndType(currentSndType);
|
||||
createObsvdSndUairList();
|
||||
}
|
||||
});
|
||||
|
||||
uairBtn = new Button(topGp, SWT.RADIO | SWT.BORDER);
|
||||
uairBtn.setText(FILE_UAIR);
|
||||
uairBtn.setEnabled(true);
|
||||
uairBtn.setBounds(topGp.getBounds().x + NsharpConstants.btnGapX,
|
||||
bufruaBtn.getBounds().y + bufruaBtn.getBounds().height
|
||||
+ NsharpConstants.btnGapY, NsharpConstants.btnWidth,
|
||||
NsharpConstants.btnHeight);
|
||||
uairBtn.setFont(newFont);
|
||||
uairBtn.addListener(SWT.MouseUp, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
sndTimeList.removeAll();
|
||||
currentSndType = NcSoundingProfile.ObsSndType.NCUAIR;
|
||||
ldDia.setActiveObsSndType(currentSndType);
|
||||
createObsvdSndUairList();
|
||||
}
|
||||
});
|
||||
|
||||
timeBtn = new Button(topGp, SWT.CHECK | SWT.BORDER);
|
||||
timeBtn.setText("00Z and 12Z only");
|
||||
timeBtn.setEnabled(true);
|
||||
timeBtn.setFont(newFont);
|
||||
timeBtn.addListener(SWT.MouseUp, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if (timeBtn.getSelection())
|
||||
timeLimit = true;
|
||||
else
|
||||
timeLimit = false;
|
||||
// refresh sounding list if file type is selected already
|
||||
if (currentSndType == NcSoundingProfile.ObsSndType.NCUAIR
|
||||
|| currentSndType == NcSoundingProfile.ObsSndType.BUFRUA) {
|
||||
createObsvdSndUairList();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
rawBtn = new Button(topGp, SWT.CHECK | SWT.BORDER);
|
||||
rawBtn.setText("raw data");
|
||||
rawBtn.setEnabled(true);
|
||||
rawBtn.setBounds(timeBtn.getBounds().x + timeBtn.getBounds().width,
|
||||
timeBtn.getBounds().y, timeBtn.getBounds().width,
|
||||
timeBtn.getBounds().height);
|
||||
rawBtn.setFont(newFont);
|
||||
rawBtn.addListener(SWT.MouseUp, new Listener() {
|
||||
public void handleEvent(Event event) {
|
||||
if (rawBtn.getSelection())
|
||||
rawData = true;
|
||||
else
|
||||
rawData = false;
|
||||
;
|
||||
}
|
||||
});
|
||||
// create file widget list
|
||||
sndTimeListGp = new Group(parent, SWT.SHADOW_NONE);
|
||||
|
||||
sndTimeListGp.setFont(newFont);
|
||||
sndTimeList = new org.eclipse.swt.widgets.List(sndTimeListGp,
|
||||
SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
|
||||
sndTimeList.setBounds(topGp.getBounds().x + NsharpConstants.btnGapX,
|
||||
sndTimeListGp.getBounds().y + NsharpConstants.labelGap,
|
||||
D2DNsharpLoadDialog.getDialogWidth()-40, NsharpConstants.listHeight * 6);
|
||||
sndTimeList.setFont(newFont);
|
||||
|
||||
// create a selection listener to handle user's selection on list
|
||||
sndTimeList.addListener(SWT.Selection, new Listener() {
|
||||
// private String selectedSndTime=null;
|
||||
public void handleEvent(Event e) {
|
||||
handleSndTimeSelection();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (currentSndType == NcSoundingProfile.ObsSndType.NCUAIR
|
||||
|| currentSndType == NcSoundingProfile.ObsSndType.BUFRUA) {
|
||||
if (currentSndType == NcSoundingProfile.ObsSndType.NCUAIR)
|
||||
uairBtn.setSelection(true);
|
||||
else
|
||||
bufruaBtn.setSelection(true);
|
||||
createObsvdSndUairList();
|
||||
selectedTimeList = ldDia.getObsSelectedTimeList();
|
||||
Object[] selTimeObjectArray = selectedTimeList.toArray();
|
||||
String[] selTimeStringArray = Arrays.copyOf(selTimeObjectArray,
|
||||
selTimeObjectArray.length, String[].class);
|
||||
sndTimeList.setSelection(selTimeStringArray);
|
||||
handleSndTimeSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (sndTimeList != null) {
|
||||
sndTimeList.removeListener(SWT.Selection,
|
||||
sndTimeList.getListeners(SWT.Selection)[0]);
|
||||
sndTimeList.dispose();
|
||||
sndTimeList = null;
|
||||
}
|
||||
if (sndTimeListGp != null) {
|
||||
sndTimeListGp.dispose();
|
||||
sndTimeListGp = null;
|
||||
}
|
||||
if (timeBtn != null) {
|
||||
timeBtn.removeListener(SWT.MouseUp,
|
||||
timeBtn.getListeners(SWT.MouseUp)[0]);
|
||||
timeBtn.dispose();
|
||||
timeBtn = null;
|
||||
}
|
||||
if (rawBtn != null) {
|
||||
rawBtn.removeListener(SWT.MouseUp,
|
||||
rawBtn.getListeners(SWT.MouseUp)[0]);
|
||||
rawBtn.dispose();
|
||||
rawBtn = null;
|
||||
}
|
||||
/*
|
||||
* if(browseBtn != null){ browseBtn.removeListener(SWT.MouseUp,
|
||||
* browseBtn.getListeners(SWT.MouseUp)[0]); browseBtn.dispose();
|
||||
* browseBtn = null; }
|
||||
*
|
||||
*
|
||||
* if(tamBtn != null){ tamBtn.removeListener(SWT.MouseUp,
|
||||
* tamBtn.getListeners(SWT.MouseUp)[0]); tamBtn.dispose(); tamBtn =
|
||||
* null; }
|
||||
*/
|
||||
if (bufruaBtn != null) {
|
||||
bufruaBtn.removeListener(SWT.MouseUp,
|
||||
bufruaBtn.getListeners(SWT.MouseUp)[0]);
|
||||
bufruaBtn.dispose();
|
||||
bufruaBtn = null;
|
||||
}
|
||||
if (uairBtn != null) {
|
||||
uairBtn.removeListener(SWT.MouseUp,
|
||||
uairBtn.getListeners(SWT.MouseUp)[0]);
|
||||
uairBtn.dispose();
|
||||
uairBtn = null;
|
||||
}
|
||||
/*
|
||||
* if(newTabBtn != null){ newTabBtn.removeListener(SWT.MouseUp,
|
||||
* newTabBtn.getListeners(SWT.MouseUp)[0]); newTabBtn.dispose();
|
||||
* newTabBtn = null; }
|
||||
*/
|
||||
D2DNsharpLoadDialog ldDia = D2DNsharpLoadDialog.getAccess();
|
||||
if (topGp != null) {
|
||||
topGp.dispose();
|
||||
topGp = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
*
|
||||
* com.raytheon.uf.viz.d2d.nsharp.display.map.D2DNsharpMapMouseHandler
|
||||
*
|
||||
* This java class performs the NSHARP Modal functions.
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 03/23/2010 229 Chin Chen Initial coding
|
||||
* 03/11/2013 972 Greg Hull NatlCntrsEditor
|
||||
* 09/28/2015 RM#10295 Chin Chen Let sounding data query run in its own thread to avoid gui locked out during load
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.raytheon.uf.viz.d2d.nsharp.display.map;
|
||||
|
||||
import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.display.map.NsharpObservedSoundingQuery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.ui.progress.UIJob;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.viz.core.map.IMapDescriptor;
|
||||
import com.raytheon.uf.viz.d2d.nsharp.display.D2DNsharpLoadDialog;
|
||||
import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||
import com.raytheon.viz.ui.input.InputAdapter;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
||||
public class D2DNsharpMapMouseHandler extends InputAdapter {
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(D2DNsharpMapMouseHandler.class);
|
||||
|
||||
public D2DNsharpMapMouseHandler() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private static final double NctextuiPointMinDistance = 45000;
|
||||
|
||||
private static D2DNsharpMapMouseHandler instance;
|
||||
|
||||
private double lat, lon;
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public double getLon() {
|
||||
return lon;
|
||||
}
|
||||
|
||||
public static D2DNsharpMapMouseHandler getAccess() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (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;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.ui.input.IInputHandler#handleMouseDownMove(int,
|
||||
* int, int) handle left button, so user be able to shift map while it is
|
||||
* down
|
||||
*/
|
||||
@Override
|
||||
public boolean handleMouseDownMove(int x, int y, int button) {
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseMove(int x, int y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.ui.input.IInputHandler#handleMouseUp(int, int, int)
|
||||
* handle right button, so user be able to pick stn and print text report
|
||||
*/
|
||||
@Override
|
||||
public boolean handleMouseUp(int x, int y, int button) {
|
||||
if (!D2DNsharpMapResource.getMapRsc().isEditable())
|
||||
return false;
|
||||
// button 1 is left mouse button
|
||||
if (button == 1) {
|
||||
AbstractEditor mapEditor = D2DNsharpMapResource.getMapEditor();
|
||||
if (mapEditor != null) {
|
||||
// Check if mouse is in geographic extent
|
||||
Coordinate loc = mapEditor.translateClick(x, y);
|
||||
if (loc == null)
|
||||
return false;
|
||||
D2DNsharpLoadDialog loadDia = D2DNsharpLoadDialog.getAccess();
|
||||
if (loadDia != null) {
|
||||
int activeLoadType = loadDia
|
||||
.getActiveLoadSoundingType();
|
||||
List<NsharpStationInfo> points = D2DNsharpMapResource
|
||||
.getOrCreateNsharpMapResource().getPoints();
|
||||
if (points.isEmpty() == false) {
|
||||
|
||||
// get the stn close to loc "enough" and retrieve
|
||||
// report for it
|
||||
// Note::One stn may have more than one dataLine, if
|
||||
// user picked multiple data time lines
|
||||
List<NsharpStationInfo> stnPtDataLineLst = getPtWithinMinDist(
|
||||
points, loc);
|
||||
if (stnPtDataLineLst != null
|
||||
&& stnPtDataLineLst.size() > 0) {
|
||||
// hash map, use stn display info as key
|
||||
Map<String, List<NcSoundingLayer>> soundingLysLstMap = new HashMap<String, List<NcSoundingLayer>>();
|
||||
// String soundingType;
|
||||
if (activeLoadType == D2DNsharpLoadDialog.OBSER_SND) {
|
||||
NsharpObservedSoundingQuery obsQry = new NsharpObservedSoundingQuery(
|
||||
"Querying Sounding Data...");
|
||||
obsQry.getObservedSndData(stnPtDataLineLst,
|
||||
loadDia.getObsDialog().isRawData(),
|
||||
soundingLysLstMap);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (button == 3) {
|
||||
// button 3 is right button.
|
||||
bringSkewTEdToTop();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Chin Note: If calling NsharpEditor.bringSkewTEditorToTop() directly in
|
||||
* mouse handler API, e.g. handleMouseUp(), then handleMouseUp() will be
|
||||
* called one more time by System. Do not know the root cause of it. To
|
||||
* avoid handling such event twice (e.g. query sounding data twice), we will
|
||||
* call NsharpEditor.bringSkewTEditorToTop() from an UiJob.
|
||||
*/
|
||||
private void bringSkewTEdToTop() {
|
||||
Job uijob = new UIJob("bring skewT to top") {
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
NsharpEditor.bringEditorToTop();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
};
|
||||
uijob.setSystem(true);
|
||||
uijob.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nearest point of an selected element to the input point
|
||||
*
|
||||
* @param el
|
||||
* element
|
||||
* @param pt
|
||||
* input point
|
||||
* @return
|
||||
*/
|
||||
private List<NsharpStationInfo> getPtWithinMinDist(
|
||||
List<NsharpStationInfo> points, Coordinate pt) {
|
||||
|
||||
NsharpStationInfo thePoint = null;
|
||||
double minDistance = NctextuiPointMinDistance;
|
||||
GeodeticCalculator gc;
|
||||
List<NsharpStationInfo> thePoints = new ArrayList<NsharpStationInfo>();
|
||||
// can't assume this is a map Editor/MapDescriptor
|
||||
AbstractEditor mapEditor = D2DNsharpMapResource.getMapEditor();
|
||||
if (mapEditor != null) {
|
||||
IMapDescriptor desc = (IMapDescriptor) mapEditor
|
||||
.getActiveDisplayPane().getRenderableDisplay()
|
||||
.getDescriptor();
|
||||
gc = new GeodeticCalculator(desc.getCRS());
|
||||
gc.setStartingGeographicPoint(pt.x, pt.y);
|
||||
for (NsharpStationInfo point : points) {
|
||||
|
||||
gc.setDestinationGeographicPoint(point.getLongitude(),
|
||||
point.getLatitude());
|
||||
double dist;
|
||||
try {
|
||||
dist = gc.getOrthodromicDistance();
|
||||
if (dist < minDistance) {
|
||||
|
||||
minDistance = dist;
|
||||
thePoint = point;
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
// Chin, there may be more than one point for a selected stn. As
|
||||
// user may selected more than one data time,
|
||||
// For same stn, each data time will have one point to represent it.
|
||||
// So, a stn may have more than one points
|
||||
if (thePoint != null) {
|
||||
for (NsharpStationInfo point : points) {
|
||||
if ((thePoint.getLatitude() == point.getLatitude())
|
||||
&& (thePoint.getLongitude() == point.getLongitude())) {
|
||||
thePoints.add(point);
|
||||
}
|
||||
}
|
||||
|
||||
// marked X on selected point
|
||||
D2DNsharpMapResource.getOrCreateNsharpMapResource()
|
||||
.setPickedPoint(thePoint);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return thePoints;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,483 @@
|
|||
package com.raytheon.uf.viz.d2d.nsharp.display.map;
|
||||
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpConstants;
|
||||
import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Cursor;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
|
||||
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.PixelExtent;
|
||||
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.ResourceList.RemoveListener;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||
import com.raytheon.viz.ui.input.EditableManager;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
*
|
||||
* com.raytheon.uf.viz.d2d.nsharp.display.map.D2DNsharpMapResource
|
||||
*
|
||||
* This java class performs the NSHARP Resource functions.
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 03/23/2010 229 Chin Chen Initial coding
|
||||
* 08/17/2012 655 B. Hebbard Added paintProps as parameter to IDisplayable draw (2)
|
||||
* 03/11/2013 972 Greg Hull NatlCntrsEditor
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class D2DNsharpMapResource extends
|
||||
AbstractVizResource<D2DNsharpMapResourceData, MapDescriptor> implements
|
||||
RemoveListener {
|
||||
private static D2DNsharpMapResource mapRsc = null;
|
||||
|
||||
private static D2DNsharpMapResourceData mapRscData = null;
|
||||
|
||||
private static AbstractEditor mapEditor = null;
|
||||
|
||||
private static D2DNsharpMapMouseHandler mouseHandler;
|
||||
|
||||
private static Cursor waitCursor = null;
|
||||
|
||||
private static Control cursorControl;
|
||||
|
||||
private static boolean mouseHandlerRegistered = false;
|
||||
|
||||
public static void bringMapEditorToTop() {
|
||||
// get current map editor, if non existent create one.
|
||||
try {
|
||||
if (mapEditor != null
|
||||
&& PlatformUI.getWorkbench() != null
|
||||
&& PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
|
||||
&& PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
||||
.getActivePage() != null) {
|
||||
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
||||
.getActivePage().bringToTop(mapEditor);
|
||||
mapEditor.refresh();
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
public static AbstractEditor getMapEditor() {
|
||||
return mapEditor;
|
||||
}
|
||||
|
||||
public static D2DNsharpMapResource getMapRsc() {
|
||||
return mapRsc;
|
||||
}
|
||||
|
||||
private D2DNsharpMapResourceData nsharpMapResourceData;
|
||||
|
||||
/** The set of symbols with similar attributes across many locations */
|
||||
private List<DrawableCircle> symbolSet = null;
|
||||
|
||||
private List<DrawableString> symbolText = null;
|
||||
|
||||
private DrawableCircle symbolToMark = null;
|
||||
|
||||
private List<NsharpStationInfo> points = new ArrayList<NsharpStationInfo>();
|
||||
|
||||
private List<NsharpStationInfo> pickedPoint = new ArrayList<NsharpStationInfo>();
|
||||
|
||||
public void setPickedPoint(NsharpStationInfo point) {
|
||||
this.pickedPoint.add(point);
|
||||
}
|
||||
|
||||
public List<NsharpStationInfo> getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
public void setPoints(List<NsharpStationInfo> points) {
|
||||
if (points == null) {
|
||||
this.pickedPoint.clear();
|
||||
symbolToMark = null;
|
||||
symbolSet = null;
|
||||
this.points.clear();
|
||||
} else {
|
||||
this.points = points;
|
||||
}
|
||||
}
|
||||
|
||||
public void addPoint(NsharpStationInfo point) {
|
||||
points.add(point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
protected D2DNsharpMapResource(D2DNsharpMapResourceData d2dNsharpMapResourceData,
|
||||
LoadProperties loadProperties) {
|
||||
super(d2dNsharpMapResourceData, loadProperties);
|
||||
getCapability(EditableCapability.class).setEditable(true);
|
||||
this.nsharpMapResourceData = d2dNsharpMapResourceData;
|
||||
}
|
||||
|
||||
public static void startWaitCursor() {
|
||||
waitCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT);
|
||||
cursorControl = Display.getCurrent().getCursorControl();
|
||||
if (cursorControl != null && waitCursor != null)
|
||||
cursorControl.setCursor(waitCursor);
|
||||
}
|
||||
|
||||
public static void stopWaitCursor() {
|
||||
if (cursorControl != null && waitCursor != null) {
|
||||
cursorControl.setCursor(null);
|
||||
}
|
||||
if (waitCursor != null) {
|
||||
waitCursor.dispose();
|
||||
waitCursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void createMapEditor() {
|
||||
try {
|
||||
mapEditor = (AbstractEditor) EditorUtil.getActiveEditor();
|
||||
} catch (Exception ve) {
|
||||
System.out
|
||||
.println("D2DNsharpMapResource Could not load initial editor: "
|
||||
+ ve.getMessage());
|
||||
ve.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerMouseHandler() {
|
||||
if (mouseHandlerRegistered)
|
||||
return;
|
||||
|
||||
mouseHandler = getMouseHandler();
|
||||
if (mapEditor != null && mouseHandler != null) {
|
||||
mapEditor.registerMouseHandler((IInputHandler) mouseHandler);
|
||||
mouseHandlerRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregisterMouseHandler() {
|
||||
if (!mouseHandlerRegistered)
|
||||
return;
|
||||
mouseHandler = getMouseHandler();
|
||||
if (mapEditor != null && mouseHandler != null) {
|
||||
mapEditor.unregisterMouseHandler((IInputHandler) mouseHandler);
|
||||
mouseHandlerRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MapResource and add it to the current editor.
|
||||
*
|
||||
* @return the MapResource
|
||||
*/
|
||||
public static D2DNsharpMapResource getOrCreateNsharpMapResource() {
|
||||
if (mapRsc == null) {
|
||||
if (mapEditor == null) {
|
||||
createMapEditor();
|
||||
}
|
||||
if (mapEditor != null) {
|
||||
IMapDescriptor desc = (IMapDescriptor) mapEditor
|
||||
.getActiveDisplayPane().getRenderableDisplay()
|
||||
.getDescriptor();
|
||||
try {
|
||||
if (mapRscData == null)
|
||||
mapRscData = new D2DNsharpMapResourceData();
|
||||
mapRsc = mapRscData.construct(new LoadProperties(), desc);
|
||||
desc.getResourceList().add(mapRsc);
|
||||
mapRsc.init(mapEditor.getActiveDisplayPane().getTarget());
|
||||
|
||||
// register mouse handler
|
||||
mouseHandler = getMouseHandler();
|
||||
mapEditor
|
||||
.registerMouseHandler((IInputHandler) mouseHandler);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mapRsc;
|
||||
}
|
||||
|
||||
public static void deleteNsharpMapResource() {
|
||||
if (mapRsc != null) {
|
||||
mapRsc.dispose();
|
||||
mapRsc = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
pickedPoint = null;
|
||||
points = null;
|
||||
symbolSet = null;
|
||||
symbolToMark = null;
|
||||
mapRsc = null;
|
||||
mapRscData = null;
|
||||
if (waitCursor != null)
|
||||
waitCursor.dispose();
|
||||
waitCursor = null;
|
||||
mouseHandlerRegistered = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.rsc.IVizResource#getCoordinateReferenceSystem()
|
||||
*/
|
||||
public CoordinateReferenceSystem getCoordinateReferenceSystem() {
|
||||
if (descriptor == null)
|
||||
return null;
|
||||
return descriptor.getCRS();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see com.raytheon.viz.core.rsc.IVizResource#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NSHARP Display";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 = null;
|
||||
|
||||
symbolText = new ArrayList<DrawableString>(mapRsc.getPoints().size());
|
||||
symbolSet = new ArrayList<DrawableCircle>(mapRsc.getPoints().size());
|
||||
|
||||
if (points.isEmpty() == true) {
|
||||
symbolSet = null;
|
||||
} else {
|
||||
Coordinate[] locations = new Coordinate[points.size()];
|
||||
int i = 0;
|
||||
type = nsharpMapResourceData.getMarkerType().toString();
|
||||
for (NsharpStationInfo p : points) {
|
||||
double lon, lat;
|
||||
lon = p.getLongitude();
|
||||
lat = p.getLatitude();
|
||||
locations[i++] = new Coordinate(lon, lat);
|
||||
|
||||
DrawableCircle circle = new DrawableCircle();
|
||||
double[] pixel = descriptor.worldToPixel(new double[] { lon, lat });
|
||||
circle.setCoordinates(pixel[0], pixel[1]);
|
||||
circle.lineWidth = nsharpMapResourceData.getMarkerWidth();
|
||||
circle.screenRadius = getRadius()*1.4;
|
||||
circle.basics.color = NsharpConstants.color_green;
|
||||
circle.filled = false;
|
||||
symbolSet.add(circle);
|
||||
|
||||
DrawableString drawString = new DrawableString(p.getStnId());
|
||||
drawString.basics.color = NsharpConstants.color_white;
|
||||
drawString.setCoordinates(pixel[0], pixel[1]);
|
||||
drawString.setText(p.getStnId(), NsharpConstants.color_white);
|
||||
symbolText.add(drawString);
|
||||
}
|
||||
}
|
||||
|
||||
// generate symbol for picked stn to mark X
|
||||
if (pickedPoint != null && pickedPoint.size() > 0) {
|
||||
Coordinate[] locations = new Coordinate[pickedPoint.size()];
|
||||
type = nsharpMapResourceData.getStnMarkerType().toString();
|
||||
|
||||
int i = 0;
|
||||
for (NsharpStationInfo p : pickedPoint) {
|
||||
double lon, lat;
|
||||
lon = p.getLongitude();
|
||||
lat = p.getLatitude();
|
||||
locations[i++] = new Coordinate(lon, lat);
|
||||
|
||||
DrawableCircle circle = new DrawableCircle();
|
||||
double[] pixel = descriptor.worldToPixel(new double[] { lon, lat });
|
||||
circle.setCoordinates(pixel[0], pixel[1]);
|
||||
circle.lineWidth = nsharpMapResourceData.getMarkerWidth();
|
||||
circle.screenRadius = getRadius()*1.4;
|
||||
circle.basics.color = NsharpConstants.color_red;
|
||||
circle.filled = false;
|
||||
symbolSet.add(circle);
|
||||
|
||||
}
|
||||
} else {
|
||||
symbolToMark = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected double getRadius() {
|
||||
return 5 * getCapability(MagnificationCapability.class)
|
||||
.getMagnification();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 {
|
||||
|
||||
generateSymbolForDrawing();
|
||||
if (symbolSet != null) {
|
||||
target.drawCircle(symbolSet.toArray(new DrawableCircle[0]));
|
||||
target.drawStrings(symbolText);
|
||||
}
|
||||
|
||||
// if (symbolToMark != null) {
|
||||
// ArrayList<IDisplayable> elements = df.createDisplayElements(
|
||||
// symbolToMark, paintProps);
|
||||
// for (IDisplayable each : elements) {
|
||||
// try {
|
||||
// each.draw(target, paintProps);
|
||||
// each.dispose();
|
||||
// } catch (Exception e) {e.printStackTrace();}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
* (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 {
|
||||
// System.out.println("NctextuiResource: project ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mouse handler.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static D2DNsharpMapMouseHandler getMouseHandler() {
|
||||
|
||||
if (mouseHandler == null) {
|
||||
|
||||
mouseHandler = new D2DNsharpMapMouseHandler();
|
||||
|
||||
}
|
||||
|
||||
return mouseHandler;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean okToUnload() {
|
||||
/*
|
||||
* DisAllow unloading of Resource
|
||||
*/
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyRemove(ResourcePair rp) throws VizException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package com.raytheon.uf.viz.d2d.nsharp.display.map;
|
||||
|
||||
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 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* com.raytheon.uf.viz.d2d.nsharp.display.map.D2DNsharpMapResourceData
|
||||
*
|
||||
* This java class performs the NSHARP ResourceData functions.
|
||||
* This code has been developed by the NCEP-SIB for use in the AWIPS2 system.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------- ------- -------- -----------
|
||||
* 03/23/2010 229 Chin Chen Initial coding
|
||||
* 06/15/2023 tiffanym@ucar Added into Unidata v20.3.2
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Chin Chen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class D2DNsharpMapResourceData extends AbstractResourceData {
|
||||
|
||||
private MarkerState markerState = MarkerState.MARKER_ONLY;
|
||||
|
||||
private MarkerType markerType = MarkerType.DIAMOND;
|
||||
|
||||
private Float markerSize = 1f;
|
||||
|
||||
private Integer markerWidth = 2;
|
||||
|
||||
private MarkerTextSize markerTextSize = MarkerTextSize.MEDIUM;
|
||||
|
||||
private String mapName = "NSHARP";
|
||||
|
||||
private MarkerType stnMarkerType = MarkerType.LARGE_X;
|
||||
|
||||
public MarkerType getStnMarkerType() {
|
||||
return stnMarkerType;
|
||||
}
|
||||
|
||||
public D2DNsharpMapResourceData() {
|
||||
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 D2DNsharpMapResource construct(LoadProperties loadProperties,
|
||||
IDescriptor descriptor) throws VizException {
|
||||
// TODO Auto-generated method stub
|
||||
return new D2DNsharpMapResource(this, loadProperties);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object
|
||||
* )
|
||||
*/
|
||||
@Override
|
||||
public void update(Object updateData) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof D2DNsharpMapResourceData))
|
||||
return false;
|
||||
D2DNsharpMapResourceData rdata = (D2DNsharpMapResourceData) 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.stnMarkerType.equals(rdata.getStnMarkerType()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -73,6 +73,7 @@ import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
|
|||
* Jan 15, 2019 7697 bsteffen Individually add soundings so station info
|
||||
* is not shared.
|
||||
* Apr 15 2019 7480 bhurley Improved auto-update
|
||||
* Jun 15, 2023 tiffanym@ucar reimplement NSHARP load functionality
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -212,8 +213,8 @@ public class D2DNSharpResource
|
|||
@Override
|
||||
protected void initInternal(IGraphicsTarget target) throws VizException {
|
||||
getHandler().setSoundingType(resourceData.getSoundingType());
|
||||
partListener = new D2DNSharpPartListener(this);
|
||||
partListener.enable();
|
||||
//partListener = new D2DNSharpPartListener(this);
|
||||
//partListener.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
BIN
cave/com.raytheon.uf.viz.d2d.ui/icons/nsharp.png
Normal file
BIN
cave/com.raytheon.uf.viz.d2d.ui/icons/nsharp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
|
@ -620,6 +620,20 @@
|
|||
</toolbar>
|
||||
<toolbar
|
||||
id="applications">
|
||||
<command
|
||||
commandId="com.raytheon.uf.viz.d2d.nsharp.dialog"
|
||||
icon="icons/nsharp.png"
|
||||
id="com.raytheon.uf.viz.d2d.nsharp.dialog"
|
||||
label="Nsharp"
|
||||
mode="FORCE_TEXT"
|
||||
style="push"
|
||||
tooltip="Nsharp">
|
||||
<visibleWhen>
|
||||
<reference
|
||||
definitionId="com.raytheon.uf.viz.d2d.ui.inD2DActionSet">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
<command
|
||||
commandId="com.raytheon.uf.viz.productbrowser.productBrowser"
|
||||
icon="icons/plus.png"
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<includes
|
||||
id="com.raytheon.uf.common.base.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.foss.org.apache.commons.management.feature"
|
||||
version="0.0.0"/>
|
||||
|
@ -283,4 +284,8 @@
|
|||
id="com.raytheon.uf.edex.goesr.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.ncep.nco.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
</feature>
|
||||
|
|
Loading…
Add table
Reference in a new issue