V1_0.java [src/java/m/rse/cfactor] Revision: default Date:
package m.rse.cfactor;
import csip.ModelDataService;
import csip.ServiceException;
import csip.annotations.*;
import csip.utils.JSONUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import javax.ws.rs.Path;
import m.rse.cfactor.utils.Const;
import m.rse.cfactor.utils.PGTools;
import oms3.annotations.*;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
//import org.geotools.coverage.grid.GridCoverage2D;
//import org.geotools.coverage.grid.io.AbstractGridFormat;
//import org.geotools.coverage.grid.io.GridCoverage2DReader;
//import org.geotools.coverage.grid.io.GridFormatFinder;
//import org.geotools.factory.Hints;
//import org.geotools.gce.geotiff.GeoTiffReader;
//import org.geotools.geometry.DirectPosition2D;
//import org.opengis.geometry.DirectPosition;
//import org.opengis.parameter.GeneralParameterValue;
//import org.opengis.referencing.crs.CoordinateReferenceSystem;
/**
* CFactor Model service.
*
* @author od, wl, sc
*/
@Name("cfactor")
@Description("Returns CFactor value for a given lat/long point")
//@Path("m/cfactor/1.0")
@Polling(first = 5000, next = 2000)
public class V1_0 extends ModelDataService {
// gets called when the context shuts down.
public static void onContextDestroy() {
//PGTools.shutdownDataSource(); //The use of try-with resources auto-closes them at the end of the statement scope.
}
String lat = null;
String lon = null;
double cfactor = -1;
double cfactorraster = -1;
@Override
protected void preProcess() throws Exception {
if (JSONUtils.checkKeyExistsB(getParamMap(), Const.RSE_LAT)
&& JSONUtils.checkKeyExistsB(getParamMap(), Const.RSE_LON)) {
lat = getStringParam(Const.RSE_LAT);
lon = getStringParam(Const.RSE_LON);
}
}
@Override
protected String process() throws Exception {
try {
if (lat != null && lon != null) {
cfactor = getCFactor(lat, lon);
//cfactorraster = getCFactorRaster(lat, lon);
} else {
boolean bFoundAoi = false;
// Iterate through polygons, retrieving c factor for each
Collection<JSONObject> coll = getParamMap().values();
for (JSONObject jsonobj : coll) {
LOG.info("json obj name='" + jsonobj.getString("name") + "'");
if (jsonobj.getString("name").equals(Const.RSE_AOI)) {
bFoundAoi = true;
LOG.info("json obj=" + jsonobj.toString());
JSONObject aoiobj = jsonobj.optJSONObject("value");
JSONArray features = aoiobj.optJSONArray("features");
LOG.info("features obj=" + features.toString());
for (int i = 0; i < features.length(); i++) {
JSONObject poly = features.getJSONObject(i);
LOG.info("poly obj #" + i + poly.toString());
JSONObject geometry = poly.optJSONObject("geometry");
LOG.info("geometry obj=" + geometry.toString());
JSONArray coords = geometry.optJSONArray("coordinates");
LOG.info("coords obj=" + coords.toString());
for (int j = 0; j < coords.length(); j++) {
JSONArray shape = coords.getJSONArray(j);
LOG.info("shape obj=" + shape.toString());
String newPolygon = "geometry::STPolyFromText('POLYGON((";
double firstLong = 0.0;
for (int k = 0; k < shape.length(); k++) {
JSONArray point = shape.getJSONArray(k);
if (firstLong == 0) {
firstLong = point.getDouble(0);
}
if (k > 0) {
newPolygon += ",";
}
newPolygon += point.getDouble(0) + " " + point.getDouble(1);
}
newPolygon += "))',4326)";
LOG.info("Polygon of interest=" + newPolygon);
PGTools.Centroid centroid = PGTools.getCentroid(newPolygon, LOG);
cfactor = getCFactor(centroid.lat, centroid.lon);
LOG.info("Skipping other polygons if present...");
break; // only do the first polygon
}
}
}
}
if (!bFoundAoi) {
return "No AoI found in GeoJSON parameter";
}
}
if (cfactor == -1) {
return "error: cfactor is -1, check log file...";
}
return EXEC_OK;
} catch (SQLException E) {
return "Error retrieving C-Factor value from database:" + E.toString();
}
}
@Override
protected void postProcess() throws Exception {
putResult("cfactor", cfactor, Const.SERVICE_DESC, null);
//putResult("cfactorRaster", cfactorraster, SERVICE_DESC, null);
}
private double getCFactor(String slat, String slon) throws SQLException, ServiceException {
double lat = Double.parseDouble(slat);
double lon = Double.parseDouble(slon);
double c_fact = Const.UNKNOWN_CFACTOR;
// Alaska
if (lat >= Const.ALASKA_MIN_LATITUDE) {
appendMetainfoWarning(Const.ALASKA_REGION_WARNING_MSG);
return c_fact;
}
// continental US only
if (lat > 24.396308 && lon > -124.848974 && lat < 49.384358 && lon < -66.885444) {
String intersect_polygons = "SELECT [C_FACTOR_]"
+ " FROM [dbo].[c_factor]"
+ " where (geometry::STGeomFromText('POINT(" + lon + " " + lat + ")', 4326).STIntersects([geometry])!= 0);";
try (Connection c = PGTools.getConnection("legacy.cfactor", LOG)) {
try (Statement s = c.createStatement()) {
try (ResultSet r = s.executeQuery(intersect_polygons)) {;
LOG.info("query sql=" + intersect_polygons);
int cols = r.getMetaData().getColumnCount();
if (cols != 1) {
LOG.severe("invalid columns in getCFactor 'intersect polygons' query");
throw new ServiceException("invalid Columns");
}
// If no intersect find C-Factor using step 2 of algorithm
if (!r.next()) {
try (Connection c2 = PGTools.getConnection("legacy.cfactor", LOG)) {
try (Statement s2 = c2.createStatement()) {
String dist_from_polylines = "SELECT [C_VALUE]"
+ " ,(geometry::STGeomFromText('POINT(" + lon + " " + lat + ")', 4326).STDistance([geometry])) as distance"
+ " FROM [dbo].[us_cvals_aea]"
+ " order by distance ";
try (ResultSet r2 = s2.executeQuery(dist_from_polylines)) {
LOG.info("query sql=" + dist_from_polylines);
int cols2 = r2.getMetaData().getColumnCount();
if (cols2 != 2) {
LOG.severe("invalid columns in getCFactor 'dist from polylines' query");
throw new ServiceException("invalid Columns");
}
if (r2.next()) {
LOG.info("getting CFactor from 'distance from polylines' query");
LOG.info("nearest c factor=" + r2.getNString(1));
LOG.info("distance from polyline=" + r2.getString(2));
c_fact = Double.parseDouble(r2.getNString(1));
}
}
}
}
} else {
LOG.info("getting CFactor from 'intersect polygons' query");
c_fact = Double.parseDouble(r.getString(1));
}
}
}
}
return c_fact;
}
throw new ServiceException("Illegal lat/lon as parameter or cenroid: " + lat + "/" + lon);
}
// // geotools attempt
// private double getCFactorRaster(String slat, String slon) throws SQLException, ServiceException, IOException {
// double lat = Double.parseDouble(slat);
// double lon = Double.parseDouble(slon);
// double c_fact = UNKNOWN_CFACTOR;
//
// File tiffFile = new File("/tmp/us_cvalues_topo2ras_masked.tif");
// AbstractGridFormat format = GridFormatFinder.findFormat(tiffFile);
// LOG.info("format name=" + format.getName());
// LOG.info("vendor=" + format.getVendor());
// LOG.info("version=" + format.getVersion());
// LOG.info("desc=" + format.getDescription());
// LOG.info("doc-url=" + format.getDocURL());
//// try
//// {
// GeoTiffReader reader = new GeoTiffReader(tiffFile, new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE));
// GeneralParameterValue[] gpv = {null};
// GridCoverage2D coverage = reader.read(gpv);
// CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem2D();
// DirectPosition position = new DirectPosition2D(crs, lon, lat);
// double[] sample = (double[]) coverage.evaluate(position);
//
// for (int i=0; i < sample.length; i ++)
// {
// LOG.info("sample value #" + i + "=" + sample[i]);
// }
//// }
//// catch (Exception e)
//// {
//// StackTraceElement[] ste = e.getStackTrace();
//// for (int i=0 ; i < ste.length; i++)
//// LOG.severe("STACK TRACE=" + ste[i].toString());
//// LOG.severe("ERROR=" + e.toString());
//// return c_fact;
//// }
//
// //GridCoverage2DReader reader = format.getReader(tiffFile);
// // grid =reader.read(null);
// // gridData = grid.getRenderedImage().getData();
//
//
// return c_fact;
// }
}