package com.aerodynelabs.habtk.atmosphere; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.Calendar; import java.util.TimeZone; /** * A class to retrieve GFS soundings from http://rucsoundings.noaa.gov * * @author Ethan Harstad * */ public class RUCGFS implements AtmosphereSource { @Override public File getAtmosphere(int time, double lat, double lon) { // Adjust fields to match model int startTime = (time / 10800) * 10800; double rlat = (int)(lat / 0.5) * 0.5; double rlon = (int)(lon / 0.5) * 0.5; // Get the time the model was last run Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); int modelRun = (cal.get(Calendar.HOUR_OF_DAY) / 12) * 12; cal.set(Calendar.HOUR_OF_DAY, modelRun); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); int modelTime = (int)(cal.getTimeInMillis() / 1000); // Check for local copy File local = null; File root = new File("wind/"); if(root.exists()) { File files[] = root.listFiles(new Filter(startTime, rlat, rlon)); if(files.length > 0) local = files[files.length - 1]; } else { root.mkdir(); } // Get a new model if needed boolean old = true; if(local != null) { String name = local.getName(); int s = name.lastIndexOf('_'); int e = name.lastIndexOf('.'); int t = Integer.parseInt(name.substring(s + 1, e)); old = modelTime > t; } File net = null; if(old) net = download(startTime, modelTime, rlat, rlon); // Return the best model if(net == null) { return local; } else { return net; } } private File download(int time, int modelTime, double lat, double lon) { String address = "http://rucsoundings.noaa.gov/get_soundings.cgi?data_source=GFS;airport=" + lat + "," + lon + ";hydrometeors=false&startSecs=" + time + "&endSecs=" + (time+1); URL url; InputStream is = null; InputStreamReader isr = null; try { url = new URL(address); is = url.openStream(); } catch(MalformedURLException e) { e.printStackTrace(); return null; } catch(IOException e) { e.printStackTrace(); return null; } isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); File file = new File("wind/gfs_" + (int)(lat*10) + "_" + (int)(lon*10) + "_" + time + "_" + modelTime + ".gsd"); FileWriter fw = null; try { fw = new FileWriter(file); } catch (IOException e1) { e1.printStackTrace(); return null; } String line = null; try( BufferedWriter bw = new BufferedWriter(fw); PrintWriter writer = new PrintWriter(bw); ) { while((line = br.readLine()) != null) { writer.println(line); } writer.flush(); } catch(Exception e) { e.printStackTrace(); return null; } finally { if(fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } return file; } class Filter implements FilenameFilter { private String filter; public Filter(int time, double lat, double lon) { filter = "gfs_" + (int)(lat*10) + "_" + (int)(lon*10) + "_" + time + "_"; } @Override public boolean accept(File dir, String name) { if(!name.startsWith(filter)) return false; if(!name.endsWith(".gsd")) return false; return true; } } }