13.5.2-2 baseline
Former-commit-id: 6cecce21eb6a7c9b72d7a61936dcbe4f4688fba9
This commit is contained in:
parent
73dd0f166c
commit
4a47fb97c5
77 changed files with 5798 additions and 1713 deletions
2
MHSEmulator/.gitignore
vendored
Normal file
2
MHSEmulator/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
out/
|
||||
*.jar
|
Binary file not shown.
Binary file not shown.
|
@ -5,10 +5,30 @@ import java.io.BufferedWriter;
|
|||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Library module for MHS emulator.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2099 dgilling Use safer exception handling for file I/O.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MhsUtil {
|
||||
|
||||
public static final SimpleDateFormat logDateFormat = new SimpleDateFormat(
|
||||
|
@ -19,32 +39,51 @@ public class MhsUtil {
|
|||
|
||||
public static final String END_TOKEN = "------!!!!END!!!!------";
|
||||
|
||||
public static final File MY_MHS_FILE = new File(
|
||||
"/awips2/.myMHS");
|
||||
public static final File MY_MHS_FILE = new File("/awips2/.myMHS");
|
||||
|
||||
public static final File MSG_ID_FILE = new File(
|
||||
"/awips2/.msgCount");
|
||||
public static final File MSG_ID_FILE = new File("/awips2/.msgCount");
|
||||
|
||||
public static String getMsgId() throws Exception {
|
||||
if (!MSG_ID_FILE.exists()) {
|
||||
MSG_ID_FILE.createNewFile();
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write("0");
|
||||
out.close();
|
||||
private MhsUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static String getMsgId() throws IOException {
|
||||
if (MSG_ID_FILE.createNewFile()) {
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write("0");
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedReader in = null;
|
||||
in = new BufferedReader(new FileReader(MSG_ID_FILE));
|
||||
String msgId = in.readLine().trim();
|
||||
int newMsgNumber = Integer.parseInt(msgId) + 1;
|
||||
in.close();
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write(String.valueOf(newMsgNumber));
|
||||
out.close();
|
||||
for (int i = msgId.length(); i < 6; i++) {
|
||||
msgId = "0" + msgId;
|
||||
int newMsgNumber;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(MSG_ID_FILE));
|
||||
String msgId = in.readLine().trim();
|
||||
newMsgNumber = Integer.parseInt(msgId) + 1;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
return msgId;
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write(String.valueOf(newMsgNumber));
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
NumberFormat formatter = new DecimalFormat("000000");
|
||||
return formatter.format(newMsgNumber);
|
||||
}
|
||||
|
||||
public static int byteArrayToInt(byte[] b, int offset) {
|
||||
|
@ -73,26 +112,26 @@ public class MhsUtil {
|
|||
logFile = new File(logDir
|
||||
+ InetAddress.getLocalHost().getCanonicalHostName() + "-"
|
||||
+ mode + "-" + MhsUtil.logDateFormat.format(new Date()));
|
||||
logFile.createNewFile();
|
||||
|
||||
if (logFile != null) {
|
||||
if (!logFile.exists()) {
|
||||
logFile.createNewFile();
|
||||
}
|
||||
}
|
||||
message += MhsUtil.logMsgFormat.format(new Date());
|
||||
for (Object obj : msg) {
|
||||
message += obj.toString() + " ";
|
||||
}
|
||||
message += "\n";
|
||||
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(logFile,
|
||||
true));
|
||||
out.write(message.trim());
|
||||
out.write("\n");
|
||||
out.close();
|
||||
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(logFile, true));
|
||||
out.write(message.trim());
|
||||
out.write("\n");
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,59 +1,68 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class RsyncThread extends Thread {
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2099 dgilling Modify to support recursive file listing
|
||||
* since export grids dir structure uses
|
||||
* multiple folders.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RsyncThread implements Runnable {
|
||||
|
||||
private static final Map<String, Long> fileVersion = new HashMap<String, Long>();
|
||||
|
||||
private Properties props;
|
||||
|
||||
private Map<String, Long> fileVersion;
|
||||
|
||||
public RsyncThread(Properties props) {
|
||||
this.props = props;
|
||||
fileVersion = new HashMap<String, Long>();
|
||||
this.setDaemon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String exportGridsDir = props.getProperty("EXPORT_GRIDS");
|
||||
String centralServerDir = props.getProperty("CENTRAL_SERVER");
|
||||
String packScriptDir = props.getProperty("UTIL_DIR");
|
||||
|
||||
String exportGridsDir = (String) props.getProperty("EXPORT_GRIDS");
|
||||
String centralServerDir = (String) props
|
||||
.getProperty("CENTRAL_SERVER");
|
||||
File[] fileList = new File(exportGridsDir).listFiles();
|
||||
Collection<File> fileList = listCdfFiles(new File(exportGridsDir));
|
||||
for (File file : fileList) {
|
||||
if (file.isFile()) {
|
||||
String currentFilePath = file.getPath();
|
||||
|
||||
String currentFilePath = null;
|
||||
for (File file : fileList) {
|
||||
if (file.isDirectory()) {
|
||||
continue;
|
||||
boolean copy = true;
|
||||
if ((fileVersion.containsKey(currentFilePath))
|
||||
&& (fileVersion.get(currentFilePath) >= file
|
||||
.lastModified())) {
|
||||
copy = false;
|
||||
}
|
||||
currentFilePath = file.getPath();
|
||||
|
||||
boolean copy = false;
|
||||
if (fileVersion.containsKey(currentFilePath)) {
|
||||
if (fileVersion.get(currentFilePath).longValue() != file
|
||||
.lastModified()) {
|
||||
copy = true;
|
||||
}
|
||||
} else {
|
||||
copy = true;
|
||||
}
|
||||
if (copy) {
|
||||
String[] copyCmd = new String[] {
|
||||
centralServerDir + "/../util/packageFile",file.getPath(),
|
||||
centralServerDir + "/../util/",
|
||||
file.getName().substring(0, 3), centralServerDir };
|
||||
packScriptDir + "/packageFile", currentFilePath,
|
||||
packScriptDir, file.getName().substring(0, 3),
|
||||
centralServerDir };
|
||||
try {
|
||||
Runtime.getRuntime().exec(copyCmd);
|
||||
fileVersion.put(file.getPath(), file.lastModified());
|
||||
fileVersion.put(currentFilePath, file.lastModified());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -61,4 +70,34 @@ public class RsyncThread extends Thread {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<File> listCdfFiles(File path) {
|
||||
Collection<File> fileList = new LinkedList<File>();
|
||||
FileFilter cdfFilter = new FileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return (pathname.isDirectory() || pathname.getName().endsWith(
|
||||
".netcdf"));
|
||||
}
|
||||
};
|
||||
innerListFiles(path, fileList, cdfFilter);
|
||||
return fileList;
|
||||
}
|
||||
|
||||
private void innerListFiles(File path, Collection<File> fileList,
|
||||
FileFilter filter) {
|
||||
try {
|
||||
File[] matchingFiles = path.listFiles(filter);
|
||||
for (File file : matchingFiles) {
|
||||
if (file.isDirectory()) {
|
||||
innerListFiles(file, fileList, filter);
|
||||
} else if (file.isFile()) {
|
||||
fileList.add(file);
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
|
@ -7,27 +8,64 @@ import java.io.FileInputStream;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2009 dgilling Code cleanup.
|
||||
* Jul 23, 2013 #2009 dgilling Fix NullPointerException on start up.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SocketSrv {
|
||||
|
||||
private File propertiesFile;
|
||||
|
||||
private boolean runRsync;
|
||||
|
||||
private String myMHS;
|
||||
|
||||
private Properties serverProps;
|
||||
|
||||
private ExecutorService mhsRequestHandler;
|
||||
|
||||
private ScheduledExecutorService rsyncThread;
|
||||
|
||||
private int fileIndex = 0;
|
||||
|
||||
private String fileBase;
|
||||
|
||||
private Properties serverProps;
|
||||
|
||||
private String configDir;
|
||||
|
||||
private String centralServerDir;
|
||||
|
@ -38,131 +76,191 @@ public class SocketSrv {
|
|||
|
||||
private Map<Integer, String> commandMap;
|
||||
|
||||
private RsyncThread rsync;
|
||||
|
||||
private String propertiesFile;
|
||||
|
||||
private String myMHS;
|
||||
private int serverPort;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
if (!System.getProperty("user.name").equals("root")) {
|
||||
System.out
|
||||
.println("Socket Server must be run as root user! Current user: "
|
||||
+ System.getProperty("user.name"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File propertiesFile = new File(args[0]);
|
||||
String mhsId = args[1];
|
||||
boolean startRsync = Boolean.parseBoolean(args[2]);
|
||||
|
||||
if (!propertiesFile.isFile()) {
|
||||
System.out.println("Specified properties file ["
|
||||
+ propertiesFile.toString() + "] does not exist. Exiting.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
SocketSrv srv = null;
|
||||
srv = new SocketSrv(args[0], args[1], args[2]);
|
||||
srv.run();
|
||||
final SocketSrv server = new SocketSrv(propertiesFile, mhsId,
|
||||
startRsync);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
server.shutdown();
|
||||
}
|
||||
});
|
||||
server.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private SocketSrv(String propertiesFile, String myMHS, String startRsync)
|
||||
throws Exception {
|
||||
this.propertiesFile = propertiesFile;
|
||||
this.myMHS = myMHS;
|
||||
|
||||
writeMyMHS(myMHS);
|
||||
private SocketSrv(File propertiesFile, String mhsId, boolean startRsync)
|
||||
throws UnknownHostException, IOException {
|
||||
System.out.println("Setting up server ("
|
||||
+ InetAddress.getLocalHost().getCanonicalHostName() + ")");
|
||||
commandMap = new HashMap<Integer, String>();
|
||||
configDir = propertiesFile.substring(0,
|
||||
propertiesFile.lastIndexOf(File.separator) + 1);
|
||||
loadProperties(true);
|
||||
if (startRsync.equals("true")) {
|
||||
System.out.println("Starting Rsync Thread...");
|
||||
rsync = new RsyncThread(serverProps);
|
||||
rsync.start();
|
||||
System.out.println("Rsync Thread started!");
|
||||
}
|
||||
|
||||
}
|
||||
this.propertiesFile = propertiesFile;
|
||||
this.myMHS = mhsId;
|
||||
this.runRsync = startRsync;
|
||||
|
||||
private void writeMyMHS(String myMHS) throws Exception {
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(
|
||||
MhsUtil.MY_MHS_FILE));
|
||||
out.write(myMHS + "\n");
|
||||
out.write(this.propertiesFile);
|
||||
out.close();
|
||||
}
|
||||
writeMyMHS(myMHS);
|
||||
|
||||
private void loadProperties(boolean print) throws Exception {
|
||||
serverProps = new Properties();
|
||||
FileInputStream fis = new FileInputStream(propertiesFile);
|
||||
serverProps.load(fis);
|
||||
fis.close();
|
||||
fileBase = serverProps.getProperty("DATA_FOLDER");
|
||||
centralServerDir = serverProps.getProperty("CENTRAL_SERVER");
|
||||
binDir = serverProps.getProperty("UTIL_DIR");
|
||||
this.commandMap = new HashMap<Integer, String>();
|
||||
this.configDir = this.propertiesFile.getParent();
|
||||
loadProperties();
|
||||
loadRcvHandlerTable();
|
||||
if (print) {
|
||||
System.out.println(" Received Data directory: " + fileBase);
|
||||
System.out.println("Central Server Data Directory: "
|
||||
+ centralServerDir);
|
||||
System.out.println(" Config directory: " + configDir);
|
||||
|
||||
this.fileBase = serverProps.getProperty("DATA_FOLDER");
|
||||
this.centralServerDir = serverProps.getProperty("CENTRAL_SERVER");
|
||||
this.binDir = serverProps.getProperty("UTIL_DIR");
|
||||
this.serverPort = Integer.parseInt(serverProps
|
||||
.getProperty("SERVER_PORT"));
|
||||
|
||||
System.out.println("\tReceived Data directory: " + fileBase);
|
||||
System.out.println("\tCentral Server Data Directory: "
|
||||
+ centralServerDir);
|
||||
System.out.println("\tConfig directory: " + configDir);
|
||||
|
||||
this.mhsRequestHandler = Executors.newSingleThreadExecutor();
|
||||
if (this.runRsync) {
|
||||
System.out.println("Starting Rsync Thread...");
|
||||
this.rsyncThread = Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
public void run() throws IOException {
|
||||
if (rsyncThread != null) {
|
||||
Runnable rsyncJob = new RsyncThread(serverProps);
|
||||
rsyncThread
|
||||
.scheduleWithFixedDelay(rsyncJob, 1, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
int port = Integer.parseInt((String) serverProps.get("SERVER_PORT"));
|
||||
ServerSocket srv = new ServerSocket(port);
|
||||
ServerSocket socket = new ServerSocket(serverPort);
|
||||
while (!mhsRequestHandler.isShutdown()) {
|
||||
try {
|
||||
log("Waiting for connections...");
|
||||
final Socket conn = socket.accept();
|
||||
Runnable processTask = new Runnable() {
|
||||
|
||||
while (true) {
|
||||
log("Waiting for connections...");
|
||||
Socket socket = srv.accept();
|
||||
InetSocketAddress client = (InetSocketAddress) socket
|
||||
.getRemoteSocketAddress();
|
||||
log("Connected to client: " + client.getHostName() + " at "
|
||||
+ client);
|
||||
loadProperties(false);
|
||||
String sender = getMhsOfSender(client);
|
||||
log("Message is from: " + sender);
|
||||
|
||||
InputStream in = socket.getInputStream();
|
||||
byte[] message = null;
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
String flag = "";
|
||||
while (true) {
|
||||
if (in.available() == 0) {
|
||||
Thread.sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
message = getMessage(in);
|
||||
|
||||
if (message.length < 50) {
|
||||
String strMessage = new String(message);
|
||||
if (strMessage.equals(MhsUtil.END_TOKEN)) {
|
||||
log("Disconnected from client: " + client);
|
||||
if (params.containsKey("-c")) {
|
||||
executeAction(sender, params);
|
||||
files.clear();
|
||||
params.clear();
|
||||
flag = "";
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
handleRequest(conn);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (strMessage.startsWith("-")) {
|
||||
flag = strMessage;
|
||||
} else {
|
||||
params.put(flag, strMessage);
|
||||
}
|
||||
} else {
|
||||
log("File Received of size: " + message.length);
|
||||
files.add(writeToFile(myMHS + "-" + params.get("-MSGID"),
|
||||
message));
|
||||
};
|
||||
mhsRequestHandler.execute(processTask);
|
||||
} catch (RejectedExecutionException e) {
|
||||
if (!mhsRequestHandler.isShutdown()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
mhsRequestHandler.shutdown();
|
||||
if (rsyncThread != null) {
|
||||
rsyncThread.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRequest(Socket connection) throws IOException,
|
||||
InterruptedException {
|
||||
InetSocketAddress client = (InetSocketAddress) connection
|
||||
.getRemoteSocketAddress();
|
||||
log("Connected to client: " + client.getHostName() + " at " + client);
|
||||
|
||||
loadProperties();
|
||||
String sender = getMhsOfSender(client);
|
||||
log("Message is from: " + sender);
|
||||
|
||||
InputStream in = connection.getInputStream();
|
||||
byte[] message = null;
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
String flag = "";
|
||||
while (true) {
|
||||
if (in.available() == 0) {
|
||||
Thread.sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
message = getMessage(in);
|
||||
|
||||
if (message.length < 50) {
|
||||
String strMessage = new String(message);
|
||||
if (strMessage.equals(MhsUtil.END_TOKEN)) {
|
||||
log("Disconnected from client: " + client);
|
||||
if (params.containsKey("-c")) {
|
||||
executeAction(sender, params);
|
||||
files.clear();
|
||||
params.clear();
|
||||
flag = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (strMessage.startsWith("-")) {
|
||||
flag = strMessage;
|
||||
} else {
|
||||
params.put(flag, strMessage);
|
||||
}
|
||||
} else {
|
||||
log("File Received of size: " + message.length);
|
||||
files.add(writeToFile(myMHS + "-" + params.get("-MSGID"),
|
||||
message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMyMHS(String myMHS) throws IOException {
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MhsUtil.MY_MHS_FILE));
|
||||
out.write(myMHS + "\n");
|
||||
out.write(propertiesFile.getPath());
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadProperties() throws IOException {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(propertiesFile);
|
||||
Properties newProps = new Properties();
|
||||
newProps.load(fis);
|
||||
serverProps = newProps;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeAction(String sender, Map<String, String> params)
|
||||
throws Exception {
|
||||
throws IOException, InterruptedException {
|
||||
int action = Integer.parseInt(params.get("-c"));
|
||||
|
||||
if (!commandMap.containsKey(action)) {
|
||||
|
@ -200,31 +298,19 @@ public class SocketSrv {
|
|||
command = command.replace("%SENDER", sender.toLowerCase());
|
||||
String[] cmdArray = command.split(" ");
|
||||
log("Executing: " + command);
|
||||
//
|
||||
// Map<String, String> sysEnv = System.getenv();
|
||||
// Map<String, String> newEnv = new HashMap<String, String>();
|
||||
// for (String key : sysEnv.keySet()) {
|
||||
// newEnv.put(key, sysEnv.get(key));
|
||||
// }
|
||||
// newEnv.put("PATH", "/awips2/python/bin/:"+sysEnv.get("PATH"));
|
||||
// newEnv.put("LD_PRELOAD", "/awips2/python/lib/libpython2.7.so");
|
||||
// newEnv.put("LD_LIBRARY_PATH", "/awips2/python/lib");
|
||||
// String[] envp = new String[newEnv.keySet().size()];
|
||||
// int i = 0;
|
||||
// for (String key : newEnv.keySet()) {
|
||||
// envp[i] = key.trim() + "=" + newEnv.get(key).trim();
|
||||
// i++;
|
||||
// }
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
p = Runtime.getRuntime().exec(cmdArray);
|
||||
p.waitFor();
|
||||
} finally {
|
||||
p.destroy();
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getMessage(InputStream in) throws Exception {
|
||||
private byte[] getMessage(InputStream in) throws IOException {
|
||||
byte[] sizeBytes = new byte[4];
|
||||
readBytes(in, sizeBytes);
|
||||
int expectedSize = MhsUtil.byteArrayToInt(sizeBytes, 0);
|
||||
|
@ -233,7 +319,7 @@ public class SocketSrv {
|
|||
return message;
|
||||
}
|
||||
|
||||
private void readBytes(InputStream in, byte[] bytes) throws Exception {
|
||||
private void readBytes(InputStream in, byte[] bytes) throws IOException {
|
||||
int expectedSize = bytes.length;
|
||||
int bytesRead = 0;
|
||||
int totalBytesRead = 0;
|
||||
|
@ -245,13 +331,20 @@ public class SocketSrv {
|
|||
}
|
||||
|
||||
private String writeToFile(String fileName, byte[] contents)
|
||||
throws Exception {
|
||||
throws IOException, InterruptedException {
|
||||
String fileFQN = fileBase + fileName + "." + getFileIndex();
|
||||
log("Writing file: " + fileFQN);
|
||||
FileOutputStream fos = new FileOutputStream(new File(fileFQN));
|
||||
fos.write(contents);
|
||||
fos.flush();
|
||||
fos.close();
|
||||
|
||||
BufferedOutputStream out = null;
|
||||
try {
|
||||
out = new BufferedOutputStream(new FileOutputStream(new File(
|
||||
fileFQN)));
|
||||
out.write(contents);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
|
@ -259,7 +352,9 @@ public class SocketSrv {
|
|||
new String[] { "/bin/chmod", "777", fileFQN });
|
||||
p.waitFor();
|
||||
} finally {
|
||||
p.destroy();
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
return fileFQN;
|
||||
}
|
||||
|
@ -269,40 +364,34 @@ public class SocketSrv {
|
|||
if (fileIndex == 1000) {
|
||||
fileIndex = 0;
|
||||
}
|
||||
String fileNumber = String.valueOf(fileIndex);
|
||||
if (fileNumber.length() == 1) {
|
||||
fileNumber = "00" + fileNumber;
|
||||
} else if (fileNumber.length() == 2) {
|
||||
fileNumber = "0" + fileNumber;
|
||||
}
|
||||
return fileNumber;
|
||||
|
||||
NumberFormat formatter = new DecimalFormat("000");
|
||||
return formatter.format(fileIndex);
|
||||
}
|
||||
|
||||
private void loadRcvHandlerTable() throws Exception {
|
||||
private void loadRcvHandlerTable() throws IOException {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(configDir
|
||||
in = new BufferedReader(new FileReader(configDir + File.separator
|
||||
+ "rcv_handler.tbl"));
|
||||
String str = null;
|
||||
String[] tokens = null;
|
||||
|
||||
String str = null;
|
||||
while ((str = in.readLine()) != null) {
|
||||
String command = "";
|
||||
tokens = str.split(" ");
|
||||
StringBuilder commandBuilder = new StringBuilder();
|
||||
String[] tokens = str.split(" ");
|
||||
for (int i = 1; i < tokens.length; i++) {
|
||||
String cmd = tokens[i].trim();
|
||||
if (!cmd.isEmpty()) {
|
||||
if (i != 1) {
|
||||
command += " ";
|
||||
commandBuilder.append(' ');
|
||||
}
|
||||
command += cmd;
|
||||
commandBuilder.append(cmd);
|
||||
}
|
||||
}
|
||||
command = command.trim();
|
||||
|
||||
commandMap.put(Integer.parseInt(tokens[0]), command);
|
||||
String commandString = commandBuilder.toString().trim();
|
||||
commandMap.put(Integer.parseInt(tokens[0]), commandString);
|
||||
}
|
||||
in.close();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
|
@ -311,20 +400,19 @@ public class SocketSrv {
|
|||
}
|
||||
|
||||
private String getMhsOfSender(InetSocketAddress address) {
|
||||
|
||||
String hostAddress = address.getAddress().getHostAddress();
|
||||
for (Object key : serverProps.keySet()) {
|
||||
String value = serverProps.getProperty((String) key);
|
||||
for (String mhsId : serverProps.stringPropertyNames()) {
|
||||
String value = serverProps.getProperty(mhsId);
|
||||
if (value.contains(",")) {
|
||||
String[] addrs = value.split(",");
|
||||
for (String addr : addrs) {
|
||||
if (addr.contains(hostAddress)) {
|
||||
return (String) key;
|
||||
return mhsId;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (value.contains(hostAddress)) {
|
||||
return (String) key;
|
||||
return mhsId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine if we are running on a 32-bit or 64-bit OS.
|
||||
IF NOT EXIST C:\Windows\SysWOW64\reg.exe (
|
||||
SET REG_EXE=C:\Windows\System32\reg.exe
|
||||
) ELSE (
|
||||
SET REG_EXE=C:\Windows\SysWOW64\reg.exe
|
||||
)
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Registry Query Variables.
|
||||
SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java"
|
||||
SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python"
|
||||
REM Determine where AWIPS II Java (the jre) is located.
|
||||
%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO (
|
||||
SET JavaJreDirectory=%%B)
|
||||
REM Determine where AWIPS II Python is located.
|
||||
%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO (
|
||||
SET PythonInstallDirectory=%%B)
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
SET REG_EXE=
|
||||
SET A2_JAVA_REG=
|
||||
SET A2_PYTHON_REG=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'.
|
||||
REM Start AlertViz (and implement the alertviz restart capability).
|
||||
:AlertVizLoopStart
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1
|
||||
IF %ERRORLEVEL% == 0 (EXIT)
|
||||
echo Restarting AlertViz.
|
||||
GOTO AlertVizLoopStart
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
@echo OFF
|
||||
|
||||
REM Determine if we are running on a 32-bit or 64-bit OS.
|
||||
IF NOT EXIST C:\Windows\SysWOW64\reg.exe (
|
||||
SET REG_EXE=C:\Windows\System32\reg.exe
|
||||
) ELSE (
|
||||
SET REG_EXE=C:\Windows\SysWOW64\reg.exe
|
||||
)
|
||||
|
||||
REM Determine where we are located.
|
||||
SET CONTAINING_DIRECTORY=%~dp0
|
||||
|
||||
REM Prepare the environment.
|
||||
|
||||
REM Registry Query Variables.
|
||||
SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java"
|
||||
SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python"
|
||||
REM Determine where AWIPS II Java (the jre) is located.
|
||||
%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO (
|
||||
SET JavaJreDirectory=%%B)
|
||||
REM Determine where AWIPS II Python is located.
|
||||
%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1
|
||||
IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT)
|
||||
FOR /F "tokens=2* delims= " %%A IN (
|
||||
'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO (
|
||||
SET PythonInstallDirectory=%%B)
|
||||
|
||||
REM Add Java and Python to the path.
|
||||
SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path%
|
||||
SET Path=%JavaJreDirectory%\bin;%Path%
|
||||
REM Add the CAVE lib directory to the path.
|
||||
SET Path=%CONTAINING_DIRECTORY%lib;%Path%
|
||||
REM Define 'PythonPath'.
|
||||
SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath%
|
||||
SET PythonPath=%PythonInstallDirectory%;%PythonPath%
|
||||
|
||||
REM Eliminate variables that will no longer be used.
|
||||
SET PythonInstallDirectory=
|
||||
SET JavaJreDirectory=
|
||||
SET REG_EXE=
|
||||
SET A2_JAVA_REG=
|
||||
SET A2_PYTHON_REG=
|
||||
|
||||
REM Determine where we will be logging to.
|
||||
SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH%
|
||||
SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs
|
||||
SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME%
|
||||
IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%")
|
||||
|
||||
SET RND=%random%
|
||||
SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp
|
||||
REM Python is used to retrieve the current date and time because the order
|
||||
REM of the Windows date/time fields is not necessarily guaranteed and the
|
||||
REM Windows date/time fields can only be extracted using substring operations
|
||||
REM instead of -formatter- strings like Linux allows.
|
||||
python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE%
|
||||
SET /p LOG_DATETIME= < %RND_DATETIME_FILE%
|
||||
DEL %RND_DATETIME_FILE%
|
||||
|
||||
echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME!
|
||||
cd %HOMEPATH%
|
||||
REM Start CAVE.
|
||||
"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1
|
||||
IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE)
|
||||
|
||||
EXIT
|
|
@ -21,6 +21,7 @@ package com.raytheon.uf.viz.core;
|
|||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -41,6 +42,8 @@ import com.raytheon.uf.viz.core.data.resp.NumericImageData;
|
|||
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.FontType;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.Style;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||
|
@ -62,6 +65,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 25, 2012 bsteffen Initial creation
|
||||
* Jul 18, 2013 2189 mschenke Added ability to specify font type
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -82,6 +86,11 @@ public abstract class AbstractGraphicsTarget implements IGraphicsTarget {
|
|||
extensionManager = new GraphicsExtensionManager(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
return initializeFont(fontFile, FontType.TRUETYPE, size, styles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawRasters(PaintProperties paintProps,
|
||||
DrawableImage... images) throws VizException {
|
||||
|
|
|
@ -59,6 +59,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
* track any needed updates to the Target extents.
|
||||
* This functionality is primarily used by the
|
||||
* Feature Following Zoom Tool at this time.
|
||||
* 7/18/13 #2189 mschenke Added ability to specify font type
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -234,8 +235,10 @@ public interface IGraphicsTarget extends IImagingExtension {
|
|||
IFont.Style[] styles);
|
||||
|
||||
/**
|
||||
* Create a font object from a truetype font
|
||||
* Create a font object from a truetype font file
|
||||
*
|
||||
* @deprecated {@link #initializeFont(File, com.raytheon.uf.viz.core.drawables.IFont.FontType, float, com.raytheon.uf.viz.core.drawables.IFont.Style[])}
|
||||
* should be used instead
|
||||
*
|
||||
* @param fontFile
|
||||
* the truetype font
|
||||
|
@ -245,9 +248,27 @@ public interface IGraphicsTarget extends IImagingExtension {
|
|||
* the font styles
|
||||
* @return a prepared font reference
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract IFont initializeFont(File fontFile, float size,
|
||||
IFont.Style[] styles);
|
||||
|
||||
/**
|
||||
* Create a font object from font file
|
||||
*
|
||||
*
|
||||
* @param fontFile
|
||||
* the font file
|
||||
* @param type
|
||||
* the type of the font file
|
||||
* @param size
|
||||
* the size in points
|
||||
* @param styles
|
||||
* the font styles
|
||||
* @return a prepared font reference
|
||||
*/
|
||||
public abstract IFont initializeFont(File fontFile, IFont.FontType type,
|
||||
float size, IFont.Style[] styles);
|
||||
|
||||
/**
|
||||
* Draw a raster to a target, given an extent and an alpha (transparency)
|
||||
* value. Assumes synchronous operation.
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.core.drawables;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple abstract base class for an AWT-based IFont implementations
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 24, 2013 2189 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class AbstractAWTFont implements IFont {
|
||||
|
||||
protected Font font;
|
||||
|
||||
protected boolean scaleFont;
|
||||
|
||||
protected boolean smoothing;
|
||||
|
||||
protected AbstractAWTFont(String fontName, float fontSize, Style[] styles) {
|
||||
this(new Font(fontName, toAwtStyle(styles), (int) fontSize));
|
||||
}
|
||||
|
||||
protected AbstractAWTFont(File fontFile, FontType fontType, float fontSize,
|
||||
Style[] styles) {
|
||||
this(createFont(fontFile, fontType, fontSize, styles));
|
||||
}
|
||||
|
||||
protected AbstractAWTFont(Font font) {
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getFontName() {
|
||||
return font.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#getStyle()
|
||||
*/
|
||||
@Override
|
||||
public final Style[] getStyle() {
|
||||
return toVizStyles(font.getStyle());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#setSmoothing(boolean)
|
||||
*/
|
||||
@Override
|
||||
public final void setSmoothing(boolean smooth) {
|
||||
this.smoothing = smooth;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#getSmoothing()
|
||||
*/
|
||||
@Override
|
||||
public final boolean getSmoothing() {
|
||||
return smoothing;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#isScaleFont()
|
||||
*/
|
||||
@Override
|
||||
public final boolean isScaleFont() {
|
||||
return scaleFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#setScaleFont(boolean)
|
||||
*/
|
||||
@Override
|
||||
public final void setScaleFont(boolean scaleFont) {
|
||||
this.scaleFont = scaleFont;
|
||||
}
|
||||
|
||||
protected static Font createFont(File fontFile, FontType fontType,
|
||||
float fontSize, Style[] styles) {
|
||||
try {
|
||||
return Font.createFont(toAwtFontType(fontType), fontFile)
|
||||
.deriveFont(fontSize).deriveFont(toAwtStyle(styles));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Bad Font File", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static int toAwtFontType(FontType type) {
|
||||
switch (type) {
|
||||
case TYPE1:
|
||||
return Font.TYPE1_FONT;
|
||||
case TRUETYPE:
|
||||
default:
|
||||
return Font.TRUETYPE_FONT;
|
||||
}
|
||||
}
|
||||
|
||||
protected static int toAwtStyle(Style[] styles) {
|
||||
int styleInt = Font.PLAIN;
|
||||
if (styles == null || styles.length == 0) {
|
||||
return styleInt;
|
||||
}
|
||||
for (Style style : styles) {
|
||||
if (style == Style.BOLD) {
|
||||
styleInt |= Font.BOLD;
|
||||
} else if (style == Style.ITALIC) {
|
||||
styleInt |= Font.ITALIC;
|
||||
}
|
||||
}
|
||||
return styleInt;
|
||||
}
|
||||
|
||||
protected static Style[] toVizStyles(int style) {
|
||||
List<Style> styles = new ArrayList<Style>();
|
||||
if ((style & Font.BOLD) != 0) {
|
||||
styles.add(Style.BOLD);
|
||||
}
|
||||
if ((style & Font.ITALIC) != 0) {
|
||||
styles.add(Style.ITALIC);
|
||||
}
|
||||
return styles.toArray(new Style[0]);
|
||||
}
|
||||
}
|
|
@ -37,15 +37,12 @@ import org.geotools.coverage.grid.GeneralGridEnvelope;
|
|||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.GeneralEnvelope;
|
||||
import org.geotools.referencing.CRS;
|
||||
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
import org.opengis.referencing.crs.GeneralDerivedCRS;
|
||||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.TransformFactory;
|
||||
import com.raytheon.uf.common.serialization.adapters.GridGeometryAdapter;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
|
@ -78,8 +75,6 @@ import com.raytheon.uf.viz.core.time.TimeMatchingJob;
|
|||
* Aug 15, 2007 chammack Initial Creation.
|
||||
* Nov 30, 2007 461 bphillip Using VizTime now for time matching
|
||||
* Oct 22, 2009 #3348 bsteffen added ability to limit number of frames
|
||||
* July 20, 2013 NCEP #1015 Greg Hull check for rotated/derived CRS in getWorldToCRSTransform()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -711,18 +706,9 @@ public abstract class AbstractDescriptor extends ResourceGroup implements
|
|||
|
||||
protected void setupTransforms() throws Exception {
|
||||
GeneralGridGeometry gridGeometry = getGridGeometry();
|
||||
MathTransform worldToCRS = getWorldToCRSTransform(gridGeometry);
|
||||
if (worldToCRS != null) {
|
||||
MathTransform crsToPixel = gridGeometry.getGridToCRS(
|
||||
PixelInCell.CELL_CENTER).inverse();
|
||||
worldToPixel = new DefaultMathTransformFactory()
|
||||
.createConcatenatedTransform(worldToCRS, crsToPixel);
|
||||
pixelToWorld = worldToPixel.inverse();
|
||||
|
||||
} else {
|
||||
pixelToWorld = null;
|
||||
worldToPixel = null;
|
||||
}
|
||||
worldToPixel = TransformFactory.worldToGrid(gridGeometry,
|
||||
PixelInCell.CELL_CENTER);
|
||||
pixelToWorld = (worldToPixel != null ? worldToPixel.inverse() : null);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -862,35 +848,4 @@ public abstract class AbstractDescriptor extends ResourceGroup implements
|
|||
false), envelope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world to CRS transform used for {@link #worldToPixel(double[])}
|
||||
* and {@link #pixelToWorld(double[])}
|
||||
*
|
||||
* @param gridGeometry
|
||||
* @return The world to gridGeometry CRS transform or null if there is none
|
||||
*/
|
||||
public static MathTransform getWorldToCRSTransform(
|
||||
GeneralGridGeometry gridGeometry) {
|
||||
CoordinateReferenceSystem crs = gridGeometry.getEnvelope()
|
||||
.getCoordinateReferenceSystem();
|
||||
if (crs instanceof GeneralDerivedCRS) {
|
||||
GeneralDerivedCRS projCRS = (GeneralDerivedCRS) crs;
|
||||
CoordinateReferenceSystem worldCRS = projCRS.getBaseCRS();
|
||||
|
||||
// NCEP #1015 : support of for ICAO-B PredefinedArea which
|
||||
// has a FITTED_CS (ie rotated) CRS
|
||||
if( worldCRS instanceof GeneralDerivedCRS ) {
|
||||
worldCRS = ((GeneralDerivedCRS)worldCRS).getBaseCRS();
|
||||
}
|
||||
|
||||
try {
|
||||
return CRS.findMathTransform(worldCRS, crs);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error setting up Math Transforms,"
|
||||
+ " this descriptor may not work properly", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ package com.raytheon.uf.viz.core.drawables;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 7, 2007 chammack Initial Creation.
|
||||
*
|
||||
* Jul 18, 2013 2189 mschenke Added ability to specify font type
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -43,6 +43,11 @@ public interface IFont {
|
|||
BOLD, ITALIC
|
||||
};
|
||||
|
||||
/** Type of font */
|
||||
public static enum FontType {
|
||||
TRUETYPE, TYPE1
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the font
|
||||
*
|
||||
|
|
|
@ -23,9 +23,8 @@ import java.awt.Font;
|
|||
import java.awt.FontFormatException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.AbstractAWTFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
|
||||
/**
|
||||
|
@ -39,25 +38,20 @@ import com.raytheon.uf.viz.core.drawables.IFont;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
* Jul 24, 2013 2189 mschenke Refactored to share common awt font code
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlFont implements IFont {
|
||||
|
||||
private Font font;
|
||||
public class KmlFont extends AbstractAWTFont implements IFont {
|
||||
|
||||
private float magnification;
|
||||
|
||||
private boolean scaleFont;
|
||||
|
||||
private boolean smoothing;
|
||||
|
||||
public KmlFont(Font font) {
|
||||
this.font = font;
|
||||
super(font);
|
||||
this.magnification = 1.0f;
|
||||
}
|
||||
|
||||
|
@ -67,7 +61,6 @@ public class KmlFont implements IFont {
|
|||
|
||||
public KmlFont(String fontName) {
|
||||
this(new Font(fontName, Font.PLAIN, 10));
|
||||
|
||||
}
|
||||
|
||||
public KmlFont(String fontName, float fontSize) {
|
||||
|
@ -78,15 +71,10 @@ public class KmlFont implements IFont {
|
|||
this(new Font(fontName, toAwtStyle(styles), (int) fontSize));
|
||||
}
|
||||
|
||||
public KmlFont(File fontFile, float fontSize, Style[] styles)
|
||||
throws FontFormatException, IOException {
|
||||
this(Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(fontSize)
|
||||
.deriveFont(toAwtStyle(styles)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontName() {
|
||||
return this.font.getFontName();
|
||||
public KmlFont(File fontFile, FontType fontType, float fontSize,
|
||||
Style[] styles) throws FontFormatException, IOException {
|
||||
this(Font.createFont(toAwtFontType(fontType), fontFile)
|
||||
.deriveFont(fontSize).deriveFont(toAwtStyle(styles)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,11 +82,6 @@ public class KmlFont implements IFont {
|
|||
return this.font.getSize2D();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Style[] getStyle() {
|
||||
return toVizStyles(font.getStyle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
|
@ -128,26 +111,6 @@ public class KmlFont implements IFont {
|
|||
return magnification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmoothing(boolean smooth) {
|
||||
this.smoothing = smooth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSmoothing() {
|
||||
return smoothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScaleFont() {
|
||||
return scaleFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleFont(boolean scaleFont) {
|
||||
this.scaleFont = scaleFont;
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
return font;
|
||||
}
|
||||
|
@ -156,30 +119,4 @@ public class KmlFont implements IFont {
|
|||
this.font = font;
|
||||
}
|
||||
|
||||
private static int toAwtStyle(Style[] styles) {
|
||||
int styleInt = Font.PLAIN;
|
||||
if (styles == null || styles.length == 0) {
|
||||
return styleInt;
|
||||
}
|
||||
for (Style style : styles) {
|
||||
if (style == Style.BOLD) {
|
||||
styleInt |= Font.BOLD;
|
||||
} else if (style == Style.ITALIC) {
|
||||
styleInt |= Font.ITALIC;
|
||||
}
|
||||
}
|
||||
return styleInt;
|
||||
}
|
||||
|
||||
private static Style[] toVizStyles(int style) {
|
||||
List<Style> styles = new ArrayList<Style>();
|
||||
if ((style & Font.BOLD) != 0) {
|
||||
styles.add(Style.BOLD);
|
||||
}
|
||||
if ((style & Font.ITALIC) != 0) {
|
||||
styles.add(Style.ITALIC);
|
||||
}
|
||||
return styles.toArray(new Style[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import com.raytheon.uf.viz.core.IExtent;
|
|||
import com.raytheon.uf.viz.core.IView;
|
||||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.FontType;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.Style;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
|
@ -134,9 +135,10 @@ public class KmlGraphicsTarget extends AbstractGraphicsTarget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KmlFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
public IFont initializeFont(File fontFile, FontType type, float size,
|
||||
Style[] styles) {
|
||||
try {
|
||||
return new KmlFont(fontFile, size, styles);
|
||||
return new KmlFont(fontFile, type, size, styles);
|
||||
} catch (FontFormatException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -60,6 +60,7 @@ import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
|||
import com.raytheon.uf.viz.core.data.resp.NumericImageData;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.FontType;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.Style;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
|
@ -246,8 +247,24 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
* float, com.raytheon.uf.viz.core.drawables.IFont.Style[])
|
||||
*/
|
||||
public IFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
return new DispatchingFont(wrappedObject.initializeFont(fontFile, size,
|
||||
styles), getDispatcher(), fontFile);
|
||||
return initializeFont(fontFile, FontType.TRUETYPE, size, styles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fontFile
|
||||
* @param type
|
||||
* @param size
|
||||
* @param styles
|
||||
* @return
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.IGraphicsTarget#initializeFont(java.io.File,
|
||||
* com.raytheon.uf.viz.core.drawables.IFont.FontType float,
|
||||
* com.raytheon.uf.viz.core.drawables.IFont.Style[])
|
||||
*/
|
||||
public IFont initializeFont(File fontFile, FontType type, float size,
|
||||
Style[] styles) {
|
||||
return new DispatchingFont(wrappedObject.initializeFont(fontFile, type,
|
||||
size, styles), getDispatcher(), fontFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
package com.raytheon.viz.core.gl.internal;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.io.File;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.AbstractAWTFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.viz.core.gl.IGLFont;
|
||||
import com.sun.opengl.util.j2d.TextRenderer;
|
||||
|
@ -36,6 +36,7 @@ import com.sun.opengl.util.j2d.TextRenderer;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 7, 2007 chammack Initial Creation.
|
||||
* Jul 24, 2013 2189 mschenke Refactored to share common awt font code
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -43,78 +44,33 @@ import com.sun.opengl.util.j2d.TextRenderer;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GLFont implements IGLFont {
|
||||
public class GLFont extends AbstractAWTFont implements IGLFont {
|
||||
|
||||
private boolean disposed = false;
|
||||
|
||||
private String fontName;
|
||||
|
||||
private float fontSize;
|
||||
|
||||
private float currentFontSize;
|
||||
|
||||
private Style[] styles;
|
||||
|
||||
private Font font;
|
||||
|
||||
private TextRenderer textRenderer;
|
||||
|
||||
private boolean smoothing = true;
|
||||
|
||||
private File fontFile;
|
||||
|
||||
private FontType fontType;
|
||||
|
||||
private float magnification = 1.0f;
|
||||
|
||||
private boolean scaleFont = true;
|
||||
|
||||
public GLFont() {
|
||||
;
|
||||
}
|
||||
|
||||
public GLFont(File font, float fontSize, Style[] styles) {
|
||||
try {
|
||||
this.fontName = font.getName();
|
||||
this.font = Font.createFont(Font.TRUETYPE_FONT, font).deriveFont(
|
||||
fontSize);
|
||||
this.currentFontSize = this.fontSize = fontSize;
|
||||
this.styles = styles;
|
||||
|
||||
if (styles != null && styles.length > 0) {
|
||||
for (Style style : styles) {
|
||||
if (style == Style.BOLD) {
|
||||
this.font = this.font.deriveFont(Font.BOLD);
|
||||
} else if (style == Style.ITALIC) {
|
||||
this.font = this.font.deriveFont(Font.ITALIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("Bad font file", e);
|
||||
}
|
||||
public GLFont(File font, FontType type, float fontSize, Style[] styles) {
|
||||
super(font, type, fontSize, styles);
|
||||
this.fontFile = font;
|
||||
this.fontType = type;
|
||||
this.currentFontSize = this.fontSize = fontSize;
|
||||
this.textRenderer = TextRendererCache.getRenderer(this.font);
|
||||
}
|
||||
|
||||
public GLFont(String fontName, float fontSize, Style[] styles) {
|
||||
this.fontName = fontName;
|
||||
super(fontName, fontSize, styles);
|
||||
this.currentFontSize = this.fontSize = fontSize;
|
||||
this.styles = styles;
|
||||
|
||||
int style = Font.PLAIN;
|
||||
|
||||
if (styles != null) {
|
||||
for (Style s : styles) {
|
||||
if (s == IFont.Style.BOLD) {
|
||||
style = (Font.BOLD | style);
|
||||
} else if (s == IFont.Style.ITALIC) {
|
||||
style = (Font.ITALIC | style);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.font = new Font(this.fontName, style, (int) fontSize);
|
||||
this.textRenderer = TextRendererCache.getRenderer(this.font);
|
||||
}
|
||||
|
||||
|
@ -127,15 +83,6 @@ public class GLFont implements IGLFont {
|
|||
disposeInternal();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.drawables.IFont#getFontName()
|
||||
*/
|
||||
public String getFontName() {
|
||||
return this.fontName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -145,15 +92,6 @@ public class GLFont implements IGLFont {
|
|||
return currentFontSize;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.drawables.IFont#getStyle()
|
||||
*/
|
||||
public Style[] getStyle() {
|
||||
return this.styles;
|
||||
}
|
||||
|
||||
public TextRenderer getTextRenderer() {
|
||||
return textRenderer;
|
||||
}
|
||||
|
@ -168,9 +106,9 @@ public class GLFont implements IGLFont {
|
|||
GLFont newFont = null;
|
||||
if (this.fontFile != null) {
|
||||
// File based construction
|
||||
newFont = new GLFont(this.fontFile, size, styles);
|
||||
newFont = new GLFont(this.fontFile, fontType, size, getStyle());
|
||||
} else {
|
||||
newFont = new GLFont(this.fontName, size, styles);
|
||||
newFont = new GLFont(getFontName(), size, getStyle());
|
||||
}
|
||||
|
||||
return newFont;
|
||||
|
@ -215,46 +153,6 @@ public class GLFont implements IGLFont {
|
|||
return magnification;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#getSmoothing()
|
||||
*/
|
||||
@Override
|
||||
public boolean getSmoothing() {
|
||||
return smoothing;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#setSmoothing(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setSmoothing(boolean smoothing) {
|
||||
this.smoothing = smoothing;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#isScaleFont()
|
||||
*/
|
||||
@Override
|
||||
public boolean isScaleFont() {
|
||||
return scaleFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IFont#setScaleFont(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setScaleFont(boolean scaleFont) {
|
||||
this.scaleFont = scaleFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -71,6 +71,7 @@ import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
|||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.FontType;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.Style;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
|
@ -1224,15 +1225,10 @@ public class GLTarget extends AbstractGraphicsTarget implements IGLTarget {
|
|||
return new GLImage(imageCallback, GLDefaultImagingExtension.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.IGraphicsTarget#initializeFont(java.io.File,
|
||||
* float, com.raytheon.viz.core.drawables.IFont.Style[])
|
||||
*/
|
||||
@Override
|
||||
public IFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
return new GLFont(fontFile, size, styles);
|
||||
public IFont initializeFont(File fontFile, FontType type, float size,
|
||||
Style[] styles) {
|
||||
return new GLFont(fontFile, type, size, styles);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,697 +47,123 @@ import com.raytheon.viz.mpe.util.DailyQcUtils.Station;
|
|||
|
||||
public class RenderPcp {
|
||||
|
||||
private static boolean first = true;
|
||||
|
||||
Pcp pcp = DailyQcUtils.pcp;
|
||||
|
||||
/*
|
||||
* QC codes
|
||||
*/
|
||||
private static final int MISSING = -1;
|
||||
|
||||
private static final int STANDARD = 0;
|
||||
|
||||
private static final int FAILED = 1;
|
||||
|
||||
private static final int MANUAL = 2;
|
||||
|
||||
private static final int QUESTIONABLE = 3;
|
||||
|
||||
private static final int PARTIAL = 4;
|
||||
|
||||
private static final int ESTIMATED = 5;
|
||||
|
||||
private static final int TIMEDISTRIBUTED = 6;
|
||||
|
||||
private static final int VERIFIED = 8;
|
||||
|
||||
/**
|
||||
* Converts point precipitation data in struct pdata to hrap grid. The 20
|
||||
* closest stations are precalculated for each grid point - this speeds
|
||||
* computations for data sets with many precipitation points. If there are
|
||||
* no good precipitation points for a grid point, then a recalculation is
|
||||
* made using all precipitation points. 1/R**2 interpolation is used. If
|
||||
* requested, the final interpolation is scaled using seasonal isohyets. The
|
||||
* grid is saved as a disk file and used later for a raster or vector (HRAP)
|
||||
* plot.
|
||||
*
|
||||
* @param m
|
||||
* @param k
|
||||
* @param mk
|
||||
* @param numPstations
|
||||
* @param precip_stations
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
public void render_pcp(int pcpn_day, int pcpn_time, int pcpn_time_step,
|
||||
int numPstations, ArrayList<Station> precip_stations,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
int isom = DailyQcUtils.isom;
|
||||
int method = DailyQcUtils.method;
|
||||
int mpe_dqc_max_precip_neighbors = DailyQcUtils.mpe_dqc_max_precip_neighbors;
|
||||
int i, j, h, hh, time_pos, htotal;
|
||||
double distance, dist1, dist2, dist, value;
|
||||
double temp;
|
||||
int totals[] = new int[5];
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
totals[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pcpn_time_step is a function parameter. It specifies whether to
|
||||
* interpolate 6hr or 24hr HRAP grid
|
||||
*/
|
||||
/*
|
||||
* pcpn_time is a function parameter. It specifies which 6hr HRAP grid
|
||||
* to generate. It takes 0,1,2,or 3 to represent different 6hr period of
|
||||
* a day.
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for 6hr data) or 4 (for
|
||||
* 24hr data). This value is used in
|
||||
* pdata[pcpn_day].stn[hh].frain[time_pos].data to control whether to
|
||||
* retrieve 6hr data or 24hr data.
|
||||
*/
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_time; // for 6 hour data: 0,1,2,3.
|
||||
} else {
|
||||
time_pos = 4; // for 24 hour data
|
||||
|
||||
/*
|
||||
* in case the 24hr grid rendering is required, we check
|
||||
* 24hr_grid_gen_method_token() to determine how to generate the
|
||||
* grid. New Post OB9.2
|
||||
*/
|
||||
|
||||
if (getTokenValue24hrGridGenMeth() == 1) {
|
||||
render24hrPcpUsingFour6hr(pcpn_day, pcpn_time, numPstations,
|
||||
precip_stations, hrap_grid, pdata, pcp_in_use);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* begin to interpolate value for each bin in the HRAP grid */
|
||||
/*
|
||||
* to interpolate, two quantities are needed first: value and distance.
|
||||
* They are calculated by using the neighboring stations.
|
||||
*/
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
/*
|
||||
* Check if the grid cell is covered by an HSA. If not, then do
|
||||
* not estimate precipitation for it.
|
||||
*/
|
||||
if (hrap_grid.owner[i][j] == -1) {
|
||||
pcp.value[i][j] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
value = 0.0;
|
||||
distance = 0.0;
|
||||
htotal = 0;
|
||||
|
||||
/*
|
||||
* the following for loop is to calculate two quantities: value
|
||||
* and distance, which later on, are used to interpret the HRAP
|
||||
* grid.
|
||||
*/
|
||||
/*
|
||||
* It uses neighbor stations of a HRAP grid bin to calculate
|
||||
* value and distance.
|
||||
*/
|
||||
/* for each neighbor station of the grid bin, do the following */
|
||||
|
||||
/* For each of the closest stations. */
|
||||
for (h = 0; h < mpe_dqc_max_precip_neighbors; h++) {
|
||||
hh = hrap_grid.gage[i][j].index[h];
|
||||
// hh is index of stations
|
||||
if (pdata[pcpn_day].stn[hh].frain[time_pos].data < 0) {
|
||||
/* No precip data. */
|
||||
continue;
|
||||
} // frain refers to level 2 data; rrain refers to level 1
|
||||
|
||||
if (method == 2 && precip_stations.get(hh).isoh[isom] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pdata[pcpn_day].stn[hh].frain[time_pos].qual != 0
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 8
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 6
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 3
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 4
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 2) {
|
||||
/* The station has a bad qc flag. Do not use it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the coordinates of the grid and station in
|
||||
* lat/lon into distance.
|
||||
*/
|
||||
dist1 = (i + (hrap_grid.hrap_minx - precip_stations.get(hh).hrap_x));
|
||||
dist2 = (j + (hrap_grid.hrap_miny - precip_stations.get(hh).hrap_y));
|
||||
|
||||
dist = Math.pow(dist1, 2) + Math.pow(dist2, 2);
|
||||
|
||||
if (dist < .00001) {
|
||||
dist = .00001;
|
||||
}
|
||||
|
||||
dist = 1 / dist;
|
||||
|
||||
temp = pdata[pcpn_day].stn[hh].frain[time_pos].data * dist;
|
||||
|
||||
if (method == 2 && precip_stations.get(hh).isoh[isom] > 0) {
|
||||
temp = temp * hrap_grid.isoh[isom][i][j]
|
||||
/ (precip_stations.get(hh).isoh[isom] * 25.4);
|
||||
}
|
||||
|
||||
value = value + temp;
|
||||
|
||||
distance = distance + dist;
|
||||
|
||||
htotal++;
|
||||
|
||||
if (htotal == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* end for loop (h = 0; h < mpe_dqc_max_precip_neighbors;h++)
|
||||
* the above for loop is for each neighbor station.
|
||||
*/
|
||||
/*
|
||||
* the above for loop is to calculate value and distance, which
|
||||
* later on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* the resulting htotal is the valid number of neighbor stations
|
||||
* that are used to calculate value and distance, which later
|
||||
* on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* if there is not enough valid neighbor station, such as htotal
|
||||
* <4, the code below handle this situation. Basically, the code
|
||||
* recalculate the value and distance using all the stations --
|
||||
* see the for (h = 0; h < max_stations; h++) loop below.
|
||||
*/
|
||||
if (htotal < 4) {
|
||||
|
||||
value = 0.0;
|
||||
distance = 0.0;
|
||||
htotal = 0;
|
||||
|
||||
for (h = 0; h < numPstations; h++) {
|
||||
if (pdata[pcpn_day].stn[h].frain[time_pos].data < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pdata[pcpn_day].stn[h].frain[time_pos].qual != 0
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 8
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 6
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 3
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 4
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method == 2
|
||||
&& precip_stations.get(h).isoh[isom] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dist1 = (i + (hrap_grid.hrap_minx - precip_stations
|
||||
.get(h).hrap_x));
|
||||
dist2 = (j + (hrap_grid.hrap_miny - precip_stations
|
||||
.get(h).hrap_y));
|
||||
|
||||
dist = Math.pow(dist1, 2) + Math.pow(dist2, 2);
|
||||
|
||||
/*
|
||||
* if distance from grid box to station is >
|
||||
* mpe_dqc_grid_max_distbins,
|
||||
*/
|
||||
/* then do not use station */
|
||||
if (dist < .00001) {
|
||||
dist = .00001;
|
||||
}
|
||||
|
||||
else if (Math.sqrt(dist) > DailyQcUtils.mpe_dqc_grid_max_dist) {
|
||||
continue;
|
||||
}
|
||||
dist = 1 / dist;
|
||||
|
||||
temp = pdata[pcpn_day].stn[h].frain[time_pos].data
|
||||
* dist;
|
||||
|
||||
if (method == 2
|
||||
&& precip_stations.get(h).isoh[isom] > 0) {
|
||||
temp = temp
|
||||
* hrap_grid.isoh[isom][i][j]
|
||||
/ (precip_stations.get(h).isoh[isom] * 25.4);
|
||||
}
|
||||
|
||||
value = value + temp;
|
||||
|
||||
distance = distance + dist;
|
||||
|
||||
htotal++;
|
||||
|
||||
}
|
||||
|
||||
}/* end the handling of special case : if (htotal < 4), */
|
||||
/* which means there is no enough neighboring stations */
|
||||
|
||||
if (htotal == 0) {
|
||||
pcp.value[i][j] = 0;
|
||||
} else {
|
||||
pcp.value[i][j] = (int) (value / distance * 100.0);
|
||||
}
|
||||
// if (htotal != 0) {
|
||||
// pcp.value[i][j] += (int) (value / distance * 100);
|
||||
// }
|
||||
if (pcp.value[i][j] < .01) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
} // end of the ( k = 0; k<4; k++) loop, which interpolates 4 6hr HRAP
|
||||
// grid.
|
||||
|
||||
/* final adjustment of the pcp->value */
|
||||
// for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
// hrap_grid comes from the function parameter
|
||||
// for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
//
|
||||
// if (pcp.value[i][j] < .01) {
|
||||
// pcp.value[i][j] = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_day * 4 + 3 - pcpn_time;
|
||||
} else {
|
||||
time_pos = 40 + pcpn_day;
|
||||
}
|
||||
// notice that time_pos is a variable defined inside the function, and
|
||||
// its value do not need to be limited as 0,1,2,3,or 4. Here it is
|
||||
// assigned with bigger numbers.
|
||||
// time_pos = 40 + pcpn_day;
|
||||
|
||||
// pcp_in_use[i] = 1 -- grids rendered via Render button OR Save Level2
|
||||
// option
|
||||
// = -1 --grids for this time period not rendered (initialization value)
|
||||
pcp_in_use[time_pos] = 1;
|
||||
|
||||
ReadQPFGrids rqp = new ReadQPFGrids();
|
||||
rqp.write_file("pcp", time_pos, pcp);
|
||||
}
|
||||
|
||||
/*
|
||||
* get the token value of token mpe_24hr_grid_gen_method. This token will
|
||||
* determine how we generate the 24hr grid. We can either use the 24hr gage
|
||||
* values, which is the old way, or we can use four 6hr gage values and add
|
||||
* them together.
|
||||
*/
|
||||
/* there is some problem with the static */
|
||||
|
||||
/**
|
||||
* @param pcpn_day
|
||||
* @param pcpn_time
|
||||
* @param numPstations
|
||||
* @param precip_stations
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
private void render24hrPcpUsingFour6hr(int pcpn_day, int pcpn_time,
|
||||
int numPstations, ArrayList<Station> precip_stations,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
int i, j, k, h, hh, time_pos, htotal;
|
||||
double distance, dist1, dist2, dist, value;
|
||||
double temp;
|
||||
int isom = DailyQcUtils.isom;
|
||||
int method = DailyQcUtils.method;
|
||||
int totals[] = new int[5];
|
||||
int all_total = 0;
|
||||
int neighbor_total = 0;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
totals[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pcpn_time_step is function parameter. It specifies whether to
|
||||
* interpolate 6hr or 24hr HRAP grid
|
||||
*/
|
||||
/*
|
||||
* pcpn_time is a function parameter. It specifies which 6hr HRAP grid
|
||||
* to generate. It takes 0,1,2,or 3 to represent different 6hr period of
|
||||
* a day.
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for 6hr data) or 4 (for
|
||||
* 24hr data). This value is used in
|
||||
* pdata[pcpn_day].stn[hh].frain[time_pos].data to control whether to
|
||||
* retrieve 6hr data or 24hr data.
|
||||
*/
|
||||
|
||||
/* initialization of the pcp->value */
|
||||
for (i = 0; i < hrap_grid.maxi; i++) { /*
|
||||
* hrap_grid comes from the
|
||||
* function parameter
|
||||
*/
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* begin to interpolate 4 6hr grids. At the end of each iteration, the
|
||||
* calculated interpolation value is added to pcp->value[i][j].
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for four 6hr data). This
|
||||
* value is used in pdata[pcpn_day].stn[hh].frain[time_pos].data to
|
||||
* retrieve 6hr data.
|
||||
*/
|
||||
for (k = 0; k < 4; k++) {
|
||||
time_pos = k; /* for 6 hour data: 0, 1,2,3. */
|
||||
|
||||
/* begin to interpolate value for each bin in the HRAP grid */
|
||||
/*
|
||||
* to interpolate, two quantities are needed first: value and
|
||||
* distance. They are calculated by using the neighboring stations.
|
||||
*/
|
||||
|
||||
for (i = 0; i < hrap_grid.maxi; i++) { /*
|
||||
* hrap_grid comes from the
|
||||
* function parameter
|
||||
*/
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
/*
|
||||
* Check if the grid cell is covered by an HSA. If not, then
|
||||
* do not estimate precipitation for it.
|
||||
*/
|
||||
if (hrap_grid.owner[i][j] == -1) {
|
||||
pcp.value[i][j] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
value = 0.0;
|
||||
distance = 0.0;
|
||||
htotal = 0;
|
||||
|
||||
/*
|
||||
* the following for loop is to calculate two quantities:
|
||||
* value and distance, which later on, are used to interpret
|
||||
* the HRAP grid.
|
||||
*/
|
||||
/*
|
||||
* It uses neighbor stations of a HRAP grid bin to calculate
|
||||
* value and distance.
|
||||
*/
|
||||
/*
|
||||
* for each neighbor station of the grid bin, do the
|
||||
* following
|
||||
*/
|
||||
int mpe_dqc_max_precip_neighbors = DailyQcUtils.mpe_dqc_max_precip_neighbors;
|
||||
|
||||
for (h = 0; h < mpe_dqc_max_precip_neighbors; h++) {
|
||||
hh = hrap_grid.gage[i][j].index[h];/*
|
||||
* hh is index of
|
||||
* stations
|
||||
*/
|
||||
|
||||
if (pdata[pcpn_day].stn[hh].frain[time_pos].data < 0) {
|
||||
/* No precip data. */
|
||||
continue;
|
||||
} /*
|
||||
* frain refers to level 2 data; rain refers to level
|
||||
* 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* generate something for output later on if in debug
|
||||
* mode
|
||||
*/
|
||||
// if (debug_level >= 1) {
|
||||
// if (pdata[pcpn_day].stn[hh].frain[time_pos].qual
|
||||
// == MISSING)
|
||||
// {
|
||||
// missing_total++;
|
||||
// }
|
||||
//
|
||||
// if (pdata[pcpn_day].stn[hh].frain[time_pos].qual
|
||||
// == ESTIMATED)
|
||||
// {
|
||||
// estimated_total++;
|
||||
// }
|
||||
//
|
||||
// if (pdata[pcpn_day].stn[hh].frain[time_pos].qual
|
||||
// == FAILED)
|
||||
// {
|
||||
// failed_total++;
|
||||
// }
|
||||
//
|
||||
// if (method == 2 && station[hh].isoh[isom] <= 0)
|
||||
// {
|
||||
// climo_total++;
|
||||
// }
|
||||
// } /* end if (debug_level >= 1) */
|
||||
|
||||
if (DailyQcUtils.method == 2
|
||||
&& precip_stations.get(hh).isoh[isom] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pdata[pcpn_day].stn[hh].frain[time_pos].qual != 0
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 8
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 6
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 3
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 4
|
||||
&& pdata[pcpn_day].stn[hh].frain[time_pos].qual != 2) {
|
||||
/* The station has a bad qc flag. Do not use it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the coordinates of the grid and station in
|
||||
* lat/lon into distance.
|
||||
*/
|
||||
dist1 = (i + hrap_grid.hrap_minx - precip_stations
|
||||
.get(hh).hrap_x);
|
||||
dist2 = (j + hrap_grid.hrap_miny - precip_stations
|
||||
.get(hh).hrap_y);
|
||||
|
||||
dist = Math.pow(dist1, 2) + Math.pow(dist2, 2);
|
||||
|
||||
if (dist < .00001) {
|
||||
dist = .00001;
|
||||
}
|
||||
|
||||
dist = 1 / dist;
|
||||
|
||||
temp = pdata[pcpn_day].stn[hh].frain[time_pos].data
|
||||
* dist;
|
||||
|
||||
if (method == 2
|
||||
&& precip_stations.get(hh).isoh[isom] > 0) {
|
||||
temp = temp
|
||||
* hrap_grid.isoh[isom][i][j]
|
||||
/ (precip_stations.get(hh).isoh[isom] * 25.4);
|
||||
}
|
||||
|
||||
value = value + temp;
|
||||
|
||||
distance = distance + dist;
|
||||
|
||||
htotal++;
|
||||
|
||||
if (htotal == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* end for loop (h = 0; h <
|
||||
* mpe_dqc_max_precip_neighbors;h++)
|
||||
*/
|
||||
/* the above for loop is for each neighbor station. */
|
||||
/*
|
||||
* the above for loop is to calculate value and distance,
|
||||
* which later on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* the resulting htotal is the valid number of neighbor
|
||||
* stations that are used to calculate value and distance,
|
||||
* which later on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* if there is not enough valid neighbor station, such as
|
||||
* htotal <4, the code below handle this situation.
|
||||
* Basically, the code recalculate the value and distance
|
||||
* using all the stations -- see the for (h = 0; h <
|
||||
* max_stations; h++) loop below.
|
||||
*/
|
||||
if (htotal < 4) {
|
||||
|
||||
value = 0.0;
|
||||
distance = 0.0;
|
||||
htotal = 0;
|
||||
|
||||
for (h = 0; h < numPstations; h++) {
|
||||
if (pdata[pcpn_day].stn[h].frain[time_pos].data < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pdata[pcpn_day].stn[h].frain[time_pos].qual != 0
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 8
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 6
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 3
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 4
|
||||
&& pdata[pcpn_day].stn[h].frain[time_pos].qual != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method == 2
|
||||
&& precip_stations.get(h).isoh[isom] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dist1 = (i + hrap_grid.hrap_minx - precip_stations
|
||||
.get(h).hrap_x);
|
||||
dist2 = (j + hrap_grid.hrap_miny - precip_stations
|
||||
.get(h).hrap_y);
|
||||
|
||||
dist = Math.pow(dist1, 2) + Math.pow(dist2, 2);
|
||||
|
||||
if (dist < .00001) {
|
||||
dist = .00001;
|
||||
}
|
||||
|
||||
dist = 1 / dist;
|
||||
|
||||
temp = pdata[pcpn_day].stn[h].frain[time_pos].data
|
||||
* dist;
|
||||
|
||||
if (method == 2
|
||||
&& precip_stations.get(h).isoh[isom] > 0) {
|
||||
temp = temp
|
||||
* hrap_grid.isoh[isom][i][j]
|
||||
/ (precip_stations.get(h).isoh[isom] * 25.4);
|
||||
}
|
||||
|
||||
value = value + temp;
|
||||
|
||||
distance = distance + dist;
|
||||
|
||||
htotal++;
|
||||
|
||||
}
|
||||
neighbor_total++;
|
||||
} /* end the handling of special case : if (htotal < 4), */
|
||||
/* which means there is no enough neighboring stations */
|
||||
|
||||
/*
|
||||
* add the interpreted value for the bin of the HRAP_grid
|
||||
*/
|
||||
/*
|
||||
* if (htotal == 0) { pcp->value[i][j] += 0; } else {
|
||||
* pcp->value[i][j] += (int) (value / distance * 100); }
|
||||
*/
|
||||
if (htotal != 0) {
|
||||
pcp.value[i][j] += (int) (value / distance * 100);
|
||||
}
|
||||
|
||||
/*
|
||||
* if (pcp->value[i][j] < .01) { pcp->value[i][j] = 0; }
|
||||
*/
|
||||
all_total++;
|
||||
|
||||
} /* end of for loop (j = 0; j < hrap_grid->maxj; j++) */
|
||||
} /* end of for loop (i = 0; i < hrap_grid->maxi; i++) */
|
||||
/* At this moment, the interpretation of HRAP grid is done */
|
||||
|
||||
}/*
|
||||
* end of the ( k = 0; k<4; k++) loop, which interpolates 4 6hr HRAP
|
||||
* grid.
|
||||
*/
|
||||
|
||||
/* final adjustment of the pcp->value */
|
||||
for (i = 0; i < hrap_grid.maxi; i++) { /*
|
||||
* hrap_grid comes from the
|
||||
* function parameter
|
||||
*/
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
|
||||
if (pcp.value[i][j] < .01) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* time_pos = pcpn_day * 4 + 3 - pcpn_time; */
|
||||
time_pos = 40 + pcpn_day;
|
||||
|
||||
/*
|
||||
* pcp_in_use[i] = 1 -- grids rendered via Render button OR Save Level2
|
||||
* option = -1 --grids for this time period not rendered (initialization
|
||||
* value)
|
||||
*/
|
||||
pcp_in_use[time_pos] = 1;
|
||||
|
||||
/*
|
||||
* results of grid rendering routines (render_t, render_t6, render_pcp,
|
||||
* render_z) are written to scratch files using the write_file routine.
|
||||
* scratch file is stored in the scratch directory.
|
||||
*/
|
||||
ReadQPFGrids rqp = new ReadQPFGrids();
|
||||
rqp.write_file("pcp", time_pos, pcp);
|
||||
|
||||
}
|
||||
|
||||
int getTokenValue24hrGridGenMeth() {
|
||||
|
||||
int token_of_24hr_grid_gen_method = 0;
|
||||
|
||||
/* int token_of_24hr_grid_gen_method = 0; */
|
||||
|
||||
if (first == true) {
|
||||
String token_name_of_24hr_grid_gen_method_token = "mpe_dqc_24hr_precip_grid_meth";
|
||||
|
||||
/* char strTokenValue[50] = { '\0' }; */
|
||||
String DQC24hrPrecipMeth;
|
||||
|
||||
// char message[GAGEQC_MESSAGE_LEN] = { '\0' };
|
||||
|
||||
AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
DQC24hrPrecipMeth = appsDefaults
|
||||
.getToken(token_name_of_24hr_grid_gen_method_token);
|
||||
// sprintf(message, "\nSTATUS: token value of \"%s\" : %s\n",
|
||||
// token_name_of_24hr_grid_gen_method_token, strTokenValue);
|
||||
// logMessage(message);
|
||||
|
||||
if (DQC24hrPrecipMeth != null && DQC24hrPrecipMeth.length() > 0) {
|
||||
/* we use the token ACCUM_6HR and USE_24HR */
|
||||
if (DQC24hrPrecipMeth.equalsIgnoreCase("ACCUM_6HR")) {
|
||||
token_of_24hr_grid_gen_method = 1;
|
||||
}
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
return token_of_24hr_grid_gen_method;
|
||||
}
|
||||
}
|
||||
private static boolean first = true;
|
||||
|
||||
Pcp pcp = DailyQcUtils.pcp;
|
||||
|
||||
/*
|
||||
* QC codes
|
||||
*/
|
||||
private static final int MISSING = -1;
|
||||
|
||||
private static final int STANDARD = 0;
|
||||
|
||||
private static final int SCREENED = 0;
|
||||
|
||||
private static final int FAILED = 1;
|
||||
|
||||
private static final int MANUAL = 2;
|
||||
|
||||
private static final int QUESTIONABLE = 3;
|
||||
|
||||
private static final int PARTIAL = 4;
|
||||
|
||||
private static final int ESTIMATED = 5;
|
||||
|
||||
private static final int TIMEDISTRIBUTED = 6;
|
||||
|
||||
private static final int VERIFIED = 8;
|
||||
|
||||
private static final String MPE_DQC_GRID_RENDERING_METHOD_TOKEN = "mpe_dqc_grid_render_method";
|
||||
|
||||
private static final int maxDistSquared = DailyQcUtils.mpe_dqc_grid_max_dist
|
||||
* DailyQcUtils.mpe_dqc_grid_max_dist;
|
||||
|
||||
/**
|
||||
* Converts point precipitation data in struct pdata to hrap grid. The 20
|
||||
* closest stations are precalculated for each grid point - this speeds
|
||||
* computations for data sets with many precipitation points. If there are
|
||||
* no good precipitation points for a grid point, then a recalculation is
|
||||
* made using all precipitation points. 1/R**2 interpolation is used. If
|
||||
* requested, the final interpolation is scaled using seasonal isohyets. The
|
||||
* grid is saved as a disk file and used later for a raster or vector (HRAP)
|
||||
* plot.
|
||||
*
|
||||
* @param m
|
||||
* @param k
|
||||
* @param mk
|
||||
* @param numPstations
|
||||
* @param
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
// mpe_dqc_grid_render_method
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
public void render_pcp(int pcpn_day, int pcpn_time, int pcpn_time_step,
|
||||
int numPstations, ArrayList<Station> precip_stations,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
String header = "RenderPcp.render_pcp(): ";
|
||||
|
||||
AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
|
||||
String tokenValue = appsDefaults
|
||||
.getToken(MPE_DQC_GRID_RENDERING_METHOD_TOKEN);
|
||||
|
||||
// System.out.println(header + "tokenValue = " + tokenValue);
|
||||
|
||||
// tokenValue = "BLOCKING";
|
||||
// tokenValue = "DISTANCE_SQUARED";
|
||||
|
||||
System.out.println(header + "now tokenValue = " + tokenValue);
|
||||
|
||||
if (tokenValue != null && tokenValue.equalsIgnoreCase("BLOCKING")) {
|
||||
RenderPcpBlocking renderer = new RenderPcpBlocking();
|
||||
|
||||
renderer.render_pcp(pcpn_day, pcpn_time, pcpn_time_step,
|
||||
numPstations, precip_stations, hrap_grid, pdata, pcp_in_use);
|
||||
}
|
||||
|
||||
else {
|
||||
RenderPcpStandard renderer = new RenderPcpStandard();
|
||||
|
||||
renderer.render_pcp(pcpn_day, pcpn_time, pcpn_time_step,
|
||||
numPstations, precip_stations, hrap_grid, pdata, pcp_in_use);
|
||||
|
||||
}
|
||||
|
||||
determineMaxPrecip(hrap_grid);
|
||||
|
||||
}
|
||||
|
||||
private int determineMaxPrecip(Hrap_Grid hrap_grid) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
String header = "RenderPcp.determineMaxPrecip(): ";
|
||||
|
||||
int value = 0;
|
||||
int maxValue = -1;
|
||||
|
||||
for (int col = 0; col < hrap_grid.maxi; col++) {
|
||||
for (int row = 0; row < hrap_grid.maxj; row++) {
|
||||
value = pcp.value[row][col];
|
||||
|
||||
if (value > maxValue) {
|
||||
maxValue = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
System.out.println(header + "maxValue = " + maxValue);
|
||||
|
||||
return maxValue;
|
||||
|
||||
} // end determineMaxPrecip()
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
} // end class RenderPcp
|
|
@ -0,0 +1,957 @@
|
|||
/**
|
||||
* 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.mpe.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.raytheon.uf.common.ohd.AppsDefaults;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Hrap_Grid;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Pcp;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Pdata;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Station;
|
||||
|
||||
/**
|
||||
* DESCRIPTION: Maps precipitation station values to an HRAP grid. Produces the
|
||||
* DailyQC version of the GageOnly analysis.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 11, 2009 snaples Initial creation
|
||||
* May 02, 2011 8962 snaples Added render24hrPcpUsingFour6hr() method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author snaples
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RenderPcpBlocking {
|
||||
|
||||
private static boolean first = true;
|
||||
|
||||
Pcp pcp = DailyQcUtils.pcp;
|
||||
|
||||
/*
|
||||
* QC codes
|
||||
*/
|
||||
private static final int MISSING = -1;
|
||||
private static final int STANDARD = 0;
|
||||
private static final int SCREENED = 0;
|
||||
private static final int FAILED = 1;
|
||||
private static final int MANUAL = 2;
|
||||
private static final int QUESTIONABLE = 3;
|
||||
private static final int PARTIAL = 4;
|
||||
private static final int ESTIMATED = 5;
|
||||
private static final int TIMEDISTRIBUTED = 6;
|
||||
private static final int VERIFIED = 8;
|
||||
|
||||
// private static final String MPE_DQC_GRID_RENDERING_METHOD_TOKEN =
|
||||
// "mpe_dqc_grid_render_method";
|
||||
|
||||
private static final int maxDistSquared = DailyQcUtils.mpe_dqc_grid_max_dist
|
||||
* DailyQcUtils.mpe_dqc_grid_max_dist;
|
||||
|
||||
// private static final int maxDistSquared = 400;
|
||||
|
||||
/**
|
||||
* Converts point precipitation data in struct pdata to hrap grid. The 20
|
||||
* closest stations are precalculated for each grid point - this speeds
|
||||
* computations for data sets with many precipitation points. If there are
|
||||
* no good precipitation points for a grid point, then a recalculation is
|
||||
* made using all precipitation points. 1/R**2 interpolation is used. If
|
||||
* requested, the final interpolation is scaled using seasonal isohyets. The
|
||||
* grid is saved as a disk file and used later for a raster or vector (HRAP)
|
||||
* plot.
|
||||
*
|
||||
* @param m
|
||||
* @param k
|
||||
* @param mk
|
||||
* @param numPstations
|
||||
* @param
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
// mpe_dqc_grid_render_method
|
||||
|
||||
private boolean usingSingleDirectionCloseOutMode = true;
|
||||
private static final int MIN_PREFERRED_USED_GRID_CELLS = 4;
|
||||
private static final int MIN_REQUIRED_USED_GRID_CELLS = 1;
|
||||
|
||||
private SearchDirection north = new SearchDirection();
|
||||
private SearchDirection south = new SearchDirection();
|
||||
private SearchDirection east = new SearchDirection();
|
||||
private SearchDirection west = new SearchDirection();
|
||||
|
||||
private int colMin;
|
||||
private int colMax;
|
||||
private int rowMin;
|
||||
private int rowMax;
|
||||
private int prevColMin;
|
||||
private int prevColMax;
|
||||
private int prevRowMin;
|
||||
private int prevRowMax;
|
||||
|
||||
// weighting variables
|
||||
private int usedGridCellCount = 0;
|
||||
private double totalWeightedValue = 0;
|
||||
private double totalDistanceWeight = 0;
|
||||
|
||||
// grid variables
|
||||
private int binStationCount[][];
|
||||
|
||||
private int usableStationCount = 0;
|
||||
|
||||
private double valueGrid[][];
|
||||
private double prismStationGrid[][];
|
||||
|
||||
private int isom = -1;
|
||||
|
||||
class SearchDirection {
|
||||
private boolean isOpen;
|
||||
private int level;
|
||||
|
||||
public SearchDirection() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
setOpen(true);
|
||||
setLevel(0);
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
public void setOpen(boolean isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
setOpen(false);
|
||||
}
|
||||
|
||||
void expandSearchIfAllowed() {
|
||||
if (isOpen()) {
|
||||
incrementLevel();
|
||||
|
||||
if (getLevel() > DailyQcUtils.mpe_dqc_grid_max_dist) {
|
||||
setLevel(DailyQcUtils.mpe_dqc_grid_max_dist);
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void incrementLevel() {
|
||||
this.level++;
|
||||
}
|
||||
|
||||
private void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
} // end inner class SearchDirection
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
int getTokenValue24hrGridGenMeth() {
|
||||
|
||||
int token_of_24hr_grid_gen_method = 0;
|
||||
|
||||
if (first == true) {
|
||||
String tokenName = "mpe_dqc_24hr_precip_grid_meth";
|
||||
|
||||
String dqc24hrPrecipMeth;
|
||||
|
||||
// char message[GAGEQC_MESSAGE_LEN] = { '\0' };
|
||||
|
||||
AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
dqc24hrPrecipMeth = appsDefaults.getToken(tokenName);
|
||||
|
||||
if (dqc24hrPrecipMeth != null) {
|
||||
/* allowed token values: (ACCUM_6HR, USE_24HR) */
|
||||
if (dqc24hrPrecipMeth.equalsIgnoreCase("ACCUM_6HR")) {
|
||||
token_of_24hr_grid_gen_method = 1;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
return token_of_24hr_grid_gen_method;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
public void render_pcp(int pcpn_day, int pcpn_time, int pcpn_time_step,
|
||||
int numPstations, ArrayList<Station> stationList,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
isom = DailyQcUtils.isom;
|
||||
|
||||
int time_pos;
|
||||
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_time; // for 6 hour data: 0,1,2,3.
|
||||
|
||||
boolean save_grids = true;
|
||||
boolean accumulate_grids = false;
|
||||
|
||||
render_pcp_internal(pcpn_day, pcpn_time, pcpn_time_step,
|
||||
numPstations, stationList, hrap_grid, pdata, pcp_in_use,
|
||||
save_grids, accumulate_grids);
|
||||
} else {
|
||||
time_pos = 4; // for 24 hour data
|
||||
|
||||
/*
|
||||
* in case the 24hr grid rendering is required, we check
|
||||
* 24hr_grid_gen_method_token() to determine how to generate the
|
||||
* grid. New Post OB9.2
|
||||
*/
|
||||
|
||||
// debug
|
||||
// first = true;
|
||||
|
||||
if (getTokenValue24hrGridGenMeth() == 1) {
|
||||
render24hrPcpUsingFour6hr(pcpn_day, pcpn_time, numPstations,
|
||||
stationList, hrap_grid, pdata, pcp_in_use);
|
||||
return;
|
||||
} else // calculate 24-hour grids the regular way
|
||||
{
|
||||
|
||||
boolean save_grids = true;
|
||||
boolean accumulate_grids = false;
|
||||
|
||||
render_pcp_internal(pcpn_day, pcpn_time, pcpn_time_step,
|
||||
numPstations, stationList, hrap_grid, pdata,
|
||||
pcp_in_use, save_grids, accumulate_grids);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void render_pcp_internal(int pcpn_day, int pcpn_time,
|
||||
int pcpn_time_step, int numPstations,
|
||||
ArrayList<Station> stationList, Hrap_Grid hrap_grid, Pdata[] pdata,
|
||||
int[] pcp_in_use, boolean save_grids, boolean should_accumulate) {
|
||||
// String header = "RenderPcpBlocking.render_pcp_internal(): ";
|
||||
|
||||
int isom = DailyQcUtils.isom;
|
||||
|
||||
double resultingPrecipValue = 0.0;
|
||||
|
||||
/*-----------------------------------------------------*/
|
||||
|
||||
allocateGrids(hrap_grid);
|
||||
|
||||
initializeGrids(hrap_grid, should_accumulate);
|
||||
|
||||
placeStationsInGrid(pcpn_day, pcpn_time, pcpn_time_step, numPstations,
|
||||
stationList, hrap_grid, pdata);
|
||||
|
||||
// for every grid location, determine its estimated value
|
||||
for (int col = 0; col < hrap_grid.maxi; col++) {
|
||||
for (int row = 0; row < hrap_grid.maxj; row++) {
|
||||
|
||||
/*
|
||||
* Check if the grid cell is covered by an HSA. If not, then do
|
||||
* not estimate precipitation for it.
|
||||
*/
|
||||
if (hrap_grid.owner[col][row] == -1) {
|
||||
pcp.value[row][col] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (binStationCount[col][row] > 0) // if any station is in this
|
||||
// grid bin
|
||||
{
|
||||
resultingPrecipValue = valueGrid[col][row];
|
||||
|
||||
// adjust grid bin with actual gage by the prism factor
|
||||
if (prismStationGrid[col][row] > 0) {
|
||||
double prismStationValue = prismStationGrid[col][row] * 25.4;
|
||||
double prismGridValue = hrap_grid.isoh[isom][col][row];
|
||||
|
||||
double prismFactor = (double) prismGridValue
|
||||
/ prismStationValue;
|
||||
|
||||
resultingPrecipValue *= prismFactor;
|
||||
} else {
|
||||
resultingPrecipValue = 0.0;
|
||||
}
|
||||
|
||||
// pcp.value[row][col] is the value of grid,
|
||||
// so we don't need to estimate a value for [row][col]
|
||||
}
|
||||
|
||||
else // this grid location requires an estimate to be generated
|
||||
{
|
||||
resultingPrecipValue = estimateValue(isom, col, row,
|
||||
hrap_grid);
|
||||
}
|
||||
|
||||
if (resultingPrecipValue >= 0.0) {
|
||||
int precipInHundredthsOfMm = (int) Math
|
||||
.floor((resultingPrecipValue * 100.0));
|
||||
|
||||
if (should_accumulate) { // for case where we want to make
|
||||
// 24 = 4 6hr periods added
|
||||
// together
|
||||
pcp.value[col][row] += precipInHundredthsOfMm;
|
||||
} else {
|
||||
pcp.value[col][row] = precipInHundredthsOfMm;
|
||||
}
|
||||
}
|
||||
|
||||
} /* end for (col = 0 ... */
|
||||
|
||||
} /* end for (row = 0 ... */
|
||||
|
||||
// System.out.println(header + "maxPrecip in hundredths of mm = " +
|
||||
// maxPrecip);
|
||||
|
||||
int time_pos;
|
||||
/*
|
||||
* notice that time_pos is a variable defined inside the function, and
|
||||
* its value do not need to be limited as 0,1,2,3,or 4. Here it is
|
||||
* assigned with bigger numbers.
|
||||
*/
|
||||
if (pcpn_time_step == 0) // one of the 6-hr periods
|
||||
{
|
||||
time_pos = pcpn_day * 4 + 3 - pcpn_time;
|
||||
} else // 24 hr
|
||||
{
|
||||
time_pos = 40 + pcpn_day;
|
||||
}
|
||||
|
||||
if (save_grids) {
|
||||
/*
|
||||
* pcp_in_use[i] = 1 -- grids rendered via Render button OR Save
|
||||
* Level2 option = -1 --grids for this time period not rendered
|
||||
* (initialization value)
|
||||
*/
|
||||
pcp_in_use[time_pos] = 1;
|
||||
|
||||
/*
|
||||
* results of grid rendering routines (render_t, render_t6,
|
||||
* render_pcp, render_z) are written to scratch files using the
|
||||
* write_file routine. scratch file is stored in the scratch
|
||||
* directory.
|
||||
*/
|
||||
|
||||
ReadQPFGrids rqp = new ReadQPFGrids();
|
||||
rqp.write_file("pcp", time_pos, pcp);
|
||||
}
|
||||
|
||||
} // end render_pcp_internal()
|
||||
|
||||
private double estimateValue(int isom, int col, int row, Hrap_Grid hrap_grid) {
|
||||
|
||||
// String header = "RenderPcpBlocking.estimateValue(): ";
|
||||
int r;
|
||||
int c;
|
||||
|
||||
double estimatedPrecipValue = 0.0;
|
||||
|
||||
if (hrap_grid.isoh[isom][col][row] < 0.01) {
|
||||
estimatedPrecipValue = 0;
|
||||
return estimatedPrecipValue; // can't do anything more, quit
|
||||
}
|
||||
|
||||
// look through surrounding grid bins only for
|
||||
// values to be used in the distance-weighted interpolation
|
||||
|
||||
// set to open and level = 0
|
||||
north.reset();
|
||||
south.reset();
|
||||
east.reset();
|
||||
west.reset();
|
||||
|
||||
// initialize
|
||||
totalWeightedValue = 0.0;
|
||||
totalDistanceWeight = 0.0;
|
||||
usedGridCellCount = 0;
|
||||
|
||||
rowMax = row;
|
||||
rowMin = row;
|
||||
colMax = col;
|
||||
colMin = col;
|
||||
|
||||
prevRowMax = rowMax;
|
||||
prevRowMin = rowMin;
|
||||
prevColMax = colMax;
|
||||
prevColMin = colMin;
|
||||
|
||||
while (north.isOpen() || south.isOpen() || east.isOpen()
|
||||
|| west.isOpen()) {
|
||||
// expand search levels as appropriate
|
||||
// changes rowMin, rowMax, colMin, colMax
|
||||
expandGridSearch(col, row, hrap_grid);
|
||||
|
||||
if (rowMin < prevRowMin) // grew the top side
|
||||
{
|
||||
r = rowMin;
|
||||
for (c = colMin; c <= colMax; c++) {
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
} else // didn't grow the top side
|
||||
{
|
||||
if (colMin < prevColMin) // still need to check top left corner
|
||||
{
|
||||
c = colMin;
|
||||
r = rowMin;
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
|
||||
if (colMax > prevColMax) // still need to check top right corner
|
||||
{
|
||||
c = colMax;
|
||||
r = rowMin;
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (rowMax > prevRowMax) // grew the bottom side
|
||||
{
|
||||
r = rowMax;
|
||||
for (c = colMin; c <= colMax; c++) {
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
} else // didn't grow the bottom side
|
||||
{
|
||||
if (colMin < prevColMin) // still need to check bottom left
|
||||
// corner
|
||||
{
|
||||
c = colMin;
|
||||
r = rowMax;
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
if (colMax > prevColMax) // still need to check bottom right
|
||||
// corner
|
||||
{
|
||||
c = colMax;
|
||||
r = rowMax;
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
}
|
||||
|
||||
if (colMin < prevColMin) // grew left side
|
||||
{
|
||||
c = colMin;
|
||||
for (r = rowMin + 1; r < rowMax; r++) {
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
}
|
||||
|
||||
if (colMax > prevColMax) // grew right side
|
||||
{
|
||||
c = colMax;
|
||||
for (r = rowMin + 1; r < rowMax; r++) {
|
||||
processGriddedStationValues(col, row, c, r, hrap_grid);
|
||||
}
|
||||
}
|
||||
|
||||
if (usedGridCellCount >= MIN_PREFERRED_USED_GRID_CELLS) // have
|
||||
// enough
|
||||
// cells to
|
||||
// look at,
|
||||
// can quit
|
||||
// now
|
||||
{
|
||||
north.close();
|
||||
south.close();
|
||||
east.close();
|
||||
west.close();
|
||||
|
||||
// System.out.println(header +
|
||||
// "met minimum cell preference, resultingPrecipValue = " +
|
||||
// resultingPrecipValue);
|
||||
}
|
||||
|
||||
} /* end while (northLevelOpen ... */
|
||||
|
||||
// set weighted value to the cell or set value to 0.0 if there is not
|
||||
// enough data
|
||||
if (usedGridCellCount >= MIN_REQUIRED_USED_GRID_CELLS) {
|
||||
estimatedPrecipValue = totalWeightedValue / totalDistanceWeight;
|
||||
|
||||
// System.out.println(header +
|
||||
// "met minimum cell requirement, resultingPrecipValue = " +
|
||||
// resultingPrecipValue);
|
||||
} else // set to zero precip
|
||||
{
|
||||
estimatedPrecipValue = 0.0;
|
||||
}
|
||||
|
||||
return estimatedPrecipValue;
|
||||
|
||||
} // end estimateValue()
|
||||
|
||||
// *--------------------------------------------------------------------------
|
||||
|
||||
void processGriddedStationValues(int renderingCol, int renderingRow,
|
||||
int gridCol, int gridRow, Hrap_Grid hrap_grid) {
|
||||
|
||||
String header = "RenderPcpBlocking.processGriddedStationValues(): ";
|
||||
|
||||
int usedCells = 0;
|
||||
// sprintf(message,
|
||||
// "renderingCol = %d, renderingRow = %d, gridCol = %d, gridRow = %d \n",
|
||||
// renderingCol, renderingRow, gridCol, gridRow);
|
||||
|
||||
// logMessage(message);
|
||||
|
||||
if ((gridCol < 0) || (gridCol > hrap_grid.maxi) || (gridRow < 0)
|
||||
|| (gridRow > hrap_grid.maxj)) {
|
||||
System.out.println(header + "OUT OF RANGE gridCol = " + gridCol
|
||||
+ " gridRow = " + gridRow);
|
||||
}
|
||||
|
||||
double gageValue = valueGrid[gridCol][gridRow];
|
||||
|
||||
if (gageValue >= 0.0) // there is a gage
|
||||
// located at (gridCol,gridRow)
|
||||
// with a valid precip value
|
||||
{
|
||||
|
||||
usedCells = adjustWeights(gageValue, gridRow, gridCol,
|
||||
renderingRow, renderingCol, hrap_grid, isom,
|
||||
prismStationGrid);
|
||||
|
||||
usedGridCellCount += usedCells;
|
||||
// if data was found, close off a direction, usually 2 directions,
|
||||
// such as north and west
|
||||
|
||||
if (usedCells > 0) {
|
||||
determineDirectionFoundAndCloseOff(renderingCol, renderingRow,
|
||||
gridCol, gridRow);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
} // end processGriddedStationValues()
|
||||
|
||||
// *--------------------------------------------------------------------------
|
||||
|
||||
void expandGridSearch(int col, int row, Hrap_Grid hrap_grid) {
|
||||
// expand search levels as appropriate
|
||||
|
||||
north.expandSearchIfAllowed();
|
||||
south.expandSearchIfAllowed();
|
||||
east.expandSearchIfAllowed();
|
||||
west.expandSearchIfAllowed();
|
||||
|
||||
// save previous values of row and col min and max
|
||||
prevRowMax = rowMax;
|
||||
prevRowMin = rowMin;
|
||||
prevColMax = colMax;
|
||||
prevColMin = colMin;
|
||||
|
||||
// determine nested for loop ranges
|
||||
rowMax = row + north.getLevel();
|
||||
if (rowMax >= hrap_grid.maxj) {
|
||||
rowMax = hrap_grid.maxj - 1;
|
||||
north.close();
|
||||
}
|
||||
|
||||
rowMin = row - south.getLevel(); // row
|
||||
if (rowMin < 0) {
|
||||
rowMin = 0;
|
||||
south.close();
|
||||
}
|
||||
|
||||
colMin = col - west.getLevel();
|
||||
if (colMin < 0) {
|
||||
colMin = 0;
|
||||
west.close();
|
||||
}
|
||||
|
||||
colMax = col + east.getLevel();
|
||||
if (colMax >= hrap_grid.maxi) {
|
||||
colMax = hrap_grid.maxi - 1;
|
||||
east.close();
|
||||
}
|
||||
|
||||
return;
|
||||
} // end expandGridSearch()
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void determineDirectionFoundAndCloseOffSimpleVersion(int renderingCol,
|
||||
int renderingRow, int stationCol, int stationRow) {
|
||||
if (stationRow < renderingRow) {
|
||||
south.close();
|
||||
} else if (stationRow > renderingRow) {
|
||||
north.close();
|
||||
}
|
||||
|
||||
if (stationCol < renderingCol) {
|
||||
west.close();
|
||||
} else if (stationCol > renderingCol) {
|
||||
east.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void determineDirectionFoundAndCloseOff(int renderingCol, int renderingRow,
|
||||
int stationCol, int stationRow) {
|
||||
|
||||
final int closeEnoughToBeEqual = 2;
|
||||
|
||||
// String header =
|
||||
// "RenderPcpBlocking.determineDirectionFoundAndCloseOff(): ";
|
||||
|
||||
// consider taking a diff and a point is considered in a straightline if
|
||||
// its difference is < 3 from the grid bin to render
|
||||
|
||||
int northSouthDifference = Math.abs(stationRow - renderingRow);
|
||||
int eastWestDifference = Math.abs(stationCol - renderingCol);
|
||||
|
||||
boolean isNorthOrSouth = false;
|
||||
boolean isEastOrWest = false;
|
||||
|
||||
if (northSouthDifference - eastWestDifference <= closeEnoughToBeEqual) {
|
||||
isNorthOrSouth = true;
|
||||
isEastOrWest = true;
|
||||
} else if (northSouthDifference > eastWestDifference) {
|
||||
isNorthOrSouth = true;
|
||||
} else {
|
||||
isEastOrWest = true;
|
||||
}
|
||||
|
||||
if (usingSingleDirectionCloseOutMode) {
|
||||
// System.out.println(header +
|
||||
// "Using usingSingleDirectionCloseOutMode difference-based close off.");
|
||||
|
||||
if (isNorthOrSouth) {
|
||||
// this point functions as the north-south representative, since
|
||||
// it is primarily north or south
|
||||
|
||||
if (stationRow < renderingRow) {
|
||||
south.close();
|
||||
} else if (stationRow > renderingRow) {
|
||||
north.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (isEastOrWest) {
|
||||
if (stationCol < renderingCol) {
|
||||
west.close();
|
||||
} else if (stationCol > renderingCol) {
|
||||
east.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else // in mode in which points represent 2 directions (unless directly
|
||||
// North-south or east-west)
|
||||
{
|
||||
// System.out.println(header +
|
||||
// "Using traditional difference cutoff.");
|
||||
if (stationRow < renderingRow) {
|
||||
south.close();
|
||||
} else if (stationRow > renderingRow) {
|
||||
north.close();
|
||||
}
|
||||
|
||||
if (stationCol < renderingCol) {
|
||||
west.close();
|
||||
} else if (stationCol > renderingCol) {
|
||||
east.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
} // determineDirectionFoundAndCloseOff()
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void allocateGrids(Hrap_Grid hrap_grid) {
|
||||
|
||||
int maxI = hrap_grid.maxi;
|
||||
int maxJ = hrap_grid.maxj;
|
||||
|
||||
binStationCount = new int[maxI][maxJ];
|
||||
|
||||
valueGrid = new double[maxI][maxJ];
|
||||
|
||||
prismStationGrid = new double[maxI][maxJ];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void initializeGrids(Hrap_Grid hrap_grid, boolean should_accumulate) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
/* initialize grids */
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
binStationCount[i][j] = 0;
|
||||
valueGrid[i][j] = DailyQcUtils.MOSAIC_DEFAULT; // precip in
|
||||
// inches
|
||||
prismStationGrid[i][j] = DailyQcUtils.MOSAIC_DEFAULT; // prism
|
||||
// station
|
||||
// value
|
||||
// mapped
|
||||
// to
|
||||
// grid
|
||||
// (this
|
||||
// algorithm
|
||||
// only)
|
||||
|
||||
if (!should_accumulate) {
|
||||
// in special 24hr = sum of 4 6hr periods mode,
|
||||
// we accumulate in this grid, so we don't reinit every time
|
||||
|
||||
pcp.value[i][j] = (int) DailyQcUtils.MOSAIC_DEFAULT; // final
|
||||
// precip
|
||||
// in
|
||||
// hundredths
|
||||
// of
|
||||
// mm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void placeStationsInGrid(int pcpn_day, int pcpn_time, int pcpn_time_step,
|
||||
int max_stations, ArrayList<Station> stationList,
|
||||
Hrap_Grid hrap_grid, Pdata pdata[]) {
|
||||
|
||||
int method = DailyQcUtils.method;
|
||||
String header = "RenderPcpBlocking.placeStationsInGrid(): ";
|
||||
|
||||
int time_pos;
|
||||
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_time; // for 6 hour data: 0,1,2,3.
|
||||
} else {
|
||||
time_pos = 4; // for 24 hour data
|
||||
}
|
||||
|
||||
int hx, hy;
|
||||
int h = 0;
|
||||
|
||||
int noPrismCount = 0;
|
||||
|
||||
// System.out.println("max_stations = " + max_stations);
|
||||
|
||||
int maxPrecip = 0;
|
||||
|
||||
for (h = 0; h < max_stations; h++) {
|
||||
Station station = stationList.get(h);
|
||||
|
||||
hx = (int) (station.hrap_x - hrap_grid.hrap_minx);
|
||||
hy = (int) (station.hrap_y - hrap_grid.hrap_miny);
|
||||
|
||||
/* check that station is within the site's area */
|
||||
if (hx >= hrap_grid.maxi || hy >= hrap_grid.maxj || (hx < 0)
|
||||
|| (hy < 0)) {
|
||||
// This station cannot be used, because its coordinates are out
|
||||
// of range
|
||||
continue;
|
||||
}
|
||||
|
||||
// debug only
|
||||
|
||||
int stationCount = binStationCount[hx][hy];
|
||||
|
||||
double precipValue = pdata[pcpn_day].stn[h].frain[time_pos].data;
|
||||
|
||||
short qualCode = pdata[pcpn_day].stn[h].frain[time_pos].qual;
|
||||
|
||||
// skip if not an acceptable quality code
|
||||
if (qualCode != SCREENED && qualCode != VERIFIED
|
||||
&& qualCode != TIMEDISTRIBUTED && qualCode != QUESTIONABLE
|
||||
&& qualCode != PARTIAL && qualCode != MANUAL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((method == 2) && (station.isoh[isom] <= 0)) // no prism data for
|
||||
// the station
|
||||
{
|
||||
noPrismCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if station value is missing, ignore */
|
||||
if (precipValue >= 0.0) {
|
||||
|
||||
int precipIn_h_mm = (int) Math.floor(precipValue * 100.0);
|
||||
|
||||
if (precipIn_h_mm > maxPrecip) {
|
||||
maxPrecip = precipIn_h_mm;
|
||||
}
|
||||
|
||||
// we have data and no other station has been assigned to this
|
||||
// bin yet
|
||||
if (binStationCount[hx][hy] == 0) {
|
||||
binStationCount[hx][hy] = 1;
|
||||
valueGrid[hx][hy] = precipValue;
|
||||
prismStationGrid[hx][hy] = station.isoh[isom];
|
||||
|
||||
usableStationCount++;
|
||||
}
|
||||
|
||||
else if (stationCount > 0) // we have at least 1 value for this
|
||||
// grid location
|
||||
{
|
||||
|
||||
double valueGridTotalValue = (valueGrid[hx][hy] * stationCount)
|
||||
+ precipValue;
|
||||
double prismGridTotalValue = (prismStationGrid[hx][hy] * stationCount)
|
||||
+ station.isoh[isom];
|
||||
binStationCount[hx][hy]++;
|
||||
stationCount++;
|
||||
|
||||
double newGridAvgValue = valueGridTotalValue / stationCount;
|
||||
double newPrismAvgValue = prismGridTotalValue
|
||||
/ stationCount;
|
||||
|
||||
valueGrid[hx][hy] = newGridAvgValue;
|
||||
prismStationGrid[hx][hy] = newPrismAvgValue;
|
||||
|
||||
usableStationCount++;
|
||||
|
||||
} // end else
|
||||
} // end if
|
||||
|
||||
} // end for (h = 0; h < max_stations; h++)
|
||||
|
||||
System.out.println(header + " maxPrecip in hundredths of mm = "
|
||||
+ maxPrecip);
|
||||
|
||||
// System.out.println(header +
|
||||
// " number of stations missing PRISM data = " + noPrismCount);
|
||||
// System.out.println(header + " usableStationCount = " +
|
||||
// usableStationCount);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
/*
|
||||
* get the token value of token mpe_24hr_grid_gen_method. This token will
|
||||
* determine how we generate the 24hr grid. We can either use the 24hr gage
|
||||
* values, which is the old way, or we can use four 6hr gage values and add
|
||||
* them together.
|
||||
*/
|
||||
/* there is some problem with the static */
|
||||
|
||||
private void render24hrPcpUsingFour6hr(int pcpn_day, int pcpn_time,
|
||||
int numPstations, ArrayList<Station> stationList,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
/* initialization of the pcp.value */
|
||||
for (int i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (int j = 0; j < hrap_grid.maxj; j++) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
boolean save_grids = false;
|
||||
boolean should_accumulate = true;
|
||||
|
||||
for (int k = 0; k < 4; k++) {
|
||||
int pcpn_time_internal = k;
|
||||
|
||||
int pcpn_time_step = 0; // means it is one of the 6-hr periods
|
||||
|
||||
render_pcp_internal(pcpn_day, pcpn_time_internal, pcpn_time_step,
|
||||
numPstations, stationList, hrap_grid, pdata, pcp_in_use,
|
||||
save_grids, should_accumulate);
|
||||
|
||||
}
|
||||
|
||||
} // end render24hrPcpUsingFour6hr()
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
int adjustWeights(double originalValue, int otherRow, int otherColumn,
|
||||
int renderingRow, int renderingColumn, Hrap_Grid hrap_grid,
|
||||
int monthIndex, double[][] prismStationGrid) {
|
||||
|
||||
String header = "RenderPcpBlocking.adjustWeights(): ";
|
||||
|
||||
final double MIN_DISTANCE = 0.00001;
|
||||
int usedCount = 0;
|
||||
|
||||
double distanceWeight = 0.0;
|
||||
double weightedValue = 0.0;
|
||||
|
||||
int rowDiff = otherRow - renderingRow;
|
||||
int colDiff = otherColumn - renderingColumn;
|
||||
double distanceSquared = (rowDiff * rowDiff) + (colDiff * colDiff);
|
||||
|
||||
// int maxDistSquared = DailyQcUtils.mpe_dqc_grid_max_dist *
|
||||
// DailyQcUtils.mpe_dqc_grid_max_dist;
|
||||
|
||||
if (distanceSquared < MIN_DISTANCE) {
|
||||
distanceSquared = MIN_DISTANCE;
|
||||
}
|
||||
|
||||
/*
|
||||
* mpe_dqc_grid_max_dist = max distance of influence of a gage in units
|
||||
* of grid bins
|
||||
*/
|
||||
|
||||
if (distanceSquared <= maxDistSquared) {
|
||||
distanceWeight = 1.0 / distanceSquared;
|
||||
weightedValue = originalValue * distanceWeight;
|
||||
|
||||
// adjust by PRISM factor
|
||||
if (prismStationGrid[renderingColumn][renderingRow] > 0) {
|
||||
double prismFactor = (double) hrap_grid.isoh[monthIndex][renderingColumn][renderingRow]
|
||||
/ (prismStationGrid[renderingColumn][renderingRow] * 25.4);
|
||||
weightedValue *= prismFactor;
|
||||
|
||||
System.out.println(header + " prismFactor > 0 " + prismFactor);
|
||||
|
||||
}
|
||||
|
||||
totalWeightedValue += weightedValue;
|
||||
totalDistanceWeight += distanceWeight;
|
||||
|
||||
usedCount++;
|
||||
}
|
||||
|
||||
return usedCount;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
}
|
|
@ -0,0 +1,603 @@
|
|||
/**
|
||||
* 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.mpe.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.ohd.AppsDefaults;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Hrap_Grid;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Pcp;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Pdata;
|
||||
import com.raytheon.viz.mpe.util.DailyQcUtils.Station;
|
||||
|
||||
/**
|
||||
* DESCRIPTION: Maps precipitation station values to an HRAP grid. Produces the
|
||||
* DailyQC version of the GageOnly analysis.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 11, 2009 snaples Initial creation
|
||||
* May 02, 2011 8962 snaples Added render24hrPcpUsingFour6hr() method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author snaples
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class RenderPcpStandard {
|
||||
|
||||
private static final int MINIMUM_NEAREST_NEIGHBOR_GAGES = 4;
|
||||
|
||||
private static final int SUFFICIENT_NEAREST_NEIGHBOR_GAGES = 10;
|
||||
|
||||
private static boolean first = true;
|
||||
|
||||
Pcp pcp = DailyQcUtils.pcp;
|
||||
|
||||
/*
|
||||
* QC codes
|
||||
*/
|
||||
private static final int MISSING = -1;
|
||||
|
||||
private static final int STANDARD = 0;
|
||||
|
||||
private static final int SCREENED = 0;
|
||||
|
||||
private static final int FAILED = 1;
|
||||
|
||||
private static final int MANUAL = 2;
|
||||
|
||||
private static final int QUESTIONABLE = 3;
|
||||
|
||||
private static final int PARTIAL = 4;
|
||||
|
||||
private static final int ESTIMATED = 5;
|
||||
|
||||
private static final int TIMEDISTRIBUTED = 6;
|
||||
|
||||
private static final int VERIFIED = 8;
|
||||
|
||||
private static final String MPE_DQC_GRID_RENDERING_METHOD_TOKEN = "mpe_dqc_grid_render_method";
|
||||
|
||||
private static final int maxDistSquared = DailyQcUtils.mpe_dqc_grid_max_dist
|
||||
* DailyQcUtils.mpe_dqc_grid_max_dist;
|
||||
|
||||
private static final double BOGUS_ESTIMATED_GRID_VALUE = -1.0;
|
||||
|
||||
// weighting variables
|
||||
|
||||
// consider making these members of a local variable of an inner class
|
||||
private double totalWeightedValue = 0;
|
||||
private double totalDistanceWeight = 0;
|
||||
|
||||
/**
|
||||
* Converts point precipitation data in struct pdata to hrap grid. The 20
|
||||
* closest stations are precalculated for each grid point - this speeds
|
||||
* computations for data sets with many precipitation points. If there are
|
||||
* no good precipitation points for a grid point, then a recalculation is
|
||||
* made using all precipitation points. 1/R**2 interpolation is used. If
|
||||
* requested, the final interpolation is scaled using seasonal isohyets. The
|
||||
* grid is saved as a disk file and used later for a raster or vector (HRAP)
|
||||
* plot.
|
||||
*
|
||||
* @param m
|
||||
* @param k
|
||||
* @param mk
|
||||
* @param numPstations
|
||||
* @param
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
public void render_pcp(int pcpn_day, int pcpn_time, int pcpn_time_step,
|
||||
int numPstations, ArrayList<Station> precip_stations,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
// String header = "RenderPcpStandard.render_pcp_original(): ";
|
||||
|
||||
int isom = DailyQcUtils.isom;
|
||||
int method = DailyQcUtils.method;
|
||||
int mpe_dqc_max_precip_neighbors = DailyQcUtils.mpe_dqc_max_precip_neighbors;
|
||||
int i, j, h, hh, time_pos;
|
||||
|
||||
int usedStationCount = 0;
|
||||
int totals[] = new int[5];
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
totals[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pcpn_time_step is a function parameter. It specifies whether to
|
||||
* interpolate 6hr or 24hr HRAP grid
|
||||
*/
|
||||
/*
|
||||
* pcpn_time is a function parameter. It specifies which 6hr HRAP grid
|
||||
* to generate. It takes 0,1,2,or 3 to represent different 6hr period of
|
||||
* a day.
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for 6hr data) or 4 (for
|
||||
* 24hr data). This value is used in
|
||||
* pdata[pcpn_day].stn[hh].frain[time_pos].data to control whether to
|
||||
* retrieve 6hr data or 24hr data.
|
||||
*/
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_time; // for 6 hour data: 0,1,2,3.
|
||||
} else {
|
||||
time_pos = 4; // for 24 hour data
|
||||
|
||||
/*
|
||||
* in case the 24hr grid rendering is required, we check
|
||||
* 24hr_grid_gen_method_token() to determine how to generate the
|
||||
* grid. New Post OB9.2
|
||||
*/
|
||||
|
||||
if (getTokenValue24hrGridGenMeth() == 1) {
|
||||
render24hrPcpUsingFour6hr(pcpn_day, pcpn_time, numPstations,
|
||||
precip_stations, hrap_grid, pdata, pcp_in_use);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* begin to interpolate value for each bin in the HRAP grid */
|
||||
/*
|
||||
* to interpolate, two quantities are needed first: value and distance.
|
||||
* They are calculated by using the neighboring stations.
|
||||
*/
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
/*
|
||||
* Check if the grid cell is covered by an HSA. If not, then do
|
||||
* not estimate precipitation for it.
|
||||
*/
|
||||
if (hrap_grid.owner[i][j] == -1) {
|
||||
pcp.value[i][j] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
totalDistanceWeight = 0.0;
|
||||
totalWeightedValue = 0.0;
|
||||
usedStationCount = 0;
|
||||
boolean usedStation = false;
|
||||
/*
|
||||
* the following for loop is to calculate two quantities: value
|
||||
* and distance, which later on, are used to interpret the HRAP
|
||||
* grid.
|
||||
*/
|
||||
/*
|
||||
* It uses neighbor stations of a HRAP grid bin to calculate
|
||||
* value and distance.
|
||||
*/
|
||||
/* for each neighbor station of the grid bin, do the following */
|
||||
|
||||
/* For each of the closest stations. */
|
||||
for (h = 0; h < mpe_dqc_max_precip_neighbors; h++) {
|
||||
|
||||
// hh is index of stations
|
||||
|
||||
hh = hrap_grid.gage[i][j].index[h];
|
||||
|
||||
int gageIndex = hh;
|
||||
|
||||
usedStation = processStation(gageIndex, isom, i, j,
|
||||
pcpn_day, pcpn_time, time_pos, method,
|
||||
precip_stations, hrap_grid, pdata, pcp_in_use,
|
||||
false);
|
||||
|
||||
if (usedStation) {
|
||||
usedStationCount++;
|
||||
}
|
||||
|
||||
if (usedStationCount == SUFFICIENT_NEAREST_NEIGHBOR_GAGES) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* end for loop (h = 0; h < mpe_dqc_max_precip_neighbors;h++)
|
||||
* the above for loop is for each neighbor station.
|
||||
*/
|
||||
/*
|
||||
* the above for loop is to calculate value and distance, which
|
||||
* later on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* the resulting htotal is the valid number of neighbor stations
|
||||
* that are used to calculate value and distance, which later
|
||||
* on, are used to interpret the HRAP grid
|
||||
*/
|
||||
|
||||
/*
|
||||
* if there is not enough valid neighbor station, such as
|
||||
* usedStationCount < MINIMUM_NEAREST_NEIGHBOR_GAGES the code
|
||||
* below handle this situation. Basically, the code recalculate
|
||||
* the value and distance using all the stations -- see the for
|
||||
* (h = 0; h < max_stations; h++) loop below.
|
||||
*/
|
||||
|
||||
if (usedStationCount < MINIMUM_NEAREST_NEIGHBOR_GAGES) {
|
||||
|
||||
totalWeightedValue = 0.0;
|
||||
totalDistanceWeight = 0.0;
|
||||
usedStationCount = 0;
|
||||
|
||||
for (h = 0; h < numPstations; h++) {
|
||||
|
||||
int gageIndex = h;
|
||||
|
||||
usedStation = processStation(gageIndex, isom, i, j,
|
||||
pcpn_day, pcpn_time, time_pos, method,
|
||||
precip_stations, hrap_grid, pdata, pcp_in_use,
|
||||
true);
|
||||
|
||||
if (usedStation) {
|
||||
usedStationCount++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}/*
|
||||
* end the handling of special case : if (usedStationCount <
|
||||
* MINIMUM_NEAREST_NEIGHBOR_GAGES),
|
||||
*/
|
||||
/* which means there are not enough neighboring stations */
|
||||
|
||||
// found no usable gages
|
||||
if (usedStationCount == 0) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
pcp.value[i][j] = (int) (totalWeightedValue
|
||||
/ totalDistanceWeight * 100.0);
|
||||
}
|
||||
|
||||
if (pcp.value[i][j] < .01) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
|
||||
} // end for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
} // end for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
|
||||
if (pcpn_time_step == 0) {
|
||||
time_pos = pcpn_day * 4 + 3 - pcpn_time;
|
||||
} else {
|
||||
time_pos = 40 + pcpn_day;
|
||||
}
|
||||
// notice that time_pos is a variable defined inside the function, and
|
||||
// its value do not need to be limited as 0,1,2,3,or 4. Here it is
|
||||
// assigned with bigger numbers.
|
||||
// time_pos = 40 + pcpn_day;
|
||||
|
||||
// pcp_in_use[i] = 1 -- grids rendered via Render button OR Save Level2
|
||||
// option
|
||||
// = -1 --grids for this time period not rendered (initialization value)
|
||||
pcp_in_use[time_pos] = 1;
|
||||
|
||||
ReadQPFGrids rqp = new ReadQPFGrids();
|
||||
rqp.write_file("pcp", time_pos, pcp);
|
||||
}
|
||||
|
||||
private boolean processStation(int gageIndex, int isom, int col, int row,
|
||||
int pcpn_day, int pcpn_time, int time_pos, int method,
|
||||
ArrayList<Station> stationList, Hrap_Grid hrap_grid, Pdata[] pdata,
|
||||
int[] pcp_in_use, boolean checkDistance) {
|
||||
boolean usedStation = false;
|
||||
|
||||
Station station = stationList.get(gageIndex);
|
||||
|
||||
float value = pdata[pcpn_day].stn[gageIndex].frain[time_pos].data;
|
||||
|
||||
if (value < 0) {
|
||||
return usedStation;// false
|
||||
}
|
||||
|
||||
int qualityCode = pdata[pcpn_day].stn[gageIndex].frain[time_pos].qual;
|
||||
|
||||
if (qualityCode != 0 && qualityCode != 8 && qualityCode != 6
|
||||
&& qualityCode != 3 && qualityCode != 4 && qualityCode != 2) {
|
||||
return usedStation; // false
|
||||
}
|
||||
|
||||
if (method == 2 && station.isoh[isom] <= 0) {
|
||||
return usedStation; // false
|
||||
}
|
||||
|
||||
/*
|
||||
* determine distance between grid bin and the station in question of
|
||||
* the grid and station in question
|
||||
*/
|
||||
double distanceX = (col + (hrap_grid.hrap_minx - station.hrap_x));
|
||||
double distanceY = (row + (hrap_grid.hrap_miny - station.hrap_y));
|
||||
|
||||
double distanceSquared = (distanceX * distanceX)
|
||||
+ (distanceY * distanceY);
|
||||
|
||||
if (distanceSquared < .00001) {
|
||||
distanceSquared = .00001;
|
||||
}
|
||||
|
||||
if (checkDistance) {
|
||||
if (distanceSquared > maxDistSquared) // too far away, don't use the
|
||||
// station
|
||||
{
|
||||
return usedStation; // false, bail out, don't adjust weight with
|
||||
// this reading
|
||||
}
|
||||
}
|
||||
|
||||
double distanceWeight = 1 / distanceSquared;
|
||||
double weightedValue = value * distanceWeight;
|
||||
|
||||
float prismValue = station.isoh[isom];
|
||||
|
||||
if (method == 2 && prismValue > 0) {
|
||||
weightedValue = weightedValue * hrap_grid.isoh[isom][col][row]
|
||||
/ (prismValue * 25.4);
|
||||
}
|
||||
|
||||
totalWeightedValue += weightedValue;
|
||||
totalDistanceWeight += distanceWeight;
|
||||
|
||||
usedStation = true;
|
||||
return usedStation;
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
/*
|
||||
* get the token value of token mpe_24hr_grid_gen_method. This token will
|
||||
* determine how we generate the 24hr grid. We can either use the 24hr gage
|
||||
* values, which is the old way, or we can use four 6hr gage values and add
|
||||
* them together.
|
||||
*/
|
||||
/* there is some problem with the static */
|
||||
|
||||
/**
|
||||
* @param pcpn_day
|
||||
* @param pcpn_time
|
||||
* @param numPstations
|
||||
* @param precip_stations
|
||||
* @param hrap_grid
|
||||
* @param pdata
|
||||
* @param pcp_in_use
|
||||
*/
|
||||
private void render24hrPcpUsingFour6hr(int pcpn_day, int pcpn_time,
|
||||
int numPstations, ArrayList<Station> precip_stations,
|
||||
Hrap_Grid hrap_grid, Pdata[] pdata, int[] pcp_in_use) {
|
||||
|
||||
int i, j, k, h, hh, time_pos;
|
||||
boolean usedStation = false;
|
||||
int isom = DailyQcUtils.isom;
|
||||
int method = DailyQcUtils.method;
|
||||
int totals[] = new int[5];
|
||||
int all_total = 0;
|
||||
int neighbor_total = 0;
|
||||
|
||||
int usedStationCount;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
totals[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pcpn_time_step is function parameter. It specifies whether to
|
||||
* interpolate 6hr or 24hr HRAP grid
|
||||
*/
|
||||
/*
|
||||
* pcpn_time is a function parameter. It specifies which 6hr HRAP grid
|
||||
* to generate. It takes 0,1,2,or 3 to represent different 6hr period of
|
||||
* a day.
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for 6hr data) or 4 (for
|
||||
* 24hr data). This value is used in
|
||||
* pdata[pcpn_day].stn[hh].frain[time_pos].data to control whether to
|
||||
* retrieve 6hr data or 24hr data.
|
||||
*/
|
||||
|
||||
/* initialization of the pcp.value */
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* begin to interpolate 4 6hr grids. At the end of each iteration, the
|
||||
* calculated interpolation value is added to pcp.value[i][j].
|
||||
*/
|
||||
/*
|
||||
* time_pos is assigned a value of 0,1,2,or 3 (for four 6hr data). This
|
||||
* value is used in pdata[pcpn_day].stn[hh].frain[time_pos].data to
|
||||
* retrieve 6hr data.
|
||||
*/
|
||||
for (k = 0; k < 4; k++) {
|
||||
time_pos = k; /* for 6 hour data: 0, 1,2,3. */
|
||||
|
||||
/* begin to interpolate value for each bin in the HRAP grid */
|
||||
/*
|
||||
* to interpolate, two quantities are needed first: value and
|
||||
* distance. They are calculated by using the neighboring stations.
|
||||
*/
|
||||
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
/*
|
||||
* Check if the grid cell is covered by an HSA. If not, then
|
||||
* do not estimate precipitation for it.
|
||||
*/
|
||||
if (hrap_grid.owner[i][j] == -1) {
|
||||
pcp.value[i][j] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
totalDistanceWeight = 0.0;
|
||||
totalWeightedValue = 0.0;
|
||||
usedStationCount = 0;
|
||||
|
||||
/*
|
||||
* for each neighbor station of the grid bin, do the
|
||||
* following
|
||||
*/
|
||||
int mpe_dqc_max_precip_neighbors = DailyQcUtils.mpe_dqc_max_precip_neighbors;
|
||||
|
||||
for (h = 0; h < mpe_dqc_max_precip_neighbors; h++) {
|
||||
hh = hrap_grid.gage[i][j].index[h];/*
|
||||
* hh is index of
|
||||
* stations
|
||||
*/
|
||||
int gageIndex = hh;
|
||||
|
||||
usedStation = processStation(gageIndex, isom, i, j,
|
||||
pcpn_day, pcpn_time, time_pos, method,
|
||||
precip_stations, hrap_grid, pdata, pcp_in_use,
|
||||
false);
|
||||
|
||||
if (usedStation) {
|
||||
usedStationCount++;
|
||||
}
|
||||
|
||||
if (usedStationCount == SUFFICIENT_NEAREST_NEIGHBOR_GAGES) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (usedStationCount < MINIMUM_NEAREST_NEIGHBOR_GAGES) {
|
||||
|
||||
// not enough gages, so extend search to all gages
|
||||
totalWeightedValue = 0.0;
|
||||
totalDistanceWeight = 0.0;
|
||||
usedStationCount = 0;
|
||||
|
||||
for (h = 0; h < numPstations; h++) {
|
||||
|
||||
int gageIndex = h;
|
||||
|
||||
usedStation = processStation(gageIndex, isom, i, j,
|
||||
pcpn_day, pcpn_time, time_pos, method,
|
||||
precip_stations, hrap_grid, pdata,
|
||||
pcp_in_use, false);
|
||||
|
||||
if (usedStation) {
|
||||
usedStationCount++;
|
||||
}
|
||||
|
||||
}
|
||||
neighbor_total++;
|
||||
}
|
||||
|
||||
if (usedStationCount != 0) {
|
||||
pcp.value[i][j] += (int) ((totalWeightedValue / totalDistanceWeight) * 100);
|
||||
}
|
||||
|
||||
/*
|
||||
* if (pcp.value[i][j] < .01) { pcp.value[i][j] = 0; }
|
||||
*/
|
||||
all_total++;
|
||||
|
||||
} /* end of for loop (j = 0; j < hrap_grid.maxj; j++) */
|
||||
} /* end of for loop (i = 0; i < hrap_grid.maxi; i++) */
|
||||
/* At this moment, the interpretation of HRAP grid is done */
|
||||
|
||||
}/*
|
||||
* end of the ( k = 0; k<4; k++) loop, which interpolates 4 6hr HRAP
|
||||
* grid.
|
||||
*/
|
||||
|
||||
/* final adjustment of the pcp.value */
|
||||
for (i = 0; i < hrap_grid.maxi; i++) {
|
||||
for (j = 0; j < hrap_grid.maxj; j++) {
|
||||
|
||||
if (pcp.value[i][j] < .01) { // this doesn't really make sense,
|
||||
// since this is an integer
|
||||
pcp.value[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* time_pos = pcpn_day * 4 + 3 - pcpn_time; */
|
||||
time_pos = 40 + pcpn_day;
|
||||
|
||||
/*
|
||||
* pcp_in_use[i] = 1 -- grids rendered via Render button OR Save Level2
|
||||
* option = -1 --grids for this time period not rendered (initialization
|
||||
* value)
|
||||
*/
|
||||
pcp_in_use[time_pos] = 1;
|
||||
|
||||
/*
|
||||
* results of grid rendering routines (render_t, render_t6, render_pcp,
|
||||
* render_z) are written to scratch files using the write_file routine.
|
||||
* scratch file is stored in the scratch directory.
|
||||
*/
|
||||
ReadQPFGrids rqp = new ReadQPFGrids();
|
||||
rqp.write_file("pcp", time_pos, pcp);
|
||||
|
||||
} // end render24hrPcpUsingFour6hr()
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
int getTokenValue24hrGridGenMeth() {
|
||||
|
||||
int token_of_24hr_grid_gen_method = 0;
|
||||
|
||||
if (first == true) {
|
||||
String tokenName = "mpe_dqc_24hr_precip_grid_meth";
|
||||
|
||||
String dqc24hrPrecipMeth;
|
||||
|
||||
// char message[GAGEQC_MESSAGE_LEN] = { '\0' };
|
||||
|
||||
AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
dqc24hrPrecipMeth = appsDefaults.getToken(tokenName);
|
||||
|
||||
if (dqc24hrPrecipMeth != null) {
|
||||
/* allowed token values: (ACCUM_6HR, USE_24HR) */
|
||||
if (dqc24hrPrecipMeth.equalsIgnoreCase("ACCUM_6HR")) {
|
||||
token_of_24hr_grid_gen_method = 1;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
return token_of_24hr_grid_gen_method;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
}
|
|
@ -25,7 +25,8 @@ Require-Bundle: org.eclipse.ui,
|
|||
com.raytheon.uf.common.dataplugin.radar;bundle-version="1.0.0",
|
||||
org.apache.commons.logging,
|
||||
com.raytheon.uf.viz.localization,
|
||||
com.raytheon.uf.common.auth;bundle-version="1.12.1174"
|
||||
com.raytheon.uf.common.auth;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.dataplugin.warning;bundle-version="1.12.1174"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.raytheon.viz.texteditor,
|
||||
com.raytheon.viz.texteditor.alarmalert.dialogs,
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
* 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.texteditor.dialogs;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.GetActiveTableRequest;
|
||||
import com.raytheon.uf.common.activetable.GetActiveTableResponse;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
import com.raytheon.viz.texteditor.util.VtecObject;
|
||||
import com.raytheon.viz.texteditor.util.VtecUtil;
|
||||
|
||||
/**
|
||||
* Produces the product message and mode message for the warngen confirmation
|
||||
* dialog for emergency warnings.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 23, 2013 2176 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class EmergencyConfirmationMsg implements IWarnGenConfirmationable {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(EmergencyConfirmationMsg.class);
|
||||
|
||||
private String productMessage;
|
||||
|
||||
private static class EmergencyType {
|
||||
|
||||
private static final EmergencyType TORNADO = new EmergencyType(
|
||||
"TORNADO EMERGENCY", "TO.W");
|
||||
|
||||
private static final EmergencyType FLASH_FLOOD = new EmergencyType(
|
||||
"FLASH FLOOD EMERGENCY", "FF.W");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String phensig;
|
||||
|
||||
private final static EmergencyType[] values = new EmergencyType[] {
|
||||
TORNADO, FLASH_FLOOD };
|
||||
|
||||
private EmergencyType(String type, String phensig) {
|
||||
this.value = type;
|
||||
this.phensig = phensig;
|
||||
}
|
||||
|
||||
public static EmergencyType valueOf(String phensig) {
|
||||
EmergencyType type = null;
|
||||
for (EmergencyType t : values) {
|
||||
if (t.phensig.equals(phensig)) {
|
||||
type = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Orders the ActiveTableRecord based on the issue time (ascending)
|
||||
*/
|
||||
private class ActiveTableRecordComparator implements
|
||||
Comparator<ActiveTableRecord> {
|
||||
|
||||
@Override
|
||||
public int compare(ActiveTableRecord o1, ActiveTableRecord o2) {
|
||||
return o1.getIssueTime().compareTo(o2.getIssueTime());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkWarningInfo(String header, String body, String nnn) {
|
||||
VtecObject vtec = VtecUtil.parseMessage(body);
|
||||
EmergencyType type = null;
|
||||
WarningAction action = null;
|
||||
if (vtec != null) {
|
||||
type = EmergencyType.valueOf(vtec.getPhensig());
|
||||
action = WarningAction.valueOf(vtec.getAction());
|
||||
if (action == WarningAction.CAN && body.split("\\$\\$").length > 2) {
|
||||
// It is possible for a warning products to have two segments: a
|
||||
// CAN and a CON.'$$' denotes the end of one segment. VtecUtil
|
||||
// only grabs the first VTEC. If there are multiple segments CAN
|
||||
// should always be the first VTEC
|
||||
action = WarningAction.CANCON;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the warning product is a valid EmergencyType.
|
||||
if (type != null) {
|
||||
boolean currentEmergency = body.contains("EMERGENCY");
|
||||
if (action == WarningAction.NEW && currentEmergency) {
|
||||
// Only occurs when the warning is first issued and not any
|
||||
// other action
|
||||
productMessage = "This is a " + type.value;
|
||||
} else if (action == WarningAction.CON
|
||||
|| action == WarningAction.EXT
|
||||
|| action == WarningAction.CANCON) {
|
||||
// Check if the warning was an upgrade or downgrade in the
|
||||
// emergency warning for continuation, extension (FFW), or a
|
||||
// cancel
|
||||
// and continuation.
|
||||
GetActiveTableRequest request = new GetActiveTableRequest();
|
||||
if (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) {
|
||||
request.setMode(ActiveTableMode.PRACTICE);
|
||||
} else {
|
||||
request.setMode(ActiveTableMode.OPERATIONAL);
|
||||
}
|
||||
request.setSiteID(vtec.getOffice());
|
||||
request.setPhensigList(vtec.getPhensig());
|
||||
request.setEtn(String.format("%04d", vtec.getSequence()));
|
||||
try {
|
||||
GetActiveTableResponse response = (GetActiveTableResponse) ThriftClient
|
||||
.sendRequest(request);
|
||||
List<ActiveTableRecord> records = response.getActiveTable();
|
||||
// There should be existing records since this is for follow
|
||||
// ups. This is just a precaution
|
||||
if (records != null && !records.isEmpty()) {
|
||||
// Get latest active table record
|
||||
Collections.sort(records,
|
||||
new ActiveTableRecordComparator());
|
||||
ActiveTableRecord record = records
|
||||
.get(records.size() - 1);
|
||||
boolean wasEmergency = record.getRawmessage().contains(
|
||||
"EMERGENCY");
|
||||
if (!wasEmergency && currentEmergency) {
|
||||
productMessage = "This is an upgrade of a "
|
||||
+ type.value;
|
||||
} else if (wasEmergency && !currentEmergency) {
|
||||
productMessage = "This is a downgrade of a "
|
||||
+ type.value;
|
||||
}
|
||||
}
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error making request to active table.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return productMessage == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Severe Weather Product";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProductMessage() {
|
||||
return productMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModeMessage() {
|
||||
return "Should we proceed?\n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.texteditor.dialogs;
|
||||
|
||||
/**
|
||||
* Interface to retrieve the WarnGen Confirmation Dialog message values.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 23, 2013 2176 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface IWarnGenConfirmationable {
|
||||
/**
|
||||
* Returns true if the WarnGen Confirmation Dialog needs to pop-up.
|
||||
*
|
||||
* @param header
|
||||
* @param body
|
||||
* @param nnn
|
||||
* @return
|
||||
*/
|
||||
public boolean checkWarningInfo(String header, String body, String nnn);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the title for the WarnGen Confirmation Dialog
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the product message in the WarnGen Confirmation Dialog
|
||||
*/
|
||||
public String getProductMessage();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the mode message in the WarnGen Confirmation Dialog
|
||||
*/
|
||||
public String getModeMessage();
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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.texteditor.dialogs;
|
||||
|
||||
import com.raytheon.viz.texteditor.qc.QualityControl;
|
||||
|
||||
/**
|
||||
* Produces the product message and mode message for the warngen confirmation
|
||||
* dialog for warnings failing QC.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 23, 2013 2176 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class QCConfirmationMsg implements IWarnGenConfirmationable {
|
||||
|
||||
private QualityControl qcCheck = new QualityControl();
|
||||
|
||||
@Override
|
||||
public boolean checkWarningInfo(String header, String body, String nnn) {
|
||||
return qcCheck.checkWarningInfo(header, body, nnn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Problem Detected by QC";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProductMessage() {
|
||||
return qcCheck.getErrorMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModeMessage() {
|
||||
return "Do you really want to Send?\n";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* 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.texteditor.dialogs;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
import com.raytheon.viz.texteditor.qc.QualityControl;
|
||||
|
||||
/**
|
||||
* Produces the product message and mode message for the warngen confirmation
|
||||
* dialog for sending a warning.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 23, 2013 2176 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class SendConfirmationMsg implements IWarnGenConfirmationable {
|
||||
|
||||
private String title;
|
||||
|
||||
private boolean resend;
|
||||
|
||||
private String afosId;
|
||||
|
||||
public SendConfirmationMsg(boolean resend, String afosId, String nnn) {
|
||||
this.resend = resend;
|
||||
this.afosId = afosId;
|
||||
title = QualityControl.getProductWarningType(nnn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkWarningInfo(String header, String body, String nnn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProductMessage() {
|
||||
StringBuilder productMessage = new StringBuilder();
|
||||
if (resend) {
|
||||
productMessage.append("You are about to RESEND a " + afosId + "\n");
|
||||
productMessage.append(title).append(".\n");
|
||||
} else {
|
||||
productMessage.append("You are about to SEND a " + afosId + "\n");
|
||||
productMessage.append(title).append(".\n");
|
||||
}
|
||||
return productMessage.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModeMessage() {
|
||||
CAVEMode mode = CAVEMode.getMode();
|
||||
StringBuilder modeMessage = new StringBuilder();
|
||||
modeMessage.append("The workstation is in ").append(mode)
|
||||
.append(" mode.");
|
||||
if (resend) {
|
||||
modeMessage.append("\nThere is no QC check for resend product.");
|
||||
}
|
||||
|
||||
Pattern p = Pattern.compile(".\\%[s].");
|
||||
Matcher m = p.matcher(TextEditorDialog.STORED_SENT_MSG);
|
||||
boolean result = (CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
||||
.equals(mode));
|
||||
modeMessage.append(result ? m.replaceAll(" ") : m.replaceAll(" not "));
|
||||
|
||||
return modeMessage.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -85,8 +85,8 @@ import org.eclipse.swt.events.ShellAdapter;
|
|||
import org.eclipse.swt.events.ShellEvent;
|
||||
import org.eclipse.swt.events.VerifyEvent;
|
||||
import org.eclipse.swt.events.VerifyListener;
|
||||
import org.eclipse.swt.graphics.Cursor;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Cursor;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.FontMetrics;
|
||||
|
@ -100,7 +100,6 @@ import org.eclipse.swt.layout.RowLayout;
|
|||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
|
@ -142,7 +141,6 @@ import com.raytheon.uf.common.time.SimulatedTime;
|
|||
import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||
import com.raytheon.uf.edex.services.textdbsrv.IQueryTransport;
|
||||
import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
||||
// import com.raytheon.uf.viz.core.RGBColors;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.auth.UserController;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
@ -176,7 +174,6 @@ import com.raytheon.viz.texteditor.msgs.ITextEditorCallback;
|
|||
import com.raytheon.viz.texteditor.msgs.IWmoBrowserCallback;
|
||||
import com.raytheon.viz.texteditor.notify.NotifyExpiration;
|
||||
import com.raytheon.viz.texteditor.print.PrintDisplay;
|
||||
import com.raytheon.viz.texteditor.qc.QualityControl;
|
||||
import com.raytheon.viz.texteditor.scripting.dialogs.IScriptEditor;
|
||||
import com.raytheon.viz.texteditor.scripting.dialogs.IScriptEditorObserver;
|
||||
import com.raytheon.viz.texteditor.scripting.dialogs.ScriptEditorDialog;
|
||||
|
@ -191,6 +188,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||
import com.raytheon.viz.ui.dialogs.SWTMessageBox;
|
||||
|
||||
// import com.raytheon.uf.viz.core.RGBColors;
|
||||
|
||||
/**
|
||||
* Main Text Editor dialog.
|
||||
*
|
||||
|
@ -328,6 +327,7 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox;
|
|||
* *.xml files in localization;
|
||||
* add selection listener to catch the highlight words and
|
||||
* set the highlight colors.
|
||||
* 23Jul2013 2176 jsanchez Added a new confirmation message for emergency warnings.
|
||||
* 25July2013 15733 GHull Read font and color prefs from TextEditorCfg.
|
||||
* 23Aug2013 DR 16514 D. Friedman Fix handling of completed product requests. Do not change
|
||||
* command history or close browser window for "update obs".
|
||||
|
@ -378,9 +378,9 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* System colro to use for foreground color when an obs is updated.
|
||||
*/
|
||||
private static final int UPDATE_FG = SWT.COLOR_WHITE;
|
||||
|
||||
|
||||
private final int HIGHLIGHT_BG = SWT.COLOR_RED;
|
||||
|
||||
|
||||
/**
|
||||
* The length of BEGIN_ELEMENT_TAG.
|
||||
*/
|
||||
|
@ -791,19 +791,19 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
/**
|
||||
* Small font menu item.
|
||||
*/
|
||||
// private MenuItem smallFontItem;
|
||||
// private MenuItem smallFontItem;
|
||||
|
||||
/**
|
||||
* Medium font menu item.
|
||||
*/
|
||||
// private MenuItem mediumFontItem;
|
||||
// private MenuItem mediumFontItem;
|
||||
|
||||
/**
|
||||
* Large font menu item.
|
||||
*/
|
||||
// private MenuItem largeFontItem;
|
||||
// private MenuItem largeFontItem;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Overstrike (overwrite) menu item.
|
||||
*/
|
||||
private MenuItem overStrikeItem;
|
||||
|
@ -1017,12 +1017,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* Styled text editor.
|
||||
*/
|
||||
private StyledText textEditor;
|
||||
|
||||
|
||||
/**
|
||||
* default font
|
||||
*/
|
||||
private Font dftFont;
|
||||
|
||||
|
||||
/**
|
||||
* Composite containing the editor buttons.
|
||||
*/
|
||||
|
@ -1289,12 +1289,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
*/
|
||||
private static final String[] popupItems = { "Select All", "Cut", "Copy",
|
||||
"Paste" };
|
||||
|
||||
|
||||
/**
|
||||
* Currently active popupItems.
|
||||
*/
|
||||
private static final boolean[] isPopItemDefault = { true, false, true,
|
||||
false };
|
||||
false };
|
||||
|
||||
/**
|
||||
* Indictes this instance of dialog if for a warnGen.
|
||||
|
@ -1372,14 +1372,16 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* needs to be done.
|
||||
*/
|
||||
private boolean isPreviousLineWrapped;
|
||||
|
||||
|
||||
private Color textForeground;
|
||||
|
||||
private Color textBackground;
|
||||
|
||||
private Color highlightForeground;
|
||||
|
||||
private Color highlightBackground;
|
||||
|
||||
// protected Color color;
|
||||
|
||||
// protected Color color;
|
||||
|
||||
/**
|
||||
* Constructor with additional cave style rules
|
||||
|
@ -2041,7 +2043,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
Menu fontSizeSubMenu = new Menu(shell, SWT.DROP_DOWN);
|
||||
fontSizeMenuItem.setMenu(fontSizeSubMenu);
|
||||
createFontSizeSubMenu(fontSizeSubMenu);
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// Create overstrike menu item
|
||||
// ------------------------------
|
||||
|
@ -2862,7 +2864,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
private void createAutoWrapSubMenu(Menu autoWrapSubMenu) {
|
||||
AutoWrapCfg autoWrapcfg = getAutoWrapCfg();
|
||||
for (WrapButtonCfg buttonCfg : autoWrapcfg.getButtons()) {
|
||||
MenuItem item = new MenuItem(autoWrapSubMenu, SWT.RADIO);
|
||||
MenuItem item = new MenuItem(autoWrapSubMenu, SWT.RADIO);
|
||||
item.setText(buttonCfg.getLabelName());
|
||||
item.setSelection(buttonCfg.isSelected());
|
||||
item.setData(buttonCfg);
|
||||
|
@ -2950,11 +2952,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* The font size sub menu.
|
||||
*/
|
||||
private void createFontSizeSubMenu(Menu fontSizeSubMenu) {
|
||||
|
||||
FontSizeCfg fontSizeCfg = TextEditorCfg.getTextEditorCfg().getFontSizeCfg();
|
||||
SizeButtonCfg seldFontBtn = TextEditorCfg.getTextEditorCfg().getSelectedFontButton();
|
||||
|
||||
for (SizeButtonCfg buttonCfg : fontSizeCfg.getButtons()) {
|
||||
|
||||
FontSizeCfg fontSizeCfg = TextEditorCfg.getTextEditorCfg().getFontSizeCfg();
|
||||
SizeButtonCfg seldFontBtn = TextEditorCfg.getTextEditorCfg().getSelectedFontButton();
|
||||
|
||||
for (SizeButtonCfg buttonCfg : fontSizeCfg.getButtons()) {
|
||||
MenuItem item = new MenuItem(fontSizeSubMenu, SWT.RADIO);
|
||||
item.setText(buttonCfg.getLabelName());
|
||||
item.setSelection( false );
|
||||
|
@ -2962,33 +2964,33 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
|
||||
// if this button is the initial selection.
|
||||
if( seldFontBtn.getLabelName().equals( buttonCfg.getLabelName() ) ) {
|
||||
item.setSelection(true);
|
||||
item.setSelection(true);
|
||||
setDefaultFont( seldFontBtn.getFontSize(), seldFontBtn.getFontName() );
|
||||
}
|
||||
|
||||
|
||||
item.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
MenuItem item = (MenuItem) event.getSource();
|
||||
if (item.getSelection()) {
|
||||
int selectFontSize = ( (SizeButtonCfg) item.getData()).getFontSize();
|
||||
MenuItem item = (MenuItem) event.getSource();
|
||||
if (item.getSelection()) {
|
||||
int selectFontSize = ( (SizeButtonCfg) item.getData()).getFontSize();
|
||||
String seldFontName = ((SizeButtonCfg) item.getData()).getFontName();
|
||||
|
||||
setDefaultFont( selectFontSize, seldFontName );
|
||||
|
||||
textEditor.setFont(dftFont);
|
||||
headerTF.setFont(dftFont);
|
||||
}
|
||||
|
||||
textEditor.setFont(dftFont);
|
||||
headerTF.setFont(dftFont);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setDefaultFont( int fontSize, String fontName ) {
|
||||
dftFont = new Font( getDisplay(), fontName, fontSize, SWT.NORMAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the components and put them on the display.
|
||||
*/
|
||||
|
@ -3029,7 +3031,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
displayAfosBrowser();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Add the Load History button.
|
||||
rd = new RowData(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||
loadHistoryBtn = new Button(topBtnRowComp, SWT.PUSH);
|
||||
|
@ -3554,7 +3556,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
headerTF = new Text(headerTFComp, SWT.BORDER | SWT.MULTI
|
||||
| SWT.READ_ONLY);
|
||||
headerTF.setLayoutData(gd);
|
||||
|
||||
|
||||
headerTF.setFont(dftFont);
|
||||
headerTF.setEditable(false);
|
||||
|
||||
|
@ -3722,7 +3724,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
textEditorComp = new Composite(shell, SWT.NONE);
|
||||
GridLayout gridLayout = new GridLayout(1, false);
|
||||
// TextColorsCfg textColorCfg = null;
|
||||
|
||||
|
||||
textEditorComp.setLayout(gridLayout);
|
||||
textEditorComp.setLayoutData(gd);
|
||||
|
||||
|
@ -3742,31 +3744,32 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
textEditor.setEditable(false);
|
||||
airportToolTip = new DefaultToolTip(textEditor, SWT.DEFAULT, true);
|
||||
textEditor.setKeyBinding(SWT.INSERT, SWT.NULL); // DR 7826
|
||||
|
||||
|
||||
// textColorCfg = getTextColorCfg();
|
||||
setDefaultTextColor( TextEditorCfg.getTextEditorCfg() );
|
||||
textEditor.setForeground(textForeground);
|
||||
textEditor.setBackground(textBackground);
|
||||
|
||||
|
||||
textEditor.addSelectionListener(new SelectionListener() {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
System.out.println("\ntextEditor default selection event --" + e.toString());
|
||||
System.out.println("\ntextEditor default selection event --"
|
||||
+ e.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
|
||||
StyledText stylText = (StyledText) e.getSource();
|
||||
|
||||
// String slctText = stylText.getSelectionText();
|
||||
// int length = slctText.length();
|
||||
|
||||
stylText.setSelectionBackground(highlightBackground);
|
||||
stylText.setSelectionForeground(highlightForeground);
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
|
||||
StyledText stylText = (StyledText) e.getSource();
|
||||
|
||||
// String slctText = stylText.getSelectionText();
|
||||
// int length = slctText.length();
|
||||
|
||||
stylText.setSelectionBackground(highlightBackground);
|
||||
stylText.setSelectionForeground(highlightForeground);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
textEditor.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
|
@ -3832,8 +3835,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
public void verifyKey(VerifyEvent event) {
|
||||
// Ignore edit keys when not in edit mode.
|
||||
if (textEditor.getEditable() == false) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (event.keyCode == SWT.DEL || event.keyCode == SWT.BS
|
||||
|| event.keyCode == SWT.SHIFT) {
|
||||
// Do nothing...
|
||||
|
@ -3933,7 +3936,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
}
|
||||
|
||||
if (e.button == 3) {
|
||||
processPopup();
|
||||
processPopup();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3973,6 +3976,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
//
|
||||
// return textColorsCfg;
|
||||
// }
|
||||
|
||||
|
||||
private void setDefaultTextColor(TextEditorCfg txtClrCfg ) {
|
||||
|
||||
|
@ -3981,52 +3985,52 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
highlightBackground = new Color(shell.getDisplay(), txtClrCfg.getHighlightTextBackgroundColor() );
|
||||
highlightForeground = new Color(shell.getDisplay(), txtClrCfg.getHighlightTextForegroundColor() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the user choice from the popup list. DR14842 - re-written
|
||||
*/
|
||||
private void processPopup() {
|
||||
Menu menu = new Menu(shell, SWT.POP_UP);
|
||||
List<String> items = Arrays.asList(popupItems);
|
||||
for (String pi : popupItems) {
|
||||
MenuItem mi = new MenuItem(menu, SWT.PUSH);
|
||||
mi.setText(pi);
|
||||
if (isEditMode()) {
|
||||
mi.setEnabled(true);
|
||||
} else {
|
||||
mi.setEnabled(isPopItemDefault[items.indexOf(pi)]);
|
||||
}
|
||||
mi.addListener(SWT.Selection, new Listener() {
|
||||
private void processPopup() {
|
||||
Menu menu = new Menu(shell, SWT.POP_UP);
|
||||
List<String> items = Arrays.asList(popupItems);
|
||||
for (String pi : popupItems) {
|
||||
MenuItem mi = new MenuItem(menu, SWT.PUSH);
|
||||
mi.setText(pi);
|
||||
if (isEditMode()) {
|
||||
mi.setEnabled(true);
|
||||
} else {
|
||||
mi.setEnabled(isPopItemDefault[items.indexOf(pi)]);
|
||||
}
|
||||
mi.addListener(SWT.Selection, new Listener() {
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
handleSelection(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
menu.setVisible(true);
|
||||
}
|
||||
|
||||
public void handleEvent(Event event) {
|
||||
handleSelection(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
menu.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the selection from the popup menu
|
||||
* Handle the selection from the popup menu
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
protected void handleSelection(Event event) {
|
||||
MenuItem item = (MenuItem) event.widget;
|
||||
String choice = item.getText();
|
||||
if (choice != null) {
|
||||
if (popupItems[0].equals(choice)) {
|
||||
textEditor.selectAll();
|
||||
} else if (popupItems[1].equals(choice)) {
|
||||
cutText();
|
||||
} else if (popupItems[2].equals(choice)) {
|
||||
copyText();
|
||||
} else if (popupItems[3].equals(choice)) {
|
||||
pasteText();
|
||||
}
|
||||
textEditor.update();
|
||||
}
|
||||
}
|
||||
protected void handleSelection(Event event) {
|
||||
MenuItem item = (MenuItem) event.widget;
|
||||
String choice = item.getText();
|
||||
if (choice != null) {
|
||||
if (popupItems[0].equals(choice)) {
|
||||
textEditor.selectAll();
|
||||
} else if (popupItems[1].equals(choice)) {
|
||||
cutText();
|
||||
} else if (popupItems[2].equals(choice)) {
|
||||
copyText();
|
||||
} else if (popupItems[3].equals(choice)) {
|
||||
pasteText();
|
||||
}
|
||||
textEditor.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the bar containing the script runner controls.
|
||||
|
@ -4841,47 +4845,31 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* true if product is to be resent
|
||||
*/
|
||||
synchronized private void sendProduct(final boolean resend) {
|
||||
final CAVEMode mode = CAVEMode.getMode();
|
||||
StdTextProduct prod = getStdTextProduct();
|
||||
String afosId = prod.getCccid() + prod.getNnnid() + prod.getXxxid();
|
||||
final String title = QualityControl.getProductWarningType(prod
|
||||
.getNnnid());
|
||||
final StringBuilder productMessage = new StringBuilder();
|
||||
|
||||
final StringBuilder modeMessage = new StringBuilder();
|
||||
modeMessage.append("The workstation is in ").append(mode)
|
||||
.append(" mode.");
|
||||
|
||||
if (resend) {
|
||||
productMessage.append("You are about to RESEND a " + afosId + "\n");
|
||||
productMessage.append(title).append(".\n");
|
||||
modeMessage.append("\nThere is no QC check for resend product.");
|
||||
} else if (warnGenFlag) {
|
||||
productMessage.append("You are about to SEND a " + afosId + "\n");
|
||||
productMessage.append(title).append(".\n");
|
||||
|
||||
QualityControl qcCheck = new QualityControl();
|
||||
if (qcCheck.checkWarningInfo(headerTF.getText().toUpperCase(),
|
||||
textEditor.getText().toUpperCase(), prod.getNnnid()) == false) {
|
||||
if (warnGenFlag) {
|
||||
QCConfirmationMsg qcMsg = new QCConfirmationMsg();
|
||||
if (!qcMsg.checkWarningInfo(headerTF.getText().toUpperCase(),
|
||||
textEditor.getText().toUpperCase(), prod.getNnnid())) {
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell,
|
||||
"Problem Detected by QC", qcCheck.getErrorMessage(),
|
||||
"Do you really want to Send?\n", mode);
|
||||
qcMsg.getTitle(), qcMsg.getProductMessage(),
|
||||
qcMsg.getModeMessage());
|
||||
wgcd.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
@Override
|
||||
public void dialogClosed(Object returnValue) {
|
||||
if (Boolean.TRUE.equals(returnValue))
|
||||
finishSendProduct(resend, title, mode,
|
||||
productMessage, modeMessage);
|
||||
if (Boolean.TRUE.equals(returnValue)) {
|
||||
checkEmergencyProduct(resend);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
wgcd.open();
|
||||
|
||||
return;
|
||||
} else {
|
||||
checkEmergencyProduct(resend);
|
||||
}
|
||||
} else {
|
||||
finishSendProduct(resend);
|
||||
}
|
||||
finishSendProduct(resend, title, mode, productMessage, modeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4890,21 +4878,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* the WarnGen being sent.
|
||||
*
|
||||
* @param resend
|
||||
* @param title
|
||||
* @param mode
|
||||
* @param productMessage
|
||||
* @param modeMessage
|
||||
*/
|
||||
private void finishSendProduct(final boolean resend, String title,
|
||||
CAVEMode mode, StringBuilder productMessage,
|
||||
StringBuilder modeMessage) {
|
||||
Pattern p = Pattern.compile(".\\%[s].");
|
||||
Matcher m = p.matcher(STORED_SENT_MSG);
|
||||
|
||||
final boolean result = (CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
||||
.equals(mode));
|
||||
modeMessage.append(result ? m.replaceAll(" ") : m.replaceAll(" not "));
|
||||
|
||||
private void finishSendProduct(final boolean resend) {
|
||||
if (statusBarLabel.getText().startsWith("Attachment:")) {
|
||||
StringBuilder sb = new StringBuilder("An Attachment file (");
|
||||
int startIndex = "Attachment:".length() + 1;
|
||||
|
@ -4927,21 +4902,58 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
if (!verifyRequiredFields()) {
|
||||
return;
|
||||
}
|
||||
StdTextProduct prod = getStdTextProduct();
|
||||
String afosId = prod.getCccid() + prod.getNnnid() + prod.getXxxid();
|
||||
SendConfirmationMsg sendMsg = new SendConfirmationMsg(resend, afosId,
|
||||
prod.getNnnid());
|
||||
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell, title,
|
||||
productMessage.toString(), modeMessage.toString(), mode);
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell,
|
||||
sendMsg.getTitle(), sendMsg.getProductMessage(),
|
||||
sendMsg.getModeMessage());
|
||||
wgcd.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
@Override
|
||||
public void dialogClosed(Object returnValue) {
|
||||
if (Boolean.TRUE.equals(returnValue)) {
|
||||
warngenCloseCallback(resend, result);
|
||||
warngenCloseCallback(resend);
|
||||
}
|
||||
}
|
||||
});
|
||||
wgcd.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the product is a emergency warning product and opens up the
|
||||
* WarnGen Confirmation Dialog if necessary.
|
||||
*
|
||||
* @param resend
|
||||
* true if product is to be resent
|
||||
*/
|
||||
private void checkEmergencyProduct(final boolean resend) {
|
||||
StdTextProduct prod = getStdTextProduct();
|
||||
EmergencyConfirmationMsg emergencyMsg = new EmergencyConfirmationMsg();
|
||||
if (emergencyMsg.checkWarningInfo(headerTF.getText().toUpperCase(),
|
||||
textEditor.getText().toUpperCase(), prod.getNnnid()) == false) {
|
||||
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell,
|
||||
emergencyMsg.getTitle(), emergencyMsg.getProductMessage(),
|
||||
emergencyMsg.getModeMessage());
|
||||
wgcd.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
@Override
|
||||
public void dialogClosed(Object returnValue) {
|
||||
if (Boolean.TRUE.equals(returnValue)) {
|
||||
finishSendProduct(resend);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
wgcd.open();
|
||||
} else {
|
||||
finishSendProduct(resend);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by finishedSendProduct as the call back to the warnGen
|
||||
* confirmaiton Dialog.
|
||||
|
@ -4949,10 +4961,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
* @param resend
|
||||
* @param result
|
||||
*/
|
||||
private void warngenCloseCallback(boolean resend, boolean isOperational) {
|
||||
private void warngenCloseCallback(boolean resend) {
|
||||
|
||||
// DR14553 (make upper case in product)
|
||||
String body = textEditor.getText().toUpperCase();
|
||||
CAVEMode mode = CAVEMode.getMode();
|
||||
boolean isOperational = (CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
||||
.equals(mode));
|
||||
if (isOperational) {
|
||||
removeOptionalFields();
|
||||
|
||||
|
@ -5605,93 +5620,94 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
textEditor.setText("");
|
||||
}
|
||||
} else {
|
||||
// TODO FIX PARSING
|
||||
// TODO FIX PARSING
|
||||
|
||||
// First, set the current header by assuming that it usually
|
||||
// consists of the first two lines of text in the text product,
|
||||
// though there will be exceptions to that "rule" as handled below.
|
||||
// So, obtain the AFOS NNNxxx. If it's where it is supposed to be
|
||||
// in the new format, then the existing header is already an AWIPS
|
||||
// First, set the current header by assuming that it usually
|
||||
// consists of the first two lines of text in the text product,
|
||||
// though there will be exceptions to that "rule" as handled below.
|
||||
// So, obtain the AFOS NNNxxx. If it's where it is supposed to be
|
||||
// in the new format, then the existing header is already an AWIPS
|
||||
// text product identifier. Otherwise it is a legacy AFOS
|
||||
// identifier.
|
||||
if (TextDisplayModel.getInstance().hasStdTextProduct(token)) {
|
||||
StdTextProduct textProd = TextDisplayModel.getInstance()
|
||||
.getStdTextProduct(token);
|
||||
StdTextProductId prodId = textProd.getProdId();
|
||||
try {
|
||||
// start of second line of text
|
||||
start = textEditor.getOffsetAtLine(thisLine + 1);
|
||||
if ((textEditor.getText(start, start + afosNnnLimit)
|
||||
.equals(prodId.getNnnid()))
|
||||
if (TextDisplayModel.getInstance().hasStdTextProduct(token)) {
|
||||
StdTextProduct textProd = TextDisplayModel.getInstance()
|
||||
.getStdTextProduct(token);
|
||||
StdTextProductId prodId = textProd.getProdId();
|
||||
try {
|
||||
// start of second line of text
|
||||
start = textEditor.getOffsetAtLine(thisLine + 1);
|
||||
if ((textEditor.getText(start, start + afosNnnLimit)
|
||||
.equals(prodId.getNnnid()))
|
||||
&& (textEditor.getText(start + afosNnnLimit + 1,
|
||||
start + afosXxxLimit).equals(prodId
|
||||
.getXxxid()))) {
|
||||
// Text matches the products nnnid and xxxid
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
// Text matches the products nnnid and xxxid
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else if (textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals(
|
||||
AFOSParser.DRAFT_PIL)
|
||||
|| textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals("TTAA0")) {
|
||||
// Text matches temporary WRKWG#
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else {
|
||||
// Text matches temporary WRKWG#
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else {
|
||||
// Assume this header block is a legacy AFOS identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Assume this header block is a legacy AFOS identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Assume this header block is a legacy AFOS identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
start = 0;
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText) - 1;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// The text does not span enough lines so use the full extent
|
||||
// of the product.
|
||||
finish = textEditor.getCharCount() - 1;
|
||||
}
|
||||
try {
|
||||
start = 0;
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText) - 1;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// The text does not span enough lines so use the full extent
|
||||
// of the product.
|
||||
finish = textEditor.getCharCount() - 1;
|
||||
}
|
||||
|
||||
// Set the content of the header block to consist of just the header of
|
||||
// the text product... it will get reunited with the body when it is
|
||||
// saved.
|
||||
if (finish > start) {
|
||||
headerTF.setText(textEditor.getText(start, finish));
|
||||
} else {
|
||||
headerTF.setText("");
|
||||
}
|
||||
// Set the content of the header block to consist of just the header
|
||||
// of
|
||||
// the text product... it will get reunited with the body when it is
|
||||
// saved.
|
||||
if (finish > start) {
|
||||
headerTF.setText(textEditor.getText(start, finish));
|
||||
} else {
|
||||
headerTF.setText("");
|
||||
}
|
||||
|
||||
// Next, set the current body by assuming that it always
|
||||
// consists of the rest of the text product beyond the line(s)
|
||||
// of text in the header.
|
||||
try {
|
||||
int numberOfBlankLines = -1;
|
||||
String line = null;
|
||||
do {
|
||||
numberOfBlankLines++;
|
||||
// Next, set the current body by assuming that it always
|
||||
// consists of the rest of the text product beyond the line(s)
|
||||
// of text in the header.
|
||||
try {
|
||||
int numberOfBlankLines = -1;
|
||||
String line = null;
|
||||
do {
|
||||
numberOfBlankLines++;
|
||||
line = textEditor.getLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
} while (line.length() == 0 || line.equals(""));
|
||||
// Note: 'st' is a reference to 'textEditor'...
|
||||
// delelete the header from the text in 'textEditor'
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
textEditor.setSelection(start, finish);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.invokeAction(SWT.DEL);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
} while (line.length() == 0 || line.equals(""));
|
||||
// Note: 'st' is a reference to 'textEditor'...
|
||||
// delelete the header from the text in 'textEditor'
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
textEditor.setSelection(start, finish);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.invokeAction(SWT.DEL);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
}
|
||||
// set editor status flags
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the editor's header text field.
|
||||
*
|
||||
|
@ -5901,9 +5917,9 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
statusBarLabel.update();
|
||||
setBusy(true);
|
||||
|
||||
if (queryTransport == null) {
|
||||
queryTransport = TextEditorUtil.getTextDbsrvTransport();
|
||||
}
|
||||
if (queryTransport == null) {
|
||||
queryTransport = TextEditorUtil.getTextDbsrvTransport();
|
||||
}
|
||||
productQueryJob.addRequest(command, isObsUpdated,
|
||||
accumChkBtn.getSelection());
|
||||
}
|
||||
|
@ -7588,9 +7604,9 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
protected void disposed() {
|
||||
textEditor.setFont(shell.getFont());
|
||||
headerTF.setFont(shell.getFont());
|
||||
|
||||
|
||||
if (dftFont != null) {
|
||||
dftFont.dispose();
|
||||
dftFont.dispose();
|
||||
}
|
||||
|
||||
if (clipboard != null) {
|
||||
|
@ -8182,7 +8198,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
private void displayAirportTooltip(Point location) {
|
||||
String word = parseProduct(textEditor, location.y);
|
||||
if (word != null) {
|
||||
String result = AfosBrowserModel.getInstance().getNodeHelp(word);
|
||||
String result = AfosBrowserModel.getInstance().getNodeHelp(word);
|
||||
if (result != null) {
|
||||
// dispaly below and to the right of location.
|
||||
location.x += 5;
|
||||
|
@ -8208,29 +8224,29 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
|
||||
String result = new String("");
|
||||
try {
|
||||
char c = lineText.charAt(0);
|
||||
if ((c == 'M') || (c == 'S') || (c == 'T')) {
|
||||
char c = lineText.charAt(0);
|
||||
if ((c == 'M') || (c == 'S') || (c == 'T')) {
|
||||
// # Most obs start with METAR, SPECI, TESTM, or TESTS. Skip
|
||||
// over
|
||||
// that tag,
|
||||
// # a space, and the K or P, to get to the 3-char station ID.
|
||||
if (lineText.length() > 10) {
|
||||
result = lineText.substring(7, 10);
|
||||
} else {
|
||||
result = lineText.substring(lineText.length() - 3);
|
||||
}
|
||||
} else if ((c == 'W') || (c == 'Y')) {
|
||||
// that tag,
|
||||
// # a space, and the K or P, to get to the 3-char station ID.
|
||||
if (lineText.length() > 10) {
|
||||
result = lineText.substring(7, 10);
|
||||
} else {
|
||||
result = lineText.substring(lineText.length() - 3);
|
||||
}
|
||||
} else if ((c == 'W') || (c == 'Y')) {
|
||||
// # Canadian SAOs have 3-character IDs, starting with W or Y.
|
||||
// Grab
|
||||
// 'em.
|
||||
result = lineText.substring(0, 3);
|
||||
} else {
|
||||
// 'em.
|
||||
result = lineText.substring(0, 3);
|
||||
} else {
|
||||
// # Some military obs don't get tagged. Skip the K or P and get
|
||||
// 3
|
||||
// chars.
|
||||
int wordLineStart = 1;
|
||||
result = lineText.substring(wordLineStart, wordLineStart + 4);
|
||||
}
|
||||
// chars.
|
||||
int wordLineStart = 1;
|
||||
result = lineText.substring(wordLineStart, wordLineStart + 4);
|
||||
}
|
||||
} catch (StringIndexOutOfBoundsException ex) {
|
||||
// User has non METAR/SAO products and the parsing failed.
|
||||
result = null;
|
||||
|
|
|
@ -71,7 +71,7 @@ public class WarnGenConfirmationDlg extends CaveSWTDialog {
|
|||
private String IMAGE_PRACTICE = "res/images/twsPractice.gif";
|
||||
|
||||
protected WarnGenConfirmationDlg(Shell parentShell, String title,
|
||||
String productMessage, String modeMessage, CAVEMode mode) {
|
||||
String productMessage, String modeMessage) {
|
||||
super(parentShell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL, CAVE.NONE
|
||||
| CAVE.DO_NOT_BLOCK);
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class WarnGenConfirmationDlg extends CaveSWTDialog {
|
|||
|
||||
this.productMessage = productMessage;
|
||||
this.modeMessage = modeMessage;
|
||||
this.mode = mode;
|
||||
this.mode = CAVEMode.getMode();
|
||||
setReturnValue(Boolean.FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.List;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 11, 2007 #601 chammack Initial Creation.
|
||||
* Aug 19, 2013 2177 jsanchez Removed suppress attribute.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -49,11 +50,6 @@ public class AffectedAreas {
|
|||
*/
|
||||
protected List<String> partOfArea;
|
||||
|
||||
/**
|
||||
* The partOfArea to suppress (e.g. "ns")
|
||||
*/
|
||||
protected String suppress;
|
||||
|
||||
/** The notation of the area affected (e.g. "COUNTY") */
|
||||
protected String areaNotation;
|
||||
|
||||
|
@ -89,17 +85,15 @@ public class AffectedAreas {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the areaNotation
|
||||
*/
|
||||
|
|
|
@ -46,7 +46,6 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.raytheon.viz.warngen.suppress.SuppressMap;
|
||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
||||
|
@ -74,6 +73,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
|||
* Nov 9, 2012 DR 15430 D. Friedman Extracted method converFeAreaToPartList.
|
||||
* Apr 29, 2013 1955 jsanchez Ignored comparing the geometry's user data when finding intersected areas.
|
||||
* May 2, 2013 1963 jsanchez Updated method to determine partOfArea.
|
||||
* Aug 19, 2013 2177 jsanchez Used portionsUtil to calculate area portion descriptions.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -89,13 +89,15 @@ public class Area {
|
|||
*/
|
||||
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
||||
|
||||
private Area() {
|
||||
private PortionsUtil portionsUtil;
|
||||
|
||||
public Area(PortionsUtil portionsUtil) {
|
||||
this.portionsUtil = portionsUtil;
|
||||
}
|
||||
|
||||
public static AffectedAreas[] findAffectedAreas(
|
||||
WarngenConfiguration config, Geometry polygon,
|
||||
Geometry warningArea, String localizedSite) throws VizException {
|
||||
public AffectedAreas[] findAffectedAreas(WarngenConfiguration config,
|
||||
Geometry polygon, Geometry warningArea, String localizedSite)
|
||||
throws VizException {
|
||||
|
||||
// --- Begin argument checking ---
|
||||
Validate.notNull(config.getGeospatialConfig().getAreaSource(),
|
||||
|
@ -113,7 +115,7 @@ public class Area {
|
|||
localizedSite, geoms);
|
||||
}
|
||||
|
||||
private static AffectedAreas[] findAffectedAreas(
|
||||
private AffectedAreas[] findAffectedAreas(
|
||||
AreaSourceConfiguration areaConfig,
|
||||
GeospatialConfiguration geospatialConfig, Geometry polygon,
|
||||
String localizedSite, List<Geometry> geoms) throws VizException {
|
||||
|
@ -183,7 +185,6 @@ public class Area {
|
|||
area.stateabbr = regionFeature.attributes.get(areaNotationField)
|
||||
.toString();
|
||||
area.size = regionGeom.getArea();
|
||||
area.suppress = suppressType(areaSource, area.stateabbr, area.fips);
|
||||
|
||||
Object tzData = regionFeature.attributes.get(timezonePathcastField);
|
||||
|
||||
|
@ -219,9 +220,16 @@ public class Area {
|
|||
double tolerCheck = regionGeom.getArea()
|
||||
* DEFAULT_PORTION_TOLERANCE;
|
||||
if (areaIntersection < tolerCheck) {
|
||||
area.partOfArea = GisUtil
|
||||
.asStringList(GisUtil.calculatePortion(regionGeom,
|
||||
intersection, true, true));
|
||||
try {
|
||||
String entityID = area.stateabbr + areaSource.charAt(0)
|
||||
+ area.fips.substring(2);
|
||||
area.partOfArea = GisUtil.asStringList(portionsUtil
|
||||
.getPortions(entityID, regionGeom, intersection,
|
||||
true));
|
||||
} catch (Exception e) {
|
||||
statusHandler.error("Unable to calculate part of area for "
|
||||
+ area.name, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Search the parent region
|
||||
|
@ -277,10 +285,9 @@ public class Area {
|
|||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public static Map<String, Object> findInsectingAreas(
|
||||
WarngenConfiguration config, Geometry warnPolygon,
|
||||
Geometry warnArea, String localizedSite, WarngenLayer warngenLayer)
|
||||
throws VizException {
|
||||
public Map<String, Object> findInsectingAreas(WarngenConfiguration config,
|
||||
Geometry warnPolygon, Geometry warnArea, String localizedSite,
|
||||
WarngenLayer warngenLayer) throws VizException {
|
||||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||
|
||||
String hatchedAreaSource = config.getHatchedAreaSource()
|
||||
|
@ -311,18 +318,6 @@ public class Area {
|
|||
|
||||
}
|
||||
|
||||
private static String suppressType(String areaSource, String state,
|
||||
String fips) {
|
||||
String retVal = SuppressMap.NONE;
|
||||
String type = areaSource.equalsIgnoreCase("zone") ? "Z" : "C";
|
||||
|
||||
if (state != null && fips != null) {
|
||||
String key = state + type + fips.substring(2);
|
||||
retVal = SuppressMap.getInstance().getType(key);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static List<String> converFeAreaToPartList(String feArea) {
|
||||
final List<String> partList = new ArrayList<String>();
|
||||
if (feArea == null) {
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/**
|
||||
* 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.gis;
|
||||
|
||||
/**
|
||||
* Port of A1 constants applied to a grid to determine county or zone portions.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 5, 2013 2177 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class CoverageConstants {
|
||||
|
||||
public static final int XSOUTH = 0x0001;
|
||||
|
||||
public static final int SOUTH = 0x0002;
|
||||
|
||||
public static final int NORTH = 0x0040;
|
||||
|
||||
public static final int XNORTH = 0x0080;
|
||||
|
||||
public static final int CENTER_NS = 0x0018;
|
||||
|
||||
public static final int CENTRAL_NS = 0x0024;
|
||||
|
||||
public static final int XWEST = 0x0100;
|
||||
|
||||
public static final int WEST = 0x0200;
|
||||
|
||||
public static final int EAST = 0x4000;
|
||||
|
||||
public static final int XEAST = 0x8000;
|
||||
|
||||
public static final int CENTER_EW = 0x1800;
|
||||
|
||||
public static final int CENTRAL_EW = 0x2400;
|
||||
|
||||
public static final int SOUTHERN = 0x0003;
|
||||
|
||||
public static final int NORTHERN = 0x00C0;
|
||||
|
||||
public static final int WESTERN = 0x0300;
|
||||
|
||||
public static final int EASTERN = 0xC000;
|
||||
|
||||
public static final int SOUTHSIDE = 0x000F;
|
||||
|
||||
public static final int NORTHSIDE = 0x00F0;
|
||||
|
||||
public static final int WESTSIDE = 0x0F00;
|
||||
|
||||
public static final int EASTSIDE = 0xF000;
|
||||
|
||||
public static final int EXTREME = 0x8181;
|
||||
|
||||
public static final int NOT_EXTREME = 0x7E7E;
|
||||
|
||||
public static final int EXTREME_NS = 0x0081;
|
||||
|
||||
public static final int EXTREME_EW = 0x8100;
|
||||
|
||||
public static final int CENTRAL = 0x2424;
|
||||
|
||||
public static final int CENTER = 0x1818;
|
||||
|
||||
public static final int NOT_CENTRAL = 0xC3C3;
|
||||
|
||||
public static final int NORTH_SOUTH = 0x00FF;
|
||||
|
||||
public static final int EAST_WEST = 0xFF00;
|
||||
|
||||
public static final int NNE = 0x0001;
|
||||
|
||||
public static final int ENE = 0x0002;
|
||||
|
||||
public static final int ESE = 0x0004;
|
||||
|
||||
public static final int SSE = 0x0008;
|
||||
|
||||
public static final int SSW = 0x0010;
|
||||
|
||||
public static final int WSW = 0x0020;
|
||||
|
||||
public static final int WNW = 0x0040;
|
||||
|
||||
public static final int NNW = 0x0080;
|
||||
|
||||
public static final int EXTREME_YES = 0xFFFF00;
|
||||
|
||||
public static final int EXTREME_NO = 0x00FF;
|
||||
|
||||
public static final int EXTREME_CORNER = 0xFF0000;
|
||||
|
||||
public static int[] NS_MASK = new int[256];
|
||||
|
||||
public static int[] EW_MASK = new int[256];
|
||||
|
||||
static {
|
||||
int i;
|
||||
|
||||
NS_MASK[0] = 0;
|
||||
for (i = 1; i < 256; i++) {
|
||||
if (i < 87) {
|
||||
NS_MASK[i] = XSOUTH | SOUTH;
|
||||
} else if (i > 167) {
|
||||
NS_MASK[i] = XNORTH | NORTH;
|
||||
} else if (i < 106) {
|
||||
NS_MASK[i] = SOUTH;
|
||||
} else if (i > 148) {
|
||||
NS_MASK[i] = NORTH;
|
||||
} else if (i < 118) {
|
||||
NS_MASK[i] = CENTRAL_NS | SOUTH;
|
||||
} else if (i > 138) {
|
||||
NS_MASK[i] = CENTRAL_NS | NORTH;
|
||||
} else if (i < 127) {
|
||||
NS_MASK[i] = CENTER_NS | CENTRAL_NS | SOUTH;
|
||||
} else if (i > 127) {
|
||||
NS_MASK[i] = CENTER_NS | CENTRAL_NS | NORTH;
|
||||
} else {
|
||||
NS_MASK[i] = CENTER_NS | CENTRAL_NS;
|
||||
}
|
||||
}
|
||||
|
||||
EW_MASK[0] = 0;
|
||||
for (i = 1; i < 256; i++) {
|
||||
if (i < 87) {
|
||||
EW_MASK[i] = XWEST | WEST;
|
||||
} else if (i > 167) {
|
||||
EW_MASK[i] = XEAST | EAST;
|
||||
} else if (i < 106) {
|
||||
EW_MASK[i] = WEST;
|
||||
} else if (i > 145) {
|
||||
EW_MASK[i] = EAST;
|
||||
} else if (i < 118) {
|
||||
EW_MASK[i] = CENTRAL_EW | WEST;
|
||||
} else if (i > 138) {
|
||||
EW_MASK[i] = CENTRAL_EW | EAST;
|
||||
} else if (i < 127) {
|
||||
EW_MASK[i] = CENTER_EW | CENTRAL_EW | WEST;
|
||||
} else if (i > 127) {
|
||||
EW_MASK[i] = CENTER_EW | CENTRAL_EW | EAST;
|
||||
} else {
|
||||
EW_MASK[i] = CENTER_EW | CENTRAL_EW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CoverageConstants() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.gis;
|
||||
|
||||
/**
|
||||
* Simple port of an A1 struct created by GridUtil and used by PortionsUtil.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 5, 2013 2177 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class EntityData {
|
||||
|
||||
private int meanMask = 0;
|
||||
|
||||
private int coverageMask = 0;
|
||||
|
||||
private int octants = 0;
|
||||
|
||||
public EntityData(int meanMask, int coverageMask, int octants) {
|
||||
this.meanMask = meanMask;
|
||||
this.coverageMask = coverageMask;
|
||||
this.octants = octants;
|
||||
}
|
||||
|
||||
public int getMeanMask() {
|
||||
return meanMask;
|
||||
}
|
||||
|
||||
public int getCoverageMask() {
|
||||
return coverageMask;
|
||||
}
|
||||
|
||||
public int getOctants() {
|
||||
return octants;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,616 @@
|
|||
/**
|
||||
* 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.gis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
import org.opengis.metadata.spatial.PixelOrientation;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||
import com.vividsolutions.jts.geom.Envelope;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
||||
|
||||
/**
|
||||
* Converts the county or zone and the intersecting warning area to grids. The
|
||||
* county or zone is also weighted to determine the northern, southern, eastern,
|
||||
* and western parts of the county or zone. Most of the code is ported from A1
|
||||
* to create an EntityData object that will be used by PortionsUtil to determine
|
||||
* the applicable impacted portions of a county or zone.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 5, 2013 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GridUtil {
|
||||
|
||||
private int ny = 0;
|
||||
|
||||
private int nx = 0;
|
||||
|
||||
private int[] ewGrid;
|
||||
|
||||
private int[] nsGrid;
|
||||
|
||||
private byte[] warnedAreaGrid;
|
||||
|
||||
private byte[] countyOrZoneGrid;
|
||||
|
||||
private WarngenLayer layer;
|
||||
|
||||
private MathTransform latLonToContour, contourToLatLon;
|
||||
|
||||
public GridUtil(WarngenLayer layer, GeneralGridGeometry localGridGeometry,
|
||||
MathTransform localToLatLon) throws Exception {
|
||||
this.layer = layer;
|
||||
|
||||
GridEnvelope range = localGridGeometry.getGridRange();
|
||||
this.nx = range.getHigh(0);
|
||||
this.ny = range.getHigh(1);
|
||||
|
||||
org.opengis.geometry.Envelope ge = localGridGeometry.getEnvelope();
|
||||
contourToLatLon = new DefaultMathTransformFactory()
|
||||
.createConcatenatedTransform(new GridGeometry2D(range, ge)
|
||||
.getGridToCRS(PixelOrientation.CENTER), localToLatLon);
|
||||
latLonToContour = contourToLatLon.inverse();
|
||||
|
||||
ewGrid = new int[nx * ny];
|
||||
nsGrid = new int[nx * ny];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the countyOrZone geometry and the warnedArea into grids and sets
|
||||
* the appropriate data in an EntityData object.
|
||||
*
|
||||
* @param countyOrZone
|
||||
* @param warnedArea
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public EntityData calculateGrids(Geometry countyOrZone, Geometry warnedArea)
|
||||
throws Exception {
|
||||
countyOrZoneGrid = toByteArray(countyOrZone);
|
||||
warnedAreaGrid = toByteArray(warnedArea);
|
||||
int[] bounds = awips1FinishAreaEntity();
|
||||
EntityData entityData = finishDefineArea(bounds);
|
||||
return entityData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the geometry into a byte array that is expected by ported A1
|
||||
* code.
|
||||
*
|
||||
* @param geometry
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
private byte[] toByteArray(Geometry geometry) throws VizException {
|
||||
byte[] bytes = new byte[nx * ny];
|
||||
float[][] floatData = toFloatData(geometry);
|
||||
|
||||
// Rotates grid
|
||||
int k = 0;
|
||||
for (int j = ny - 1; j >= 0; j--) {
|
||||
for (int i = 0; i < nx; i++) {
|
||||
if (floatData[i][j] == 1) {
|
||||
bytes[k] = 1;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the geometry into a 2-D float array.
|
||||
*
|
||||
* @param geometry
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
private float[][] toFloatData(Geometry geometry) throws VizException {
|
||||
Geometry contoured = layer.convertGeom(geometry, latLonToContour);
|
||||
List<Geometry> geomList = new ArrayList<Geometry>(
|
||||
contoured.getNumGeometries());
|
||||
GeometryUtil.buildGeometryList(geomList, contoured);
|
||||
List<PreparedGeometry> prepped = new ArrayList<PreparedGeometry>(
|
||||
geomList.size());
|
||||
for (Geometry g : geomList) {
|
||||
prepped.add(PreparedGeometryFactory.prepare(g));
|
||||
}
|
||||
|
||||
GeometryFactory gf = geometry.getFactory();
|
||||
Point point = gf.createPoint(new Coordinate(0, 0));
|
||||
CoordinateSequence pointCS = point.getCoordinateSequence();
|
||||
float[][] contourAreaData = new float[nx][ny];
|
||||
for (PreparedGeometry geom : prepped) {
|
||||
Envelope env = geom.getGeometry().getEnvelopeInternal();
|
||||
int startX = (int) env.getMinX();
|
||||
int startY = (int) env.getMinY();
|
||||
int width = (int) env.getMaxX();
|
||||
int height = (int) env.getMaxY();
|
||||
if (startX < 0 || width > nx || startY < 0 || height > ny) {
|
||||
continue;
|
||||
}
|
||||
startX = Math.max(0, startX - 1);
|
||||
startY = Math.max(0, startY - 1);
|
||||
width = Math.min(nx, width + 1);
|
||||
height = Math.min(ny, height + 1);
|
||||
for (int x = startX; x < width; ++x) {
|
||||
for (int y = startY; y < height; ++y) {
|
||||
|
||||
pointCS.setOrdinate(0, 0, x);
|
||||
pointCS.setOrdinate(0, 1, y);
|
||||
point.geometryChanged();
|
||||
if (contourAreaData[x][y] == 0.0f && geom.intersects(point)) {
|
||||
contourAreaData[x][y] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return contourAreaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ported only the logic from A1 code
|
||||
* GeoEntityLookupTable::finishDefineArea() that calculates the meanMask,
|
||||
* coverageMask,and octants for an entity (i.e. county or zone).
|
||||
*
|
||||
* @param countyOrZone
|
||||
* @param warnedArea
|
||||
* @return
|
||||
*/
|
||||
private EntityData finishDefineArea(int[] bounds) {
|
||||
int meanMask = 0;
|
||||
int coverageMask = 0;
|
||||
int octants = 0;
|
||||
|
||||
int ewCount = 0;
|
||||
int nsCount = 0;
|
||||
int ewTotal = 0;
|
||||
int nsTotal = 0;
|
||||
|
||||
int k = 0;
|
||||
int min_i = bounds[0];
|
||||
int max_i = bounds[1];
|
||||
int min_j = bounds[2];
|
||||
int max_j = bounds[3];
|
||||
for (int j = min_j; j < max_j; j++) {
|
||||
k = nx * j + min_i;
|
||||
for (int i = min_i; i < max_i; i++, k++) {
|
||||
if (warnedAreaGrid[k] == 1) {
|
||||
int e = countyOrZoneGrid[k];
|
||||
|
||||
int ii = ewGrid[k];
|
||||
int jj = nsGrid[k];
|
||||
|
||||
if (ii == 0 && jj == 0) {
|
||||
continue;
|
||||
}
|
||||
ewTotal += ii;
|
||||
if (ii > 0) {
|
||||
ewCount++;
|
||||
}
|
||||
nsTotal += jj;
|
||||
if (jj > 0) {
|
||||
nsCount++;
|
||||
}
|
||||
int m = CoverageConstants.EW_MASK[ii]
|
||||
| CoverageConstants.NS_MASK[jj];
|
||||
coverageMask |= m;
|
||||
if ((m & CoverageConstants.CENTRAL) == CoverageConstants.CENTRAL) {
|
||||
continue;
|
||||
}
|
||||
if (ii == 0) {
|
||||
ii = 127;
|
||||
}
|
||||
if (jj == 0) {
|
||||
jj = 127;
|
||||
}
|
||||
if (ii < 127) {
|
||||
if (jj < 127) {
|
||||
e = (ii > jj ? CoverageConstants.SSW
|
||||
: CoverageConstants.WSW);
|
||||
} else {
|
||||
e = (ii > 254 - jj ? CoverageConstants.NNW
|
||||
: CoverageConstants.WNW);
|
||||
}
|
||||
} else {
|
||||
if (jj < 127) {
|
||||
e = (ii < 254 - jj ? CoverageConstants.SSE
|
||||
: CoverageConstants.ESE);
|
||||
} else {
|
||||
e = (ii < jj ? CoverageConstants.NNE
|
||||
: CoverageConstants.ENE);
|
||||
}
|
||||
}
|
||||
if ((m & CoverageConstants.EXTREME_NS) > 0) {
|
||||
e <<= 8;
|
||||
}
|
||||
if ((m & CoverageConstants.EXTREME_EW) > 0) {
|
||||
e <<= 8;
|
||||
}
|
||||
octants |= e;
|
||||
} else {
|
||||
warnedAreaGrid[k] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ewCount > 0) {
|
||||
ewTotal = (ewTotal + ewCount / 2) / ewCount;
|
||||
}
|
||||
if (nsCount > 0) {
|
||||
nsTotal = (nsTotal + nsCount / 2) / nsCount;
|
||||
}
|
||||
|
||||
meanMask = CoverageConstants.NS_MASK[nsTotal]
|
||||
| CoverageConstants.EW_MASK[ewTotal];
|
||||
return new EntityData(meanMask, coverageMask, octants);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the _ewGrid and _nsGrid via A1 ~~ mAgIc ~~
|
||||
*/
|
||||
private int[] awips1FinishAreaEntity() {
|
||||
|
||||
final double EXTREME_FRAC = 0.1;
|
||||
final double MIN_EXTREME = 87;
|
||||
final double MAX_EXTREME = 167;
|
||||
|
||||
int k = 0;
|
||||
int ii, jj;
|
||||
|
||||
/*
|
||||
* identify those points on the boundary of the entity so we can shrink
|
||||
* from there
|
||||
*/
|
||||
int i_mean = 0;
|
||||
int j_mean = 0;
|
||||
int new_tot = 0;
|
||||
int ii_mean = 0;
|
||||
int jj_mean = 0;
|
||||
int min_i = Integer.MAX_VALUE;
|
||||
int min_j = Integer.MAX_VALUE;
|
||||
int max_i = Integer.MIN_VALUE;
|
||||
int max_j = Integer.MIN_VALUE;
|
||||
|
||||
for (jj = 0; jj < ny; jj++) {
|
||||
k = nx * jj;
|
||||
for (ii = 0; ii < nx; ii++, k++) {
|
||||
// If the entity is not 1 then it's not part of the county or
|
||||
// zone area.
|
||||
if (countyOrZoneGrid[k] != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ii > max_i) {
|
||||
max_i = ii;
|
||||
}
|
||||
|
||||
if (ii < min_i) {
|
||||
min_i = ii;
|
||||
}
|
||||
|
||||
if (jj > max_j) {
|
||||
max_j = jj;
|
||||
}
|
||||
if (jj < min_j) {
|
||||
min_j = jj;
|
||||
}
|
||||
++new_tot;
|
||||
ii_mean += ii;
|
||||
jj_mean += jj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* restablish some things that might have changed since the first time
|
||||
* they were calculated.
|
||||
*/
|
||||
// if (!outside) {
|
||||
ii_mean /= new_tot;
|
||||
jj_mean /= new_tot;
|
||||
i_mean = ii_mean;
|
||||
j_mean = jj_mean;
|
||||
// }/*endif*/
|
||||
|
||||
/* assign correct base for directional computation */
|
||||
// I changed this from ii_mean to this
|
||||
double i_base = (min_i + max_i) / 2;
|
||||
// I changed this from jj_mean to this
|
||||
double j_base = (min_j + max_j) / 2;
|
||||
|
||||
/*
|
||||
* calculate needed rotation factors for computation of amount each
|
||||
* point is north and east of centroid
|
||||
*/
|
||||
double x_intcpg = 0.5;
|
||||
double y_intcpg = 0.5;
|
||||
|
||||
double dx = 1, dy = 1;
|
||||
double x = (i_base - x_intcpg);
|
||||
double y = (j_base - y_intcpg);
|
||||
|
||||
// Below is some code from the original A1 code. I assumed that x_intcpg
|
||||
// to be 0.5 to avoid porting all the methods in gelt_maker.c.
|
||||
// xy_to_ll(&x,&y,&lat,&lon,&my_proj);
|
||||
// lat01=lat+0.1;
|
||||
// ll_to_xy(&lat01,&lon,&dx,&dy,&my_proj);
|
||||
// dx -= x;
|
||||
|
||||
dy -= y;
|
||||
|
||||
double mag = Math.sqrt(dx * dx + dy * dy);
|
||||
dx /= mag;
|
||||
dy /= mag;
|
||||
double erot_i = -dy;
|
||||
double erot_j = -dx;
|
||||
|
||||
double nrot_i = dx;
|
||||
double nrot_j = dy;
|
||||
|
||||
int[] ew_hist = new int[nx * ny];
|
||||
int[] ns_hist = new int[nx * ny];
|
||||
|
||||
/* Calculate north/south & east/west offsets, create histogram of these. */
|
||||
// TODO I did not fully implement the histograms as used in a1. Using
|
||||
// the histograms created index out of bounds errors. If the field is
|
||||
// unhappy with the portions, then porting the histograms needs to be
|
||||
// re-investigated.
|
||||
int ns1 = 0, ns2 = 0, ew1 = 0, ew2 = 0;
|
||||
int np_n = 0, np_s = 0, np_e = 0, np_w = 0;
|
||||
ns_hist[0] = 0;
|
||||
ew_hist[0] = 0;
|
||||
for (jj = min_j; jj < max_j; jj++) {
|
||||
k = nx * jj + min_i;
|
||||
for (ii = min_i; ii < max_i; ii++, k++) {
|
||||
// If the entity is not 1 then it's not part of the county or
|
||||
// zone area.
|
||||
if (countyOrZoneGrid[k] != 1) {
|
||||
continue;
|
||||
}
|
||||
double di = ii - i_base;
|
||||
double dj = jj - j_base;
|
||||
|
||||
double dns = (int) (nrot_i * di + nrot_j * dj);
|
||||
while (ns1 > dns) {
|
||||
// ns_hist[--ns1] = 0;
|
||||
--ns1;
|
||||
}
|
||||
|
||||
while (ns2 < dns) {
|
||||
// ns_hist[++ns2] = 0;
|
||||
++ns2;
|
||||
}
|
||||
// ns_hist[(int) dns]++;
|
||||
|
||||
double dew = (int) (erot_i * di + erot_j * dj);
|
||||
while (ew1 > dew) {
|
||||
// ew_hist[--ew1] = 0;
|
||||
--ew1;
|
||||
}
|
||||
while (ew2 < dew) {
|
||||
// ew_hist[++ew2] = 0;
|
||||
++ew2;
|
||||
}
|
||||
// ew_hist[(int) dew]++;
|
||||
|
||||
if (dew < 0) {
|
||||
np_w++;
|
||||
}
|
||||
if (dew > 0) {
|
||||
np_e++;
|
||||
}
|
||||
if (dns < 0) {
|
||||
np_s++;
|
||||
}
|
||||
if (dns > 0) {
|
||||
np_n++;
|
||||
}
|
||||
}/* end for */
|
||||
}/* end for */
|
||||
|
||||
/*
|
||||
* Transform n-s & e-w offsets into normalized distances north and
|
||||
* south. This is done based on a preferred fraction of each area that
|
||||
* is "extreme".
|
||||
*/
|
||||
|
||||
// a lot of assumptions were made here. therefore, not everything in
|
||||
// this part was fully ported.
|
||||
double target = np_w * EXTREME_FRAC;
|
||||
// for (ii = 0, k = ew1; k < -1 && ii < target; k++) {
|
||||
// ii += ew_hist[k];
|
||||
// }
|
||||
// if (ii / target > 1.5) {
|
||||
// k--;
|
||||
// }
|
||||
// if (k < ew1) {
|
||||
// k = ew1;
|
||||
// }
|
||||
|
||||
k = ew1;
|
||||
double mu_w = (MIN_EXTREME - 127) / (k + 0.5);
|
||||
|
||||
target = np_e * EXTREME_FRAC;
|
||||
// for (ii = 0, k = ew2; k > 1 && ii < target; k--) {
|
||||
// ii += ew_hist[k];
|
||||
// }
|
||||
// if (ii / target > 1.5) {
|
||||
// k++;
|
||||
// }
|
||||
// if (k > ew2) {
|
||||
// k = ew2;
|
||||
// }
|
||||
|
||||
k = ew2;
|
||||
double mu_e = (MAX_EXTREME - 127) / (k - 0.5);
|
||||
|
||||
target = np_s * EXTREME_FRAC;
|
||||
// for (ii = 0, k = ns1; k < -1 && ii < target; k++) {
|
||||
// ii += ns_hist[k];
|
||||
// }
|
||||
// if (ii / target > 1.5) {
|
||||
// k--;
|
||||
// }
|
||||
// if (k < ns1) {
|
||||
// k = ns1;
|
||||
// }
|
||||
|
||||
k = ns1;// TODO - REPLACE WITH ABOVE
|
||||
double mu_s = (MIN_EXTREME - 127) / (k + 0.5);
|
||||
|
||||
target = np_n * EXTREME_FRAC;
|
||||
// for (ii = 0, k = ns2; k > 1 && ii < target; k--) {
|
||||
// ii += ns_hist[k];
|
||||
// }
|
||||
// if (ii / target > 1.5) {
|
||||
// k++;
|
||||
// }
|
||||
// if (k > ns2) {
|
||||
// k = ns2;
|
||||
// }
|
||||
|
||||
k = ns2;
|
||||
double mu_n = (MAX_EXTREME - 127) / (k - 0.5);
|
||||
|
||||
for (jj = min_j; jj < max_j; jj++) {
|
||||
k = nx * jj + min_i;
|
||||
for (ii = min_i; ii < max_i; ii++, k++) {
|
||||
// If the entity is not 1 then it's not part of the county or
|
||||
// zone area.
|
||||
if (countyOrZoneGrid[k] != 1) {
|
||||
ewGrid[k] = 0;
|
||||
nsGrid[k] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
double di = ii - i_base;
|
||||
double dj = jj - j_base;
|
||||
double dns = (int) (nrot_i * di + nrot_j * dj);
|
||||
double dew = (int) (erot_i * di + erot_j * dj);
|
||||
int c_ns2 = (int) (dns);
|
||||
int c_ew2 = (int) (dew);
|
||||
|
||||
if (c_ew2 < 0) {
|
||||
dx = c_ew2 * mu_w;
|
||||
} else {
|
||||
dx = c_ew2 * mu_e;
|
||||
}
|
||||
|
||||
if (dx > 127) {
|
||||
dx = 127;
|
||||
}
|
||||
|
||||
if (dx < -127) {
|
||||
dx = -127;
|
||||
}
|
||||
|
||||
ewGrid[k] = (int) (127 + (int) (dx));
|
||||
|
||||
if (c_ns2 < 0) {
|
||||
dy = c_ns2 * mu_s;
|
||||
} else {
|
||||
dy = c_ns2 * mu_n;
|
||||
}
|
||||
|
||||
if (dy > 127) {
|
||||
dy = 127;
|
||||
}
|
||||
|
||||
if (dy < -127) {
|
||||
dy = -127;
|
||||
}
|
||||
|
||||
nsGrid[k] = (int) (127 + (int) (dy));
|
||||
}
|
||||
}
|
||||
// System.out.println("-----------------------------------");
|
||||
// printGrids(countyOrZoneGrid, min_i, max_i, min_j, max_j);
|
||||
// System.out.println("-----------------------------------");
|
||||
// printGrids(_currentArea, min_i, max_i, min_j, max_j);
|
||||
// System.out.println("-------------- EAST WEST ---------------------");
|
||||
// printGrids(ewGrid, min_i, max_i, min_j, max_j);
|
||||
// System.out.println("-------------- NORTH SOUTH ---------------------");
|
||||
// printGrids(nsGrid, min_i, max_i, min_j, max_j);
|
||||
// System.out.println("north/south - east/west done");
|
||||
return new int[] { min_i, max_i, min_j, max_j };
|
||||
|
||||
}
|
||||
|
||||
// For debugging and view the grid in ascii format.
|
||||
private void printGrids(int[] grid, int min_i, int max_i, int min_j,
|
||||
int max_j) {
|
||||
int k = 0;
|
||||
for (int jj = min_j; jj < max_j; jj++) {
|
||||
k = nx * jj + min_i;
|
||||
for (int ii = min_i; ii < max_i; ii++) {
|
||||
System.out.print((int) grid[k]);
|
||||
k++;
|
||||
}
|
||||
System.out.println("-");
|
||||
}
|
||||
}
|
||||
|
||||
// For debugging and view the grid in ascii format.
|
||||
private void printGrids(byte[] grid, int min_i, int max_i, int min_j,
|
||||
int max_j) {
|
||||
int k = 0;
|
||||
for (int jj = min_j; jj < max_j; jj++) {
|
||||
k = nx * jj + min_i;
|
||||
for (int ii = min_i; ii < max_i; ii++) {
|
||||
System.out.print((int) grid[k]);
|
||||
k++;
|
||||
}
|
||||
System.out.println("-");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
/**
|
||||
* 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.gis;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
/**
|
||||
* Port of A1 code that determines the portions of the county or zone
|
||||
* descriptions, such as NORTHWEST.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 5, 2013 2177 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PortionsUtil {
|
||||
|
||||
private GridUtil gridUtil;
|
||||
|
||||
public PortionsUtil(WarngenLayer layer) throws Exception {
|
||||
gridUtil = new GridUtil(layer, layer.getLocalGridGeometry(),
|
||||
layer.getlocalToLatLon());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the the appropriate portion description for the warnedArea
|
||||
* intersecting the countyOrZone.
|
||||
*
|
||||
* @param entityID
|
||||
* @param countyOrZone
|
||||
* @param warnedArea
|
||||
* @param useExtreme
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public EnumSet<Direction> getPortions(String entityID,
|
||||
Geometry countyOrZone, Geometry warnedArea, boolean useExtreme)
|
||||
throws Exception {
|
||||
countyOrZone.getUserData();
|
||||
EntityData entityData = gridUtil.calculateGrids(countyOrZone,
|
||||
warnedArea);
|
||||
EnumSet<Direction> portions = getAreaDesc(entityData.getMeanMask(),
|
||||
entityData.getCoverageMask(), entityData.getOctants(),
|
||||
useExtreme);
|
||||
return suppressPortions(entityID, portions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up if the designated entity ID has an suppressed directions. For
|
||||
* example, a county or zone may not need to include the north and sound
|
||||
* direction description if it was included in the area.suppress file.
|
||||
*
|
||||
* @param entityID
|
||||
* @param portions
|
||||
* @return
|
||||
*/
|
||||
private EnumSet<Direction> suppressPortions(String entityID,
|
||||
EnumSet<Direction> portions) {
|
||||
Map<String, List<Direction>> suppressedCounties = SuppressMap
|
||||
.getInstance().getAreas();
|
||||
if (entityID != null && suppressedCounties != null
|
||||
&& !suppressedCounties.isEmpty()) {
|
||||
List<Direction> suppressedDirections = suppressedCounties
|
||||
.get(entityID.toUpperCase());
|
||||
if (suppressedDirections != null && !suppressedDirections.isEmpty()) {
|
||||
portions.removeAll(suppressedDirections);
|
||||
}
|
||||
}
|
||||
|
||||
return portions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Port from A1 code of GeoEntityLookupTable::getAreaDesc.
|
||||
*
|
||||
* @param meanMask
|
||||
* @param areaMask
|
||||
* @param octants
|
||||
* @param exYes
|
||||
*/
|
||||
private static EnumSet<Direction> getAreaDesc(int meanMask, int areaMask,
|
||||
int octants, boolean exYes) {
|
||||
EnumSet<Direction> portions = EnumSet.noneOf(Direction.class);
|
||||
|
||||
// Test for case where we cannot do portions
|
||||
if (meanMask == 0 || areaMask == 0) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
// The next block of code is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// Test for case where area is completely within one subsection.
|
||||
// if (meanMask == areaMask) {
|
||||
// return getPointDesc(meanMask, exYes);
|
||||
// }
|
||||
|
||||
// Test for central by not being near adjacent borders.
|
||||
if (octants == 0
|
||||
|| ((octants & CoverageConstants.EXTREME_YES) == 0)
|
||||
&& (meanMask & CoverageConstants.CENTER) == CoverageConstants.CENTER) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
return portions;
|
||||
}
|
||||
|
||||
if ((octants & 0xFFFF) == 0xFFFF) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
// Identify quadrants in use, q is typical, qq is diagonal.
|
||||
int xoctant = octants >> 8;
|
||||
int xxoctant = octants >> 16;
|
||||
int nn, ss, ee, ww, ne, nw, se, sw;
|
||||
nn = ss = ee = ww = ne = nw = se = sw = 0;
|
||||
int omerge = xxoctant | xoctant | octants;
|
||||
if ((omerge & (CoverageConstants.NNE | CoverageConstants.ENE)) > 0) {
|
||||
ne = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.SSE | CoverageConstants.ESE)) > 0) {
|
||||
se = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.NNW | CoverageConstants.WNW)) > 0) {
|
||||
nw = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.SSW | CoverageConstants.WSW)) > 0) {
|
||||
sw = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.NNE | CoverageConstants.NNW)) > 0) {
|
||||
nn = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.SSE | CoverageConstants.SSW)) > 0) {
|
||||
ss = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.WNW | CoverageConstants.WSW)) > 0) {
|
||||
ww = 1;
|
||||
}
|
||||
if ((omerge & (CoverageConstants.ENE | CoverageConstants.ESE)) > 0) {
|
||||
ee = 1;
|
||||
}
|
||||
if ((areaMask & CoverageConstants.NORTH_SOUTH) == 0) {
|
||||
nn = ss = ne = nw = se = sw = 0;
|
||||
}
|
||||
if ((areaMask & CoverageConstants.EAST_WEST) == 0) {
|
||||
ee = ww = ne = nw = se = sw = 0;
|
||||
}
|
||||
int q = ne + nw + se + sw;
|
||||
int qq = nn + ss + ee + ww;
|
||||
|
||||
// Identify extremes in use.
|
||||
int nnx, ssx, eex, wwx;
|
||||
nnx = ssx = eex = wwx = 0;
|
||||
if ((areaMask & CoverageConstants.XNORTH) > 0) {
|
||||
nnx = 1;
|
||||
}
|
||||
if ((areaMask & CoverageConstants.XSOUTH) > 0) {
|
||||
ssx = 1;
|
||||
}
|
||||
if ((areaMask & CoverageConstants.XWEST) > 0) {
|
||||
wwx = 1;
|
||||
}
|
||||
if ((areaMask & CoverageConstants.XEAST) > 0) {
|
||||
eex = 1;
|
||||
}
|
||||
int xxx = nnx + ssx + eex + wwx;
|
||||
|
||||
// Modify masks based on whether we can use extreme.
|
||||
if ((octants & CoverageConstants.EXTREME_NO) > 0
|
||||
&& (areaMask & CoverageConstants.EXTREME) > 0) {
|
||||
areaMask &= CoverageConstants.NOT_EXTREME;
|
||||
meanMask &= CoverageConstants.NOT_EXTREME;
|
||||
}
|
||||
|
||||
// Possible case of a stripe across the middle
|
||||
if (q == 0) {
|
||||
;// Only one direction encoded
|
||||
} else if (q == 2 && nw == se || q == 2 && ne == sw || qq == 2
|
||||
&& nn == ss || qq == 2 && ee == ww) {
|
||||
if ((meanMask & CoverageConstants.CENTRAL) == CoverageConstants.CENTRAL
|
||||
|| nnx == ssx && wwx == eex) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
return portions;
|
||||
}
|
||||
return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
|
||||
}
|
||||
|
||||
// Modify masks based on whether we can use central.
|
||||
if (xxx > 2 || nnx != ssx && wwx != eex) {
|
||||
areaMask &= CoverageConstants.NOT_CENTRAL;
|
||||
meanMask &= CoverageConstants.NOT_CENTRAL;
|
||||
}
|
||||
|
||||
// Another possible case of a stripe across the middle.
|
||||
if (q == 4 && (meanMask & CoverageConstants.CENTER) > 0) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
return portions;
|
||||
}
|
||||
|
||||
// All quadrants in use.
|
||||
if (q == 4 && qq == 4) {
|
||||
return EnumSet.noneOf(Direction.class);
|
||||
}
|
||||
|
||||
// Only one typical quadrant in use.
|
||||
if (q == 1) {
|
||||
// if (ne == 1) {
|
||||
// portions.add(Direction.NORTH);
|
||||
// portions.add(Direction.EAST);
|
||||
// } else if (nw == 1) {
|
||||
// portions.add(Direction.NORTH);
|
||||
// portions.add(Direction.WEST);
|
||||
// } else if (se == 1) {
|
||||
// portions.add(Direction.SOUTH);
|
||||
// portions.add(Direction.EAST);
|
||||
// } else if (sw == 1) {
|
||||
// portions.add(Direction.SOUTH);
|
||||
// portions.add(Direction.WEST);
|
||||
// }
|
||||
// return portions;
|
||||
return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
|
||||
}
|
||||
|
||||
// Further modify masks based on whether we can use central.
|
||||
if (xxx >= 2) {
|
||||
areaMask &= CoverageConstants.NOT_CENTRAL;
|
||||
meanMask &= CoverageConstants.NOT_CENTRAL;
|
||||
}
|
||||
|
||||
// No more than two quadrants of any kind in use, or all quadrants.
|
||||
if (q < 3 && qq < 3) {
|
||||
if (nnx != ssx && wwx != eex
|
||||
|| (meanMask & CoverageConstants.CENTRAL) > 0) {
|
||||
return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
|
||||
|
||||
} else {
|
||||
return getPointDesc2(areaMask, exYes, nn, ss, ee, ww);
|
||||
}
|
||||
}
|
||||
|
||||
// Three typical quadrants in use.
|
||||
if (q == 3 && qq != 3) {
|
||||
|
||||
if (ne == 0) {
|
||||
// The next line is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// if (ne == 0 && (xxoctant & (SSW | WSW)) > 0) {
|
||||
portions.add(Direction.SOUTH);
|
||||
portions.add(Direction.WEST);
|
||||
|
||||
} else if (se == 0) {
|
||||
// The next line is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// } else if (se == 0 && (xxoctant & (NNW | WNW)) > 0) {
|
||||
portions.add(Direction.NORTH);
|
||||
portions.add(Direction.WEST);
|
||||
|
||||
} else if (nw == 0) {
|
||||
// The next line is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// } else if (nw == 0 && (xxoctant & (SSE | ESE)) > 0) {
|
||||
portions.add(Direction.SOUTH);
|
||||
portions.add(Direction.EAST);
|
||||
|
||||
} else if (sw == 0) {
|
||||
// The next line is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// } else if (sw == 0 && (xxoctant & (NNE | ENE)) > 0) {
|
||||
portions.add(Direction.NORTH);
|
||||
portions.add(Direction.EAST);
|
||||
}
|
||||
// The next line is the original port of A1 code but prevented
|
||||
// producing the correct result:
|
||||
// return getPointDesc(meanMask, exYes);
|
||||
}
|
||||
|
||||
// Three diagonal quadrants in use.
|
||||
if (qq == 3 && portions.isEmpty()) {
|
||||
if (nn == 0) {
|
||||
portions.add(Direction.SOUTH);
|
||||
} else if (ss == 0) {
|
||||
portions.add(Direction.NORTH);
|
||||
} else if (ww == 0) {
|
||||
portions.add(Direction.EAST);
|
||||
} else if (ee == 0) {
|
||||
portions.add(Direction.WEST);
|
||||
}
|
||||
}
|
||||
|
||||
// add extreme for three quadrant case.
|
||||
if (!portions.isEmpty()) {
|
||||
if (exYes && ((areaMask & CoverageConstants.EXTREME)) > 0) {
|
||||
portions.add(Direction.EXTREME);
|
||||
}
|
||||
return portions;
|
||||
}
|
||||
|
||||
// All of either type of quadrant in use.
|
||||
if (q == 4 || qq == 4) {
|
||||
return EnumSet.noneOf(Direction.class);
|
||||
}
|
||||
|
||||
// Case of a pure simple direction.
|
||||
nn = areaMask & CoverageConstants.NORTHERN;
|
||||
ss = areaMask & CoverageConstants.SOUTHERN;
|
||||
ee = areaMask & CoverageConstants.EASTERN;
|
||||
ww = areaMask & CoverageConstants.WESTERN;
|
||||
if (ss > 0 && nn > 0 || q == 0) {
|
||||
if (ee == 0 && ww > 0) {
|
||||
portions.add(Direction.WEST);
|
||||
}
|
||||
if (ww == 0 && ee > 0) {
|
||||
portions.add(Direction.EAST);
|
||||
}
|
||||
} else if (ee > 0 && ww > 0 || q == 0) {
|
||||
if (nn == 0 && ss > 0) {
|
||||
portions.add(Direction.SOUTH);
|
||||
}
|
||||
if (ss == 0 && nn > 0) {
|
||||
portions.add(Direction.NORTH);
|
||||
}
|
||||
}
|
||||
|
||||
// add extreme for simple direction case.
|
||||
if (!portions.isEmpty()) {
|
||||
if (exYes && ((areaMask & CoverageConstants.EXTREME)) > 0) {
|
||||
portions.add(Direction.EXTREME);
|
||||
}
|
||||
return portions;
|
||||
}
|
||||
|
||||
// Catch with the point descriptor one last time
|
||||
return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
|
||||
}
|
||||
|
||||
/**
|
||||
* Port from A1 code of GeoEntityLookupTable::getPointDesc.
|
||||
*
|
||||
* @param mask
|
||||
* @param exYes
|
||||
* @return
|
||||
*/
|
||||
private static EnumSet<Direction> getPointDesc(int mask, boolean exYes) {
|
||||
EnumSet<Direction> portions = EnumSet.noneOf(Direction.class);
|
||||
|
||||
if (mask == 0) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
int cc = mask & CoverageConstants.CENTRAL;
|
||||
if (cc == CoverageConstants.CENTRAL) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
return portions;
|
||||
}
|
||||
|
||||
if ((mask & CoverageConstants.NORTH_SOUTH) == 0) {
|
||||
;
|
||||
} else if ((mask & CoverageConstants.SOUTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
|
||||
portions.add(Direction.SOUTH);
|
||||
} else if ((mask & CoverageConstants.NORTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
|
||||
portions.add(Direction.NORTH);
|
||||
}
|
||||
|
||||
if ((mask & CoverageConstants.EAST_WEST) == 0) {
|
||||
;
|
||||
} else if ((mask & CoverageConstants.WESTERN) == (mask & CoverageConstants.EAST_WEST)) {
|
||||
portions.add(Direction.WEST);
|
||||
} else if ((mask & CoverageConstants.EASTERN) == (mask & CoverageConstants.EAST_WEST)) {
|
||||
portions.add(Direction.EAST);
|
||||
}
|
||||
|
||||
if (portions.isEmpty()) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
if (cc != 0) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
}
|
||||
|
||||
if (exYes && ((int) (mask & CoverageConstants.EXTREME) > 0)) {
|
||||
portions.add(Direction.EXTREME);
|
||||
}
|
||||
|
||||
return portions;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not a direct port from A1. The original getPointDesc did
|
||||
* not produce the expected results. This method is a modified version of
|
||||
* getPointDesct that uses the calculated qq values instead of just the
|
||||
* meanMask.
|
||||
*
|
||||
* @param mask
|
||||
* @param exYes
|
||||
* @return
|
||||
*/
|
||||
private static EnumSet<Direction> getPointDesc2(int mask, boolean exYes,
|
||||
int nn, int ss, int ee, int ww) {
|
||||
EnumSet<Direction> portions = EnumSet.noneOf(Direction.class);
|
||||
|
||||
if (mask == 0) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
if (nn > 0 && ss > 0) {
|
||||
;
|
||||
} else if (ss > 0) {
|
||||
portions.add(Direction.SOUTH);
|
||||
counter++;
|
||||
} else if (nn > 0) {
|
||||
portions.add(Direction.NORTH);
|
||||
counter++;
|
||||
}
|
||||
|
||||
if (ee > 0 && ww > 0) {
|
||||
;
|
||||
} else if (ww > 0) {
|
||||
portions.add(Direction.WEST);
|
||||
counter++;
|
||||
} else if (ee > 0) {
|
||||
portions.add(Direction.EAST);
|
||||
counter++;
|
||||
}
|
||||
|
||||
if (portions.isEmpty()) {
|
||||
return portions;
|
||||
}
|
||||
|
||||
int cc = mask & CoverageConstants.CENTRAL;
|
||||
boolean useCentral = counter < 2;
|
||||
if (useCentral && cc != 0) {
|
||||
portions.add(Direction.CENTRAL);
|
||||
}
|
||||
|
||||
if (exYes && ((int) (mask & CoverageConstants.EXTREME) > 0)) {
|
||||
portions.add(Direction.EXTREME);
|
||||
}
|
||||
|
||||
return portions;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.suppress;
|
||||
package com.raytheon.viz.warngen.gis;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -25,7 +25,10 @@ import java.io.FileInputStream;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -38,9 +41,11 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Creates a map of all the site's area suppress files.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -48,6 +53,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 2, 2010 jsanchez Initial creation
|
||||
* Aug 15,2013 2177 jsanchez Refactored.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -66,16 +72,26 @@ public class SuppressMap {
|
|||
private static final Pattern ugcPattern = Pattern
|
||||
.compile("[A-Z]{2}[CZ][0-9]{3}");
|
||||
|
||||
public static final String NORTH_SOUTH = "NS";
|
||||
private static final List<Direction> NORTH_SOUTH = Arrays.asList(
|
||||
Direction.NORTH, Direction.SOUTH);
|
||||
|
||||
public static final String EAST_WEST = "EW";
|
||||
private static final List<Direction> EAST_WEST = Arrays.asList(
|
||||
Direction.EAST, Direction.WEST);
|
||||
|
||||
public static final String NONE = "NONE";
|
||||
private static final List<Direction> ALL = Arrays.asList(Direction.NORTH,
|
||||
Direction.SOUTH, Direction.EAST, Direction.WEST, Direction.CENTRAL,
|
||||
Direction.EXTREME);
|
||||
|
||||
public static final String ALL = "ALL";
|
||||
private static Map<String, Map<String, List<Direction>>> suppressMap = new HashMap<String, Map<String, List<Direction>>>();
|
||||
|
||||
private Map<String, String> suppressMap = new HashMap<String, String>();
|
||||
private SuppressMap() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return an instance of the SuppressMap object.
|
||||
*/
|
||||
public static SuppressMap getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new SuppressMap();
|
||||
|
@ -83,64 +99,82 @@ public class SuppressMap {
|
|||
return instance;
|
||||
}
|
||||
|
||||
private SuppressMap() {
|
||||
readFile();
|
||||
/**
|
||||
* Returns the suppressed area map for the current localized site.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, List<Direction>> getAreas() {
|
||||
String threeLetterSiteID = LocalizationManager.getInstance()
|
||||
.getCurrentSite();
|
||||
Map<String, List<Direction>> areas = suppressMap.get(threeLetterSiteID);
|
||||
|
||||
if (areas == null) {
|
||||
areas = new HashMap<String, List<Direction>>();
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
LocalizationContext lc = pm.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
|
||||
File file = pm.getFile(lc, AREA_SUPPRESS_FILENAME);
|
||||
loadFile(file, areas);
|
||||
}
|
||||
|
||||
return areas;
|
||||
}
|
||||
|
||||
private void readFile() {
|
||||
// load site
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext lc = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
|
||||
File file = pathMgr.getFile(lc, AREA_SUPPRESS_FILENAME);
|
||||
loadFile(file, suppressMap);
|
||||
}
|
||||
|
||||
private void loadFile(File file, Map<String, String> aliasMap) {
|
||||
/**
|
||||
* Loads the areas map with the suppress information in the file
|
||||
*
|
||||
* @param file
|
||||
* @param areas
|
||||
*/
|
||||
private void loadFile(File file, Map<String, List<Direction>> areas) {
|
||||
if ((file != null) && file.exists()) {
|
||||
Matcher m = null;
|
||||
BufferedReader fis = null;
|
||||
try {
|
||||
BufferedReader fis = new BufferedReader(new InputStreamReader(
|
||||
fis = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(file)));
|
||||
|
||||
String line = null;
|
||||
try {
|
||||
while ((line = fis.readLine()) != null) {
|
||||
m = ugcPattern.matcher(line);
|
||||
if (m.find()) {
|
||||
String dataKey = m.group();
|
||||
String data = ALL;
|
||||
List<Direction> suppressedDirections = new ArrayList<Direction>();
|
||||
String ugc = m.group();
|
||||
if (line.indexOf("ns") > 5) {
|
||||
data = NORTH_SOUTH;
|
||||
suppressedDirections = NORTH_SOUTH;
|
||||
} else if (line.indexOf("ew") > 5) {
|
||||
data = EAST_WEST;
|
||||
suppressedDirections = EAST_WEST;
|
||||
} else {
|
||||
suppressedDirections = ALL;
|
||||
}
|
||||
aliasMap.put(dataKey, data);
|
||||
areas.put(ugc, suppressedDirections);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block. Please revise as
|
||||
// appropriate.
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Could not read counties file: "
|
||||
+ AREA_SUPPRESS_FILENAME, e);
|
||||
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block. Please revise as
|
||||
// appropriate.
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Failed to find counties file: "
|
||||
+ AREA_SUPPRESS_FILENAME, e);
|
||||
|
||||
} finally {
|
||||
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error trying to close buffered reader ", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getType(String key) {
|
||||
if (suppressMap.containsKey(key)) {
|
||||
return suppressMap.get(key);
|
||||
} else {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,8 +35,10 @@ import com.raytheon.uf.common.time.util.TimeUtil;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Initial creation
|
||||
* May 7, 2013 1973 rferrel Changes to properly display Issue Time.
|
||||
* Jul 22, 2013 2176 jsanchez Added EMER to the display string in the update list.
|
||||
* Aug 7, 2013 2243 jsanchez Set all the attributes of an AbstractWarningRecord and added an expiration string. Removed calendar object.
|
||||
* Aug 15,2013 2243 jsanchez Improved the expiration string off by one minute. Fixed for practice mode.
|
||||
* Aug 15,2013 2243 jsanchez Improved the expiration string off by one minute.
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
|
@ -94,6 +96,9 @@ public class FollowupData extends AbstractWarningRecord {
|
|||
rval.append(buildExpStr(status, record));
|
||||
}
|
||||
|
||||
if (record.getRawmessage().contains("EMERGENCY")) {
|
||||
rval.append(" EMER");
|
||||
}
|
||||
equvialentString = rval.substring(0,
|
||||
record.getProductClass().equals("T") ? 20 : 18);
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ import org.eclipse.swt.graphics.RGB;
|
|||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.geotools.coverage.grid.GeneralGridEnvelope;
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.geometry.GeneralEnvelope;
|
||||
import org.geotools.geometry.jts.JTS;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
|
@ -57,7 +60,6 @@ import org.opengis.referencing.operation.MathTransform;
|
|||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.AreaType;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.BulletActionGroup;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.GridSpacing;
|
||||
|
@ -185,6 +187,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* 07/26/2013 DR 16376 Qinglu Lin Moved adjustVertex() and computeSlope() to PolygonUtil; removed calculateDistance();
|
||||
* updated AreaHatcher's run().
|
||||
* 07/26/2013 DR 16450 D. Friedman Fix logic errors when frame count is one.
|
||||
* 08/19/2013 2177 jsanchez Set a GeneralGridGeometry object in the GeospatialDataList.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -212,24 +215,28 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
IExtent localExtent;
|
||||
|
||||
int nx, ny;
|
||||
|
||||
GeneralGridGeometry localGridGeometry;
|
||||
}
|
||||
|
||||
private static class GeospatialDataAccessor {
|
||||
GeospatialDataList geoData;
|
||||
|
||||
AreaSourceConfiguration areaConfig;
|
||||
|
||||
public GeospatialDataAccessor(GeospatialDataList geoData,
|
||||
AreaSourceConfiguration areaConfig) {
|
||||
if (geoData == null || areaConfig == null) {
|
||||
throw new IllegalArgumentException("GeospatialDataAccessor must not be null");
|
||||
throw new IllegalArgumentException(
|
||||
"GeospatialDataAccessor must not be null");
|
||||
}
|
||||
this.geoData = geoData;
|
||||
this.areaConfig = areaConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the geometry area that intersects the cwa filter for the polygon in
|
||||
* local projection space
|
||||
* Build the geometry area that intersects the cwa filter for the
|
||||
* polygon in local projection space
|
||||
*
|
||||
* @param polygon
|
||||
* polygon to intersect with in lat/lon space
|
||||
|
@ -243,8 +250,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
PreparedGeometry prepGeom = (PreparedGeometry) r.attributes
|
||||
.get(GeospatialDataList.LOCAL_PREP_GEOM);
|
||||
try {
|
||||
Geometry intersection = GeometryUtil.intersection(polygon,
|
||||
prepGeom);
|
||||
Geometry intersection = GeometryUtil.intersection(
|
||||
polygon, prepGeom);
|
||||
if (intersection.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -407,7 +414,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
|
||||
try {
|
||||
warningPolygon = PolygonUtil.removeDuplicateCoordinate(warningPolygon);
|
||||
warningPolygon = PolygonUtil
|
||||
.removeDuplicateCoordinate(warningPolygon);
|
||||
Polygon hatched = polygonUtil.hatchWarningArea(
|
||||
warningPolygon,
|
||||
removeCounties(warningArea,
|
||||
|
@ -425,27 +433,37 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
LinearRing lr = gf.createLinearRing(coords);
|
||||
hatchedArea = gf.createPolygon(lr, null);
|
||||
int adjustPolygon_counter = 0;
|
||||
while (!hatchedArea.isValid() && adjustPolygon_counter < 1) {
|
||||
System.out.println("Calling adjustPolygon #" + adjustPolygon_counter);
|
||||
while (!hatchedArea.isValid()
|
||||
&& adjustPolygon_counter < 1) {
|
||||
System.out.println("Calling adjustPolygon #"
|
||||
+ adjustPolygon_counter);
|
||||
PolygonUtil.adjustPolygon(coords);
|
||||
PolygonUtil.round(coords, 2);
|
||||
coords = PolygonUtil.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil.removeOverlaidLinesegments(coords);
|
||||
coords = PolygonUtil
|
||||
.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil
|
||||
.removeOverlaidLinesegments(coords);
|
||||
lr = gf.createLinearRing(coords);
|
||||
hatchedArea = gf.createPolygon(lr, null);
|
||||
adjustPolygon_counter += 1;
|
||||
}
|
||||
int counter = 0;
|
||||
if (!hatchedArea.isValid() && counter < 2) {
|
||||
System.out.println("calling adjustVertex & alterVertexes: loop #" + counter);
|
||||
System.out
|
||||
.println("calling adjustVertex & alterVertexes: loop #"
|
||||
+ counter);
|
||||
int adjustVertex_counter = 0;
|
||||
lr = gf.createLinearRing(coords);
|
||||
hatchedArea = gf.createPolygon(lr, null);
|
||||
while (!hatchedArea.isValid() && adjustVertex_counter < 5) {
|
||||
System.out.println(" Calling adjustVertex #" + adjustVertex_counter);
|
||||
while (!hatchedArea.isValid()
|
||||
&& adjustVertex_counter < 5) {
|
||||
System.out.println(" Calling adjustVertex #"
|
||||
+ adjustVertex_counter);
|
||||
coords = PolygonUtil.adjustVertex(coords);
|
||||
coords = PolygonUtil.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil.removeOverlaidLinesegments(coords);
|
||||
coords = PolygonUtil
|
||||
.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil
|
||||
.removeOverlaidLinesegments(coords);
|
||||
lr = gf.createLinearRing(coords);
|
||||
hatchedArea = gf.createPolygon(lr, null);
|
||||
adjustVertex_counter += 1;
|
||||
|
@ -453,10 +471,14 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
int inner_counter = 0;
|
||||
System.out.println("");
|
||||
while (!hatchedArea.isValid() && inner_counter < 5) {
|
||||
System.out.println(" Calling alterVertexes #" + inner_counter);
|
||||
System.out
|
||||
.println(" Calling alterVertexes #"
|
||||
+ inner_counter);
|
||||
coords = PolygonUtil.alterVertexes(coords);
|
||||
coords = PolygonUtil.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil.removeOverlaidLinesegments(coords);
|
||||
coords = PolygonUtil
|
||||
.removeDuplicateCoordinate(coords);
|
||||
coords = PolygonUtil
|
||||
.removeOverlaidLinesegments(coords);
|
||||
lr = gf.createLinearRing(coords);
|
||||
hatchedArea = gf.createPolygon(lr, null);
|
||||
inner_counter += 1;
|
||||
|
@ -674,8 +696,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
displayState.angle = 0;
|
||||
displayState.speed = 0;
|
||||
} else if (checkStormTrackData(data = ToolsDataManager
|
||||
.getInstance()
|
||||
.getStormTrackData())) {
|
||||
.getInstance().getStormTrackData())) {
|
||||
displayState.angle = adjustAngle(data.getMotionDirection());
|
||||
displayState.speed = knotToMeterPerSec.convert(data
|
||||
.getMotionSpeed());
|
||||
|
@ -995,8 +1016,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
if (config != null) {
|
||||
init(config);
|
||||
displayState.setInitiallyMotionless(
|
||||
this.configuration.isTrackEnabled() == false
|
||||
displayState.setInitiallyMotionless(this.configuration
|
||||
.isTrackEnabled() == false
|
||||
|| this.configuration.getPathcastConfig() == null);
|
||||
}
|
||||
}
|
||||
|
@ -1044,9 +1065,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
+ (System.currentTimeMillis() - t0) + "ms");
|
||||
}
|
||||
|
||||
/** Adds geospatial data to siteMap and timezoneMap for the given
|
||||
* template configuration. This must not have any site effects on the
|
||||
* currently loaded template or the current product being edited.
|
||||
/**
|
||||
* Adds geospatial data to siteMap and timezoneMap for the given template
|
||||
* configuration. This must not have any site effects on the currently
|
||||
* loaded template or the current product being edited.
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
private void loadGeodataForConfiguration(WarngenConfiguration config) {
|
||||
|
@ -1083,7 +1106,6 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
Coordinate c = new GeometryFactory()
|
||||
.buildGeometry(geoms).getCentroid()
|
||||
.getCoordinate();
|
||||
|
||||
gData.latLonToLocal = MapUtil
|
||||
.getTransformFromLatLon(MapUtil
|
||||
.constructStereographic(
|
||||
|
@ -1146,6 +1168,18 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
gData.nx = nx;
|
||||
gData.ny = ny;
|
||||
|
||||
GeneralGridEnvelope range = new GeneralGridEnvelope(
|
||||
new int[] { 0, 0 }, new int[] { gData.nx,
|
||||
gData.ny }, false);
|
||||
GeneralEnvelope ge = new GeneralEnvelope(new double[] {
|
||||
gData.localExtent.getMinX(),
|
||||
gData.localExtent.getMaxY() }, new double[] {
|
||||
gData.localExtent.getMaxX(),
|
||||
gData.localExtent.getMinY() });
|
||||
|
||||
gData.localGridGeometry = new GeneralGridGeometry(
|
||||
range, ge);
|
||||
|
||||
System.out.println("Time to lookup geospatial data "
|
||||
+ (System.currentTimeMillis() - tq0));
|
||||
siteMap.put(currKey, gData);
|
||||
|
@ -1188,6 +1222,14 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
return new GeospatialData[0];
|
||||
}
|
||||
|
||||
public GeneralGridGeometry getLocalGridGeometry() {
|
||||
return geoData.localGridGeometry;
|
||||
}
|
||||
|
||||
public MathTransform getlocalToLatLon() {
|
||||
return geoData.localToLatLon;
|
||||
}
|
||||
|
||||
private GeospatialDataList getGeodataList(String areaSource,
|
||||
String localizedSite) {
|
||||
String key = areaSource + "." + localizedSite;
|
||||
|
@ -1303,7 +1345,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
* Returns a set of UGCs for each area in the CWA that intersects the given
|
||||
* polygon.
|
||||
*/
|
||||
public Set<String> getUgcsForCountyWatches(Polygon polygon) throws Exception {
|
||||
public Set<String> getUgcsForCountyWatches(Polygon polygon)
|
||||
throws Exception {
|
||||
GeospatialDataAccessor gda = getCountyGeospatialDataAcessor();
|
||||
Set<String> ugcs = new HashSet<String>();
|
||||
for (String fips : gda.getAllFipsInArea(gda.buildArea(polygon))) {
|
||||
|
@ -1321,17 +1364,20 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
return ugcs;
|
||||
}
|
||||
|
||||
private GeospatialDataAccessor getCountyGeospatialDataAcessor() throws Exception {
|
||||
private GeospatialDataAccessor getCountyGeospatialDataAcessor()
|
||||
throws Exception {
|
||||
GeospatialDataList gdl = searchCountyGeospatialDataAccessor();
|
||||
if (gdl == null) {
|
||||
// Cause county geospatial data to be loaded
|
||||
// TODO: Should not be referencing tornadoWarning.
|
||||
WarngenConfiguration torConfig = WarngenConfiguration.loadConfig("tornadoWarning", getLocalizedSite());
|
||||
WarngenConfiguration torConfig = WarngenConfiguration.loadConfig(
|
||||
"tornadoWarning", getLocalizedSite());
|
||||
loadGeodataForConfiguration(torConfig);
|
||||
gdl = searchCountyGeospatialDataAccessor();
|
||||
}
|
||||
|
||||
// TODO: There should be some way to get the "county" configuration by name
|
||||
// TODO: There should be some way to get the "county" configuration by
|
||||
// name
|
||||
// independent of a template
|
||||
AreaSourceConfiguration areaConfig = new AreaSourceConfiguration();
|
||||
areaConfig.setFipsField("FIPS");
|
||||
|
@ -1341,7 +1387,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
private GeospatialDataList searchCountyGeospatialDataAccessor() {
|
||||
synchronized (siteMap) {
|
||||
for (Map.Entry<String, GeospatialDataList> entry : siteMap.entrySet()) {
|
||||
for (Map.Entry<String, GeospatialDataList> entry : siteMap
|
||||
.entrySet()) {
|
||||
String[] keyParts = entry.getKey().split("\\.");
|
||||
if (keyParts.length == 2
|
||||
&& "county".equalsIgnoreCase(keyParts[0])
|
||||
|
@ -1938,8 +1985,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
return;
|
||||
}
|
||||
if (warningAction == null || warningAction == WarningAction.NEW) {
|
||||
if ((configuration.isTrackEnabled() == false ||
|
||||
configuration.getPathcastConfig() == null)
|
||||
if ((configuration.isTrackEnabled() == false || configuration
|
||||
.getPathcastConfig() == null)
|
||||
&& !this.displayState.isNonstationary()
|
||||
&& this.displayState.displayType != DisplayType.POLY) {
|
||||
createSquare();
|
||||
|
@ -2271,8 +2318,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
|
||||
Point point = displayState.dragMePoint;
|
||||
if (motdir != null && motspd != null &&
|
||||
(motspd != 0 || configuration.isTrackEnabled())) {
|
||||
if (motdir != null && motspd != null
|
||||
&& (motspd != 0 || configuration.isTrackEnabled())) {
|
||||
displayState.setInitiallyMotionless(false);
|
||||
displayState.angle = adjustAngle(motdir);
|
||||
displayState.speed = knotToMeterPerSec.convert(motspd);
|
||||
|
@ -2325,10 +2372,9 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
if (m.find()) {
|
||||
int hour = Integer.parseInt(m.group(1));
|
||||
int minute = Integer.parseInt(m.group(2));
|
||||
frameTime = TimeUtil.timeOfDayToAbsoluteTime(
|
||||
hour * TimeUtil.SECONDS_PER_HOUR +
|
||||
minute * TimeUtil.SECONDS_PER_MINUTE,
|
||||
warnRecord.getIssueTime());
|
||||
frameTime = TimeUtil.timeOfDayToAbsoluteTime(hour
|
||||
* TimeUtil.SECONDS_PER_HOUR + minute
|
||||
* TimeUtil.SECONDS_PER_MINUTE, warnRecord.getIssueTime());
|
||||
} else {
|
||||
frameTime = warnRecord.getIssueTime();
|
||||
}
|
||||
|
@ -2376,8 +2422,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
FramesInfo info = descriptor.getFramesInfo();
|
||||
int currentFrame = trackUtil.getCurrentFrame(info);
|
||||
int frameCount = trackUtil.getFrameCount(info);
|
||||
if (currentFrame == frameCount - 1
|
||||
|| ! displayState.isNonstationary()) {
|
||||
if (currentFrame == frameCount - 1 || !displayState.isNonstationary()) {
|
||||
return coordinate;
|
||||
}
|
||||
DataTime[] datatimes = trackUtil.getDataTimes(info);
|
||||
|
@ -2686,7 +2731,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
getFips(f));
|
||||
if (tmp.isEmpty()) {
|
||||
String fip = getFips(f);
|
||||
if (fip != null && uniqueFip != null && fip.equals(uniqueFip)) {
|
||||
if (fip != null && uniqueFip != null
|
||||
&& fip.equals(uniqueFip)) {
|
||||
updateWarnedAreas(true);
|
||||
}
|
||||
break;
|
||||
|
@ -2769,8 +2815,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
if (areaHatcher != null) {
|
||||
Polygon polygon = state.getWarningPolygon();
|
||||
polygon = tryToIntersectWithOriginalPolygon(polygon);
|
||||
areaHatcher.hatchArea(polygon,
|
||||
state.getWarningArea(),
|
||||
areaHatcher.hatchArea(polygon, state.getWarningArea(),
|
||||
state.getOldWarningPolygon());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ import com.raytheon.viz.warngen.gis.Area;
|
|||
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil;
|
||||
import com.raytheon.viz.warngen.gis.PathCast;
|
||||
import com.raytheon.viz.warngen.gis.PortionsUtil;
|
||||
import com.raytheon.viz.warngen.gis.Wx;
|
||||
import com.raytheon.viz.warngen.gui.BackupData;
|
||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
||||
|
@ -154,6 +155,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* May 10, 2013 1951 rjpeter Updated ugcZones references
|
||||
* May 30, 2013 DR 16237 D. Friedman Fix watch query.
|
||||
* Jun 18, 2013 2118 njensen Only calculate pathcast if it's actually used
|
||||
* Aug 19, 2013 2177 jsanchez Passed PortionsUtil to Area class.
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -301,17 +303,18 @@ public class TemplateRunner {
|
|||
AffectedAreas[] cancelareas = null;
|
||||
Map<String, Object> intersectAreas = null;
|
||||
Wx wx = null;
|
||||
Area area = new Area(new PortionsUtil(warngenLayer));
|
||||
long wwaMNDTime = 0l;
|
||||
try {
|
||||
t0 = System.currentTimeMillis();
|
||||
areas = Area.findAffectedAreas(config, warnPolygon, warningArea,
|
||||
areas = area.findAffectedAreas(config, warnPolygon, warningArea,
|
||||
threeLetterSiteId);
|
||||
System.out.println("Time to get areas = "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
context.put(config.getHatchedAreaSource().getVariable(), areas);
|
||||
|
||||
t0 = System.currentTimeMillis();
|
||||
intersectAreas = Area.findInsectingAreas(config, warnPolygon,
|
||||
intersectAreas = area.findInsectingAreas(config, warnPolygon,
|
||||
warningArea, threeLetterSiteId, warngenLayer);
|
||||
System.out.println("Time to get intersecting areas = "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
|
@ -324,10 +327,11 @@ public class TemplateRunner {
|
|||
double minSize = 1.0E-3d;
|
||||
if ((areas != null) && (areas.length > 0)) {
|
||||
Set<String> timeZones = new HashSet<String>();
|
||||
for (AffectedAreas area : areas) {
|
||||
if (area.getTimezone() != null) {
|
||||
for (AffectedAreas affectedAreas : areas) {
|
||||
if (affectedAreas.getTimezone() != null) {
|
||||
// Handles counties that span two time zones
|
||||
String oneLetterTimeZones = area.getTimezone().trim();
|
||||
String oneLetterTimeZones = affectedAreas.getTimezone()
|
||||
.trim();
|
||||
oneLetterTZ = new String[oneLetterTimeZones.length()];
|
||||
if (oneLetterTimeZones.length() == 1) {
|
||||
timeZones.add(String.valueOf(oneLetterTimeZones
|
||||
|
@ -799,14 +803,14 @@ public class TemplateRunner {
|
|||
Geometry removedAreas = warngenLayer.getWarningAreaForGids(
|
||||
oldGids, oldWarningArea);
|
||||
if (removedAreas.isEmpty() == false) {
|
||||
cancelareas = Area.findAffectedAreas(config,
|
||||
cancelareas = area.findAffectedAreas(config,
|
||||
oldWarn.getGeometry(), removedAreas,
|
||||
threeLetterSiteId);
|
||||
for (int i = 0; i < cancelareas.length; i++) {
|
||||
for (AffectedAreas area : areas) {
|
||||
for (AffectedAreas affectedAreas : areas) {
|
||||
if ((cancelareas[i] != null)
|
||||
&& cancelareas[i].getFips().equals(
|
||||
area.getFips())) {
|
||||
affectedAreas.getFips())) {
|
||||
cancelareas[i] = null;
|
||||
}
|
||||
}
|
||||
|
@ -824,7 +828,7 @@ public class TemplateRunner {
|
|||
// This may not be efficient enough. Is it possible that
|
||||
// a removed intersected county be in the affected
|
||||
// intersected county. Need an example to fully test.
|
||||
Map<String, Object> intersectRemovedAreas = Area
|
||||
Map<String, Object> intersectRemovedAreas = area
|
||||
.findInsectingAreas(config, warnPolygon,
|
||||
removedAreas, threeLetterSiteId,
|
||||
warngenLayer);
|
||||
|
|
|
@ -73,6 +73,7 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
* May 10, 2013 1951 rjpeter Updated ugcZones references
|
||||
* May 31, 2013 DR 16264 D. Friedman Fix query in prepare method.
|
||||
* Jun 05, 2013 DR 16279 D. Friedman Fix updating of issuance time for followups.
|
||||
* Jul 22, 2013 2176 jsanchez Set the raw message for an EXT.
|
||||
* Aug 14, 2013 DR 16483 Qinglu Lin Fixed no option issue in WarnGen dropdown menu after
|
||||
* issuance of an CANCON and restart of CAVE.
|
||||
* </pre>
|
||||
|
@ -314,6 +315,7 @@ public class CurrentWarnings {
|
|||
if (rval != null) {
|
||||
rval.setEndTime(warning.getEndTime());
|
||||
rval.setIssueTime(warning.getIssueTime());
|
||||
rval.setRawmessage(warning.getRawmessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
|||
* Apr 18, 2013 1877 jsanchez Had the child classes set the comparator. Fixed a null pointer.
|
||||
* Remove frameAltered condition in matchesFrame. It prevented entries from being displayed.
|
||||
* Check if geometry is null when inspecting.
|
||||
* Jul 22, 2013 2176 jsanchez Updated the wire frame and text for EMERGENCY warnings.
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
|
@ -358,14 +359,23 @@ public abstract class AbstractWWAResource extends
|
|||
}
|
||||
|
||||
if (entry != null && entry.wireframeShape != null) {
|
||||
LineStyle lineStyle = (record.getProductClass() != null && record
|
||||
.getProductClass().equals("T")) ? LineStyle.DASHED
|
||||
: LineStyle.SOLID;
|
||||
LineStyle lineStyle = LineStyle.SOLID;
|
||||
if (record.getProductClass() != null
|
||||
&& record.getProductClass().equals("T")) {
|
||||
lineStyle = LineStyle.DASHED;
|
||||
}
|
||||
|
||||
int outlineWidth = getCapability(OutlineCapability.class)
|
||||
.getOutlineWidth();
|
||||
// Make wire frame outline thicker for EMERGENCY warnings
|
||||
if (record.getRawmessage().contains("EMERGENCY")) {
|
||||
outlineWidth *= 2;
|
||||
}
|
||||
|
||||
target.drawWireframeShape(
|
||||
entry.wireframeShape,
|
||||
getCapability(ColorableCapability.class).getColor(),
|
||||
getCapability(OutlineCapability.class)
|
||||
.getOutlineWidth(), lineStyle);
|
||||
outlineWidth, lineStyle);
|
||||
} else if (entry != null && entry.shadedShape != null) {
|
||||
target.drawShadedShape(entry.shadedShape, 1);
|
||||
}
|
||||
|
@ -409,6 +419,14 @@ public abstract class AbstractWWAResource extends
|
|||
params.magnification = getCapability(
|
||||
MagnificationCapability.class).getMagnification();
|
||||
target.drawStrings(params);
|
||||
|
||||
// Draws the string again to have it appear bolder
|
||||
if (textToPrintReversed[2].endsWith("EMER")) {
|
||||
params.setText(new String[] { "", "", "EMER", "" },
|
||||
color);
|
||||
target.drawStrings(params);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -581,7 +599,11 @@ public abstract class AbstractWWAResource extends
|
|||
}
|
||||
textToPrint[0] += "." + record.getEtn();
|
||||
|
||||
textToPrint[1] = record.getPil();
|
||||
if (record.getRawmessage().contains("EMERGENCY")) {
|
||||
textToPrint[1] = record.getPil() + " EMER";
|
||||
} else {
|
||||
textToPrint[1] = record.getPil();
|
||||
}
|
||||
|
||||
SimpleDateFormat startFormat = DEFAULT_FORMAT;
|
||||
SimpleDateFormat endFormat = DEFAULT_FORMAT;
|
||||
|
|
22
deltaScripts/13.5.2/addBufrmosDataURI.sh
Normal file
22
deltaScripts/13.5.2/addBufrmosDataURI.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# DR #2275 - this script is needd to add the dataURI column back into the
|
||||
# bufrmosavn and bufrmoshpc tables.
|
||||
|
||||
PSQL="/awips2/psql/bin/psql"
|
||||
|
||||
${PSQL} -U awips -d metadata -c "ALTER TABLE bufrmosavn ADD COLUMN datauri character varying(255);"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to drop dataURI column for bufrmosavn"
|
||||
echo "FATAL: The update has failed."
|
||||
exit 1
|
||||
fi
|
||||
${PSQL} -U awips -d metadata -c "ALTER TABLE bufrmoshpc ADD COLUMN datauri character varying(255);"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Failed to add dataURI column for bufrmoshpc"
|
||||
echo "FATAL: The update has failed."
|
||||
exit 1
|
||||
fi
|
||||
${PSQL} -U awips -d metadata -c "VACUUM FULL ANALYZE bufrmosavn"
|
||||
${PSQL} -U awips -d metadata -c "VACUUM FULL ANALYZE bufrmoshpc"
|
||||
|
||||
echo "INFO: dataURI columns added successfully"
|
|
@ -28,6 +28,10 @@
|
|||
<mkdir dir="${gfesuite.directory}/products/ISC" />
|
||||
<mkdir dir="${gfesuite.directory}/products/ATBL" />
|
||||
|
||||
<!-- Create directories used by Service Backup export_grids script -->
|
||||
<mkdir dir="${gfesuite.directory}/exportgrids/primary" />
|
||||
<mkdir dir="${gfesuite.directory}/exportgrids/backup" />
|
||||
|
||||
<!-- Adjust GFESuite permissions -->
|
||||
<chmod perm="ugo+rx">
|
||||
<fileset dir="${gfesuite.directory}/bin">
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
**/
|
||||
package com.raytheon.edex.plugin.bufrmos.common;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
|
@ -48,6 +51,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|||
* May 07, 2013 1869 bsteffen Remove dataURI column from
|
||||
* PluginDataObject.
|
||||
* May 14, 2013 1869 bsteffen Remove DataURI column from bufrmos.
|
||||
* Aug 19, 2013 2275 bsteffen Add dataURI column back into bufrmos
|
||||
* types.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -77,4 +82,11 @@ public class BufrMosAvnData extends BufrMosData {
|
|||
return MOSType.AVN;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Column
|
||||
@Access(AccessType.PROPERTY)
|
||||
public String getDataURI() {
|
||||
return super.getDataURI();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
**/
|
||||
package com.raytheon.edex.plugin.bufrmos.common;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
|
@ -48,6 +51,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
|||
* May 07, 2013 1869 bsteffen Remove dataURI column from
|
||||
* PluginDataObject.
|
||||
* May 14, 2013 1869 bsteffen Remove DataURI column from bufrmos.
|
||||
* Aug 19, 2013 2275 bsteffen Add dataURI column back into bufrmos
|
||||
* types.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -77,4 +82,11 @@ public class BufrMosHpcData extends BufrMosData {
|
|||
return MOSType.HPC;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Column
|
||||
@Access(AccessType.PROPERTY)
|
||||
public String getDataURI() {
|
||||
return super.getDataURI();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ import com.raytheon.uf.edex.database.cluster.ClusterTask;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 10/15/10 6644 bphillip Initial Creation
|
||||
* Oct 15, 2010 6644 bphillip Initial Creation
|
||||
* Jul 18, 2013 2194 bsteffen Fix site override.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -191,9 +192,8 @@ public class GribLargeFileChecker implements Processor {
|
|||
File siteModelFile = new File(sitePath);
|
||||
if (siteModelFile.exists()) {
|
||||
sitePatterns = loadPatterns(siteModelFile);
|
||||
} else {
|
||||
basePatterns = loadPatterns(modelFile);
|
||||
}
|
||||
basePatterns = loadPatterns(modelFile);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.raytheon.uf.common.geospatial;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.referencing.CRS;
|
||||
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
||||
import org.geotools.referencing.operation.transform.IdentityTransform;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
|
@ -166,6 +167,27 @@ public class TransformFactory {
|
|||
return factory.createConcatenatedTransform(mt1, mt2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a transform from the "world" CRS of the crs passed in. null
|
||||
* will be returned if no "world" crs exists.
|
||||
*
|
||||
* @param crs
|
||||
* @return
|
||||
* @throws FactoryException
|
||||
*/
|
||||
public static MathTransform worldToCRS(CoordinateReferenceSystem crs)
|
||||
throws FactoryException {
|
||||
CoordinateReferenceSystem worldCRS = crs;
|
||||
while (worldCRS instanceof GeneralDerivedCRS) {
|
||||
GeneralDerivedCRS derivedCRS = (GeneralDerivedCRS) worldCRS;
|
||||
worldCRS = derivedCRS.getBaseCRS();
|
||||
}
|
||||
if (worldCRS != crs) {
|
||||
return CRS.findMathTransform(worldCRS, crs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a transform from the "world" CRS of the target geometry to the
|
||||
* grid of the targetGeometry. Will return crsToGrid if no "world" CRS
|
||||
|
@ -178,23 +200,19 @@ public class TransformFactory {
|
|||
*/
|
||||
public static MathTransform worldToGrid(GeneralGridGeometry targetGeometry,
|
||||
PixelInCell cellType) throws FactoryException {
|
||||
CoordinateReferenceSystem crs = targetGeometry.getEnvelope()
|
||||
.getCoordinateReferenceSystem();
|
||||
try {
|
||||
if (crs instanceof GeneralDerivedCRS) {
|
||||
GeneralDerivedCRS projCRS = (GeneralDerivedCRS) crs;
|
||||
CoordinateReferenceSystem worldCRS = projCRS.getBaseCRS();
|
||||
MathTransform worldToCRS = CRSCache.getInstance()
|
||||
.findMathTransform(worldCRS, crs);
|
||||
|
||||
MathTransform crsToPixel = targetGeometry
|
||||
.getGridToCRS(cellType).inverse();
|
||||
return factory.createConcatenatedTransform(worldToCRS,
|
||||
crsToPixel);
|
||||
} else {
|
||||
// No associated "world" CRS, go straight crs to grid
|
||||
return targetGeometry.getGridToCRS(cellType).inverse();
|
||||
CoordinateReferenceSystem crs = targetGeometry.getEnvelope()
|
||||
.getCoordinateReferenceSystem();
|
||||
MathTransform worldToCRS = worldToCRS(crs);
|
||||
MathTransform worldToGrid = targetGeometry.getGridToCRS(cellType)
|
||||
.inverse();
|
||||
if (worldToCRS != null) {
|
||||
worldToGrid = factory.createConcatenatedTransform(worldToCRS,
|
||||
worldToGrid);
|
||||
}
|
||||
return worldToGrid;
|
||||
} catch (FactoryException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new FactoryException(e);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.JAXBContextBuilder;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 12, 2011 mschenke Initial creation
|
||||
* June 24, 2013 #2126 bkowal Update for Java 7 compatibility
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -54,6 +55,7 @@ import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.JAXBContextBuilder;
|
|||
|
||||
public class SerializationContextFactory {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static JAXBContext createContext(Class[] classes, Map props) {
|
||||
// Construct delegate implementation
|
||||
System.setProperty(JAXBContextImpl.class.getName() + ".fastBoot",
|
||||
|
@ -68,7 +70,7 @@ public class SerializationContextFactory {
|
|||
// TODO: Can we override/extend some part of the context
|
||||
// implementation to allow for ignoring of xsi:type fields that we
|
||||
// don't have classes for?
|
||||
return new CustomJAXBContext(new JAXBContextImpl(builder));
|
||||
return new CustomJAXBContext(builder.build());
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
# 04/29/13 #1761 dgilling Remove use of NATIONAL_CENTER,
|
||||
# script caller will determine
|
||||
# which sites to export.
|
||||
# 05/16/13 #2009 dgilling New backup structure:
|
||||
# PRIMARY_SITES go to exportgrids/primary/
|
||||
# and all other go to exportgrids/backup/.
|
||||
##############################################################################
|
||||
|
||||
if [ ${#AWIPS_HOME} = 0 ]
|
||||
|
@ -114,9 +117,30 @@ else
|
|||
fi
|
||||
$LOGGER ${DB_NAME}
|
||||
|
||||
# use PRIMARY_SITES setting to determine NETCDF_PATH
|
||||
IFS=',' read -ra PRI_SITES <<< "${PRIMARY_SITES}"
|
||||
if [ ${#PRI_SITES[@]} -eq 0 ]
|
||||
then
|
||||
declare -a PRI_SITES=( "${AW_SITE_IDENTIFIER}" )
|
||||
fi
|
||||
EXPORT_FOR_PRIMARY=0
|
||||
for primary_site in "${PRI_SITES[@]}"
|
||||
do
|
||||
primary_site=`echo $primary_site | tr [a-z] [A-Z]`
|
||||
if [ "$primary_site" = "${CAPS_SITE}" ]
|
||||
then
|
||||
EXPORT_FOR_PRIMARY=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
NETCDF_PATH=${GFESUITE_HOME}/exportgrids/primary
|
||||
export NETCDF_TMP_PATH=/tmp/exportgrids
|
||||
if [ $EXPORT_FOR_PRIMARY = 0 ]
|
||||
then
|
||||
NETCDF_PATH=${GFESUITE_HOME}/exportgrids/backup
|
||||
fi
|
||||
|
||||
NETCDF_PATH=${GFESUITE_HOME}/exportgrids
|
||||
export NETCDF_TMP_PATH=${NETCDF_PATH}/tmp
|
||||
if [ ! -d ${NETCDF_TMP_PATH} ]; then
|
||||
mkdir ${NETCDF_TMP_PATH}
|
||||
chmod 777 ${NETCDF_TMP_PATH}
|
||||
|
|
Binary file not shown.
|
@ -24,30 +24,14 @@
|
|||
<Directory Id="ProgramFilesFolder" Name="PFiles">
|
||||
<Directory Id="INSTALLDIR" Name="Raytheon">
|
||||
<Directory Id="AwipsII" Name="AWIPS II">
|
||||
<Directory Id="CaveDir" Name="CAVE">
|
||||
<Component Id="caveBatch" Guid="8924277C-5B6A-4EEB-AE9F-5471481F92A6">
|
||||
<File Id="caveBAT" Name="cave.bat"
|
||||
DiskId="1" Source="SourceDir\CAVE\cave.bat" />
|
||||
<Shortcut Id="caveDesktopShortcut" Directory="DesktopFolder" Name="CAVE"
|
||||
WorkingDirectory="CaveDir" Advertise="yes" Icon="cave.exe" IconIndex="0"
|
||||
Arguments="-component thinclient" />
|
||||
<Shortcut Id="caveStartMenu" Directory="ProgramMenuDir" Name="CAVE"
|
||||
WorkingDirectory="CaveDir" Advertise="yes" Icon="cave.exe" IconIndex="0"
|
||||
Arguments="-component thinclient" />
|
||||
<Component Id="VizLauncherExe" Guid="8924277C-5B6A-4EEB-AE9F-5471481F92A6">
|
||||
<File Id="VizLauncherExe" Name="VizLauncher.exe"
|
||||
DiskId="1" Source="SourceDir\VizLauncher.exe" />
|
||||
<Shortcut Id="vizLauncherDesktopShortcut" Directory="DesktopFolder" Name="Viz Launcher"
|
||||
WorkingDirectory="SourceDir" Advertise="yes" Icon="cave.exe" IconIndex="0" />
|
||||
<Shortcut Id="vizLauncherStartMenu" Directory="ProgramMenuDir" Name="Viz Launcher"
|
||||
WorkingDirectory="SourceDir" Advertise="yes" Icon="cave.exe" IconIndex="0" />
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="AlertvizDir" Name="AlertViz">
|
||||
<Component Id="alertvizBatch" Guid="8924277C-5B6A-4EEB-AE9F-5471481F92B4">
|
||||
<File Id="alertvizBAT" Name="alertviz.bat"
|
||||
DiskId="1" Source="SourceDir\AlertViz\alertviz.bat" />
|
||||
<Shortcut Id="alertvizDesktopShortcut" Directory="DesktopFolder" Name="AlertViz"
|
||||
WorkingDirectory="AlertvizDir" Advertise="yes" Icon="alertviz.exe" IconIndex="0"
|
||||
Arguments="-component thinalertviz" />
|
||||
<Shortcut Id="alertvizStartMenu" Directory="ProgramMenuDir" Name="AlertViz"
|
||||
WorkingDirectory="AlertvizDir" Advertise="yes" Icon="alertviz.exe" IconIndex="0"
|
||||
Arguments="-component thinalertviz" />
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
|
@ -71,7 +55,6 @@
|
|||
<Feature Id="AWIPS_II_CAVE" Title="AWIPS II CAVE" Level="1"
|
||||
Display="expand" Description="AWIPS II Common AWIPS Visualization Environment (CAVE)"
|
||||
ConfigurableDirectory="INSTALLDIR">
|
||||
<ComponentRef Id="caveBatch" />
|
||||
<ComponentRef Id="ProgramMenuDir" />
|
||||
|
||||
<ComponentGroupRef Id="AWIPSII_CAVE" />
|
||||
|
@ -80,16 +63,20 @@
|
|||
<Feature Id="AWIPS_II_ALERTVIZ" Title="AWIPS II AlertViz" Level="1"
|
||||
Display="expand" Description="AWIPS II AlertViz"
|
||||
ConfigurableDirectory="INSTALLDIR">
|
||||
<ComponentRef Id="alertvizBatch" />
|
||||
|
||||
<ComponentGroupRef Id="AWIPSII_ALERTVIZ" />
|
||||
</Feature>
|
||||
|
||||
<Feature Id="AWIPS_II_LAUNCHER" Title="AWIPS II Viz Launcher" Level="1"
|
||||
Display="expand" Description="Viz Launcher - Starts both AlertViz and CAVE"
|
||||
ConfigurableDirectory="INSTALLDIR">
|
||||
<ComponentRef Id="VizLauncherExe" />
|
||||
</Feature>
|
||||
|
||||
<UIRef Id="WixUI_FeatureTree" />
|
||||
<UIRef Id="WixUI_ErrorProgressText" />
|
||||
|
||||
<Icon Id="cave.exe" SourceFile="SourceDir\CAVE\cave.exe" />
|
||||
<Icon Id="alertviz.exe" SourceFile="SourceDir\AlertViz\alertviz.exe" />
|
||||
|
||||
</Product>
|
||||
</Wix>
|
||||
|
|
20
msi/VizLauncher/VizLauncher.sln
Normal file
20
msi/VizLauncher/VizLauncher.sln
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VizLauncher", "VizLauncher\VizLauncher.csproj", "{45B15612-0725-479C-8E1B-9B63F2FB45A3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{45B15612-0725-479C-8E1B-9B63F2FB45A3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{45B15612-0725-479C-8E1B-9B63F2FB45A3}.Debug|x86.Build.0 = Debug|x86
|
||||
{45B15612-0725-479C-8E1B-9B63F2FB45A3}.Release|x86.ActiveCfg = Release|x86
|
||||
{45B15612-0725-479C-8E1B-9B63F2FB45A3}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
msi/VizLauncher/VizLauncher.suo
Normal file
BIN
msi/VizLauncher/VizLauncher.suo
Normal file
Binary file not shown.
79
msi/VizLauncher/VizLauncher/Form1.Designer.cs
generated
Normal file
79
msi/VizLauncher/VizLauncher/Form1.Designer.cs
generated
Normal file
|
@ -0,0 +1,79 @@
|
|||
namespace VizLauncher
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.lblFailureDetail = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
|
||||
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label1.Location = new System.Drawing.Point(12, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(337, 50);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Failed to Start AWIPS II Viz!";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// lblFailureDetail
|
||||
//
|
||||
this.lblFailureDetail.BackColor = System.Drawing.Color.White;
|
||||
this.lblFailureDetail.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblFailureDetail.Location = new System.Drawing.Point(14, 59);
|
||||
this.lblFailureDetail.Name = "lblFailureDetail";
|
||||
this.lblFailureDetail.Size = new System.Drawing.Size(335, 119);
|
||||
this.lblFailureDetail.TabIndex = 1;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(361, 187);
|
||||
this.Controls.Add(this.lblFailureDetail);
|
||||
this.Controls.Add(this.label1);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "Form1";
|
||||
this.ShowInTaskbar = false;
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Viz Launcher";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label lblFailureDetail;
|
||||
}
|
||||
}
|
||||
|
20
msi/VizLauncher/VizLauncher/Form1.cs
Normal file
20
msi/VizLauncher/VizLauncher/Form1.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace VizLauncher
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
public Form1(String errorText)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.lblFailureDetail.Text = errorText;
|
||||
}
|
||||
}
|
||||
}
|
120
msi/VizLauncher/VizLauncher/Form1.resx
Normal file
120
msi/VizLauncher/VizLauncher/Form1.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
31
msi/VizLauncher/VizLauncher/Program.cs
Normal file
31
msi/VizLauncher/VizLauncher/Program.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using VizLauncher.com.raytheon.viz.launcher;
|
||||
|
||||
namespace VizLauncher
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
VizLauncher.com.raytheon.viz.launcher.VizLauncher vizLauncher =
|
||||
new VizLauncher.com.raytheon.viz.launcher.VizLauncher();
|
||||
bool success = vizLauncher.run(Application.StartupPath);
|
||||
if (success == false)
|
||||
{
|
||||
// Display the "Failure" dialog.
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Form1(vizLauncher.getErrorDetail()));
|
||||
}
|
||||
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
}
|
36
msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs
Normal file
36
msi/VizLauncher/VizLauncher/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("VizLauncher")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("VizLauncher")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("7f929b46-b56e-47eb-b6e6-ff79e54f6572")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs
generated
Normal file
71
msi/VizLauncher/VizLauncher/Properties/Resources.Designer.cs
generated
Normal file
|
@ -0,0 +1,71 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.17929
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace VizLauncher.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VizLauncher.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
msi/VizLauncher/VizLauncher/Properties/Resources.resx
Normal file
117
msi/VizLauncher/VizLauncher/Properties/Resources.resx
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
30
msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs
generated
Normal file
30
msi/VizLauncher/VizLauncher/Properties/Settings.Designer.cs
generated
Normal file
|
@ -0,0 +1,30 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.17929
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace VizLauncher.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
msi/VizLauncher/VizLauncher/Properties/Settings.settings
Normal file
7
msi/VizLauncher/VizLauncher/Properties/Settings.settings
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
94
msi/VizLauncher/VizLauncher/VizLauncher.csproj
Normal file
94
msi/VizLauncher/VizLauncher/VizLauncher.csproj
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{45B15612-0725-479C-8E1B-9B63F2FB45A3}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VizLauncher</RootNamespace>
|
||||
<AssemblyName>VizLauncher</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="com\raytheon\viz\launcher\environment\EnvironmentProperties.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\environment\VizEnvironment.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\process\AbstractProcessLauncher.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\process\impl\AlertvizProcessLauncher.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\process\impl\CaveProcessLauncher.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\process\IProcessLauncher.cs" />
|
||||
<Compile Include="com\raytheon\viz\launcher\VizLauncher.cs" />
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
3
msi/VizLauncher/VizLauncher/VizLauncher.csproj.user
Normal file
3
msi/VizLauncher/VizLauncher/VizLauncher.csproj.user
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using VizLauncher.com.raytheon.viz.launcher.environment;
|
||||
using VizLauncher.com.raytheon.viz.launcher.process;
|
||||
using VizLauncher.com.raytheon.viz.launcher.process.impl;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher
|
||||
{
|
||||
public class VizLauncher
|
||||
{
|
||||
private String errorDetail;
|
||||
|
||||
public bool run(String location)
|
||||
{
|
||||
VizEnvironment vizEnvironment = new VizEnvironment(location);
|
||||
if (vizEnvironment.isReady() == false)
|
||||
{
|
||||
this.errorDetail = vizEnvironment.getExceptionText();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Alternatively, we would be able to construct both process launchers using Spring and inject them. */
|
||||
|
||||
// Construct the AlertViz Process Launcher.
|
||||
IProcessLauncher alertvizProcessLauncher = new AlertvizProcessLauncher(vizEnvironment);
|
||||
if (alertvizProcessLauncher.isReady() == false)
|
||||
{
|
||||
this.errorDetail = alertvizProcessLauncher.getExceptionText();
|
||||
return false;
|
||||
}
|
||||
Thread alertvizThread = new Thread(alertvizProcessLauncher.launchProcess);
|
||||
|
||||
// Construct the CAVE Process Launcher.
|
||||
IProcessLauncher caveProcessLauncher = new CaveProcessLauncher(vizEnvironment);
|
||||
if (caveProcessLauncher.isReady() == false)
|
||||
{
|
||||
this.errorDetail = caveProcessLauncher.getExceptionText();
|
||||
return false;
|
||||
}
|
||||
Thread caveThread = new Thread(caveProcessLauncher.launchProcess);
|
||||
|
||||
// Start AlertViz.
|
||||
alertvizThread.Start();
|
||||
|
||||
// Delay - Give Alertviz Time To Start.
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Start CAVE.
|
||||
caveThread.Start();
|
||||
|
||||
// Wait for CAVE.
|
||||
caveThread.Join();
|
||||
|
||||
// Wait for AlertViz.
|
||||
alertvizThread.Join();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getErrorDetail()
|
||||
{
|
||||
return this.errorDetail;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.environment
|
||||
{
|
||||
public abstract class EnvironmentProperties
|
||||
{
|
||||
/* Environment Properties */
|
||||
public static readonly String USER_HOME_ENV_PROPERTY = "%HOMEDRIVE%%HOMEPATH%";
|
||||
public static readonly String COMPUTER_NAME_ENV_PROPERTY = "%COMPUTERNAME%";
|
||||
|
||||
/* Registry Constants */
|
||||
public static readonly String A2_JAVA_REG = @"Software\Raytheon\Runtime Environment\AWIPS II Java";
|
||||
public static readonly String A2_PYTHON_REG = @"Software\Raytheon\Runtime Environment\AWIPS II Python";
|
||||
|
||||
public static readonly String JAVA_JRE_VALUE_NAME = "JavaJreDirectory";
|
||||
public static readonly String PYTHON_INSTALL_NAME = "PythonInstallDirectory";
|
||||
|
||||
/* Environment Additions */
|
||||
public static readonly String ENVIRONMENT_VARIABLE_PATH = "Path";
|
||||
public static readonly String ENVIRONMENT_VARIABLE_PYTHON_PATH = "PythonPath";
|
||||
|
||||
public static readonly String PATH_PYTHON_DLLS = Path.DirectorySeparatorChar + "DLLs";
|
||||
public static readonly String PATH_JAVA_BIN = Path.DirectorySeparatorChar + "bin";
|
||||
|
||||
public static readonly String PYTHON_PATH_PYTHON_LIBTK =
|
||||
Path.DirectorySeparatorChar + "Lib" + Path.DirectorySeparatorChar + "lib-tk";
|
||||
public static readonly String PYTHON_PATH_PYTHON_DLLS = Path.DirectorySeparatorChar + "DLLs";
|
||||
public static readonly String PYTHON_PATH_PYTHON_LIB = Path.DirectorySeparatorChar + "Lib";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.environment
|
||||
{
|
||||
public class VizEnvironment
|
||||
{
|
||||
private static readonly String CONSOLE_LOGS_DIRECTORY =
|
||||
Path.DirectorySeparatorChar + "caveData" + Path.DirectorySeparatorChar +
|
||||
"logs" + Path.DirectorySeparatorChar + "consoleLogs";
|
||||
private String location;
|
||||
private String logDirectory = null;
|
||||
private String path = null;
|
||||
private String pythonPath = null;
|
||||
|
||||
// did an error occur while initializing this object?
|
||||
private bool ready;
|
||||
// details about the error that has occurred.
|
||||
private String exceptionText;
|
||||
|
||||
public VizEnvironment(String location)
|
||||
{
|
||||
this.location = location;
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
/* For now we will assume that the environment properties will be available */
|
||||
// determine the location of the user's "home" directory.
|
||||
String homeDirectory =
|
||||
this.resolveEnvironmentProperty(EnvironmentProperties.USER_HOME_ENV_PROPERTY);
|
||||
|
||||
// determine the computer name.
|
||||
String computerName =
|
||||
this.resolveEnvironmentProperty(EnvironmentProperties.COMPUTER_NAME_ENV_PROPERTY);
|
||||
|
||||
// construct the path to the log directory.
|
||||
this.logDirectory = homeDirectory + CONSOLE_LOGS_DIRECTORY +
|
||||
Path.DirectorySeparatorChar + computerName;
|
||||
|
||||
// retrieve the jdk directory from the registry.
|
||||
String jdkDirectory =
|
||||
this.retrieveRegistryProperty(EnvironmentProperties.A2_JAVA_REG,
|
||||
EnvironmentProperties.JAVA_JRE_VALUE_NAME);
|
||||
if (jdkDirectory == null)
|
||||
{
|
||||
this.notReady("Unable to retrieve the Java JDK Path from the registry!");
|
||||
return;
|
||||
}
|
||||
|
||||
// retrieve the python location from the registry.
|
||||
String pythonLocation =
|
||||
this.retrieveRegistryProperty(EnvironmentProperties.A2_PYTHON_REG,
|
||||
EnvironmentProperties.PYTHON_INSTALL_NAME);
|
||||
if (pythonLocation == null)
|
||||
{
|
||||
this.notReady("Unable to retrieve the Python Install Location from the registry!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the PATH.
|
||||
this.path = pythonLocation + Path.PathSeparator;
|
||||
this.path += pythonLocation + EnvironmentProperties.PATH_PYTHON_DLLS + Path.PathSeparator;
|
||||
this.path += jdkDirectory + EnvironmentProperties.PATH_JAVA_BIN;
|
||||
|
||||
// Construct the PYTHON_PATH.
|
||||
this.pythonPath = pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_LIBTK + Path.PathSeparator;
|
||||
this.pythonPath += pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_DLLS + Path.PathSeparator;
|
||||
this.pythonPath += pythonLocation + EnvironmentProperties.PYTHON_PATH_PYTHON_LIB + Path.PathSeparator;
|
||||
this.pythonPath += pythonLocation;
|
||||
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
private String resolveEnvironmentProperty(String property)
|
||||
{
|
||||
return Environment.ExpandEnvironmentVariables(property);
|
||||
}
|
||||
|
||||
private String retrieveRegistryProperty(String registryKeyName, String valueName)
|
||||
{
|
||||
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(registryKeyName);
|
||||
if (registryKey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Object registryValue = registryKey.GetValue(valueName, null);
|
||||
if (registryValue == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return registryValue.ToString();
|
||||
}
|
||||
|
||||
private void notReady(String reason)
|
||||
{
|
||||
this.ready = false;
|
||||
this.exceptionText = reason;
|
||||
}
|
||||
|
||||
public String getLocation()
|
||||
{
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String getLogDirectory()
|
||||
{
|
||||
return this.logDirectory;
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public String getPythonPath()
|
||||
{
|
||||
return this.pythonPath;
|
||||
}
|
||||
|
||||
public bool isReady()
|
||||
{
|
||||
return this.ready;
|
||||
}
|
||||
|
||||
public String getExceptionText()
|
||||
{
|
||||
return this.exceptionText;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using VizLauncher.com.raytheon.viz.launcher.environment;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.process
|
||||
{
|
||||
public abstract class AbstractProcessLauncher : IProcessLauncher
|
||||
{
|
||||
private static readonly String LOG_DATE_FORMAT = "yyyyMMdd_HHmmss";
|
||||
protected static readonly String LOG_SUFFIX = ".log";
|
||||
protected Process process = null;
|
||||
private StreamWriter logFileWriter;
|
||||
|
||||
private bool ready = false;
|
||||
private String exceptionText = null;
|
||||
|
||||
public AbstractProcessLauncher(VizEnvironment vizEnvironment)
|
||||
{
|
||||
// Prepare the log file.
|
||||
if (Directory.Exists(vizEnvironment.getLogDirectory()) == false)
|
||||
{
|
||||
Directory.CreateDirectory(vizEnvironment.getLogDirectory());
|
||||
}
|
||||
String logName = vizEnvironment.getLogDirectory() +
|
||||
Path.DirectorySeparatorChar + this.constructLogName(this.determineLogDate());
|
||||
|
||||
// Prepare the process.
|
||||
this.process = new Process();
|
||||
this.process.StartInfo = this.constructProcessStartInfo(vizEnvironment);
|
||||
this.process.OutputDataReceived += new DataReceivedEventHandler(processOutputHandler);
|
||||
this.validate();
|
||||
if (this.ready == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Access the log file for write access; other processes will have read-only access to
|
||||
* the log file until it is closed.
|
||||
**/
|
||||
this.logFileWriter =
|
||||
new StreamWriter(File.Open(logName, FileMode.Append,
|
||||
FileAccess.Write, FileShare.Read));
|
||||
}
|
||||
|
||||
private String determineLogDate()
|
||||
{
|
||||
return DateTime.Now.ToString(LOG_DATE_FORMAT);
|
||||
}
|
||||
|
||||
private ProcessStartInfo constructProcessStartInfo(VizEnvironment vizEnvironment)
|
||||
{
|
||||
ProcessStartInfo processStartInfo =
|
||||
new ProcessStartInfo(this.constructProcessName(vizEnvironment.getLocation()));
|
||||
processStartInfo.EnvironmentVariables.Remove(EnvironmentProperties.ENVIRONMENT_VARIABLE_PATH);
|
||||
processStartInfo.EnvironmentVariables.Add(
|
||||
EnvironmentProperties.ENVIRONMENT_VARIABLE_PATH, vizEnvironment.getPath());
|
||||
processStartInfo.EnvironmentVariables.Add(
|
||||
EnvironmentProperties.ENVIRONMENT_VARIABLE_PYTHON_PATH, vizEnvironment.getPythonPath());
|
||||
processStartInfo.UseShellExecute = false;
|
||||
processStartInfo.Arguments = this.getCommandLineArguments();
|
||||
processStartInfo.RedirectStandardOutput = true;
|
||||
|
||||
return processStartInfo;
|
||||
}
|
||||
|
||||
protected void validate()
|
||||
{
|
||||
String application = this.process.StartInfo.FileName;
|
||||
/* ensure that the specified application exists. */
|
||||
if (File.Exists(application) == false)
|
||||
{
|
||||
this.ready = false;
|
||||
this.exceptionText = "Unable to find the specified Viz application: " + application;
|
||||
return;
|
||||
}
|
||||
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
public virtual void launchProcess()
|
||||
{
|
||||
this.runProcess();
|
||||
this.closeLog();
|
||||
}
|
||||
|
||||
protected void runProcess()
|
||||
{
|
||||
this.process.Start();
|
||||
this.process.BeginOutputReadLine();
|
||||
this.process.WaitForExit();
|
||||
this.process.CancelOutputRead();
|
||||
}
|
||||
|
||||
protected void closeLog()
|
||||
{
|
||||
this.logFileWriter.Close();
|
||||
}
|
||||
|
||||
private void processOutputHandler(Object sendingProcess, DataReceivedEventArgs outline)
|
||||
{
|
||||
if (String.IsNullOrEmpty(outline.Data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.logFileWriter.WriteLine(outline.Data);
|
||||
}
|
||||
|
||||
public bool isReady()
|
||||
{
|
||||
return this.ready;
|
||||
}
|
||||
|
||||
public String getExceptionText()
|
||||
{
|
||||
return this.exceptionText;
|
||||
}
|
||||
|
||||
protected abstract String constructProcessName(String location);
|
||||
|
||||
protected abstract String constructLogName(String logDate);
|
||||
|
||||
protected abstract String getCommandLineArguments();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.process
|
||||
{
|
||||
public interface IProcessLauncher
|
||||
{
|
||||
void launchProcess();
|
||||
|
||||
bool isReady();
|
||||
String getExceptionText();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using VizLauncher.com.raytheon.viz.launcher.process;
|
||||
using VizLauncher.com.raytheon.viz.launcher.environment;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.process.impl
|
||||
{
|
||||
public class AlertvizProcessLauncher : AbstractProcessLauncher
|
||||
{
|
||||
private static readonly String LOG_PREFIX = "alertviz_";
|
||||
private static readonly String COMMAND_LINE_ARGUMENTS = "-component thinalertviz";
|
||||
private static readonly String ALERTVIZ_PROCESS_NAME = "alertviz";
|
||||
private static readonly String ALERTVIZ_EXECUTABLE =
|
||||
Path.DirectorySeparatorChar + "AlertViz" +
|
||||
Path.DirectorySeparatorChar + "alertviz.exe";
|
||||
|
||||
public AlertvizProcessLauncher(VizEnvironment vizEnvironment) : base(vizEnvironment)
|
||||
{
|
||||
}
|
||||
|
||||
public override void launchProcess()
|
||||
{
|
||||
// need to verify that another AlertViz process is not already running.
|
||||
if (this.isAlertVizAlreadyRunning())
|
||||
{
|
||||
// do not start a new AlertViz process.
|
||||
return;
|
||||
}
|
||||
|
||||
this.runProcess();
|
||||
while (this.process.ExitCode != 0)
|
||||
{
|
||||
this.runProcess();
|
||||
}
|
||||
this.closeLog();
|
||||
}
|
||||
|
||||
private Boolean isAlertVizAlreadyRunning()
|
||||
{
|
||||
return (Process.GetProcessesByName(ALERTVIZ_PROCESS_NAME).Length > 0);
|
||||
}
|
||||
|
||||
protected override String constructProcessName(String location)
|
||||
{
|
||||
return location + ALERTVIZ_EXECUTABLE;
|
||||
}
|
||||
|
||||
protected override String constructLogName(String logDate)
|
||||
{
|
||||
return LOG_PREFIX + logDate + AbstractProcessLauncher.LOG_SUFFIX;
|
||||
}
|
||||
|
||||
protected override String getCommandLineArguments()
|
||||
{
|
||||
return COMMAND_LINE_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using VizLauncher.com.raytheon.viz.launcher.process;
|
||||
using VizLauncher.com.raytheon.viz.launcher.environment;
|
||||
|
||||
namespace VizLauncher.com.raytheon.viz.launcher.process.impl
|
||||
{
|
||||
public class CaveProcessLauncher : AbstractProcessLauncher
|
||||
{
|
||||
private static readonly String LOG_PREFIX = "cave_";
|
||||
private static readonly String COMMAND_LINE_ARGUMENTS = "-component thinclient";
|
||||
private static readonly String CAVE_EXECUTABLE =
|
||||
Path.DirectorySeparatorChar + "CAVE" + Path.DirectorySeparatorChar + "cave.exe";
|
||||
|
||||
public CaveProcessLauncher(VizEnvironment vizEnvironment)
|
||||
: base(vizEnvironment)
|
||||
{
|
||||
}
|
||||
|
||||
protected override String constructProcessName(String location)
|
||||
{
|
||||
return location + CAVE_EXECUTABLE;
|
||||
}
|
||||
|
||||
protected override String constructLogName(String logDate)
|
||||
{
|
||||
return LOG_PREFIX + logDate + AbstractProcessLauncher.LOG_SUFFIX;
|
||||
}
|
||||
|
||||
protected override String getCommandLineArguments()
|
||||
{
|
||||
return COMMAND_LINE_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
BIN
msi/build/A2Staging/VisualStudio/VizLauncher.exe
Normal file
BIN
msi/build/A2Staging/VisualStudio/VizLauncher.exe
Normal file
Binary file not shown.
|
@ -24,7 +24,6 @@ Export-Package: gov.noaa.nws.ncep.viz.common,
|
|||
gov.noaa.nws.ncep.viz.common.customprojection,
|
||||
gov.noaa.nws.ncep.viz.common.dbQuery,
|
||||
gov.noaa.nws.ncep.viz.common.display,
|
||||
gov.noaa.nws.ncep.viz.common.gpdQuery,
|
||||
gov.noaa.nws.ncep.viz.common.graphicUtil,
|
||||
gov.noaa.nws.ncep.viz.common.preferences,
|
||||
gov.noaa.nws.ncep.viz.common.soundingQuery,
|
||||
|
@ -35,7 +34,5 @@ Import-Package: com.raytheon.uf.common.comm,
|
|||
com.raytheon.uf.common.parameter,
|
||||
com.raytheon.viz.pointdata,
|
||||
com.vividsolutions.jts.geom,
|
||||
gov.noaa.nws.ncep.common.dataplugin.gpd.product,
|
||||
gov.noaa.nws.ncep.common.dataplugin.gpd.query,
|
||||
javax.measure.unit
|
||||
|
||||
|
|
|
@ -58,11 +58,11 @@ if [ ${RC} -ne 0 ]; then
|
|||
fi
|
||||
|
||||
# Create additional directories that are required.
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/tmp
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/primary
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids2
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/backup
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
@ -97,7 +97,6 @@ rm -rf ${RPM_BUILD_ROOT}
|
|||
/awips2/GFESuite/bin/src/*
|
||||
%dir /awips2/GFESuite/exportgrids
|
||||
/awips2/GFESuite/exportgrids/*
|
||||
%dir /awips2/GFESuite/exportgrids2
|
||||
%defattr(644,awips,fxalpha,775)
|
||||
%dir /awips2/GFESuite/products
|
||||
/awips2/GFESuite/products/*
|
||||
|
|
|
@ -58,11 +58,11 @@ if [ ${RC} -ne 0 ]; then
|
|||
fi
|
||||
|
||||
# Create additional directories that are required.
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/tmp
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/primary
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids2
|
||||
mkdir -p ${RPM_BUILD_ROOT}/awips2/GFESuite/exportgrids/backup
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
@ -97,7 +97,6 @@ rm -rf ${RPM_BUILD_ROOT}
|
|||
/awips2/GFESuite/bin/src/*
|
||||
%dir /awips2/GFESuite/exportgrids
|
||||
/awips2/GFESuite/exportgrids/*
|
||||
%dir /awips2/GFESuite/exportgrids2
|
||||
%defattr(755,awips,fxalpha,777)
|
||||
%dir /awips2/GFESuite/ServiceBackup/scripts
|
||||
/awips2/GFESuite/ServiceBackup/scripts/*
|
||||
|
|
|
@ -348,7 +348,7 @@ fi
|
|||
|
||||
if [ "${1}" = "-viz" ]; then
|
||||
buildRPM "awips2"
|
||||
# buildRPM "awips2-common-base"
|
||||
buildRPM "awips2-common-base"
|
||||
# buildRPM "awips2-rcm"
|
||||
# buildRPM "awips2-hydroapps-shared"
|
||||
# buildRPM "awips2-notification"
|
||||
|
@ -366,11 +366,11 @@ if [ "${1}" = "-edex" ]; then
|
|||
#buildRPM "awips2-common-base"
|
||||
# buildRPM "awips2-adapt-native"
|
||||
#buildRPM "awips2-python-qpid"
|
||||
buildRPM "awips2-cli"
|
||||
# buildRPM "awips2-gfesuite-client"
|
||||
# buildRPM "awips2-gfesuite-server"
|
||||
buildRPM "awips2-ncep-database"
|
||||
buildRPM "awips2-python-dynamicserialize"
|
||||
# buildRPM "awips2-cli"
|
||||
buildRPM "awips2-gfesuite-client"
|
||||
buildRPM "awips2-gfesuite-server"
|
||||
# buildRPM "awips2-ncep-database"
|
||||
# buildRPM "awips2-python-dynamicserialize"
|
||||
buildEDEX
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
|
|
Loading…
Add table
Reference in a new issue