@@ -75,7 +75,9 @@ |
} |
|
public static class StationResult { |
+ public String country; |
public String state; |
+ public String name; |
public String stationId; |
public String stationX; |
public String stationY; |
@@ -87,6 +89,19 @@ |
return "{" + state + "|" + stationId + "|" + stationX + "|" + stationY + "|" + elevation + "}"; |
} |
} |
+ |
+ public static class County { |
+ public String state_code; |
+ public String county_code; |
+ public String name; |
+ public String county_centroid_X; |
+ public String county_centroid_Y; |
+ |
+ @Override |
+ public String toString() { |
+ return "{" + state_code + county_code + "|" + name + "|" + county_centroid_X + "|" + county_centroid_Y + "}"; |
+ } |
+ } |
|
// // deactivated the singleton pattern, because we want more than 1 db conn |
// public static PostGIS singleton() throws Exception { |
@@ -681,6 +696,109 @@ |
return windgenst; |
} |
|
+ public StationResult cliGeomIntersect(double lat, double lon) throws SQLException { |
+ |
+ String select = "select st, name, st_fips, c1, lat_dd, long_dd, elev_m " |
+ + "from weps_cli_geom " |
+ + "where ST_Intersects(geom,ST_GeomFromText('POINT(" + lon + " " + lat + ")',4326));"; |
+ Statement s = createStatement(lon); |
+ logger.info("query sql=" + select); |
+ ResultSet r = s.executeQuery(select); |
+ int cols = r.getMetaData().getColumnCount(); |
+ if (cols != 7) { |
+ //s.close(); |
+ logger.severe("invalid columns in cliGeomIntersect query"); |
+ throw new IllegalArgumentException("invalid Columns"); |
+ } |
+ if (!r.next()) { |
+ //s.close(); |
+ logger.severe("no result from cliGeomIntersect query!"); |
+ return null; |
+ } |
+ StationResult clist = new StationResult(); |
+ clist.state = r.getString(3); |
+ clist.name = r.getString(2); |
+ clist.stationId = r.getString(4); |
+ clist.stationY = r.getString(5); |
+ clist.stationX = r.getString(6); |
+ clist.elevation = r.getString(7); |
+ |
+ logger.info("state=" + clist.state); |
+ logger.info("cli station id=" + clist.stationId); |
+ logger.info("cli station name=" + clist.name); |
+ logger.info("cli station elev=" + clist.elevation); |
+ return clist; |
+ } |
+ |
+ |
+ public StationResult windGeomIntersect(double lat, double lon) throws SQLException { |
+ |
+ String select = "select lat_dd, long_dd, wban, cntry, st, name " |
+ + "from weps_wind_geom " |
+ + "where ST_Intersects(geom,ST_GeomFromText('POINT(" + lon + " " + lat + ")',4326));"; |
+ Statement s = createStatement(lon); |
+ logger.info("query sql=" + select); |
+ ResultSet r = s.executeQuery(select); |
+ int cols = r.getMetaData().getColumnCount(); |
+ if (cols != 6) { |
+ //s.close(); |
+ logger.severe("invalid columns in windGeomIntersect query"); |
+ throw new IllegalArgumentException("invalid Columns"); |
+ } |
+ if (!r.next()) { |
+ //s.close(); |
+ logger.severe("no result from windGeomIntersect query!"); |
+ return null; |
+ } |
+ StationResult windgenst = new StationResult(); |
+ windgenst.stationX = r.getString(1); |
+ windgenst.stationY = r.getString(2); |
+ windgenst.stationId = r.getString(3); |
+ windgenst.country = r.getString(4); |
+ windgenst.state = r.getString(5); |
+ windgenst.name = r.getString(6); |
+ |
+ logger.info("state=" + windgenst.state); |
+ logger.info("station id=" + windgenst.stationId); |
+ logger.info("station name=" + windgenst.name); |
+ return windgenst; |
+ } |
+ |
+ // Uses a field lat long, to determine the county, then returns the county's centroid lat/long |
+ public County countyCentroid(double lat, double lon) throws SQLException { |
+ |
+ String select = "select state, county, name, ST_X(ST_Centroid(geom)) centroid_long, ST_Y(ST_Centroid(geom)) centroid_lat " |
+ + "from weps_county_geom " |
+ + "where ST_Intersects(geom,ST_GeomFromText('POINT(" + lon + " " + lat + ")',4326));"; |
+ Statement s = createStatement(lon); |
+ logger.info("query sql=" + select); |
+ ResultSet r = s.executeQuery(select); |
+ int cols = r.getMetaData().getColumnCount(); |
+ if (cols != 5) { |
+ //s.close(); |
+ logger.severe("invalid columns in countyCentroid query"); |
+ throw new IllegalArgumentException("invalid Columns"); |
+ } |
+ if (!r.next()) { |
+ //s.close(); |
+ logger.severe("no result from countyCentroid query!"); |
+ return null; |
+ } |
+ County county = new County(); |
+ county.state_code = r.getString(1); |
+ county.county_code = r.getString(2); |
+ county.name = r.getString(3); |
+ county.county_centroid_X = r.getString(4); |
+ county.county_centroid_Y = r.getString(5); |
+ |
+ logger.info("county_fips_code=" + county.state_code + county.county_code); |
+ logger.info("name=" + county.name); |
+ logger.info("centroidX=" + county.county_centroid_X); |
+ logger.info("centroidY=" + county.county_centroid_Y); |
+ return county; |
+ } |
+ |
+ |
public List<FileQryResult> findManagements(double lat, double lon) throws SQLException { |
//Statement s = createStatement(getConnection()); |
Statement s = createStatement(lon); |
@@ -193,6 +193,7 @@ |
LOG.log(Level.SEVERE, "class=" + ste.getClassName() + " method=" + ste.getMethodName() + " |" + ste.toString()); |
} |
throw new ServiceException("WEPS error: unknown error executing WEPS model>" + e.toString()); |
+ |
} |
} |
}; |
@@ -475,14 +476,39 @@ |
|
private void getClimate() throws ServiceException { |
try { |
- if (db != null) { |
- // get climate station for this lat / long |
- LOG.info("FIND NEAREST CLIGEN STATION!"); |
- LOG.info("lat=" + wmr.getLat()); |
- LOG.info("long=" + wmr.getLongitude()); |
- PostGIS.StationResult cligenStation = db.findCligenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude())); |
+ if (db != null) |
+ { |
+ double latitude = Double.parseDouble(wmr.getLat()); |
+ double longitude = Double.parseDouble(wmr.getLongitude()); |
+ PostGIS.StationResult cligenStation = null; |
+ |
+ // check if the field lat/long intersects any cli station geometries first- and use it if so |
+ PostGIS.StationResult cliStation = db.cliGeomIntersect(latitude, longitude); |
+ if (cliStation != null) |
+ { |
+ LOG.info("The cliStation name is '" + cliStation.name + "'"); |
+ if (cliStation.name.contentEquals("Out")) |
+ { |
+ // in the mountain west polygon - use the nearest cligen station |
+ cligenStation = db.findCligenStation(latitude, longitude); |
+ } |
+ else |
+ { |
+ // use the cli station found by intersecting the climate station geometries |
+ cligenStation = cliStation; |
+ } |
+ } |
+ else |
+ { |
+ // get climate station for this lat / long |
+ LOG.info("FIND NEAREST CLIGEN STATION!"); |
+ LOG.info("lat=" + wmr.getLat()); |
+ LOG.info("long=" + wmr.getLongitude()); |
+ // not in the mountain west polygon, did not intersect any climate station, use the nearest station |
+ cligenStation = db.findCligenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude())); |
+ } |
// generate cli file using this station |
- LOG.info("cligen station found is=" + cligenStation.stationId); |
+ LOG.info("using cligen station=" + cligenStation.stationId); |
if (wmr.getElevation().equals(WepsModelRun.UNSET_ELEVATION)) |
{ |
wmr.setElevation(cligenStation.elevation); |
@@ -502,106 +528,134 @@ |
//wmr.cliFile = "cligen.cli"; |
} |
} catch (Exception e) { |
+ e.printStackTrace(); |
throw new ServiceException("WEPS error: error generating climate data:" + e.toString()); |
} |
} |
|
private void generateWindData() throws ServiceException { |
try { |
+ sWindgenStation = null; |
// Always generate wind data for lat / long using wingen and possible interpolate program |
if (db != null) { |
double latitude = Double.parseDouble(wmr.getLat()); |
double longitude = Double.parseDouble(wmr.getLongitude()); |
|
- // check if in the interpolation boundary shape, if so, interpolate 3 nearest wind stations |
- // to generate an interpolated station |
- LOG.log(Level.INFO, "Check if lat/long is in interpolation boundary"); |
- if (db.IsInInterpolateBoundary(latitude, longitude)) { |
- LOG.log(Level.INFO, "YES! lat/long is in interpolation boundary"); |
- // Generate wind station interpolation |
- |
- // Generate weights file |
- ProcessComponent pcInterpolate = new ProcessComponent(); |
- String exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolate", new File(binDir)).toString(); |
- String dbpath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/wind_gen_his_upper_US.idx", new File(binDir)).toString(); |
- String polygon = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolation_boundary.pol", new File(binDir)).toString(); |
- |
- // Generate shell script to invoke interpolate |
- File interpolatesh = new File(sessionWorkDir + "/interpolate.sh"); |
- String invokeInterpolate = exepath + " -f " + dbpath + " -p " + polygon + " -lat " + latitude + " -long " + longitude; |
- FileUtils.writeStringToFile(interpolatesh, invokeInterpolate); |
- interpolatesh.setExecutable(true); |
- |
- pcInterpolate.working_dir = sessionWorkDir; |
- pcInterpolate.exe = "./interpolate.sh"; |
- pcInterpolate.args = new String[]{}; |
- pcInterpolate.execute(); |
- |
- // Added small delay because occasionally the stdout was incomplete upon parsing |
- Thread.sleep(300); |
- |
- WeightsParser wp = new WeightsParser(); |
- wp.weightsFile = pcInterpolate.stdout; |
- wp.exitValue = pcInterpolate.exitValue; |
- wp.weightsErr = pcInterpolate.stderr; |
- LOG.info("exit value from pcInterpolate execution=" + pcInterpolate.exitValue); |
- // must process this monstrosity |
- wp.parse(); |
- |
- if ((wp.station1 > 0) & (wp.station2 > 0) && (wp.station3 > 0)) { |
- // If there are wind stations then, generate interpolate wind station wdb file |
- |
- // Note the interp_wdb program is ancient Fortran and can not handle file paths of any length |
- // therefore everything has to be extracted to the workdir and done locally there. |
- // This is BAD (inefficient) because it is extra work to always extract wind station wdb's for every model run! |
- ProcessComponent pcInterpWdb = new ProcessComponent(); |
- exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interp_wdb", new File(binDir)).toString(); |
- |
-// String station1Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station1 + ".wdb", sessionWorkDir + "/" + wp.station1 + ".wdb").toString(); |
-// String station2Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station2 + ".wdb", sessionWorkDir + "/" + wp.station2 + ".wdb").toString(); |
-// String station3Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station3 + ".wdb", sessionWorkDir + "/" + wp.station3 + ".wdb").toString(); |
- String station1Db = getWindStationFile(wp.station1); |
- String station2Db = getWindStationFile(wp.station2); |
- String station3Db = getWindStationFile(wp.station3); |
- |
- // Generate shell script to invoke interpolate |
- File interpwdbsh = new File(sessionWorkDir + "/interpwdb.sh"); |
- String invokeInterpWdb = exepath + " test.wdb" + " " + station1Db + wp.weight1 + " " + station2Db + wp.weight2 + " " + station3Db + wp.weight3; |
- FileUtils.writeStringToFile(interpwdbsh, invokeInterpWdb); |
- interpwdbsh.setExecutable(true); |
- |
- pcInterpWdb.working_dir = sessionWorkDir; |
- pcInterpWdb.exe = "./interpwdb.sh"; |
- pcInterpWdb.args = new String[]{}; |
- pcInterpWdb.execute(); |
- windDbPath = "test.wdb"; |
- sWindgenStation = "999999"; // this is the magic number indicating its an interpolated wind station! |
+ // check if the field lat/long intersects any wind station geometries first- and use it if so |
+ PostGIS.StationResult windStation = db.windGeomIntersect(latitude, longitude); |
+ if (windStation != null) |
+ { |
+ LOG.info("The intersected windStation name is '" + windStation.name + "'"); |
+ // Check for Out or INT polygons - these are not wind stations, just filler polygons |
+ if ((windStation.name.contentEquals("Out")) || (windStation.name.contentEquals("INT"))) |
+ { |
+ sWindgenStation = null; |
+ } |
+ else |
+ { |
+ sWindgenStation = windStation.stationId.trim(); |
+ windDbPath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/" + DEFAULT_WIND_STATION_DB, new File(binDir)).toString(); |
} |
} |
|
- // otherwise, just use data from nearest wind station: |
- // If this is not using an interpolated wind station, then use the default one... |
- if (windDbPath.length() == 0) { |
- LOG.log(Level.INFO, "NO! lat/long is NOT in interpolation boundary"); |
- // get wind generation station for this lat / long |
- LOG.info("FIND NEAREST WIND STATION!"); |
- LOG.info("lat=" + wmr.getLat()); |
- LOG.info("long=" + wmr.getLongitude()); |
- |
- PostGIS.StationResult windgenStation = db.findWindgenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude())); |
- LOG.info("windgen station is=" + windgenStation.stationId); |
- sWindgenStation = windgenStation.stationId.trim(); |
+ // Do we still need to populate the windgen station??? |
+ if (sWindgenStation == null) |
+ { |
+ // next check if in the interpolation boundary shape, if so, interpolate 3 nearest wind stations |
+ // to generate an interpolated station |
+ LOG.log(Level.INFO, "Check if lat/long is in interpolation boundary"); |
+ if (db.IsInInterpolateBoundary(latitude, longitude)) { |
+ LOG.log(Level.INFO, "YES! lat/long is in interpolation boundary"); |
+ // Generate wind station interpolation |
|
- windDbPath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/" + DEFAULT_WIND_STATION_DB, new File(binDir)).toString(); |
+ // Generate weights file |
+ ProcessComponent pcInterpolate = new ProcessComponent(); |
+ String exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolate", new File(binDir)).toString(); |
+ String dbpath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/wind_gen_his_upper_US_NRCS.idx", new File(binDir)).toString(); |
+ String polygon = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interpolation_boundary.pol", new File(binDir)).toString(); |
+ |
+ // Get the county centroid for wind interpolation |
+ PostGIS.County wepsCounty = db.countyCentroid(latitude, longitude); |
+ |
+ // Generate shell script to invoke interpolate |
+ File interpolatesh = new File(sessionWorkDir + "/interpolate.sh"); |
+ String invokeInterpolate = exepath + " -f " + dbpath + " -p " + polygon + " -lat " + wepsCounty.county_centroid_Y + " -long " + wepsCounty.county_centroid_X; |
+ FileUtils.writeStringToFile(interpolatesh, invokeInterpolate); |
+ interpolatesh.setExecutable(true); |
+ |
+ pcInterpolate.working_dir = sessionWorkDir; |
+ pcInterpolate.exe = "./interpolate.sh"; |
+ pcInterpolate.args = new String[]{}; |
+ pcInterpolate.execute(); |
+ |
+ // Added small delay because occasionally the stdout was incomplete upon parsing |
+ Thread.sleep(300); |
+ |
+ WeightsParser wp = new WeightsParser(); |
+ wp.weightsFile = pcInterpolate.stdout; |
+ wp.exitValue = pcInterpolate.exitValue; |
+ wp.weightsErr = pcInterpolate.stderr; |
+ LOG.info("exit value from pcInterpolate execution=" + pcInterpolate.exitValue); |
+ // must process this monstrosity |
+ wp.parse(); |
+ |
+ if ((wp.station1 > 0) & (wp.station2 > 0) && (wp.station3 > 0)) { |
+ // If there are wind stations then, generate interpolate wind station wdb file |
+ |
+ // Note the interp_wdb program is ancient Fortran and can not handle file paths of any length |
+ // therefore everything has to be extracted to the workdir and done locally there. |
+ // This is BAD (inefficient) because it is extra work to always extract wind station wdb's for every model run! |
+ ProcessComponent pcInterpWdb = new ProcessComponent(); |
+ exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/interp_wdb", new File(binDir)).toString(); |
+ |
+ // String station1Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station1 + ".wdb", sessionWorkDir + "/" + wp.station1 + ".wdb").toString(); |
+ // String station2Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station2 + ".wdb", sessionWorkDir + "/" + wp.station2 + ".wdb").toString(); |
+ // String station3Db = BinUtils.unpackResourceAbsolute("/bin/" + BinUtils.getArch() + "/windstations/" + wp.station3 + ".wdb", sessionWorkDir + "/" + wp.station3 + ".wdb").toString(); |
+ String station1Db = getWindStationFile(wp.station1); |
+ String station2Db = getWindStationFile(wp.station2); |
+ String station3Db = getWindStationFile(wp.station3); |
+ |
+ // Generate shell script to invoke interpolate |
+ File interpwdbsh = new File(sessionWorkDir + "/interpwdb.sh"); |
+ String invokeInterpWdb = exepath + " test.wdb" + " " + station1Db + wp.weight1 + " " + station2Db + wp.weight2 + " " + station3Db + wp.weight3; |
+ FileUtils.writeStringToFile(interpwdbsh, invokeInterpWdb); |
+ interpwdbsh.setExecutable(true); |
+ |
+ pcInterpWdb.working_dir = sessionWorkDir; |
+ pcInterpWdb.exe = "./interpwdb.sh"; |
+ pcInterpWdb.args = new String[]{}; |
+ pcInterpWdb.execute(); |
+ windDbPath = "test.wdb"; |
+ sWindgenStation = "999999"; // this is the magic number indicating its an interpolated wind station! |
+ } |
+ } |
+ |
+ // otherwise, just use data from nearest wind station: |
+ // If this is not using an interpolated wind station, then use the default closest one... |
+ if (windDbPath.length() == 0) { |
+ LOG.log(Level.INFO, "NO! lat/long is NOT in interpolation boundary"); |
+ // get wind generation station for this lat / long |
+ LOG.info("FIND NEAREST WIND STATION!"); |
+ LOG.info("lat=" + wmr.getLat()); |
+ LOG.info("long=" + wmr.getLongitude()); |
+ |
+ PostGIS.StationResult windgenStation = db.findWindgenStation(Double.parseDouble(wmr.getLat()), Double.parseDouble(wmr.getLongitude())); |
+ LOG.info("windgen station is=" + windgenStation.stationId); |
+ sWindgenStation = windgenStation.stationId.trim(); |
+ |
+ windDbPath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/" + DEFAULT_WIND_STATION_DB, new File(binDir)).toString(); |
+ } |
} |
// generate win file using this station (or interpolated one) |
ProcessComponent pcWindGen = new ProcessComponent(); |
String exepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/wind_gen4", new File(binDir)).toString(); |
+ String winexepath = Binaries.unpackResource("/bin/" + Binaries.getArch() + "/wind_gen4.exe", new File(binDir)).toString(); |
LOG.log(Level.INFO, "Using wind database:" + windDbPath); |
|
// Generate shell script to invoke windgen |
File windgensh = new File(sessionWorkDir + "/windgen.sh"); |
- String invokeWinGen = exepath + " -f " + windDbPath + " -b 01 -y " + simulationYears + " -o thewind.win -s " + sWindgenStation; |
+ //String invokeWinGen = exepath + " -f " + windDbPath + " -b 01 -y " + simulationYears + " -o thewind.win -s " + sWindgenStation; |
+ String invokeWinGen = "wine " + winexepath + " -f " + windDbPath + " -b 01 -y " + simulationYears + " -o thewind.win -s " + sWindgenStation; |
FileUtils.writeStringToFile(windgensh, invokeWinGen); |
windgensh.setExecutable(true); |
|