Merge branch 'ss_builds' (12.11.1-3) into development
Conflicts: cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/TextEditorDialog.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/AbstractDbSourceDataAdaptor.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbPointSourceDataAdaptor.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPoint.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPointComparator.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java Former-commit-id:63ffdac2b7
[formerly0a42cb87a4
[formerly 5ebfa0e773d325c57ac8097b46537817d5d47842]] Former-commit-id:0a42cb87a4
Former-commit-id:8b7665418a
This commit is contained in:
commit
6659a96ac6
36 changed files with 1095 additions and 1151 deletions
|
@ -71,6 +71,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Feb 04, 2011 7953 bkowal Fill values will now be placed
|
||||
* in the data array for anything
|
||||
* below 300MB for RUC80.
|
||||
* Oct 2, 2012 DR 15259 M.Porricelli Allow plotting when 3 levels
|
||||
* available (DGEX)
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -145,7 +147,7 @@ public class GribCSAdapter extends AbstractCrossSectionAdapter<GribRecord> {
|
|||
}
|
||||
}
|
||||
|
||||
if (xMap.size() < 4) {
|
||||
if (xMap.size() < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -159,7 +161,7 @@ public class GribCSAdapter extends AbstractCrossSectionAdapter<GribRecord> {
|
|||
xMap.keySet().retainAll(yMap.keySet());
|
||||
yMap.keySet().retainAll(xMap.keySet());
|
||||
|
||||
if (xMap.size() < 4) {
|
||||
if (xMap.size() < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ import com.raytheon.viz.core.gl.SharedCoordMap.SharedCoordinateKey;
|
|||
*
|
||||
* SOFTWARE HISTORY Date Ticket# Engineer Description ------------ ----------
|
||||
* ----------- -------------------------- Jun 10, 2010 mschenke Initial creation
|
||||
*
|
||||
* OCT 09, 2012 15018 kshresth
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -408,6 +408,12 @@ public class RadarRadialMesh extends AbstractGLMesh {
|
|||
if (jStart == null) {
|
||||
jStart = 0;
|
||||
}
|
||||
|
||||
//check if numBins and numRadials equals to zero, then angleData does not exist
|
||||
if (numBins == 0 && numRadials == 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
float[] angleData = radarData.getAngleData();
|
||||
CacheKey key = new CacheKey(latitude, longitude, numBins, numRadials,
|
||||
gateResolution, trueElevationAngle, jStart, angleData,
|
||||
|
|
|
@ -10,6 +10,18 @@ import java.util.List;
|
|||
import com.raytheon.uf.viz.xy.graph.IGraph;
|
||||
import com.raytheon.viz.core.graphing.xy.XYData;
|
||||
|
||||
/**
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ?? ?? Initial creation
|
||||
* Oct 2, 2012 DR 15259 M.Porricelli Interpolate below 850MB
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
public class InterpUtils {
|
||||
|
||||
/**
|
||||
|
@ -55,6 +67,10 @@ public class InterpUtils {
|
|||
double maxYAxisVal = ((Number) dataList.get(0).getY()).doubleValue();
|
||||
double minYAxisVal = ((Number) dataList.get(dataList.size() - 1).getY())
|
||||
.doubleValue();
|
||||
// Allow interpolation below 850 when this is lowest level
|
||||
if (maxYAxisVal == 850.0){
|
||||
maxYAxisVal = 1000.0;
|
||||
}
|
||||
|
||||
if (maxYAxisVal < minYAxisVal) {
|
||||
double tmp = maxYAxisVal;
|
||||
|
|
|
@ -96,7 +96,12 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* The actionListeners for certain controls
|
||||
* have been updated so that they will set it
|
||||
* to true when an update is actually required.
|
||||
*
|
||||
*
|
||||
* 03 OCT 2012 #15395 Added code to handle TimeStep when default is set
|
||||
* to be "30 minutes Instantaneous" in the database.
|
||||
* 09 OCT 2012 #15396 Fixed Instantaneous precip index so legend and map display
|
||||
* will change each time duration is incremented or decremented
|
||||
* for the "30 minutes Instantaneous" rainfall map .
|
||||
* </pre>
|
||||
*
|
||||
* @author lvenable
|
||||
|
@ -599,6 +604,20 @@ public class PointDataControlDlg extends CaveSWTDialog {
|
|||
timeTF.setText(dateTimeFmt.format(cal.getTime()));
|
||||
|
||||
populatePresetData(null);
|
||||
|
||||
/* this is when in the database, the timeStep is set to be the
|
||||
default one */
|
||||
|
||||
if (timeStepRdo.getSelection() == true) {
|
||||
handleQueryModeSelection(PDCConstants.QueryMode.TIME_STEP_MODE);
|
||||
previousQueryMode = PDCConstants.QueryMode.TIME_STEP_MODE;
|
||||
shell.setCursor(waitCursor);
|
||||
updateData = true;
|
||||
drawMap();
|
||||
shell.setCursor(arrowCursor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -853,11 +872,18 @@ public class PointDataControlDlg extends CaveSWTDialog {
|
|||
upPrecipBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
PDCOptionData pcOptions = PDCOptionData.getInstance();
|
||||
if (precipIndex >= HydroConstants.InstPrecipSelection.values().length - 1) {
|
||||
precipIndex = 0;
|
||||
} else {
|
||||
precipIndex++;
|
||||
if (precipIndex == HydroConstants.InstPrecipSelection.
|
||||
values().length - 1) {
|
||||
precipIndex=0;
|
||||
}
|
||||
|
||||
}
|
||||
pcOptions.setInstPrecipAccumTimeSelection(precipIndex);
|
||||
setInstPrecipAccumText();
|
||||
shell.setCursor(waitCursor);
|
||||
updateData = true;
|
||||
|
@ -871,11 +897,21 @@ public class PointDataControlDlg extends CaveSWTDialog {
|
|||
downPrecipBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
PDCOptionData pcOptions = PDCOptionData.getInstance();
|
||||
if (precipIndex == 0) {
|
||||
precipIndex = HydroConstants.InstPrecipSelection.values().length - 1;
|
||||
precipIndex = HydroConstants.InstPrecipSelection.
|
||||
values().length - 1;
|
||||
if (precipIndex == HydroConstants.InstPrecipSelection.
|
||||
values().length - 1) {
|
||||
precipIndex=HydroConstants.InstPrecipSelection.
|
||||
values().length - 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
precipIndex--;
|
||||
}
|
||||
|
||||
pcOptions.setInstPrecipAccumTimeSelection(precipIndex);
|
||||
setInstPrecipAccumText();
|
||||
shell.setCursor(waitCursor);
|
||||
updateData = true;
|
||||
|
|
|
@ -43,7 +43,10 @@ import com.raytheon.viz.hydrocommon.data.LocationData;
|
|||
* Sep 09, 2009 2769 mpduff Added copyTableData method and the calls
|
||||
* to it for copying data from one table to another.
|
||||
* Oct 20, 2011 11266 lbousaidi added getHSAsForFilter() method to query from
|
||||
* location table instead of hsa table.
|
||||
* location table instead of hsa table.
|
||||
* Oct 05, 2011 15333 lbousaidi changed the queries that retrieves the HSAs from
|
||||
* the database.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author askripsky
|
||||
|
@ -170,15 +173,14 @@ public class AddModifyLocationDataManager extends HydroDataManager {
|
|||
public ArrayList<String> getHSAs() throws VizException {
|
||||
ArrayList<String> rval = new ArrayList<String>();
|
||||
|
||||
String query = "Select hsa from hsa order by hsa";
|
||||
|
||||
String query= "SELECT DISTINCT upper(hsa) from hsa order by upper (hsa)";
|
||||
QueryResult data = HydroDBDataManager.getInstance().runMappedQuery(
|
||||
query);
|
||||
|
||||
if (data != null) {
|
||||
for (QueryResultRow currNet : data.getRows()) {
|
||||
rval.add((String) currNet.getColumn(data.getColumnNames().get(
|
||||
"hsa")));
|
||||
"upper")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,16 +219,16 @@ public class AddModifyLocationDataManager extends HydroDataManager {
|
|||
*/
|
||||
public ArrayList<String> getWFOs() throws VizException {
|
||||
ArrayList<String> rval = new ArrayList<String>();
|
||||
|
||||
String query = "Select wfo from wfo order by wfo";
|
||||
|
||||
|
||||
String query= "SELECT DISTINCT upper(wfo) from wfo order by upper (wfo)";
|
||||
|
||||
QueryResult data = HydroDBDataManager.getInstance().runMappedQuery(
|
||||
query);
|
||||
|
||||
if (data != null) {
|
||||
for (QueryResultRow currNet : data.getRows()) {
|
||||
rval.add((String) currNet.getColumn(data.getColumnNames().get(
|
||||
"wfo")));
|
||||
"upper")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 15, 2009 mschenke Initial creation
|
||||
* OCT 04, 2012 15132 kshresth Restored "MSAS/LDAD QC plots" display data
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -38,7 +39,8 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
*/
|
||||
|
||||
public class PlotInfo {
|
||||
|
||||
public Integer id;
|
||||
|
||||
public String stationId;
|
||||
|
||||
public Double latitude;
|
||||
|
@ -76,4 +78,16 @@ public class PlotInfo {
|
|||
this.plotQueued = false;
|
||||
this.sampleQueued = false;
|
||||
}
|
||||
|
||||
public PlotInfo(String stationId, Double latitude,
|
||||
Double longitude, DataTime dataTime, String dataURI, Integer id) {
|
||||
this.stationId = stationId;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.dataTime = dataTime;
|
||||
this.dataURI = dataURI;
|
||||
this.id = id;
|
||||
this.plotQueued = false;
|
||||
this.sampleQueued = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ import com.raytheon.viz.pointdata.thread.PlotSampleGeneratorJob;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 22, 2011 njensen Initial creation
|
||||
* OCT 04, 2012 15132 kshresth Restored "MSAS/LDAD QC plots" display data
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -179,7 +180,7 @@ public class PlotModelDataRequestJob extends Job {
|
|||
|
||||
private void requestData(List<PlotInfo[]> stationQuery,
|
||||
List<PlotModelElement> pme) {
|
||||
Map<String, PlotInfo> plotMap = new HashMap<String, PlotInfo>();
|
||||
Map<Integer, PlotInfo> plotMap = new HashMap<Integer, PlotInfo>();
|
||||
List<String> params = new ArrayList<String>();
|
||||
|
||||
for (PlotModelElement p : pme) {
|
||||
|
@ -204,8 +205,8 @@ public class PlotModelDataRequestJob extends Job {
|
|||
List<String> str = new ArrayList<String>(stationQuery.size());
|
||||
for (PlotInfo[] infos : stationQuery) {
|
||||
for (PlotInfo info : infos) {
|
||||
str.add(info.dataURI);
|
||||
plotMap.put(info.dataURI, info);
|
||||
str.add(Integer.toString(info.id));
|
||||
plotMap.put(info.id, info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +220,7 @@ public class PlotModelDataRequestJob extends Job {
|
|||
index++;
|
||||
j++;
|
||||
}
|
||||
map.put("dataURI", rc);
|
||||
map.put("id", rc);
|
||||
try {
|
||||
// Try and get data from datacube
|
||||
long t0 = System.currentTimeMillis();
|
||||
|
@ -243,8 +244,8 @@ public class PlotModelDataRequestJob extends Job {
|
|||
for (int uriCounter = 0; uriCounter < pdc.getAllocatedSz(); uriCounter++) {
|
||||
PointDataView pdv = pdc.readRandom(uriCounter);
|
||||
if (pdv != null) {
|
||||
String dataURI = pdv.getString("dataURI");
|
||||
PlotInfo info = plotMap.get(dataURI);
|
||||
int id = pdv.getInt("id");
|
||||
PlotInfo info = plotMap.get(id);
|
||||
// If the id doesn't match, try to match by
|
||||
// location
|
||||
if (info == null) {
|
||||
|
@ -257,6 +258,8 @@ public class PlotModelDataRequestJob extends Job {
|
|||
- pdv.getFloat("longitude"));
|
||||
if (diffLat < 0.01 && diffLon < 0.01) {
|
||||
info = pi;
|
||||
pdv.setInt("id", pi.id);
|
||||
id = pi.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ import com.raytheon.viz.pointdata.PlotInfo;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 9, 2009 bsteffen Initial creation
|
||||
*
|
||||
* OCT 4, 2012 15132 kshresth Restored "MSAS/LDAD QC plots" display data
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
|
@ -76,6 +76,7 @@ public class PointDataPlotInfoRetriever extends AbstractDbPlotInfoRetriever {
|
|||
} else {
|
||||
dq.addColumn("dataTime");
|
||||
}
|
||||
dq.addColumn("id");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,7 +104,7 @@ public class PointDataPlotInfoRetriever extends AbstractDbPlotInfoRetriever {
|
|||
statusHandler.handle(Priority.CRITICAL, message, new Exception(
|
||||
message));
|
||||
}
|
||||
|
||||
stationInfo.id = (Integer) data[5];
|
||||
return stationInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -291,6 +291,8 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox;
|
|||
* 10SEP2012 15401 D.Friedman Fix QC problem caused by DR 15340.
|
||||
* 20SEP2012 1196 rferrel Refactor dialogs to prevent blocking.
|
||||
* 25SEP2012 1196 lvenable Refactor dialogs to prevent blocking.
|
||||
* 27SEP2012 15424 S.Naples Set focus on AFOS command text field after executing retrieval of product.
|
||||
* 09Oct2012 14889 M.Gamazaychikov Add call to checkAndWrapPreviousLine
|
||||
* 26SEP2012 1196 lvenable Refactor dialogs to prevent blocking.
|
||||
* 27SEP2012 1196 rferrel Changes for non-blocking ScriptOutputDlg.
|
||||
* 01OCT2012 1229 rferrel Change WmoBrowserDlg to non-blocking
|
||||
|
@ -346,6 +348,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* When auto wrapping the last line that needs to be wrapped.
|
||||
*/
|
||||
private int endWrapLine = -1;
|
||||
|
||||
/**
|
||||
* Last line was wrapped backwards
|
||||
*/
|
||||
private boolean isPreviousLineWrapped = false;
|
||||
|
||||
|
||||
private static final String PARAGRAPH_DELIMITERS = "*$.-/^#";
|
||||
|
||||
|
@ -960,7 +968,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
/**
|
||||
* flag to indicate it a product request is from the GUI or an updated ob.
|
||||
*/
|
||||
private AtomicInteger updateCount = new AtomicInteger(0);
|
||||
private final AtomicInteger updateCount = new AtomicInteger(0);
|
||||
|
||||
private NotifyExpiration notify;
|
||||
|
||||
|
@ -2899,11 +2907,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
});
|
||||
|
||||
afosCmdTF.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
String tmp = afosCmdTF.getText();
|
||||
tmp = tmp.trim();
|
||||
afosCmdTF.setText(tmp);
|
||||
|
@ -2924,8 +2934,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
executeCommand(CommandFactory.getAfosCommand(afosCmdTF
|
||||
.getText()));
|
||||
|
||||
// Highlight the text contained in the Afos Command Field.
|
||||
afosCmdTF.selectAll();
|
||||
// Place cursor back in the Afos Command Field.
|
||||
afosCmdTF.setFocus();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2977,7 +2987,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
});
|
||||
|
||||
wmoTtaaiiTF.addModifyListener(new ModifyListener() {
|
||||
public void modifyText(ModifyEvent event) {
|
||||
@Override
|
||||
public void modifyText(ModifyEvent event) {
|
||||
if (wmoTtaaiiTF.getCaretPosition() == wmoTtaaiiTF
|
||||
.getTextLimit()) {
|
||||
ccccTF.setFocus();
|
||||
|
@ -2986,11 +2997,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
});
|
||||
|
||||
wmoTtaaiiTF.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
wmoTtaaiiTF.setText(wmoTtaaiiTF.getText().toUpperCase());
|
||||
ccccTF.setText(ccccTF.getText().toUpperCase());
|
||||
wmoSearch();
|
||||
|
@ -3044,11 +3057,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
});
|
||||
|
||||
ccccTF.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
wmoTtaaiiTF.setText(wmoTtaaiiTF.getText().toUpperCase());
|
||||
ccccTF.setText(ccccTF.getText().toUpperCase());
|
||||
wmoSearch();
|
||||
|
@ -3105,11 +3120,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
});
|
||||
|
||||
awipsIdTF.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
awipsIdTF.setText(awipsIdTF.getText().trim().toUpperCase());
|
||||
int charCount = awipsIdTF.getCharCount();
|
||||
if (charCount < 4 || charCount > 6) {
|
||||
|
@ -3503,7 +3520,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
// });
|
||||
|
||||
textEditor.addVerifyKeyListener(new VerifyKeyListener() {
|
||||
public void verifyKey(VerifyEvent event) {
|
||||
@Override
|
||||
public void verifyKey(VerifyEvent event) {
|
||||
if (event.keyCode == SWT.DEL || event.character == SWT.BS
|
||||
|| event.keyCode == SWT.SHIFT) {
|
||||
// Do nothing...
|
||||
|
@ -5302,7 +5320,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
return TextDisplayModel.getInstance().getStdTextProduct(token);
|
||||
}
|
||||
|
||||
public void setAfosCmdField(String cmd) {
|
||||
@Override
|
||||
public void setAfosCmdField(String cmd) {
|
||||
afosCmdTF.setText(cmd);
|
||||
TextDisplayModel.getInstance().setAfosCommand(token, cmd);
|
||||
}
|
||||
|
@ -5315,7 +5334,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
return addressee;
|
||||
}
|
||||
|
||||
public void executeCommand(ICommand command) {
|
||||
@Override
|
||||
public void executeCommand(ICommand command) {
|
||||
executeCommand(command, false);
|
||||
}
|
||||
|
||||
|
@ -6475,7 +6495,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
@Override
|
||||
public void run() {
|
||||
getDisplay().syncExec(new Runnable() {
|
||||
public void run() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!shell.isDisposed()) {
|
||||
if (autoSave == AutoSaveTask.this) {
|
||||
saveEditedProduct(true, false);
|
||||
|
@ -6885,6 +6906,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
// performingWrap = true;
|
||||
int lineNumber = textEditor.getLineAtOffset(start);
|
||||
endWrapLine = textEditor.getLineAtOffset(end);
|
||||
/*
|
||||
* DR154889 - resetting isPreviousLineWrapped
|
||||
*/
|
||||
isPreviousLineWrapped = false;
|
||||
rewrapInternal(lineNumber);
|
||||
|
||||
// The rest of this method is adjusting the view of the display.
|
||||
|
@ -7118,6 +7143,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
wrapAtPositionOrLock(lineStartOffset + charWrapCol, padding);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DR14889 - add call to checkAndWrapPreviousLine
|
||||
*/
|
||||
checkAndWrapPreviousLine(lineNumber);
|
||||
|
||||
checkAndWrapNextLine(lineNumber);
|
||||
}
|
||||
|
@ -7212,11 +7242,54 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
// split at the column, no whitespace
|
||||
wrapAtPositionOrLock(lineStartOffset + charWrapCol, padding);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DR14889 - add call to checkAndWrapPreviousLine
|
||||
*/
|
||||
checkAndWrapPreviousLine(lineNumber);
|
||||
|
||||
checkAndWrapNextLine(lineNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
/** checks if the previous line is part of the same paragraph and continues
|
||||
* wrapping if it is
|
||||
* @param line
|
||||
*/
|
||||
private void checkAndWrapPreviousLine(int line) {
|
||||
// if there is a previous line
|
||||
if ( isPreviousLineWrapped ){
|
||||
return;
|
||||
}
|
||||
if (line - 1 > 0) {
|
||||
// if the previous line does not start a new paragraph
|
||||
if (!isParagraphStart(line - 1)) {
|
||||
// if the previous line is not empty ( marks the end of a paragraph
|
||||
// )
|
||||
if (!textEditor.getLine(line - 1).trim().isEmpty()) {
|
||||
// rewrap the previous line
|
||||
isPreviousLineWrapped = true;
|
||||
rewrapInternal(line - 1);
|
||||
} else if (line - 1 < endWrapLine) {
|
||||
// See if another paragraph needs to be wrapped.
|
||||
int nextLine = line - 1;
|
||||
while (nextLine <= endWrapLine
|
||||
&& textEditor.getLine(nextLine).trim().isEmpty()) {
|
||||
--nextLine;
|
||||
}
|
||||
if (nextLine <= endWrapLine) {
|
||||
isPreviousLineWrapped = true;
|
||||
rewrapInternal(nextLine);
|
||||
}
|
||||
}
|
||||
} else if (line - 1 <= endWrapLine) {
|
||||
isPreviousLineWrapped = true;
|
||||
rewrapInternal(line - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the paragraph starting at the line passed in uses two space
|
||||
* padding for subsequent lines
|
||||
*
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
@ -29,14 +10,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.geotools.geometry.jts.JTS;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
|
@ -46,112 +21,62 @@ import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
|
|||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
|
||||
import com.raytheon.viz.core.map.GeoUtil;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
|
||||
/**
|
||||
* Abstract database source adaptor to data.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sept. 18 jsanchez Added pathcast algorithm.
|
||||
* pre-history
|
||||
* Sep 25, 2012 #15425 Qinglu Lin Added getGid().
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
abstract public class AbstractDbSourceDataAdaptor {
|
||||
|
||||
private static final String transformedKey = "com.raytheon.transformed";
|
||||
protected Set<String> sortFields = new HashSet<String>(
|
||||
Arrays.asList(new String[] { "distance", "area", "parentArea" }));
|
||||
|
||||
private static final String GEOM_FIELD = "the_geom";
|
||||
|
||||
protected Set<String> undatabasedSortableFields = new HashSet<String>(
|
||||
Arrays.asList(new String[] {
|
||||
ClosestPointComparator.Sort.DISTANCE.toString(),
|
||||
ClosestPointComparator.Sort.AREA.toString(),
|
||||
ClosestPointComparator.Sort.PARENTAREA.toString() }));
|
||||
|
||||
protected GeodeticCalculator gc = new GeodeticCalculator();
|
||||
protected PointSourceConfiguration pointConfig;
|
||||
|
||||
protected Geometry searchArea;
|
||||
|
||||
protected String localizedSite;
|
||||
|
||||
protected SpatialQueryResult[] ptFeatures;
|
||||
abstract protected Set<String> createSpatialQueryField();
|
||||
|
||||
protected Map<String, RequestConstraint> filter;
|
||||
abstract protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt);
|
||||
|
||||
protected Set<String> ptFields;
|
||||
abstract protected Map<String, RequestConstraint> processFilterSubstitution();
|
||||
|
||||
protected String[] sortBy;
|
||||
|
||||
abstract protected Set<String> createSpatialQueryField(String pointField,
|
||||
String[] sortBy);
|
||||
|
||||
abstract protected ClosestPoint createClosestPoint(String pointField,
|
||||
Set<String> ptFields, SpatialQueryResult ptRslt);
|
||||
|
||||
abstract protected Map<String, RequestConstraint> processFilterSubstitution(
|
||||
Map<String, RequestConstraint> filter);
|
||||
|
||||
public AbstractDbSourceDataAdaptor(
|
||||
PathcastConfiguration pathcastConfiguration,
|
||||
UnitConverter distanceToMeters, Geometry searchArea,
|
||||
public Collection<ClosestPoint> getData(WarngenConfiguration config,
|
||||
PointSourceConfiguration pointConfig, Geometry searchArea,
|
||||
String localizedSite) throws VizException {
|
||||
this.localizedSite = localizedSite;
|
||||
this.sortBy = pathcastConfiguration.getSortBy();
|
||||
this.pointConfig = pointConfig;
|
||||
this.searchArea = searchArea;
|
||||
this.ptFields = createSpatialQueryField(
|
||||
pathcastConfiguration.getPointField(), sortBy);
|
||||
this.filter = processFilterSubstitution(pathcastConfiguration
|
||||
.getFilter());
|
||||
this.ptFeatures = spatialQuery(pathcastConfiguration.getPointSource(),
|
||||
null);
|
||||
}
|
||||
|
||||
public AbstractDbSourceDataAdaptor(
|
||||
PointSourceConfiguration pointSourceConfiguration,
|
||||
Geometry searchArea, String localizedSite) throws VizException {
|
||||
this.localizedSite = localizedSite;
|
||||
this.sortBy = pointSourceConfiguration.getSortBy();
|
||||
this.searchArea = searchArea;
|
||||
this.ptFields = createSpatialQueryField(
|
||||
pointSourceConfiguration.getPointField(), sortBy);
|
||||
this.filter = processFilterSubstitution(pointSourceConfiguration
|
||||
.getFilter());
|
||||
this.ptFeatures = spatialQuery(
|
||||
pointSourceConfiguration.getPointSource(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the maps database depending on the point source set in the
|
||||
* config.
|
||||
*
|
||||
* @param pointSource
|
||||
* @param decimationTolerance
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
private SpatialQueryResult[] spatialQuery(String pointSource,
|
||||
Double decimationTolerance) throws VizException {
|
||||
Map<String, RequestConstraint> filter = processFilterSubstitution();
|
||||
Set<String> ptFields = createSpatialQueryField();
|
||||
List<ClosestPoint> points = null;
|
||||
|
||||
SpatialQueryResult[] ptFeatures = null;
|
||||
long t0 = System.currentTimeMillis();
|
||||
try {
|
||||
long t0 = System.currentTimeMillis();
|
||||
SpatialQueryResult[] ptFeatures = null;
|
||||
Double decimationTolerance = pointConfig
|
||||
.getGeometryDecimationTolerance();
|
||||
String field = "the_geom";
|
||||
|
||||
if (decimationTolerance != null && decimationTolerance > 0) {
|
||||
// find available tolerances
|
||||
List<Double> results = DbMapQueryFactory.getMapQuery(
|
||||
"mapdata." + pointSource.toLowerCase(), GEOM_FIELD)
|
||||
List<Double> results = DbMapQueryFactory
|
||||
.getMapQuery(
|
||||
"mapdata."
|
||||
+ pointConfig.getPointSource()
|
||||
.toLowerCase(), field)
|
||||
.getLevels();
|
||||
Collections.sort(results, Collections.reverseOrder());
|
||||
|
||||
|
@ -174,212 +99,53 @@ abstract public class AbstractDbSourceDataAdaptor {
|
|||
String suffix = "_"
|
||||
+ StringUtils.replaceChars(
|
||||
df.format(decimationTolerance), '.', '_');
|
||||
ptFeatures = SpatialQueryFactory.create().query(pointSource,
|
||||
GEOM_FIELD + suffix,
|
||||
ptFeatures = SpatialQueryFactory.create().query(
|
||||
pointConfig.getPointSource(), field + suffix,
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
searchArea, filter, SearchMode.INTERSECTS);
|
||||
} else {
|
||||
ptFeatures = SpatialQueryFactory.create().query(pointSource,
|
||||
ptFeatures = SpatialQueryFactory.create().query(
|
||||
pointConfig.getPointSource(),
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
searchArea, filter, SearchMode.INTERSECTS);
|
||||
}
|
||||
System.out.println("Retrieve location data for '" + pointSource
|
||||
+ "' = " + (System.currentTimeMillis() - t0));
|
||||
|
||||
if (ptFeatures != null) {
|
||||
points = new ArrayList<ClosestPoint>(ptFeatures.length);
|
||||
} else {
|
||||
points = new ArrayList<ClosestPoint>(0);
|
||||
}
|
||||
|
||||
for (SpatialQueryResult ptRslt : ptFeatures) {
|
||||
if (ptRslt != null && ptRslt.geometry != null) {
|
||||
Object nameObj = ptRslt.attributes.get(pointConfig
|
||||
.getPointField());
|
||||
if (nameObj != null) {
|
||||
ClosestPoint cp = createClosestPoint(ptFields, ptRslt);
|
||||
points.add(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Retrieve location data for '"
|
||||
+ pointConfig.getVariable() + "' = "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
} catch (SpatialException e) {
|
||||
throw new VizException("Error querying " + pointSource + " table: "
|
||||
throw new VizException("Error querying "
|
||||
+ pointConfig.getPointSource() + " table: "
|
||||
+ e.getLocalizedMessage(), e);
|
||||
}
|
||||
|
||||
return ptFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data of the points/areas relative to the searchArea
|
||||
*
|
||||
* @param config
|
||||
* @param pointConfig
|
||||
* @param localizedSite
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public Collection<ClosestPoint> getData(WarngenConfiguration config,
|
||||
PointSourceConfiguration pointConfig, String localizedSite)
|
||||
throws VizException {
|
||||
List<ClosestPoint> points = null;
|
||||
|
||||
String pointField = pointConfig.getPointField();
|
||||
if (ptFeatures != null) {
|
||||
points = new ArrayList<ClosestPoint>(ptFeatures.length);
|
||||
} else {
|
||||
points = new ArrayList<ClosestPoint>(0);
|
||||
}
|
||||
|
||||
for (SpatialQueryResult ptRslt : ptFeatures) {
|
||||
if (ptRslt != null && ptRslt.geometry != null) {
|
||||
Object nameObj = ptRslt.attributes.get(pointConfig
|
||||
.getPointField());
|
||||
if (nameObj != null) {
|
||||
ClosestPoint cp = createClosestPoint(pointField, ptFields,
|
||||
ptRslt);
|
||||
cp.setGid(getGid(ptFields, ptRslt.attributes));
|
||||
points.add(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of implacted points/areas that are relative to the
|
||||
* centroid.
|
||||
*
|
||||
* @param pcGeom
|
||||
* @param centroid
|
||||
* @param areaFeatures
|
||||
* @param pcArea
|
||||
* @param pcParentArea
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<ClosestPoint> getPathcastData(
|
||||
PathcastConfiguration pathcastConfiguration,
|
||||
UnitConverter distanceToMeters, MathTransform latLonToLocal,
|
||||
Geometry pcGeom, Point centroid, SpatialQueryResult[] areaFeatures,
|
||||
String pcArea, String pcParentArea) throws Exception {
|
||||
String pointField = pathcastConfiguration.getPointField();
|
||||
String areaField = pathcastConfiguration.getAreaField();
|
||||
String parentAreaField = pathcastConfiguration.getParentAreaField();
|
||||
double thresholdInMeters = distanceToMeters
|
||||
.convert(pathcastConfiguration.getDistanceThreshold());
|
||||
|
||||
if (latLonToLocal != null) {
|
||||
for (SpatialQueryResult rslt : ptFeatures) {
|
||||
rslt.attributes.put(transformedKey,
|
||||
JTS.transform(rslt.geometry, latLonToLocal));
|
||||
}
|
||||
}
|
||||
|
||||
Geometry localPCGeom = null;
|
||||
if (pcGeom != null) {
|
||||
localPCGeom = JTS.transform(pcGeom, latLonToLocal);
|
||||
}
|
||||
|
||||
// Find closest points
|
||||
List<ClosestPoint> points = new ArrayList<ClosestPoint>(
|
||||
ptFeatures.length);
|
||||
for (SpatialQueryResult pointRslt : ptFeatures) {
|
||||
Geometry localPt = (Geometry) pointRslt.attributes
|
||||
.get(transformedKey);
|
||||
double minDist = Double.MAX_VALUE;
|
||||
Coordinate closestCoord = null;
|
||||
if (localPCGeom != null) {
|
||||
Coordinate[] localPts = localPCGeom.getCoordinates();
|
||||
Coordinate[] latLonPts = pcGeom.getCoordinates();
|
||||
for (int i = 0; i < localPts.length; ++i) {
|
||||
Coordinate loc = localPts[i];
|
||||
double distance = loc.distance(localPt.getCoordinate());
|
||||
if (distance <= thresholdInMeters && distance < minDist) {
|
||||
minDist = distance;
|
||||
closestCoord = latLonPts[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
closestCoord = centroid.getCoordinate();
|
||||
minDist = 0;
|
||||
}
|
||||
|
||||
if (closestCoord != null) {
|
||||
boolean found = false;
|
||||
String area = null;
|
||||
String parentArea = null;
|
||||
for (SpatialQueryResult areaRslt : areaFeatures) {
|
||||
if (areaRslt.geometry.contains(pointRslt.geometry)) {
|
||||
area = String.valueOf(areaRslt.attributes
|
||||
.get(areaField));
|
||||
parentArea = String.valueOf(areaRslt.attributes
|
||||
.get(parentAreaField));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
area = pcArea;
|
||||
parentArea = pcParentArea;
|
||||
}
|
||||
|
||||
ClosestPoint cp = createClosestPoint(pointField, pointRslt,
|
||||
minDist, closestCoord, area, parentArea,
|
||||
distanceToMeters.inverse());
|
||||
points.add(cp);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> fields = null;
|
||||
if (pathcastConfiguration.getSortBy() != null) {
|
||||
fields = Arrays.asList(pathcastConfiguration.getSortBy());
|
||||
} else {
|
||||
fields = new ArrayList<String>(0);
|
||||
}
|
||||
|
||||
if (!fields.isEmpty()) {
|
||||
// Sort the points based on sortBy fields
|
||||
Collections.sort(points, new ClosestPointComparator(fields));
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a closestPoint setting the distance, azimuth, etc. Used for
|
||||
* pathcast calculations
|
||||
*
|
||||
* @param pointRslt
|
||||
* @param minDist
|
||||
* @param closestCoord
|
||||
* @param area
|
||||
* @param parentArea
|
||||
* @return
|
||||
*/
|
||||
private ClosestPoint createClosestPoint(String pointField,
|
||||
SpatialQueryResult pointRslt, double minDist,
|
||||
Coordinate closestCoord, String area, String parentArea,
|
||||
UnitConverter metersToDistance) {
|
||||
|
||||
ClosestPoint cp = createClosestPoint(pointField, ptFields, pointRslt);
|
||||
cp.setDistance(minDist);
|
||||
cp.setRoundedDistance((int) metersToDistance.convert(minDist));
|
||||
gc.setStartingGeographicPoint(cp.getPoint().x, cp.getPoint().y);
|
||||
gc.setDestinationGeographicPoint(closestCoord.x, closestCoord.y);
|
||||
cp.setAzimuth(gc.getAzimuth());
|
||||
cp.setOppositeAzimuth(ClosestPoint.adjustAngle(cp.getAzimuth() + 180));
|
||||
cp.setRoundedAzimuth(GeoUtil.roundAzimuth(cp.getAzimuth()));
|
||||
cp.setOppositeRoundedAzimuth(ClosestPoint.adjustAngle(cp
|
||||
.getRoundedAzimuth() + 180));
|
||||
cp.setArea(area);
|
||||
cp.setParentArea(parentArea);
|
||||
cp.setGid(getGid(ptFields, pointRslt.attributes));
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the population from the attributes.
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
protected int getPopulation(Set<String> ptFields,
|
||||
Map<String, Object> attributes) {
|
||||
int population = 0;
|
||||
|
||||
if (ptFields.contains(String
|
||||
.valueOf(ClosestPointComparator.Sort.POPULATION))) {
|
||||
if (ptFields.contains("population")) {
|
||||
try {
|
||||
population = Integer
|
||||
.valueOf(String.valueOf(attributes.get(String
|
||||
.valueOf(ClosestPointComparator.Sort.POPULATION))));
|
||||
population = Integer.valueOf(String.valueOf(attributes
|
||||
.get("population")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
|
@ -388,23 +154,14 @@ abstract public class AbstractDbSourceDataAdaptor {
|
|||
return population;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the warngenlev from the attributes.
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
protected int getWangenlev(Set<String> ptFields,
|
||||
Map<String, Object> attributes) {
|
||||
int warngenlev = 3;
|
||||
int warngenlev = 0;
|
||||
|
||||
if (ptFields.contains(String
|
||||
.valueOf(ClosestPointComparator.Sort.WARNGENLEV))) {
|
||||
if (ptFields.contains("warngenlev")) {
|
||||
try {
|
||||
warngenlev = Integer
|
||||
.valueOf(String.valueOf(attributes.get(String
|
||||
.valueOf(ClosestPointComparator.Sort.WARNGENLEV))));
|
||||
warngenlev = Integer.valueOf(String.valueOf(attributes
|
||||
.get("warngenlev")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
|
@ -413,22 +170,16 @@ abstract public class AbstractDbSourceDataAdaptor {
|
|||
return warngenlev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gid.
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
protected int getGid(Set<String> ptFields, Map<String, Object> attributes) {
|
||||
protected int getGid(Set<String> ptFields,
|
||||
Map<String, Object> attributes) {
|
||||
int gid = 0;
|
||||
|
||||
if (ptFields.contains(String.valueOf(ClosestPointComparator.Sort.GID))) {
|
||||
if (ptFields.contains("gid")) {
|
||||
try {
|
||||
gid = Integer.valueOf(String.valueOf(attributes.get(String
|
||||
.valueOf(ClosestPointComparator.Sort.GID))));
|
||||
gid = Integer.valueOf(String.valueOf(attributes
|
||||
.get("gid")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,108 +1,62 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.warngen.PreferenceUtil;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Envelope;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
||||
|
||||
/**
|
||||
* Area source data adaptor for data retrieved from a Database.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sept 19, 2012 jsanchez Added pathcast use.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
* Sep 25, 2012 #15425 Qinglu Lin Updated createClosestPoint().
|
||||
*
|
||||
*/
|
||||
public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
||||
|
||||
public DbAreaSourceDataAdaptor(PathcastConfiguration pathcastConfiguration,
|
||||
UnitConverter distanceToMeters, Geometry searchArea,
|
||||
String localizedSite) throws VizException {
|
||||
super(pathcastConfiguration, distanceToMeters, searchArea,
|
||||
localizedSite);
|
||||
}
|
||||
|
||||
public DbAreaSourceDataAdaptor(
|
||||
PointSourceConfiguration pointSourceConfiguration,
|
||||
Geometry searchArea, String localizedSite) throws VizException {
|
||||
super(pointSourceConfiguration, searchArea, localizedSite);
|
||||
}
|
||||
|
||||
private static final String useDirectionField = "usedirs";
|
||||
|
||||
private static final String suppressedDirectionsField = "supdirs";
|
||||
|
||||
private static final String cwaField = "cwa";
|
||||
|
||||
private GeodeticCalculator gc = new GeodeticCalculator();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected Set<String> createSpatialQueryField(String pointField,
|
||||
String[] sortBy) {
|
||||
protected Set<String> createSpatialQueryField() {
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointField);
|
||||
ptFields.add(pointConfig.getPointField());
|
||||
ptFields.add(useDirectionField);
|
||||
ptFields.add(suppressedDirectionsField);
|
||||
|
||||
List<String> fields = null;
|
||||
if (sortBy != null && sortBy.length > 0) {
|
||||
fields = Arrays.asList(sortBy);
|
||||
} else {
|
||||
fields = new ArrayList<String>(0);
|
||||
List<String> fields = new ArrayList<String>();
|
||||
if (pointConfig.getSortBy() != null) {
|
||||
fields = Arrays.asList(pointConfig.getSortBy());
|
||||
}
|
||||
|
||||
// Sort fields don't exist in the db.
|
||||
for (String field : fields) {
|
||||
if (undatabasedSortableFields.contains(field.toUpperCase()) == false) {
|
||||
ptFields.add(field.toUpperCase());
|
||||
if (sortFields.contains(field.toLowerCase()) == false) {
|
||||
ptFields.add(field.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,31 +64,78 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a closest point object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected ClosestPoint createClosestPoint(String pointField,
|
||||
Set<String> ptFields, SpatialQueryResult ptRslt) {
|
||||
protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt) {
|
||||
Map<String, Object> attributes = ptRslt.attributes;
|
||||
|
||||
String name = String.valueOf(attributes.get(pointField));
|
||||
String name = String
|
||||
.valueOf(attributes.get(pointConfig.getPointField()));
|
||||
Coordinate point = ptRslt.geometry.getCoordinate();
|
||||
int population = getPopulation(ptFields, attributes);
|
||||
int warngenlev = getWangenlev(ptFields, attributes);
|
||||
List<String> partOfArea = getPartOfArea(ptFields, attributes,
|
||||
ptRslt.geometry);
|
||||
ClosestPoint cp = new ClosestPoint(name, point, population, warngenlev,
|
||||
partOfArea);
|
||||
cp.setGid(getGid(ptFields, attributes));
|
||||
return cp;
|
||||
int gid = getGid(ptFields, attributes);
|
||||
|
||||
return new ClosestPoint(name, point, population, warngenlev, partOfArea, gid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the filter to set the localized site.
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @param geom
|
||||
* @return
|
||||
*/
|
||||
private List<String> getPartOfArea(Set<String> ptFields,
|
||||
Map<String, Object> attributes, Geometry geom) {
|
||||
List<String> partOfArea = null;
|
||||
|
||||
boolean userDirections = Boolean.valueOf(String.valueOf(attributes
|
||||
.get(useDirectionField)));
|
||||
if (userDirections) {
|
||||
Geometry intersection = searchArea.intersection(geom);
|
||||
partOfArea = GisUtil.asStringList(GisUtil.calculatePortion(geom,
|
||||
intersection, gc, ""));
|
||||
|
||||
if (attributes.get(suppressedDirectionsField) != null) {
|
||||
String suppressedDirections = String.valueOf(
|
||||
attributes.get(suppressedDirectionsField))
|
||||
.toLowerCase();
|
||||
// supdirs can be 'nse', for example
|
||||
// TODO create an enum constructor for Directions
|
||||
for (int i = 0; i < suppressedDirections.length(); i++) {
|
||||
switch (suppressedDirections.charAt(i)) {
|
||||
case 'n':
|
||||
partOfArea.remove(Direction.NORTH.toString());
|
||||
break;
|
||||
case 's':
|
||||
partOfArea.remove(Direction.SOUTH.toString());
|
||||
break;
|
||||
case 'e':
|
||||
partOfArea.remove(Direction.EAST.toString());
|
||||
break;
|
||||
case 'w':
|
||||
partOfArea.remove(Direction.WEST.toString());
|
||||
break;
|
||||
case 'c':
|
||||
partOfArea.remove(Direction.CENTRAL.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return partOfArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution(
|
||||
Map<String, RequestConstraint> filter) {
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution() {
|
||||
Map<String, RequestConstraint> filter = pointConfig.getFilter();
|
||||
if (filter != null) {
|
||||
// Process substitutes for filter
|
||||
for (RequestConstraint rc : filter.values()) {
|
||||
|
@ -151,139 +152,4 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
|||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the part of area impacted if the userDirectionField is set to
|
||||
* true.
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @param geom
|
||||
* @return
|
||||
*/
|
||||
private List<String> getPartOfArea(Set<String> ptFields,
|
||||
Map<String, Object> attributes, Geometry geom) {
|
||||
List<String> partOfArea = null;
|
||||
|
||||
boolean userDirections = Boolean.valueOf(String.valueOf(attributes
|
||||
.get(useDirectionField)));
|
||||
if (userDirections) {
|
||||
PreparedGeometry prepGeom = PreparedGeometryFactory.prepare(geom);
|
||||
if (prepGeom.intersects(searchArea) && !prepGeom.within(searchArea)) {
|
||||
Geometry intersection = searchArea.intersection(geom);
|
||||
partOfArea = GisUtil.asStringList(calculateLocationPortion(
|
||||
geom, intersection, gc));
|
||||
|
||||
if (attributes.get(suppressedDirectionsField) != null) {
|
||||
String suppressedDirections = String.valueOf(
|
||||
attributes.get(suppressedDirectionsField))
|
||||
.toLowerCase();
|
||||
// supdirs can be 'nse', for example
|
||||
// TODO create an enum constructor for Directions
|
||||
for (int i = 0; i < suppressedDirections.length(); i++) {
|
||||
switch (suppressedDirections.charAt(i)) {
|
||||
case 'n':
|
||||
partOfArea.remove(Direction.NORTH.toString());
|
||||
break;
|
||||
case 's':
|
||||
partOfArea.remove(Direction.SOUTH.toString());
|
||||
break;
|
||||
case 'e':
|
||||
partOfArea.remove(Direction.EAST.toString());
|
||||
break;
|
||||
case 'w':
|
||||
partOfArea.remove(Direction.WEST.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (partOfArea != null && !partOfArea.isEmpty()) {
|
||||
return partOfArea;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to store cardinal ranges
|
||||
*
|
||||
* @author jsanchez
|
||||
*
|
||||
*/
|
||||
private static class CardinalRange {
|
||||
public EnumSet<Direction> directions;
|
||||
|
||||
public double lowRange;
|
||||
|
||||
public double highRange;
|
||||
|
||||
public CardinalRange(EnumSet<Direction> directions, double lowRange,
|
||||
double highRange) {
|
||||
this.directions = directions;
|
||||
this.lowRange = lowRange;
|
||||
this.highRange = highRange;
|
||||
}
|
||||
}
|
||||
|
||||
private static CardinalRange[] ranges = new CardinalRange[] {
|
||||
new CardinalRange(EnumSet.of(Direction.NORTH), 0, 22.5),
|
||||
new CardinalRange(EnumSet.of(Direction.NORTH, Direction.EAST),
|
||||
22.5, 67.5),
|
||||
new CardinalRange(EnumSet.of(Direction.EAST), 67.5, 112.5),
|
||||
new CardinalRange(EnumSet.of(Direction.SOUTH, Direction.EAST),
|
||||
112.5, 157.5),
|
||||
new CardinalRange(EnumSet.of(Direction.SOUTH), 157.5, 202.5),
|
||||
new CardinalRange(EnumSet.of(Direction.SOUTH, Direction.WEST),
|
||||
202.5, 247.5),
|
||||
new CardinalRange(EnumSet.of(Direction.WEST), 247.5, 292.5),
|
||||
new CardinalRange(EnumSet.of(Direction.NORTH, Direction.WEST),
|
||||
292.5, 337.5),
|
||||
new CardinalRange(EnumSet.of(Direction.NORTH), 337.5, 360) };
|
||||
|
||||
/**
|
||||
* Calculates the cardinal directions of a location.
|
||||
*
|
||||
* @param geom
|
||||
* @param intersection
|
||||
* @param gc
|
||||
* @return
|
||||
*/
|
||||
private static EnumSet<Direction> calculateLocationPortion(Geometry geom,
|
||||
Geometry intersection, GeodeticCalculator gc) {
|
||||
EnumSet<Direction> directions = EnumSet.noneOf(Direction.class);
|
||||
Coordinate geomCentroid = geom.convexHull().getCentroid()
|
||||
.getCoordinate();
|
||||
Coordinate intersectCentroid = intersection.convexHull().getCentroid()
|
||||
.getCoordinate();
|
||||
|
||||
gc.setStartingGeographicPoint(geomCentroid.x, geomCentroid.y);
|
||||
gc.setDestinationGeographicPoint(intersectCentroid.x,
|
||||
intersectCentroid.y);
|
||||
|
||||
Envelope envelope = geom.getEnvelopeInternal();
|
||||
double centerThresholdX = envelope.getWidth() * 0.10;
|
||||
double centerThresholdY = envelope.getHeight() * 0.10;
|
||||
double distanceX = Math.abs(intersectCentroid.x - geomCentroid.x);
|
||||
double distanceY = Math.abs(intersectCentroid.y - geomCentroid.y);
|
||||
|
||||
if (distanceX > centerThresholdX || distanceY > centerThresholdY) {
|
||||
// Convert azimuth from -180/180 to 0/360
|
||||
double degrees = gc.getAzimuth();
|
||||
if (degrees < 0) {
|
||||
degrees += 360;
|
||||
}
|
||||
|
||||
for (CardinalRange range : ranges) {
|
||||
if (degrees > range.lowRange && degrees <= range.highRange) {
|
||||
directions = range.directions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return directions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,24 +19,23 @@
|
|||
**/
|
||||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
|
||||
import com.raytheon.viz.warngen.PreferenceUtil;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
/**
|
||||
* PointSource data adaptor for data retrieved from a Database.
|
||||
|
@ -48,6 +47,7 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 26, 2011 bgonzale Initial creation
|
||||
* Sep 25, 2012 #15425 Qinglu Lin Updated createClosestPoint().
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -57,38 +57,43 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
|
||||
public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
||||
|
||||
public DbPointSourceDataAdaptor(
|
||||
PathcastConfiguration pathcastConfiguration,
|
||||
UnitConverter distanceToMeters, Geometry searchArea,
|
||||
String localizedSite) throws VizException {
|
||||
super(pathcastConfiguration, distanceToMeters, searchArea,
|
||||
localizedSite);
|
||||
}
|
||||
@Override
|
||||
protected Set<String> createSpatialQueryField() {
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointConfig.getPointField());
|
||||
|
||||
public DbPointSourceDataAdaptor(
|
||||
PointSourceConfiguration pointSourceConfiguration,
|
||||
Geometry searchArea, String localizedSite) throws VizException {
|
||||
super(pointSourceConfiguration, searchArea, localizedSite);
|
||||
List<String> fields = new ArrayList<String>();
|
||||
if (pointConfig.getSortBy() != null) {
|
||||
fields = Arrays.asList(pointConfig.getSortBy());
|
||||
}
|
||||
|
||||
for (String field : fields) {
|
||||
if (sortFields.contains(field.toLowerCase()) == false) {
|
||||
ptFields.add(field.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return ptFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClosestPoint createClosestPoint(String pointField,
|
||||
Set<String> ptFields, SpatialQueryResult ptRslt) {
|
||||
protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt) {
|
||||
Map<String, Object> attributes = ptRslt.attributes;
|
||||
|
||||
String name = String.valueOf(attributes.get(pointField));
|
||||
String name = String
|
||||
.valueOf(attributes.get(pointConfig.getPointField()));
|
||||
Coordinate point = ptRslt.geometry.getCoordinate();
|
||||
int population = getPopulation(ptFields, attributes);
|
||||
int warngenlev = getWangenlev(ptFields, attributes);
|
||||
ClosestPoint cp = new ClosestPoint(name, point, population, warngenlev,
|
||||
null);
|
||||
cp.setGid(getGid(ptFields, attributes));
|
||||
return cp;
|
||||
int gid = getGid(ptFields, attributes);
|
||||
|
||||
return new ClosestPoint(name, point, population, warngenlev, null, gid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution(
|
||||
Map<String, RequestConstraint> filter) {
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution() {
|
||||
Map<String, RequestConstraint> filter = pointConfig.getFilter();
|
||||
if (filter != null) {
|
||||
// Process substitutes for filter
|
||||
for (RequestConstraint rc : filter.values()) {
|
||||
|
@ -99,25 +104,4 @@ public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
|||
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> createSpatialQueryField(String pointField,
|
||||
String[] sortBy) {
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointField);
|
||||
|
||||
List<String> fields = new ArrayList<String>();
|
||||
if (sortBy != null) {
|
||||
fields = Arrays.asList(sortBy);
|
||||
}
|
||||
|
||||
// Sort fields don't exist in the db.
|
||||
for (String field : fields) {
|
||||
if (undatabasedSortableFields.contains(field.toUpperCase()) == false) {
|
||||
ptFields.add(field.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
return ptFields;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Dec 11, 2007 #601 chammack Initial Creation.
|
||||
* APr 18, 2012 #14733 Qinglu Lin David's fix is used, which adds
|
||||
* a copy constructor.
|
||||
* Sep 18, 2012 jsanchez Added setter methods.
|
||||
* Sep 25, 2012 #15425 Qinglu Lin Updated two ClosestPoint() and added getGid().
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -45,8 +45,6 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* @version 1
|
||||
*/
|
||||
public class ClosestPoint implements Comparable<ClosestPoint> {
|
||||
protected int gid;
|
||||
|
||||
protected String name;
|
||||
|
||||
protected String area;
|
||||
|
@ -75,6 +73,8 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
|
||||
protected List<String> partOfArea;
|
||||
|
||||
protected int gid;
|
||||
|
||||
public ClosestPoint() {
|
||||
|
||||
}
|
||||
|
@ -94,19 +94,21 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
this.warngenlev = o.warngenlev;
|
||||
this.time = o.time;
|
||||
this.partOfArea = o.partOfArea;
|
||||
this.gid = o.gid;
|
||||
}
|
||||
|
||||
public ClosestPoint(String name, Coordinate point) {
|
||||
this(name, point, 0, 0, null);
|
||||
this(name, point, 0, 0, null, 0);
|
||||
}
|
||||
|
||||
public ClosestPoint(String name, Coordinate point, int population,
|
||||
int warngenlev, List<String> partOfArea) {
|
||||
int warngenlev, List<String> partOfArea, int gid) {
|
||||
this.name = name;
|
||||
this.point = point;
|
||||
this.population = population;
|
||||
this.warngenlev = warngenlev;
|
||||
this.partOfArea = partOfArea;
|
||||
this.gid = gid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,74 +178,10 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
return partOfArea;
|
||||
}
|
||||
|
||||
public int getGid() {
|
||||
public int getGid() {
|
||||
return gid;
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public void setGid(int gid) {
|
||||
this.gid = gid;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setArea(String area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public void setParentArea(String parentArea) {
|
||||
this.parentArea = parentArea;
|
||||
}
|
||||
|
||||
public void setPoint(Coordinate point) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public void setRoundedDistance(int roundedDistance) {
|
||||
this.roundedDistance = roundedDistance;
|
||||
}
|
||||
|
||||
public void setAzimuth(double azimuth) {
|
||||
this.azimuth = azimuth;
|
||||
}
|
||||
|
||||
public void setRoundedAzimuth(double roundedAzimuth) {
|
||||
this.roundedAzimuth = roundedAzimuth;
|
||||
}
|
||||
|
||||
public void setOppositeAzimuth(double oppositeAzimuth) {
|
||||
this.oppositeAzimuth = oppositeAzimuth;
|
||||
}
|
||||
|
||||
public void setOppositeRoundedAzimuth(double oppositeRoundedAzimuth) {
|
||||
this.oppositeRoundedAzimuth = oppositeRoundedAzimuth;
|
||||
}
|
||||
|
||||
public void setPopulation(int population) {
|
||||
this.population = population;
|
||||
}
|
||||
|
||||
public void setWarngenlev(int warngenlev) {
|
||||
this.warngenlev = warngenlev;
|
||||
}
|
||||
|
||||
public void setPartOfArea(List<String> partOfArea) {
|
||||
this.partOfArea = partOfArea;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the angle from -360/360 to be between -180/180
|
||||
*
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.apache.commons.lang.ArrayUtils;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 3, 2011 jsanchez Initial creation
|
||||
* Sep 18, 2012 15428 jsanchez Updated the enum sort to be more flexible.
|
||||
* Sep 25, 2012 15425 Qinglu Lin Implemented sorting on 'gid' in ascending order.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -47,11 +47,11 @@ import org.apache.commons.lang.ArrayUtils;
|
|||
|
||||
public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
||||
|
||||
public static enum Sort {
|
||||
NAME, POPULATION, DISTANCE, WARNGENLEV, LAT, LON, AREA, PARENTAREA, GID
|
||||
private enum Sort {
|
||||
NAME, POPULATION, DISTANCE, LEVEL, LAT, LON, AREA, PARENT_AREA, GID
|
||||
}
|
||||
|
||||
private final ArrayList<Sort> list;
|
||||
private ArrayList<Sort> list;
|
||||
|
||||
private int counter;
|
||||
|
||||
|
@ -64,25 +64,25 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
counter = 0;
|
||||
list = new ArrayList<Sort>();
|
||||
for (String field : fields) {
|
||||
if (field.equalsIgnoreCase(Sort.NAME.toString())) {
|
||||
if (field.equalsIgnoreCase("name")) {
|
||||
list.add(Sort.NAME);
|
||||
} else if (field.equalsIgnoreCase(Sort.POPULATION.toString())) {
|
||||
} else if (field.equalsIgnoreCase("population")) {
|
||||
list.add(Sort.POPULATION);
|
||||
} else if (field.equalsIgnoreCase(Sort.DISTANCE.toString())) {
|
||||
} else if (field.equalsIgnoreCase("distance")) {
|
||||
list.add(Sort.DISTANCE);
|
||||
} else if (field.equalsIgnoreCase(Sort.WARNGENLEV.toString())
|
||||
} else if (field.equalsIgnoreCase("warngenlev")
|
||||
|| field.equalsIgnoreCase("watch_warn")) {
|
||||
list.add(Sort.WARNGENLEV);
|
||||
} else if (field.equalsIgnoreCase(Sort.LAT.toString())) {
|
||||
list.add(Sort.LEVEL);
|
||||
} else if (field.equalsIgnoreCase("lat")) {
|
||||
list.add(Sort.LAT);
|
||||
} else if (field.equalsIgnoreCase(Sort.LON.toString())) {
|
||||
} else if (field.equalsIgnoreCase("lon")) {
|
||||
list.add(Sort.LON);
|
||||
} else if (field.equalsIgnoreCase(Sort.AREA.toString())) {
|
||||
} else if (field.equalsIgnoreCase("area")) {
|
||||
list.add(Sort.AREA);
|
||||
} else if (field.equalsIgnoreCase(Sort.PARENTAREA.toString())) {
|
||||
list.add(Sort.PARENTAREA);
|
||||
} else if (field.equalsIgnoreCase(Sort.GID.toString())) {
|
||||
list.add(Sort.GID);
|
||||
} else if (field.equalsIgnoreCase("parentArea")) {
|
||||
list.add(Sort.PARENT_AREA);
|
||||
} else if (field.equalsIgnoreCase("gid")) {
|
||||
list.add(Sort.GID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,13 +105,13 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
list.clear();
|
||||
|
||||
ClosestPointComparator comparator = new ClosestPointComparator(
|
||||
Arrays.asList(fields));
|
||||
Collections.sort(Arrays.asList(points), comparator);
|
||||
(ArrayList<String>) Arrays.asList(fields));
|
||||
Collections
|
||||
.sort((List<ClosestPoint>) Arrays.asList(points), comparator);
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(ClosestPoint cp1, ClosestPoint cp2) {
|
||||
if (list.isEmpty()) {
|
||||
return cp1.compareTo(cp2);
|
||||
|
@ -121,7 +121,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
switch (list.get(counter)) {
|
||||
case NAME:
|
||||
if (cp1.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")
|
||||
&& cp2.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) {
|
||||
&& cp1.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) {
|
||||
value = Double.valueOf(cp1.name).compareTo(
|
||||
Double.valueOf(cp2.name));
|
||||
} else {
|
||||
|
@ -131,7 +131,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
case POPULATION:
|
||||
value = -1 * Double.compare(cp1.population, cp2.population);
|
||||
break;
|
||||
case WARNGENLEV:
|
||||
case LEVEL:
|
||||
value = Double.compare(cp1.warngenlev, cp2.warngenlev);
|
||||
break;
|
||||
case LAT:
|
||||
|
@ -143,7 +143,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
case AREA:
|
||||
value = cp1.area.compareTo(cp2.area);
|
||||
break;
|
||||
case PARENTAREA:
|
||||
case PARENT_AREA:
|
||||
value = cp1.parentArea.compareTo(cp2.parentArea);
|
||||
break;
|
||||
case DISTANCE:
|
||||
|
@ -151,7 +151,8 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
|
|||
.compareTo(cp2.roundedDistance);
|
||||
break;
|
||||
case GID:
|
||||
value = new Integer(cp1.gid).compareTo(cp2.gid);
|
||||
value = new Integer(cp1.gid)
|
||||
.compareTo(cp2.gid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
|||
import com.raytheon.viz.core.map.GeoUtil;
|
||||
import com.raytheon.viz.warngen.PreferenceUtil;
|
||||
import com.raytheon.viz.warngen.WarngenException;
|
||||
import com.raytheon.viz.warngen.config.AbstractDbSourceDataAdaptor;
|
||||
import com.raytheon.viz.warngen.config.DataAdaptorFactory;
|
||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||
import com.raytheon.viz.warnings.DateUtil;
|
||||
|
@ -98,7 +97,8 @@ import com.vividsolutions.jts.geom.Point;
|
|||
* that loops over availablePoints.
|
||||
* May 21, 2012 DR14480 Qinglu Lin Added code to prevent duplicate cities
|
||||
* in pathcast.
|
||||
* Sep 18, 2012 DR15428 jsanchez Moved the path cast data collecting to a seperate class.
|
||||
* Oct 05, 2012 DR15429 Qinglu Lin Updated code to keep duplicate names of cities
|
||||
* which are at different locations in pathcast.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -109,6 +109,8 @@ public class Wx {
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(Wx.class);
|
||||
|
||||
private static final String transformedKey = "com.raytheon.transformed";
|
||||
|
||||
private long wwaStopTime;
|
||||
|
||||
private long wwaStartTime;
|
||||
|
@ -182,6 +184,7 @@ public class Wx {
|
|||
.getPathcastConfig();
|
||||
UnitConverter distanceToMeters = config.getUnitDistance()
|
||||
.getConverterTo(SI.METER);
|
||||
UnitConverter metersToDistance = distanceToMeters.inverse();
|
||||
|
||||
int maxCount = pathcastConfiguration.getMaxResults();
|
||||
int maxGroup = pathcastConfiguration.getMaxGroup();
|
||||
|
@ -193,6 +196,7 @@ public class Wx {
|
|||
String areaNotationField = pathcastConfiguration.getAreaNotationField();
|
||||
String areaNotationAbbrevField = pathcastConfiguration
|
||||
.getAreaNotationTranslationFile();
|
||||
String timezoneTable = geospatialConfig.getTimezoneSource();
|
||||
String timezoneField = geospatialConfig.getTimezoneField();
|
||||
String pointSource = pathcastConfiguration.getPointSource();
|
||||
String pointField = pathcastConfiguration.getPointField().toLowerCase();
|
||||
|
@ -340,12 +344,18 @@ public class Wx {
|
|||
}
|
||||
}
|
||||
|
||||
AbstractDbSourceDataAdaptor pathcastDataAdaptor = null;
|
||||
SpatialQueryResult[] ptFeatures = null;
|
||||
if (pointSource != null) {
|
||||
pathcastDataAdaptor = DataAdaptorFactory
|
||||
.createPathcastDataAdaptor(pathcastConfiguration,
|
||||
distanceToMeters, bufferedPathCastArea,
|
||||
localizedSite);
|
||||
ptFeatures = SpatialQueryFactory.create().query(pointSource,
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
bufferedPathCastArea, pointFilter,
|
||||
SearchMode.INTERSECTS);
|
||||
if (latLonToLocal != null) {
|
||||
for (SpatialQueryResult rslt : ptFeatures) {
|
||||
rslt.attributes.put(transformedKey,
|
||||
JTS.transform(rslt.geometry, latLonToLocal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpatialQueryResult[] areaFeatures = null;
|
||||
|
@ -422,14 +432,99 @@ public class Wx {
|
|||
.get(timezoneField));
|
||||
}
|
||||
|
||||
List<ClosestPoint> points = null;
|
||||
if (pathcastDataAdaptor != null) {
|
||||
points = pathcastDataAdaptor.getPathcastData(
|
||||
pathcastConfiguration, distanceToMeters,
|
||||
latLonToLocal, pcGeom, centroid, areaFeatures,
|
||||
pc.area, pc.parentArea);
|
||||
} else {
|
||||
points = new ArrayList<ClosestPoint>(0);
|
||||
Geometry localPCGeom = null;
|
||||
if (pcGeom != null) {
|
||||
localPCGeom = JTS.transform(pcGeom, latLonToLocal);
|
||||
}
|
||||
|
||||
// Find closest points
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
List<ClosestPoint> points = new ArrayList<ClosestPoint>(
|
||||
ptFeatures.length);
|
||||
for (SpatialQueryResult pointRslt : ptFeatures) {
|
||||
Geometry localPt = (Geometry) pointRslt.attributes
|
||||
.get(transformedKey);
|
||||
double minDist = Double.MAX_VALUE;
|
||||
Coordinate closestCoord = null;
|
||||
if (localPCGeom != null) {
|
||||
Coordinate[] localPts = localPCGeom.getCoordinates();
|
||||
Coordinate[] latLonPts = pcGeom.getCoordinates();
|
||||
for (int i = 0; i < localPts.length; ++i) {
|
||||
Coordinate loc = localPts[i];
|
||||
double distance = loc.distance(localPt
|
||||
.getCoordinate());
|
||||
if (distance <= thresholdInMeters
|
||||
&& distance < minDist) {
|
||||
minDist = distance;
|
||||
closestCoord = latLonPts[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
closestCoord = centroid.getCoordinate();
|
||||
minDist = 0;
|
||||
}
|
||||
|
||||
if (closestCoord != null) {
|
||||
ClosestPoint cp = new ClosestPoint();
|
||||
cp.point = pointRslt.geometry.getCoordinate();
|
||||
cp.name = String.valueOf(pointRslt.attributes
|
||||
.get(pointField));
|
||||
cp.distance = minDist;
|
||||
cp.roundedDistance = (int) metersToDistance
|
||||
.convert(minDist);
|
||||
gc.setStartingGeographicPoint(cp.point.x, cp.point.y);
|
||||
gc.setDestinationGeographicPoint(closestCoord.x,
|
||||
closestCoord.y);
|
||||
cp.azimuth = gc.getAzimuth();
|
||||
cp.oppositeAzimuth = ClosestPoint
|
||||
.adjustAngle(cp.azimuth + 180);
|
||||
cp.roundedAzimuth = GeoUtil.roundAzimuth(cp.azimuth);
|
||||
cp.oppositeRoundedAzimuth = ClosestPoint
|
||||
.adjustAngle(cp.roundedAzimuth + 180);
|
||||
|
||||
boolean found = false;
|
||||
for (SpatialQueryResult areaRslt : areaFeatures) {
|
||||
if (areaRslt.geometry.contains(pointRslt.geometry)) {
|
||||
cp.area = String.valueOf(areaRslt.attributes
|
||||
.get(areaField));
|
||||
cp.parentArea = String
|
||||
.valueOf(areaRslt.attributes
|
||||
.get(parentAreaField));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
cp.area = pc.area;
|
||||
cp.parentArea = pc.parentArea;
|
||||
}
|
||||
|
||||
if (ptFields.contains("population")) {
|
||||
try {
|
||||
cp.population = Integer.valueOf(String
|
||||
.valueOf(pointRslt.attributes
|
||||
.get("population")));
|
||||
} catch (Exception e) {
|
||||
cp.population = 0;
|
||||
}
|
||||
}
|
||||
if (ptFields.contains("warngenlev")) {
|
||||
try {
|
||||
cp.warngenlev = Integer.valueOf(String
|
||||
.valueOf(pointRslt.attributes
|
||||
.get("warngenlev")));
|
||||
} catch (Exception e) {
|
||||
cp.warngenlev = 3;
|
||||
}
|
||||
}
|
||||
points.add(cp);
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.isEmpty() == false) {
|
||||
// Sort the points based on sortBy fields
|
||||
Collections
|
||||
.sort(points, new ClosestPointComparator(fields));
|
||||
}
|
||||
pcPoints.put(pc, points);
|
||||
}
|
||||
|
@ -437,7 +532,7 @@ public class Wx {
|
|||
// with first pathcast and goes through each point within maxCount,
|
||||
// check for same point in other pathcast objects. If same point
|
||||
// exists, remove from which ever pathcast is furthest away
|
||||
Set<String> closestPtNames = new HashSet<String>(30);
|
||||
Set<Coordinate> closestPtCoords = new HashSet<Coordinate>(30);
|
||||
List<ClosestPoint> tmpPoints = new ArrayList<ClosestPoint>(maxCount);
|
||||
Queue<PathCast> tmp = new ArrayDeque<PathCast>(pathcasts);
|
||||
while (tmp.isEmpty() == false) {
|
||||
|
@ -469,12 +564,12 @@ public class Wx {
|
|||
tmpPoints.clear();
|
||||
for (int i = 0; i < points.size() && i < maxCount; ++i) {
|
||||
ClosestPoint point = points.get(i);
|
||||
String name = point.getName();
|
||||
if (!closestPtNames.contains(name)) {
|
||||
Coordinate coord = point.getPoint();
|
||||
if (!closestPtCoords.contains(coord)) {
|
||||
// To prevent duplicate cities in pathcast,
|
||||
// only unused point is added to tmpPoints
|
||||
tmpPoints.add(point);
|
||||
closestPtNames.add(name);
|
||||
closestPtCoords.add(coord);
|
||||
}
|
||||
}
|
||||
if (tmpPoints.size() > 0) {
|
||||
|
@ -678,13 +773,9 @@ public class Wx {
|
|||
List<ClosestPoint> availablePoints = new ArrayList<ClosestPoint>();
|
||||
for (PointSourceConfiguration pointConfig : pointConfigs) {
|
||||
long t0 = System.currentTimeMillis();
|
||||
AbstractDbSourceDataAdaptor adaptor = DataAdaptorFactory
|
||||
.createDataAdaptor(pointConfig, bufferedSearchArea,
|
||||
localizedSite);
|
||||
if (adaptor != null) {
|
||||
availablePoints.addAll(adaptor.getData(config, pointConfig,
|
||||
localizedSite));
|
||||
}
|
||||
availablePoints.addAll(DataAdaptorFactory.createPointSource(
|
||||
pointConfig).getData(config, pointConfig,
|
||||
bufferedSearchArea, localizedSite));
|
||||
long t1 = System.currentTimeMillis();
|
||||
System.out.println("getClosestPoint.dbQuery took " + (t1 - t0)
|
||||
+ " for point source " + pointConfig.getPointSource());
|
||||
|
|
|
@ -123,6 +123,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* adjustLatLon(), etc.
|
||||
* Sep 05, 2012 DR 15261 D. Friedman Prevent additional counties from being selected for EXPs
|
||||
* Sep 27, 2012 #1196 rferrel Refactored to use non-blocking dialogs
|
||||
* Oct 03, 2012 DR 15426 Qinglu Lin Unlock WarnGen GUI for COR, implemented in corSelected();
|
||||
* but lock immediate cause, implemented in individual template.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -1864,7 +1866,6 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
allowsNewProduct = true;
|
||||
}
|
||||
}
|
||||
bulletList.setEnabled(false);
|
||||
// Special case - allows for Correction of Followups
|
||||
if (!allowsNewProduct) {
|
||||
newWarn = conSelected(data);
|
||||
|
|
|
@ -13,6 +13,7 @@ alarmwhfs.cron=0+7,17,27,37,47,57+*+*+*+?
|
|||
arealqpegen.cron=0+10,25,40,55+*+*+*+?
|
||||
subscription.cron=0+*+*+*+*+?
|
||||
dqcpreprocessor.cron=0+20+0,6,12,18+*+*+?
|
||||
freezingLevel.cron=0+5+2,8,14,20+*+*+?
|
||||
rpggenvdata.envdata.cron=0+0+*+*+*+?
|
||||
rpggenvdata.biastable.cron=0+26,46+*+*+*+?
|
||||
metartohmdb.cron=0+14+*+*+*+?
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Evan Bookbinder 2-24-2012
|
||||
Phil Kurimski 2-28-2012
|
||||
Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Qinglu Lin 10-03-2012 DR 15426. Changed ic to pc in <lockedGroupsOnFollowup> tag.
|
||||
-->
|
||||
|
||||
<warngenConfig>
|
||||
|
@ -58,7 +59,7 @@
|
|||
<duration>720</duration>
|
||||
</durations>
|
||||
|
||||
<lockedGroupsOnFollowup>ic</lockedGroupsOnFollowup>
|
||||
<lockedGroupsOnFollowup>pc</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup action="NEW" phen="FA" sig="W">
|
||||
<bullets>
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
Modified by Phil Kurimski 09-23-2011 for burn scars and mud slides
|
||||
Modified by Mike Dangelo 01-25-2012 at CRH TIM
|
||||
Modified by Mike Dangelo 02-23-2012
|
||||
Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Qinglu Lin 10-03-2012 DR 15426. Added <lockedGroupsOnFollowup> tag,
|
||||
inserted bulletGroup="ic" after bulletText="Also snow melt".
|
||||
-->
|
||||
|
||||
<warngenConfig>
|
||||
|
@ -63,6 +65,7 @@
|
|||
<duration>480</duration>
|
||||
</durations>
|
||||
|
||||
<lockedGroupsOnFollowup>ic</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup action="NEW" phen="FF" sig="W">
|
||||
<bullets>
|
||||
|
@ -115,7 +118,7 @@
|
|||
<bulletActionGroup action="EXT" phen="FF" sig="W">
|
||||
<bullets>
|
||||
<bullet bulletName="ffwEmergency" bulletText="**SELECT FOR FLASH FLOOD EMERGENCY**" parseString="FLASH FLOOD EMERGENCY"/>
|
||||
<bullet bulletName="icrs" bulletText="Also snow melt" parseString=".RS." showString=".RS."/>
|
||||
<bullet bulletName="icrs" bulletText="Also snow melt" bulletGroup="ic" parseString=".RS." showString=".RS."/>
|
||||
<bullet bulletText="*********** SOURCE (CHOOSE 1) **********" bulletType="title"/>
|
||||
<bullet bulletName="doppler" bulletText="Doppler radar indicated" bulletGroup="source" bulletDefault="true" parseString="DOPPLER RADAR INDICATED"/>
|
||||
<bullet bulletName="dopplerGauge" bulletText="Doppler radar and automated gauges" bulletGroup="source" parseString="DOPPLER RADAR AND AUTOMATED RAIN GAUGES"/>
|
||||
|
@ -163,7 +166,7 @@
|
|||
<bulletActionGroup action="COR" phen="FF" sig="W">
|
||||
<bullets>
|
||||
<bullet bulletName="ffwEmergency" bulletText="**SELECT FOR FLASH FLOOD EMERGENCY**" parseString="FLASH FLOOD EMERGENCY"/>
|
||||
<bullet bulletName="icrs" bulletText="Also snow melt" parseString=".RS." showString=".RS."/>
|
||||
<bullet bulletName="icrs" bulletText="Also snow melt" bulletGroup="ic" parseString=".RS." showString=".RS."/>
|
||||
<bullet bulletText="*********** SOURCE (CHOOSE 1) **********" bulletType="title"/>
|
||||
<bullet bulletName="doppler" bulletText="Doppler radar indicated" bulletGroup="source" bulletDefault="true" parseString="DOPPLER RADAR INDICATED"/>
|
||||
<bullet bulletName="dopplerGauge" bulletText="Doppler radar and automated gauges" bulletGroup="source" parseString="DOPPLER RADAR AND AUTOMATED RAIN GAUGES"/>
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
Modified Phil Kurimski 09-23-2011 OB 11.0.8-8
|
||||
Modified Phil Kurimski 01-26-2012 OB 12.1.1-1
|
||||
Modified Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Modified Phil Kurimski 04-27-2012 -->
|
||||
Modified Phil Kurimski 04-27-2012
|
||||
Modified Qinglu Lin 10-03-2012 DR 15426. Added damic to <lockedGroupsOnFollowup> tag.
|
||||
-->
|
||||
|
||||
<!-- Config distance/speed units -->
|
||||
<unitDistance>mi</unitDistance>
|
||||
|
@ -65,7 +67,7 @@
|
|||
<!-- Customized several sections in bullet section including:
|
||||
Added Flash Flood Emergency Headline
|
||||
Changed the CTA Bullet names for easier parsing in the vm file -->
|
||||
<lockedGroupsOnFollowup>dam,ic</lockedGroupsOnFollowup>
|
||||
<lockedGroupsOnFollowup>dam,ic,damic</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup action="NEW" phen="FF" sig="W">
|
||||
<bullets>
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
Modified Phil Kurimski 09-23-2011 OB 11.0.8-8
|
||||
Modified Phil Kurimski 01-26-2012 OB 12.1.1-1
|
||||
Modified Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Modified Phil Kurimski 04-27-2012 -->
|
||||
Modified Phil Kurimski 04-27-2012
|
||||
Modified Qinglu Lin 10-04-2012 DR 15426. Added damic to <lockedGroupsOnFollowup> tag.
|
||||
-->
|
||||
|
||||
<warngenConfig>
|
||||
|
||||
|
@ -57,7 +59,7 @@
|
|||
Added Flash Flood Emergency Headline
|
||||
Changed the CTA Bullet names for easier parsing in the vm file
|
||||
Added the Primary Cause to CAN and EXP sections for correct headlines -->
|
||||
<lockedGroupsOnFollowup>dam,ic</lockedGroupsOnFollowup>
|
||||
<lockedGroupsOnFollowup>dam,ic,damic</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup>
|
||||
<bullets>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
Modified Phil Kurimski 02-29-2012 OB 12.2.1-3
|
||||
Modified Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Modified Phil Kurimski 04-27-2012
|
||||
Modified Qinglu Lin 10-04-2012 DR 15426. Added damic to <lockedGroupsOnFollowup> tag.
|
||||
-->
|
||||
|
||||
<warngenConfig>
|
||||
|
@ -59,7 +60,7 @@
|
|||
Added Flash Flood Emergency Headline
|
||||
Changed the CTA Bullet names for easier parsing in the vm file
|
||||
Added the Primary Cause to CAN and EXP sections for correct headlines -->
|
||||
<lockedGroupsOnFollowup>dam,ic</lockedGroupsOnFollowup>
|
||||
<lockedGroupsOnFollowup>dam,ic,damic</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup>
|
||||
<bullets>
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
Modified Phil Kurimski 01-26-2012 OB 12.1.1-1
|
||||
Modified Phil Kurimski 02-29-2012 OB 12.2.1-3
|
||||
Modified Qinglu Lin 04-04-2012 DR 14691. Added <feAreaField> tag.
|
||||
Modified Phil Kurimski 04-27-2012 -->
|
||||
Modified Phil Kurimski 04-27-2012
|
||||
Modified Qinglu Lin 10-04-2012 DR 15426. Added damic to <lockedGroupsOnFollowup> tag.
|
||||
-->
|
||||
|
||||
<!-- Config distance/speed units -->
|
||||
<unitDistance>mi</unitDistance>
|
||||
|
@ -66,7 +68,7 @@
|
|||
<!-- Customized several sections in bullet section including:
|
||||
Added Flash Flood Emergency Headline
|
||||
Changed the CTA Bullet names for easier parsing in the vm file -->
|
||||
<lockedGroupsOnFollowup>dam,ic</lockedGroupsOnFollowup>
|
||||
<lockedGroupsOnFollowup>dam,ic,damic</lockedGroupsOnFollowup>
|
||||
<bulletActionGroups>
|
||||
<bulletActionGroup action="NEW" phen="FF" sig="W">
|
||||
<bullets>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
# 02/16/12 14439 jdynina modified haines thresholds
|
||||
# 02/16/12 13917 jdynina merged in changes from TRAC ticket 11391
|
||||
# 07/25/12 #957 dgilling implement edit areas as args to calc methods.
|
||||
#
|
||||
# 10/5/12 15158 ryu add Forecaster.getDb()
|
||||
#
|
||||
##
|
||||
import string, sys, re, time, types, getopt, fnmatch, LogStream, DatabaseID, JUtil, AbsTime, TimeRange
|
||||
|
@ -581,12 +581,17 @@ class Forecaster(GridUtilities):
|
|||
+ ' #Grids=' + `numGrids`
|
||||
self._client.sendUserMessage(msg, "SMARTINIT")
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Returns the IFPDB object for the given db
|
||||
#--------------------------------------------------------------------------
|
||||
def getDb(self, dbString):
|
||||
from com.raytheon.edex.plugin.gfe.smartinit import IFPDB
|
||||
return IFPDB(dbString)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Returns the source and destination databases, given the srcName.
|
||||
#--------------------------------------------------------------------------
|
||||
def _getLatest(self, client, srcNames, fcstName=None):
|
||||
from com.raytheon.edex.plugin.gfe.smartinit import IFPDB
|
||||
|
||||
# ryu: Added/modified code to allow multiple sources. The srcdb is
|
||||
# now an MDB. This is needed for (AK)NAM40 init, which sources
|
||||
# from both NAM40 and NAM20.
|
||||
|
@ -600,7 +605,7 @@ class Forecaster(GridUtilities):
|
|||
for src in srcNames:
|
||||
# source model at same model time
|
||||
fullDBName = self.__dbName.replace(modelName, src)
|
||||
db = IFPDB(fullDBName)
|
||||
db = self.getDb(fullDBName)
|
||||
if db.getKeys().size() == 0:
|
||||
LogStream.logEvent("Source database " + fullDBName + \
|
||||
" is empty.")
|
||||
|
@ -633,7 +638,7 @@ class Forecaster(GridUtilities):
|
|||
else:
|
||||
client.createDB(newdb)
|
||||
|
||||
newdb = IFPDB(newdb)
|
||||
newdb = self.getDb(newdb)
|
||||
|
||||
return srcdb, newdb
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ class TextProduct(GenericHazards.TextProduct):
|
|||
Definition["language"] = "english"
|
||||
Definition["lineLength"] = 66 #Maximum line length
|
||||
|
||||
Definition["purgeTime"] = 24 # Default Expiration in hours if
|
||||
Definition["purgeTime"] = 8 # Default Expiration in hours if
|
||||
Definition["includeCities"] = 0 # Cities not included in area header
|
||||
Definition["cityDescriptor"] = "INCLUDING THE CITIES OF"
|
||||
Definition["includeZoneNames"] = 1 # Zone names will be included in the area header
|
||||
|
|
|
@ -86,6 +86,8 @@ import com.raytheon.uf.edex.wmo.message.AFOSProductId;
|
|||
* 28Jul2010 2187 cjeanbap Fixed class exception in cccnnnxxxReadVersion.
|
||||
* 05Oct2010 cjeanbap Fixed a bug introduced on #2187; return distinct rows.
|
||||
* 23May2012 14952 rferrel Added cccnnnxxxByRefTime.
|
||||
* 03Oct2012 15244 mgamazaychikov Added the fix to query the appropriate table
|
||||
* (operational or practice)
|
||||
* </pre>
|
||||
*
|
||||
* @author garmendariz
|
||||
|
@ -133,7 +135,7 @@ public class StdTextProductDao extends CoreDao {
|
|||
|
||||
private static final String TM_QUERY_FMT = "select refTime from table_name where cccid='%s' and nnnid='%s' and xxxid='%s';";
|
||||
|
||||
private static final String AFOS_QUERY_STMT = "from StdTextProduct prod where "
|
||||
private static final String AFOS_QUERY_STMT = "from StdTextProduct where "
|
||||
+ ProdCCC_ID
|
||||
+ " = :"
|
||||
+ CCC_ID
|
||||
|
@ -309,7 +311,15 @@ public class StdTextProductDao extends CoreDao {
|
|||
}
|
||||
|
||||
tx = session.beginTransaction();
|
||||
Query query = session.createQuery(AFOS_QUERY_STMT);
|
||||
/*
|
||||
* DR15244 - Make sure that the query is performed on the appropriate
|
||||
* table based on what StdTextProduct is requested (ultimately on CAVE mode)
|
||||
*/
|
||||
Matcher m = Pattern.compile("StdTextProduct").matcher(AFOS_QUERY_STMT);
|
||||
String tableName = stdTextProduct.getClass().getSimpleName();
|
||||
String tableQuery = m.replaceAll(tableName);
|
||||
Query query = session.createQuery(tableQuery);
|
||||
|
||||
|
||||
if (version >= 0) {
|
||||
query.setMaxResults(version + 1);
|
||||
|
|
|
@ -19,7 +19,9 @@ package com.raytheon.uf.edex.dat.utils;
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -68,6 +70,9 @@ public class FreezingLevel {
|
|||
|
||||
private int eighteenCount = 0;
|
||||
|
||||
// reference time
|
||||
Calendar refTime = null;
|
||||
|
||||
public FreezingLevel(String modelName) {
|
||||
|
||||
this.modelName = modelName;
|
||||
|
@ -76,14 +81,18 @@ public class FreezingLevel {
|
|||
sixCount = 0;
|
||||
twelveCount = 0;
|
||||
eighteenCount = 0;
|
||||
refTime = Calendar.getInstance();
|
||||
// only for get data for hour 00z,06z,12z, or 18z
|
||||
int adjustedHour = (refTime.get(Calendar.HOUR_OF_DAY) / 6) * 6;
|
||||
refTime.set(Calendar.HOUR_OF_DAY, adjustedHour);
|
||||
|
||||
// populates what ever is missing, sets prevalent forecast hour
|
||||
for (Entry<String, Integer> entry : getGHLevelMap().entrySet()) {
|
||||
populateRecord(modelName, entry.getKey());
|
||||
populateRecord(modelName, entry.getKey(), refTime.getTime());
|
||||
}
|
||||
|
||||
for (Entry<String, Integer> entry : getTLevelMap().entrySet()) {
|
||||
populateRecord(modelName, entry.getKey());
|
||||
populateRecord(modelName, entry.getKey(), refTime.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,40 +131,41 @@ public class FreezingLevel {
|
|||
Integer jtopLevel = null;
|
||||
Integer ktopLevel = null;
|
||||
|
||||
System.out
|
||||
.println("********** Starting Freezing Level Calculations *****************");
|
||||
for (Integer level : ghValues.keySet()) {
|
||||
System.out
|
||||
.println("********** Starting Freezing Level Calculations *****************");
|
||||
for (Integer level : ghValues.keySet()) {
|
||||
|
||||
Double tValue = tValues.get(level);
|
||||
Double ghValue = ghValues.get(level);
|
||||
System.out.println("GH Value: "+ghValue+" TValue: "+tValue);
|
||||
Double tValue = tValues.get(level);
|
||||
Double ghValue = ghValues.get(level);
|
||||
System.out.println("GH Value: " + ghValue + " TValue: "
|
||||
+ tValue);
|
||||
|
||||
if (ghValue != null && ghValue > -9000) {
|
||||
if (tValue != null && tValue > 273.16) {
|
||||
if (ghValue != null && ghValue > -9000) {
|
||||
if (tValue != null && tValue > 273.16) {
|
||||
|
||||
fLevel = (ghValues.get(ktopLevel) - ((ghValues
|
||||
.get(ktopLevel) - ghValue) * ((273.16 - tValues
|
||||
.get(jtopLevel)
|
||||
/ (tValue - tValues.get(jtopLevel)))))) * .00328;
|
||||
System.out.println("Formula:");
|
||||
System.out.println("(" + ghValues.get(ktopLevel)
|
||||
+ " - ((" + ghValues.get(ktopLevel) + " - "
|
||||
+ ghValue + ") * ((273.16 - "
|
||||
+ tValues.get(jtopLevel) + " / (" + tValue
|
||||
+ " - " + tValues.get(jtopLevel)
|
||||
+ "))))) * .00328)");
|
||||
System.out.println("*** FreezingLevel = " + fLevel);
|
||||
freezingMap.put(coor, fLevel.floatValue());
|
||||
break;
|
||||
} else {
|
||||
jtopLevel = level;
|
||||
ktopLevel = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out
|
||||
.println("********** Finished Freezing Level Calculations *****************");
|
||||
}
|
||||
fLevel = (ghValues.get(ktopLevel) - ((ghValues
|
||||
.get(ktopLevel) - ghValue) * ((273.16 - tValues
|
||||
.get(jtopLevel)) / (tValue - tValues
|
||||
.get(jtopLevel))))) * .00328;
|
||||
System.out.println("Formula:");
|
||||
System.out.println("(" + ghValues.get(ktopLevel)
|
||||
+ " - ((" + ghValues.get(ktopLevel) + " - "
|
||||
+ ghValue + ") * ((273.16 - "
|
||||
+ tValues.get(jtopLevel) + ") / (" + tValue
|
||||
+ " - " + tValues.get(jtopLevel)
|
||||
+ ")))) * .00328");
|
||||
System.out.println("*** FreezingLevel = " + fLevel);
|
||||
freezingMap.put(coor, fLevel.floatValue());
|
||||
break;
|
||||
} else {
|
||||
jtopLevel = level;
|
||||
ktopLevel = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out
|
||||
.println("********** Finished Freezing Level Calculations *****************");
|
||||
}
|
||||
|
||||
return freezingMap;
|
||||
}
|
||||
|
@ -235,12 +245,13 @@ public class FreezingLevel {
|
|||
* @param param
|
||||
* @return
|
||||
*/
|
||||
private GribRecord populateRecord(String model, String param) {
|
||||
private GribRecord populateRecord(String model, String param, Date refTime) {
|
||||
int interval = 1440;
|
||||
|
||||
SCANModelParameterXML paramXML = new SCANModelParameterXML();
|
||||
paramXML.setModelName(model);
|
||||
paramXML.setParameterName(param);
|
||||
String sql = getSQL(interval, model, param);
|
||||
String sql = getSQL(interval, model, param, refTime);
|
||||
GribRecord modelRec = DATUtils.getMostRecentGribRecord(interval, sql,
|
||||
paramXML);
|
||||
|
||||
|
@ -327,9 +338,12 @@ public class FreezingLevel {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
private String getSQL(int interval, String model, String param) {
|
||||
private String getSQL(int interval, String model, String param, Date refTime) {
|
||||
String paramName = null;
|
||||
String level = null;
|
||||
SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
|
||||
|
||||
String refTimeStr = sdt.format(refTime);
|
||||
if (param.startsWith("GH")) {
|
||||
paramName = "GH";
|
||||
level = param.substring(2, param.length());
|
||||
|
@ -346,7 +360,9 @@ public class FreezingLevel {
|
|||
+ "\' and level_id = (select id from level where masterlevel_name = 'MB' and levelonevalue = '"
|
||||
+ level
|
||||
+ "\'"
|
||||
+ " limit 1)) order by forecasttime desc limit 1";
|
||||
+ " limit 1)) and reftime='"
|
||||
+ refTimeStr
|
||||
+ "' order by reftime desc, forecasttime desc limit 1";
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
|
||||
<bean id="dqcPreprocService" class="com.raytheon.uf.edex.ohd.pproc.DqcPreProcSrv" />
|
||||
<bean id="mpeRucFreezingLevel" class="com.raytheon.uf.edex.ohd.pproc.MpeRUCFreezingLevel" />
|
||||
|
||||
<camelContext id="dqcPreproc-context"
|
||||
xmlns="http://camel.apache.org/schema/spring"
|
||||
|
@ -29,14 +28,6 @@
|
|||
<to uri="log:dqcPreprocessor?level=ERROR&showBody=false&showCaughtException=true&showStackTrace=true"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
|
||||
<doTry>
|
||||
<bean ref="mpeRucFreezingLevel" method="processMpeRuc" />
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:dqcPreprocessor?level=ERROR&showBody=false&showCaughtException=true&showStackTrace=true"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
</camelContext>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
|
||||
<bean id="mpeRucFreezingLevel" class="com.raytheon.uf.edex.ohd.pproc.MpeRUCFreezingLevel" />
|
||||
|
||||
<camelContext id="frzLvlProc-context"
|
||||
xmlns="http://camel.apache.org/schema/spring"
|
||||
errorHandlerRef="errorHandler">
|
||||
|
||||
<endpoint id="frzLvlProcCron" uri="clusteredquartz://pproc/frzLvlProcScheduled/?cron=${freezingLevel.cron}"/>
|
||||
|
||||
<!-- Run frzLvlProc on Scheduled timer -->
|
||||
<route id="frzLvlProcScheduled">
|
||||
<from uri="frzLvlProcCron" />
|
||||
<to uri="jms-generic:queue:frzLvlProcScheduledWork" />
|
||||
</route>
|
||||
|
||||
<route id="frzLvlProcScheduledWork">
|
||||
<from uri="jms-generic:queue:frzLvlProcScheduledWork" />
|
||||
<doTry>
|
||||
<bean ref="mpeRucFreezingLevel" method="processMpeRuc" />
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:frzLvlProcessor?level=ERROR&showBody=false&showCaughtException=true&showStackTrace=true"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
</camelContext>
|
||||
|
||||
</beans>
|
|
@ -33,6 +33,7 @@ import java.io.InputStreamReader;
|
|||
import java.io.OutputStreamWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -61,9 +62,10 @@ public class MpeRUCFreezingLevel {
|
|||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 19, 2011 dhladky Initial Creation.
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ -------- --------- --------------------------
|
||||
* Nov 19, 2011 dhladky Initial Creation.
|
||||
* Oct 09, 2012 15168 wkwock Fix incorrect values.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -80,10 +82,15 @@ public class MpeRUCFreezingLevel {
|
|||
public static String modelOutputFilePath = AppsDefaults.getInstance()
|
||||
.getToken("mpe_point_freezing_dir");
|
||||
|
||||
public static String dqcPreprocessorBasetime = AppsDefaults.getInstance()
|
||||
.getToken("DQC_PREPROCESSOR_BASETIME");
|
||||
|
||||
public File stationFile = null;
|
||||
|
||||
final String RUC2 = "RUC236";
|
||||
|
||||
// models used by MPE
|
||||
public static String[] models = new String[] { "RUC130", "RUC80" };
|
||||
public static String[] models = new String[] { "RUC236" };
|
||||
|
||||
public MpeRUCFreezingLevel() {
|
||||
File directory = new File(stationFilePath);
|
||||
|
@ -97,274 +104,342 @@ public class MpeRUCFreezingLevel {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// correct env vairiable dqcPreprocessorBasetime if needed
|
||||
if (dqcPreprocessorBasetime == null) {
|
||||
dqcPreprocessorBasetime = "00z";
|
||||
}
|
||||
|
||||
dqcPreprocessorBasetime = dqcPreprocessorBasetime.toLowerCase();
|
||||
if (!dqcPreprocessorBasetime.equals("00z")
|
||||
&& !dqcPreprocessorBasetime.equals("06z")
|
||||
&& !dqcPreprocessorBasetime.equals("12z")
|
||||
&& !dqcPreprocessorBasetime.equals("18z")) {
|
||||
dqcPreprocessorBasetime = "00z";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read freezing station list from file
|
||||
* $mpe_station_list_dir/$SITENAME_freezing_station_list
|
||||
*/
|
||||
private LinkedHashMap<String, Coordinate> readFrzStnLst() {
|
||||
if (stationFile == null) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"File freezing_station_list not found....");
|
||||
return null;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, Coordinate> freezingStations = new LinkedHashMap<String, Coordinate>();
|
||||
|
||||
FileInputStream ifstream = null;
|
||||
DataInputStream in = null;
|
||||
BufferedReader br = null;
|
||||
|
||||
try {
|
||||
ifstream = new FileInputStream(stationFile);
|
||||
in = new DataInputStream(ifstream);
|
||||
br = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
Double lat = null;
|
||||
Double lon = null;
|
||||
while (br.ready()) {
|
||||
line = br.readLine();
|
||||
if (line != null) {
|
||||
statusHandler.handle(Priority.INFO, line);
|
||||
String[] aline = line.split("\\s+");
|
||||
|
||||
if (aline != null && aline.length > 0) {
|
||||
try {
|
||||
String stationId = aline[0].trim();
|
||||
lat = Double.valueOf(aline[2].trim());
|
||||
// take times negative 1 to make it true West
|
||||
lon = Double.valueOf(aline[3].trim()) * (-1);
|
||||
|
||||
if (stationId != null && lat != null && lon != null) {
|
||||
Coordinate coor = new Coordinate(lon, lat, 0.0);
|
||||
freezingStations.put(stationId, coor);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(
|
||||
Priority.INFO,
|
||||
"finished parsing "
|
||||
+ stationFile.getAbsolutePath()
|
||||
+ " \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR, "Unable to read file "
|
||||
+ stationFile.getAbsolutePath() + " \n");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (ifstream != null) {
|
||||
try {
|
||||
ifstream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return freezingStations;
|
||||
}
|
||||
|
||||
private void writeResult(
|
||||
LinkedHashMap<String, Coordinate> freezingStations,
|
||||
HashMap<String, HashMap<Integer, FreezingLevelXML>> freezingTimeMap) {
|
||||
// Now write to the result file freezing_1_SITENAME_point_yyyymmdd
|
||||
// compare first forecast hour list against all others
|
||||
FileOutputStream ofstream = null;
|
||||
DataOutputStream out = null;
|
||||
BufferedWriter bw = null;
|
||||
Calendar dates[] = getSortedDates(dqcPreprocessorBasetime);// get the
|
||||
// dates and
|
||||
// hours in
|
||||
// order
|
||||
|
||||
try {
|
||||
String site = PropertiesFactory.getInstance().getEnvProperties()
|
||||
.getEnvValue("SITENAME");
|
||||
ofstream = new FileOutputStream(getAbsoluteOutFileName(
|
||||
dates[3].getTime(), site));
|
||||
out = new DataOutputStream(ofstream);
|
||||
bw = new BufferedWriter(new OutputStreamWriter(out));
|
||||
|
||||
String dhStr = "DH" + dqcPreprocessorBasetime.substring(0, 2);
|
||||
|
||||
for (Entry<String, Coordinate> entry : freezingStations.entrySet()) {
|
||||
|
||||
Coordinate coor = entry.getValue();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
// ".E Z$stn $otdate1 DH18/HZIRZ/DIH+6/ $v0/ $v1/ $v2/ $v3\n"
|
||||
|
||||
buf.append(".E " + entry.getKey() + " "
|
||||
+ getFormattedDate(dates[3].getTime()) + " " + dhStr
|
||||
+ "/HZIRZ/DIH+6/");
|
||||
|
||||
int i = 0;
|
||||
for (int j = 0; j < dates.length; j++) {
|
||||
|
||||
FreezingLevelEntry fle = null;
|
||||
|
||||
// Does a preference for the first model defined. RUC130
|
||||
// has higher resolution so it gets preference
|
||||
if (fle == null) {
|
||||
if (freezingTimeMap.containsKey(RUC2)) {
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = freezingTimeMap
|
||||
.get(RUC2);
|
||||
|
||||
if (modelFl.containsKey(dates[j]
|
||||
.get(Calendar.HOUR_OF_DAY))) {
|
||||
FreezingLevelXML flx = modelFl.get(dates[j]
|
||||
.get(Calendar.HOUR_OF_DAY));
|
||||
if (flx != null && flx.getDate() != null) {
|
||||
// same expected year,month,day,and hour
|
||||
if (Math.floor(flx.getDate().getTime() / 1000 / 60 / 60) == Math
|
||||
.floor(dates[j].getTimeInMillis() / 1000 / 60 / 60)) {
|
||||
fle = flx.getEntry(coor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String fzlev = "M";
|
||||
|
||||
if (fle != null) {
|
||||
fzlev = String.valueOf(fle.getFreezingLevel())
|
||||
.substring(0, 4) + "S";
|
||||
}
|
||||
|
||||
buf.append(" " + fzlev);
|
||||
|
||||
if (i < 3) {
|
||||
buf.append("/");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
statusHandler.handle(Priority.INFO, buf.toString());
|
||||
bw.write(buf.toString() + "\n");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Processing Level SHEF output failed...");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.flush();
|
||||
bw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (ofstream != null) {
|
||||
try {
|
||||
ofstream.flush();
|
||||
ofstream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the MPE freezing Levels
|
||||
*/
|
||||
public void processMpeRuc() {
|
||||
Integer forecastHour = null;
|
||||
HashMap<String, HashMap<Integer, FreezingLevelXML>> freezingTimeMap = new HashMap<String, HashMap<Integer, FreezingLevelXML>>();
|
||||
LinkedHashMap<String, Coordinate> freezingStations = new LinkedHashMap<String, Coordinate>();
|
||||
|
||||
if (stationFile != null) {
|
||||
|
||||
HashMap<String, FreezingLevel> FreezeLevelMap = new HashMap<String, FreezingLevel>();
|
||||
|
||||
for (String model : models) {
|
||||
FreezingLevel fl = new FreezingLevel(model);
|
||||
if (fl != null) {
|
||||
FreezeLevelMap.put(model, fl);
|
||||
}
|
||||
}
|
||||
|
||||
Integer forecastHour = null;
|
||||
Date outputDate = null;
|
||||
HashMap<String, HashMap<Integer, FreezingLevelXML>> freezingTimeMap = new HashMap<String, HashMap<Integer, FreezingLevelXML>>();
|
||||
LinkedHashMap<String, Coordinate> freezingStations = new LinkedHashMap<String, Coordinate>();
|
||||
|
||||
FileInputStream ifstream = null;
|
||||
DataInputStream in = null;
|
||||
BufferedReader br = null;
|
||||
|
||||
try {
|
||||
ifstream = new FileInputStream(stationFile);
|
||||
in = new DataInputStream(ifstream);
|
||||
br = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
Double lat = null;
|
||||
Double lon = null;
|
||||
while (br.ready()) {
|
||||
line = br.readLine();
|
||||
if (line != null) {
|
||||
statusHandler.handle(Priority.INFO, line);
|
||||
String[] aline = line.split("\\s+");
|
||||
|
||||
if (aline != null && aline.length > 0) {
|
||||
try {
|
||||
String stationId = aline[0].trim();
|
||||
lat = Double.valueOf(aline[2].trim());
|
||||
// take times negative 1 to make it true West
|
||||
lon = Double.valueOf(aline[3].trim()) * (-1);
|
||||
|
||||
if (stationId != null && lat != null
|
||||
&& lon != null) {
|
||||
Coordinate coor = new Coordinate(lon, lat,
|
||||
0.0);
|
||||
freezingStations.put(stationId, coor);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(
|
||||
Priority.INFO,
|
||||
"finished parsing "
|
||||
+ stationFile.getAbsolutePath()
|
||||
+ " \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR, "Unable to read file "
|
||||
+ stationFile.getAbsolutePath() + " \n");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (ifstream != null) {
|
||||
try {
|
||||
ifstream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
HashMap<Coordinate, Float> freezingLevels = null;
|
||||
|
||||
for (String model : models) {
|
||||
if (FreezeLevelMap.containsKey(model)) {
|
||||
FreezingLevel fl = FreezeLevelMap.get(model);
|
||||
ArrayList<FreezingLevelEntry> freezes = null;
|
||||
|
||||
if (freezingLevels == null) {
|
||||
freezingLevels = fl
|
||||
.getFreezingLevel(getCoordinates(freezingStations));
|
||||
|
||||
freezes = new ArrayList<FreezingLevelEntry>();
|
||||
|
||||
for (Entry<Coordinate, Float> entry : freezingLevels
|
||||
.entrySet()) {
|
||||
FreezingLevelEntry fle = new FreezingLevelEntry(
|
||||
entry.getKey(), entry.getValue());
|
||||
freezes.add(fle);
|
||||
}
|
||||
}
|
||||
|
||||
FreezingLevelXML flx = new FreezingLevelXML(freezes);
|
||||
|
||||
if (forecastHour == null && outputDate == null) {
|
||||
forecastHour = getConvertedForecastHour(fl);
|
||||
outputDate = fl.getReferenceTime(fl
|
||||
.getForecastHour());
|
||||
}
|
||||
|
||||
flx.setForecastHour(forecastHour);
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = new HashMap<Integer, FreezingLevelXML>();
|
||||
modelFl.put(forecastHour, flx);
|
||||
freezingTimeMap.put(model, modelFl);
|
||||
writeFreezingLevelTemp(flx, model);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Processing Freezing Level failed...");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
FileOutputStream ofstream = null;
|
||||
DataOutputStream out = null;
|
||||
BufferedWriter bw = null;
|
||||
|
||||
try {
|
||||
// Get other hour files read in
|
||||
for (String model : models) {
|
||||
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = freezingTimeMap
|
||||
.get(model);
|
||||
|
||||
if (modelFl != null) {
|
||||
for (RUC_TIME time : RUC_TIME.values()) {
|
||||
|
||||
int fileTime = Integer.valueOf(time.getTime());
|
||||
|
||||
if (!modelFl.containsKey(fileTime)) {
|
||||
|
||||
FreezingLevelXML flx1 = readFreezingLevel(
|
||||
fileTime, model);
|
||||
|
||||
if (flx1 != null) {
|
||||
modelFl.put(flx1.getForecastHour(), flx1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freezingTimeMap.put(model, modelFl);
|
||||
}
|
||||
}
|
||||
|
||||
// compare first forecast hour list against all others
|
||||
String site = PropertiesFactory.getInstance()
|
||||
.getEnvProperties().getEnvValue("SITENAME");
|
||||
ArrayList<Integer> orderedHours = getOrderedHours(forecastHour);
|
||||
ofstream = new FileOutputStream(getAbsoluteOutFileName(
|
||||
outputDate, site));
|
||||
out = new DataOutputStream(ofstream);
|
||||
bw = new BufferedWriter(new OutputStreamWriter(out));
|
||||
|
||||
for (Entry<String, Coordinate> entry : freezingStations
|
||||
.entrySet()) {
|
||||
|
||||
Coordinate coor = entry.getValue();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
// ".E Z$stn $otdate1 DH18/HZIRZ/DIH+6/ $v0/ $v1/ $v2/ $v3\n"
|
||||
buf.append(".E " + entry.getKey() + " "
|
||||
+ getFormattedDate(outputDate)
|
||||
+ " DH18/HZIRZ/DIH+6/");
|
||||
|
||||
int i = 0;
|
||||
for (Integer hour : orderedHours) {
|
||||
|
||||
FreezingLevelEntry fle = null;
|
||||
|
||||
// Does a preference for the first model defined. RUC130
|
||||
// has higher resolution so it gets preference
|
||||
for (String model : models) {
|
||||
if (fle == null) {
|
||||
if (freezingTimeMap.containsKey(model)) {
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = freezingTimeMap
|
||||
.get(model);
|
||||
|
||||
if (modelFl.containsKey(hour)) {
|
||||
FreezingLevelXML flx = modelFl
|
||||
.get(hour);
|
||||
fle = flx.getEntry(coor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String fzlev = "M";
|
||||
|
||||
if (fle != null) {
|
||||
fzlev = "" + fle.getFreezingLevel();
|
||||
}
|
||||
|
||||
buf.append(" " + fzlev);
|
||||
|
||||
if (i < 3) {
|
||||
buf.append("/");
|
||||
} else {
|
||||
buf.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
statusHandler.handle(Priority.INFO, buf.toString());
|
||||
bw.write(buf.toString() + "\n");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Processing Level SHEF output failed...");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.flush();
|
||||
bw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (ofstream != null) {
|
||||
try {
|
||||
ofstream.flush();
|
||||
ofstream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"File freezing_station_list not found....");
|
||||
// get the freezing station list from file
|
||||
freezingStations = readFrzStnLst();
|
||||
if (freezingStations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get data from hdf5 for this run
|
||||
FreezingLevel fl = new FreezingLevel(RUC2);
|
||||
|
||||
// Save data for future use
|
||||
try {
|
||||
HashMap<Coordinate, Float> freezingLevels = null;
|
||||
|
||||
ArrayList<FreezingLevelEntry> freezes = null;
|
||||
|
||||
if (freezingLevels == null) {
|
||||
freezingLevels = fl
|
||||
.getFreezingLevel(getCoordinates(freezingStations));
|
||||
|
||||
freezes = new ArrayList<FreezingLevelEntry>();
|
||||
|
||||
for (Entry<Coordinate, Float> entry : freezingLevels.entrySet()) {
|
||||
FreezingLevelEntry fle = new FreezingLevelEntry(
|
||||
entry.getKey(), entry.getValue());
|
||||
freezes.add(fle);
|
||||
}
|
||||
}
|
||||
|
||||
FreezingLevelXML flx = new FreezingLevelXML(freezes);
|
||||
|
||||
Calendar refTime = Calendar.getInstance();
|
||||
// only for get data for hour 00z,06z,12z, or 18z
|
||||
int adjustedHour = (refTime.get(Calendar.HOUR_OF_DAY) / 6) * 6;
|
||||
refTime.set(Calendar.HOUR_OF_DAY, adjustedHour);
|
||||
flx.setDate(refTime.getTime());
|
||||
flx.setForecastHour(adjustedHour);
|
||||
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = new HashMap<Integer, FreezingLevelXML>();
|
||||
modelFl.put(forecastHour, flx);
|
||||
freezingTimeMap.put(RUC2, modelFl);
|
||||
writeFreezingLevelTemp(flx, RUC2);
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Processing Freezing Level failed...");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// get all data from previously saved data from
|
||||
// mpe/dailyQC/freezing_level/point/RUC236[0,6,12,18]zFreezingLevel.bin
|
||||
// Get other hour files read in
|
||||
for (String model : models) {
|
||||
|
||||
HashMap<Integer, FreezingLevelXML> modelFl = freezingTimeMap
|
||||
.get(model);
|
||||
|
||||
if (modelFl != null) {
|
||||
for (RUC_TIME time : RUC_TIME.values()) {
|
||||
|
||||
int fileTime = Integer.valueOf(time.getTime());
|
||||
|
||||
if (!modelFl.containsKey(fileTime)) {
|
||||
|
||||
FreezingLevelXML flx1 = readFreezingLevel(fileTime,
|
||||
model);
|
||||
|
||||
if (flx1 != null) {
|
||||
modelFl.put(flx1.getForecastHour(), flx1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freezingTimeMap.put(model, modelFl);
|
||||
}
|
||||
}
|
||||
|
||||
// now write to result file freezing_1_SITENAME_point_yyyymmdd
|
||||
writeResult(freezingStations, freezingTimeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* setup dates
|
||||
*/
|
||||
private Calendar[] getSortedDates(String dqcPreprocessorBasetime) {
|
||||
Calendar dates[] = new Calendar[4];
|
||||
|
||||
Calendar cdate = Calendar.getInstance();// start date
|
||||
Calendar tdate = Calendar.getInstance();// end date
|
||||
int currentHour = cdate.get(Calendar.HOUR_OF_DAY);
|
||||
|
||||
int dqcHour = Integer.parseInt(dqcPreprocessorBasetime.substring(0, 2));
|
||||
if (currentHour < dqcHour && dqcHour != 0) {
|
||||
cdate.add(Calendar.DATE, -1);
|
||||
} else if (dqcHour != 0) {
|
||||
tdate.add(Calendar.DATE, 1);
|
||||
}
|
||||
|
||||
Calendar startDate = tdate;
|
||||
if (dqcPreprocessorBasetime.equalsIgnoreCase("00z")) {
|
||||
startDate = (Calendar) tdate.clone();
|
||||
} else {
|
||||
startDate = (Calendar) cdate.clone();
|
||||
}
|
||||
|
||||
startDate.set(Calendar.HOUR_OF_DAY, dqcHour);
|
||||
|
||||
for (int i = 0; i < dates.length; i++) {
|
||||
dates[i] = (Calendar) startDate.clone();
|
||||
startDate.add(Calendar.HOUR_OF_DAY, 6);
|
||||
}
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -468,41 +543,6 @@ public class MpeRUCFreezingLevel {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the ordering for the SHEF output
|
||||
*
|
||||
* @param forecastHour
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<Integer> getOrderedHours(int forecastHour) {
|
||||
|
||||
ArrayList<Integer> orderedHours = new ArrayList<Integer>();
|
||||
|
||||
if (forecastHour == 0) {
|
||||
orderedHours.add(0);
|
||||
orderedHours.add(6);
|
||||
orderedHours.add(12);
|
||||
orderedHours.add(18);
|
||||
} else if (forecastHour == 6) {
|
||||
orderedHours.add(6);
|
||||
orderedHours.add(12);
|
||||
orderedHours.add(18);
|
||||
orderedHours.add(0);
|
||||
} else if (forecastHour == 12) {
|
||||
orderedHours.add(12);
|
||||
orderedHours.add(18);
|
||||
orderedHours.add(0);
|
||||
orderedHours.add(6);
|
||||
} else if (forecastHour == 18) {
|
||||
orderedHours.add(18);
|
||||
orderedHours.add(0);
|
||||
orderedHours.add(6);
|
||||
orderedHours.add(12);
|
||||
}
|
||||
|
||||
return orderedHours;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the output date
|
||||
*
|
||||
|
@ -534,30 +574,4 @@ public class MpeRUCFreezingLevel {
|
|||
|
||||
return coors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used only by the MPE RUC130 for SHEF output
|
||||
*
|
||||
* @param ft
|
||||
*/
|
||||
private int getConvertedForecastHour(FreezingLevel fl) {
|
||||
|
||||
int flTime = fl.getForecastHour();
|
||||
int retVal = 0;
|
||||
|
||||
if (flTime >= 0 && flTime < 3) {
|
||||
retVal = 0;
|
||||
} else if (flTime >= 3 && flTime < 9) {
|
||||
retVal = 6;
|
||||
} else if (flTime >= 9 && flTime < 15) {
|
||||
retVal = 12;
|
||||
} else if (flTime >= 15 && flTime < 21) {
|
||||
retVal = 18;
|
||||
} else if (flTime >= 21) {
|
||||
retVal = 0;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ XML_TEMPLATE = ""
|
|||
|
||||
import sys
|
||||
import os.path
|
||||
from os import path, access, R_OK
|
||||
import shutil
|
||||
|
||||
class MainData:
|
||||
|
@ -92,6 +93,12 @@ fileName = os.path.split(file)[1]
|
|||
|
||||
if fileName == "spotters.dat":
|
||||
workFile = "/tmp/spotters.dat"
|
||||
if path.exists(workFile) and path.isfile(workFile) and access(workFile, R_OK):
|
||||
print "Attempting to cleanup work directory"
|
||||
os.system("rm /tmp/spotters.dat")
|
||||
else:
|
||||
print "No preliminary cleanup needed - continuing"
|
||||
|
||||
shutil.copy(file, workFile)
|
||||
os.system("sed -i -e 's/spotterName/spottersName/g' /tmp/spotters.dat")
|
||||
os.system("sed -i -e 's/spotterAddr/spottersAddr/g' /tmp/spotters.dat")
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 04/06/2012 10388 mhuang Initial creation
|
||||
# 10/09/12 DR 13901 D. Friedman Add logging
|
||||
##############################################################################
|
||||
|
||||
# this allows you to run this script from outside of ./bin
|
||||
|
@ -27,5 +28,10 @@ export PYTHONPATH=${RUN_FROM_DIR}/src:$PYTHONPATH
|
|||
_PYTHON="${PYTHON_INSTALL}/bin/python"
|
||||
_MODULE="${RUN_FROM_DIR}/src/qpidNotify/mhsAckNotify.py"
|
||||
|
||||
log_file=${LOG_DIR:-/data/logs/fxa}/$(date -u +%Y%m%d)/mhsAckNotify
|
||||
if touch "$log_file"; then
|
||||
exec >& "$log_file"
|
||||
fi
|
||||
|
||||
# quoting of '$@' is used to prevent command line interpretation
|
||||
$_PYTHON $_MODULE "$@"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 09/19/11 8804 mhuang Initial creation
|
||||
# 10/09/12 DR 13901 D. Friedman Add logging
|
||||
##############################################################################
|
||||
|
||||
# this allows you to run this script from outside of ./bin
|
||||
|
@ -49,5 +50,10 @@ export PYTHONPATH=${RUN_FROM_DIR}/src:$PYTHONPATH
|
|||
_PYTHON="${PYTHON_INSTALL}/bin/python"
|
||||
_MODULE="${RUN_FROM_DIR}/src/qpidNotify/qpidNotify.py"
|
||||
|
||||
log_file=${LOG_DIR:-/data/logs/fxa}/$(date -u +%Y%m%d)/qpidNotify
|
||||
if touch "$log_file"; then
|
||||
exec >& "$log_file"
|
||||
fi
|
||||
|
||||
# quoting of '$@' is used to prevent command line interpretation
|
||||
$_PYTHON $_MODULE "$@"
|
||||
|
|
|
@ -25,8 +25,12 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 10/28/08 1585 MW Fegan Initial Creation.
|
||||
# 10/09/12 DR 13901 D. Friedman Add doWithinTime
|
||||
##############################################################################
|
||||
import sys
|
||||
import Queue
|
||||
import threading
|
||||
import traceback
|
||||
import types
|
||||
|
||||
import InputOutput as IO
|
||||
|
@ -104,3 +108,31 @@ def convListToDict(list):
|
|||
temp.append(val)
|
||||
retVal.append(temp)
|
||||
return dict(retVal)
|
||||
|
||||
def doWithinTime(target_function, description='complete the operation',
|
||||
max_tries = 3, max_try_time = 10.0, args=(), kwargs={}):
|
||||
q = Queue.Queue()
|
||||
def threadFunc(q, target_function, args, kwargs):
|
||||
try:
|
||||
r = (True, target_function(*args, **kwargs))
|
||||
except:
|
||||
traceback.print_exc()
|
||||
r = (False, sys.exc_info()[1])
|
||||
q.put(r)
|
||||
exc = None
|
||||
for i in range(0, max_tries):
|
||||
t = threading.Thread(target=threadFunc, args=(q, target_function, args, kwargs))
|
||||
t.daemon = True
|
||||
t.start()
|
||||
try:
|
||||
r, val = q.get(True, max_try_time)
|
||||
if r:
|
||||
return val
|
||||
else:
|
||||
exc = val
|
||||
break
|
||||
except Queue.Empty, e:
|
||||
continue
|
||||
reason = exc is None and " within the expected time" or (": " + str(exc))
|
||||
raise StandardError("Failed to %s%s" % (description, reason))
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 04/06/2012 10388 D. Friedman Initial version
|
||||
# 10/09/12 DR 13901 D. Friedman Limit execution time
|
||||
##############################################################################
|
||||
|
||||
import getopt
|
||||
|
@ -13,6 +14,8 @@ import os
|
|||
import os.path
|
||||
import sys
|
||||
|
||||
from lib.Util import doWithinTime
|
||||
|
||||
import qpid
|
||||
from qpid.util import connect
|
||||
from qpid.connection import Connection
|
||||
|
@ -32,6 +35,26 @@ def remove_file(*parts):
|
|||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
def get_qpid_connection(broker_addr):
|
||||
try:
|
||||
socket = connect(broker_addr, 5672)
|
||||
connection = Connection (sock=socket)
|
||||
connection.start()
|
||||
return connection
|
||||
except:
|
||||
sys.stderr.write("mhsAckNotify: connect to %s: %s\n" % (broker_addr, sys.exc_info()[1],))
|
||||
return None
|
||||
|
||||
def send_message(connection, notif):
|
||||
session = connection.session(str(uuid4()))
|
||||
|
||||
props = session.delivery_properties(routing_key=TOPIC_NAME)
|
||||
head = session.message_properties(application_headers={'sender':notif.sender,
|
||||
'response':notif.response})
|
||||
session.message_transfer(destination=DESTINATION, message=Message(props, head, notif.messageId))
|
||||
session.close(timeout=10)
|
||||
connection.close()
|
||||
|
||||
def run():
|
||||
mhs_data_dir = os.getenv('MHS_DATA', '/data/fxa/mhs')
|
||||
notif = MhsAckNotification()
|
||||
|
@ -60,32 +83,19 @@ def run():
|
|||
except:
|
||||
sys.stderr.write("mhsAckNotify: error removing MHS file: %s\n" % (sys.exc_info()[1],))
|
||||
|
||||
try:
|
||||
# TODO: Should have BROKER_ADDR in CLI setup.env.
|
||||
broker_addr = os.getenv('BROKER_ADDR')
|
||||
if broker_addr is None:
|
||||
broker_addr = os.getenv('DEFAULT_HOST')
|
||||
if broker_addr == 'ec':
|
||||
broker_addr = 'cp1f'
|
||||
if broker_addr is None:
|
||||
broker_addr = 'localhost'
|
||||
# TODO: Should have BROKER_ADDR in CLI setup.env.
|
||||
broker_addr = os.getenv('BROKER_ADDR')
|
||||
if broker_addr is None:
|
||||
broker_addr = os.getenv('DEFAULT_HOST')
|
||||
if broker_addr == 'ec':
|
||||
broker_addr = 'cp1f'
|
||||
if broker_addr is None:
|
||||
broker_addr = 'localhost'
|
||||
|
||||
socket = connect(broker_addr, 5672)
|
||||
except:
|
||||
sys.stderr.write("mhsAckNotify: connect to %s: %s\n" % (broker_addr, sys.exc_info()[1],))
|
||||
return 1
|
||||
|
||||
try:
|
||||
connection = Connection (sock=socket)
|
||||
connection.start()
|
||||
session = connection.session(str(uuid4()))
|
||||
|
||||
props = session.delivery_properties(routing_key=TOPIC_NAME)
|
||||
head = session.message_properties(application_headers={'sender':notif.sender,
|
||||
'response':notif.response})
|
||||
session.message_transfer(destination=DESTINATION, message=Message(props, head, notif.messageId))
|
||||
session.close(timeout=10)
|
||||
connection.close()
|
||||
connection = doWithinTime(get_qpid_connection, args=(broker_addr,))
|
||||
if connection:
|
||||
doWithinTime(send_message, max_tries=1, args=(connection, notif))
|
||||
except:
|
||||
sys.stderr.write("mhsAckNotify: error sending message: %s\n" % (sys.exc_info()[1],))
|
||||
return 1
|
||||
|
|
|
@ -30,21 +30,21 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 09/19/11 8804 MHuang Initial creation
|
||||
# 10/09/12 DR 13901 D. Friedman Limit execution time
|
||||
##############################################################################
|
||||
|
||||
from ufpy import qpidingest
|
||||
from lib.Util import doWithinTime
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
class mhsFileIngest:
|
||||
def __init__(self):
|
||||
print "Initializing mhsFileIngest object"
|
||||
|
||||
def qpidNotify(*args):
|
||||
def startConnection(self):
|
||||
#Find current QPID running hostname
|
||||
server=os.getenv('DEFAULT_HOST')
|
||||
# print "Current EDEX server:", server
|
||||
|
||||
#Make connection to QPID
|
||||
try:
|
||||
|
@ -52,6 +52,11 @@ class mhsFileIngest:
|
|||
except:
|
||||
print "Cannot connect qpid server:", server
|
||||
sys.exit(1)
|
||||
|
||||
self.conn = cnn
|
||||
|
||||
def qpidNotify(self):
|
||||
cnn = self.conn
|
||||
|
||||
#Get uplink files
|
||||
size=len(sys.argv) - 1
|
||||
|
@ -85,14 +90,24 @@ class mhsFileIngest:
|
|||
cnn.close()
|
||||
if fileCount == size:
|
||||
print "Successfully sent", fileCount, "file(s) to EDEX via qpidingest"
|
||||
sys.exit(0)
|
||||
return 0
|
||||
elif errCount == size:
|
||||
print "Failed to send", fileCount, "file(s) to EDEX via qpidingest"
|
||||
sys.exit(1)
|
||||
return 1
|
||||
elif errCount > 0 and fileCount < size:
|
||||
print errcount, "out of", size, "failed to be sent to EDEX via qpidingest"
|
||||
sys.exit(2)
|
||||
|
||||
return 2
|
||||
|
||||
def run():
|
||||
try:
|
||||
m = mhsFileIngest()
|
||||
doWithinTime(m.startConnection, description='connect to qpid')
|
||||
exit_code = doWithinTime(m.qpidNotify, description='send messages', max_tries=1)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(exit_code)
|
||||
|
||||
if __name__ == '__main__':
|
||||
q = mhsFileIngest()
|
||||
q.qpidNotify()
|
||||
run()
|
||||
|
|
Loading…
Add table
Reference in a new issue