V1_0.java [src/java/m/wqm/wqmsoilattributes] Revision: 6e6a5e509fe27e87d975676c794f977a73cb2d39 Date: Thu Oct 01 12:12:44 MDT 2015
package m.wqm.wqmsoilattributes;
/**
*
* @author RUMPAL SIDHU
* @author Shaun Case
*/
import oms3.annotations.*;
import csip.ModelDataService;
import csip.annotations.*;
import csip.utils.JSONUtils;
import org.codehaus.jettison.json.JSONArray;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import javax.ws.rs.Path;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
/**
*
* @author Shaun Case
*/
@Name("WQM-02: Soil Component Attributes (WQMSoilAttributes)")
@Description("This service intersects area of analysis (AoA) geometry with SSURGO soil mapunit geometry, derives a list of distinct soil components for the AoA, and gets attributes from SSURGO tables required for computing nutrient and pesticide loss potentials.")
@Path("m/wqmsoilattributes/1.0")
@Polling(first = 5000, next = 2000)
public class V1_0 extends ModelDataService {
//mapunit/ssurgo polygon intersect URI
private final String SSURGO_INTERSECT_URI = "http://csip.engr.colostate.edu:8090/csip-erosion/d/soils/1.2";
private final Double minimumPercentage = 0.05;
//Request
private String aoaId;
private JSONObject aoaGeometry;
//Response
private ArrayList<V1_0.Component> componentList;
private HashMap<String, V1_0.Component> componentMap;
private String error_msg = "";
private Connection conn = null;
private Statement statement = null;
private V1_0.ServiceCall intersectCall = null;
@Override
protected void preProcess() throws Exception {
this.error_msg = "";
JSONArray request = getRequest().optJSONArray("parameter");
if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") ){
this.aoaId = getStringParam("AoAId");
//Get the entire aoa_geometry group as it matches the input payload for the ServiceCall class
this.aoaGeometry = getJSONParam("aoa_geometry");
this.intersectCall = new ServiceCall( this.SSURGO_INTERSECT_URI );
try {
this.conn = wqm.utils.WQMTools.getConnection( "ssurgo", LOG );
this.statement = this.conn.createStatement();
} catch (SQLException se) {
LOG.info("Did not open database for WQM-02");
LOG.info(se.getMessage());
this.error_msg = "Could not open the database connection required. ";
}
}
else{
// No valid input stream for this service
this.error_msg = "No valid input parameters were found. Check your input JSON.";
}
}
@Override
protected String process() throws Exception {
if ( ( null != this.intersectCall ) && ( !this.intersectCall.getError() ) ){
HashMap<String, Double> aoa_mukeyList;
aoa_mukeyList = this.intersectCall.intersect( this.aoaGeometry );
try{
if ( (!this.intersectCall.getError() ) && ( null != aoa_mukeyList) && ( aoa_mukeyList.size() > 0) ){
ResultSet resultSet;
String query;
this.componentList = new ArrayList<>();
this.componentMap = new HashMap<>();
int mapCount = 0;
double totalAreas = 0.0;
double aoa_comp_kfact = 0.0;
String lastQueryWhere = "(";
String lastQueryWhere2 = "(";
Set keys = aoa_mukeyList.keySet();
Iterator ite = keys.iterator();
query = "SELECT ssurgo.component.mukey, ssurgo.component.cokey, ssurgo.component.compname, ssurgo.component.comppct_r, ssurgo.component.hydgrp, "
+ " ssurgo.component.slope_r, ssurgo.component.taxorder, ssurgo.chorizon.chkey, ssurgo.chorizon.om_r, ssurgo.chorizon.hzthk_r, "
+ " ssurgo.chorizon.hzdept_r, ssurgo.chorizon.hzdepb_r, ssurgo.chorizon.kwfact, ssurgo.chorizon.kffact, ssurgo.chfrags.fragvol_r, ssurgo.chfrags.chfragskey FROM ssurgo.component "
+ " LEFT OUTER JOIN ssurgo.chorizon ON ssurgo.chorizon.cokey=ssurgo.component.cokey LEFT OUTER JOIN ssurgo.chfrags on ssurgo.chfrags.chkey=ssurgo.chorizon.chkey WHERE ssurgo.component.mukey in ( '";
while (ite.hasNext()) {
if ( mapCount > 0 ){
query += ", '" + ite.next().toString() + "' ";
}
else{
query += ite.next().toString() + "' ";
}
mapCount++;
}
query += ") AND ssurgo.component.comppct_r IS NOT NULL ORDER BY ssurgo.component.mukey, ssurgo.component.cokey, ssurgo.chorizon.chkey, ssurgo.chorizon.hzdept_r;";
LOG.log(Level.INFO, "WQM-02-polygon intersect query(118):" + query);
resultSet = this.statement.executeQuery( query );
while( resultSet.next() ){
V1_0.Component tComponent;
V1_0.Component component;
String mukey = resultSet.getString( "mukey");
String cokey = resultSet.getString("cokey");
String chkey = resultSet.getString("chkey");
double aoa_Area = aoa_mukeyList.get( mukey );
if ( !this.componentMap.containsKey( (cokey) )){
component = new V1_0.Component( cokey, resultSet.getString("compname"), (aoa_Area * (resultSet.getDouble("comppct_r") / 100.0)),
resultSet.getString("hydgrp"), resultSet.getDouble("slope_r"), resultSet.getString("taxorder") );
totalAreas += component.getArea();
this.componentList.add( component );
this.componentMap.put( cokey, component );
tComponent = component;
}
else{
tComponent = this.componentMap.get( cokey );
}
//For the rest of these operations, we need to use the temp component pointer..
// Add chkeys to cokey object, some will be duplicates because they are unique by cokey:chkey:chfragkey
double kwfact;
Boolean kwfact_b;
double kffact;
Boolean kffact_b;
double hzthk_r;
Boolean hzthk_r_b;
// Keep these pairs of resultSet calls together..."wasNULL()" depends on the call previous to it.
kwfact = resultSet.getDouble("kwfact");
kwfact_b = resultSet.wasNull();
kffact = resultSet.getDouble("kffact");
kffact_b = resultSet.wasNull();
hzthk_r = resultSet.getDouble("hzthk_r");
hzthk_r_b = resultSet.wasNull();
tComponent.addHorizon(chkey, resultSet.getString("chfragskey"), kwfact, kwfact_b, kffact, kffact_b, resultSet.getDouble("om_r"), hzthk_r, hzthk_r_b, resultSet.getDouble("hzdept_r"), resultSet.getDouble("hzdepb_r"), resultSet.getDouble("fragvol_r"));
}
int componentsRemaining = 0;
//Remove components having less than minimumPercentage of total area "totalAreas" here.
for( V1_0.Component component : this.componentList ){
if ( (component.getArea() / totalAreas ) < this.minimumPercentage ){
component.setDeleted(true);
}
else{
componentsRemaining++;
component.computeHorizonResults();
if ( lastQueryWhere.length() > 1 ){
lastQueryWhere += " OR component.cokey='" + component.getCokey() + "'";
lastQueryWhere2 += " OR WT1.cokey='" + component.getCokey() + "'";
}
else{
lastQueryWhere += " component.cokey='" + component.getCokey() + "'";
lastQueryWhere2 += "WT1.cokey='" + component.getCokey() + "'";
}
}
}
if ( componentsRemaining > 0 ){
lastQueryWhere += " ) ";
lastQueryWhere2 += " ) ";
query = "With WT1 As (Select component.cokey, component.compname, component.comppct_r, MIN(cosoilmoist.soimoistdept_r) As wtbl_top_min, MAX(cosoilmoist.soimoistdepb_r) As wtbl_bot_max From ssurgo.component Inner Join ssurgo.comonth On component.cokey=comonth.cokey Inner Join ssurgo.cosoilmoist On comonth.comonthkey=cosoilmoist.comonthkey "
+"Where " + lastQueryWhere + "and cosoilmoist.soimoiststat='Wet' Group By component.cokey, component.compname, component.comppct_r Order By component.cokey), WT2 As (Select WT1.cokey, WT1.compname, WT1.comppct_r, WT1.wtbl_top_min, WT1.wtbl_bot_max, MAX(cosoilmoist.soimoistdept_r) As nonwet_top_max From WT1 Left Outer Join ssurgo.comonth On WT1.cokey=comonth.cokey Left Outer Join ssurgo.cosoilmoist On comonth.comonthkey=cosoilmoist.comonthkey "
+ "Where " + lastQueryWhere2 + " and (cosoilmoist.soimoiststat NOT IN ('Wet') OR cosoilmoist.soimoiststat IS NULL) Group By WT1.cokey, WT1.compname, WT1.comppct_r, WT1.wtbl_top_min, WT1.wtbl_bot_max) Select WT2.cokey, WT2.compname, WT2.comppct_r, WT2.wtbl_top_min, WT2.wtbl_bot_max, WT2.nonwet_top_max, case when (wtbl_bot_max < 183 or nonwet_top_max >= wtbl_bot_max) then 'Perched' else 'Apparent' end as wtkind from WT2";
LOG.log(Level.INFO, "WQM-02-polygon intersect query(189):" + query);
resultSet = this.statement.executeQuery( query );
while ( resultSet.next() ){
String tCokey = resultSet.getString("cokey");
V1_0.Component tcomponent = this.componentMap.get(tCokey);
tcomponent.setWTBL( resultSet.getString("wtkind") ); // If this is null, the set funciton will make the appropriate adjustment to "None".
tcomponent.setWtblTopMin( resultSet.getDouble("wtbl_top_min") );
}
}
} // Actual Intersect Call failed.
else{
this.error_msg += " Could not intersect polygons. ";
}
}
catch( SQLException se){
this.error_msg += "Error executing SQL: " + se.getMessage();
}
}// Creation of Client objec to make call to intersect failed.
else{
this.error_msg += " Creation of intersect service call failed. ";
}
if ( null != this.conn ){
if ( null != this.statement ){
this.statement.close();
}
this.conn.close();
}
return ( !this.error_msg.isEmpty()? this.error_msg : EXEC_OK );
}
@Override
protected void postProcess() throws Exception {
putResult("AoaId", aoaId, "Area of Analysis Identifier");
JSONArray resultArray = new JSONArray();
for (Component component : componentList) {
if ( !component.isDeleted() ){
JSONArray tmpArr = new JSONArray();
tmpArr.put(JSONUtils.dataDesc("cokey", component.getCokey(), "Soil Component Key"));
tmpArr.put(JSONUtils.dataDesc("compname", component.getName(), "Soil Component Name"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_area", component.getArea(), "Soil Component Area (Acres) in the Area of Analysis"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_hsg", component.getHsg(), "Hydrologic Soil Group of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_taxorder", component.getTaxorder(), "Taxonomic Order of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_kfact", component.getKfactor(), "K factor of the Surface Mineral Horizon of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_slope", component.getSlope(), "Slope Percentage of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_coarse_frag", component.getCoarseFrag(), "Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_om", component.getOrganicMatter(), "Organic Matter Percentage of the Surface Horizon of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_hzdepth", component.getHzdepth(), "Depth (inches) of the Surface Horizon of the Soil Component"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_wtbl", component.getWTBL(), "Kind of Water Table of the Soil Component; values are None, Apparent, Perched"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_cracksgr24", component.getCracksgr24(), "Surface Connected Macropores (Cracks) at Least 24 Inches Deep"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_slopegr15", component.getSlopegr15(), "Field Slope is Greater Than 15%"));
tmpArr.put(JSONUtils.dataDesc("aoa_comp_hwt_lt_24", component.getHwt_lt_24(), "High Water is Less than 24 Inches Under the Surface"));
resultArray.put(JSONUtils.dataDesc("soil_component", tmpArr, "Entry for Soil Component"));
};
}
putResult("soil_component_list", resultArray);
}
//Inner Classes
/**
*
*/
public class ServiceCall {
private HashMap<String, Double> aoa_mukeyList;
private final String URI;
private final csip.Client newClient;
private String error_msg;
ServiceCall( String URI ){
this.URI = URI;
this.error_msg = "";
this.aoa_mukeyList = new HashMap();
this.newClient = new csip.Client();
if ( this.URI.isEmpty() ){
this.error_msg = "SSURGO mapunit Intersect URI is empty.";
}
}
/*Calls the csip soil service to intersect AoA and SSURGO layers producing
set of AoA x mapunit polygons */
/**
*
* @param aoaGeometry
* @return
*/
public HashMap intersect(JSONObject aoaGeometry) {
if ( this.aoa_mukeyList.isEmpty() ){
try{
LOG.log(Level.INFO, "polygon intersect URI:" + this.URI);
JSONObject result;
result = this.newClient.doPOST( this.URI, this.createRequest( aoaGeometry ) );
if (( null == result ) || ( result.length() <= 0 ) ){
this.error_msg += " No data was returned from " + URI + " for this request. ";
}
else{
//Process result information
JSONArray intersectResult = result.optJSONArray("result");
if (intersectResult.length() > 0 ){
HashMap<String, Double> tempMap = new HashMap<>();
String mukey;
double aoaArea;
ArrayList<String> keys = new ArrayList<String>();
JSONArray mukeyArray = intersectResult.getJSONArray(1).getJSONArray(0);
for (int i = 0; i < mukeyArray.length(); i++) {
Map<String, JSONObject> myResult = JSONUtils.preprocess( mukeyArray.getJSONArray(i) );
mukey = JSONUtils.getStringParam (myResult,"ssurgo_mukey", "err" );
aoaArea = JSONUtils.getDoubleParam( myResult, "acres_in_aoi", 0.0);
/*
// Remember to sum the areas of same mukeys...
if ( tempMap.containsKey( mukey ) ){
double tArea = tempMap.get( mukey );
aoaArea += tArea;
}
*/
tempMap.put(mukey, aoaArea);
if ( !keys.contains( mukey ) ){
keys.add(mukey);
}
}
Collections.sort(keys);
for (String i : keys) {
this.aoa_mukeyList.put(i, tempMap.get(i));
}
}
else{
// Check this: Is this an error or does it just mean that no intersects are found??
this.error_msg += " No returned data was found in the result section from the SSURGO mapunit polygon intersect call. ";
}
}
}
catch (Exception ex) {
this.error_msg += " Cannot make a connection to that location: " + URI + ". " + ex.getMessage();
}
}
return this.aoa_mukeyList;
}
/**
*
* @return
*/
public Boolean getError(){return (!this.error_msg.isEmpty());}
/**
*
* @return
*/
public String getErrorMsg(){return this.error_msg;}
private JSONObject createRequest( JSONObject aoaGeometry) throws JSONException{
JSONObject ret_val;
JSONArray headerArray;
JSONObject metainfo;
metainfo = new JSONObject();
ret_val = new JSONObject();
headerArray = new JSONArray();
metainfo.put( "MultipartRequest", "mapunit intersect request WQM-02");
metainfo.put( "OriginalSource", getRequestHost() );
metainfo.put( "OriginalRequest", getRequestURL() );
metainfo.put( "OriginalSUID", getSUID() );
ret_val.put("metainfo", metainfo );
headerArray.put(JSONUtils.dataDesc( "AoAI", aoaGeometry, null ) );
ret_val.put( "parameter", headerArray);
return ret_val;
}
}
/**
*
*/
public class Component {
private String cokey; //Soil Component Key
private String name; //Soil Component Name
private double area; //Soil Component Area (Acres) in the Area of Analysis
private String hsg; //Hydrologic Soil Group of the Soil Component
private String taxorder; //Taxonomic Order of the Soil Component
private double slope; //Slope Percentage of the Soil Component
private double kfactor; //K factor of the Surface Mineral Horizon of the Soil Component
private double coarseFrag; //Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component
private double organicMatter; //Organic Matter Percentage of the Surface Horizon of the Soil Component
private double hzdepth; //Depth (inches) of the Surface Horizon of the Soil Component
private boolean cracksgr24; //Surface Connected Macropores (Cracks) at Least 24 Inches Deep; default is False
private boolean slopegr15; //Field Slope is Greater Than 15%; default is False
private boolean hwt_lt_24; //High Water is Less than 24 Inches Under the Surface; default is False
private double wtbl_top_min;
private String wtbl;
private double frag_vol_total;
Boolean Deleted;
private ArrayList<V1_0.Component.horizon> chKeys;
private HashMap<String, V1_0.Component.horizon> horizonMap;
/**
*
* @param cokey
* @param compname
* @param area
* @param hsg
* @param slope_r
* @param taxorder
*/
public Component( String cokey, String compname, double area, String hsg, double slope_r, String taxorder) {
this.cracksgr24 = false;
this.slopegr15 = false;
this.hwt_lt_24 = false;
this.chKeys = new ArrayList<>();
this.horizonMap = new HashMap<>();
this.cokey = cokey;
this.name = compname;
this.area = area;
this.hsg = hsg;
this.slope = slope_r;
this.taxorder = taxorder;
this.wtbl = "None";
this.wtbl_top_min = 0.0;
this.cracksgr24 = false; //Set to default false, and is not updated by the current spec.
this.Deleted = false;
this.frag_vol_total = 0.0;
this.slopegr15 = ( this.slope > 15.0 );
}
//Set Methods
/**
*
* @param key
*/
public void setCokey(String key) {
this.cokey = key;
}
public void setDeleted( Boolean deleted ){
this.Deleted = deleted;
}
/**
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @param area
*/
public void setArea(double area) {
this.area = area;
}
/**
*
* @param hsg
*/
public void setHsg(String hsg) {
this.hsg = hsg;
}
/**
*
* @param taxorder
*/
public void setTaxorder(String taxorder) {
this.taxorder = taxorder;
}
/**
*
* @param slope
*/
public void setSlope(double slope) {
this.slope = slope;
this.slopegr15 = ( this.slope > 15.0 );
}
/**
*
* @param kfactor
*/
public void setKfactor(double kfactor) {
this.kfactor = kfactor;
}
/**
*
* @param coarseFrag
*/
public void setCoarseFrag(int coarseFrag) {
this.coarseFrag = coarseFrag;
}
/**
*
* @param organicMatter
*/
public void setOrganicMatter(double organicMatter) {
this.organicMatter = organicMatter;
}
/**
*
* @param depth
*/
public void setHzdepth(double depth) {
this.hzdepth = depth;
}
public void setWTBL( String wtKind ){
if ( null == wtKind ){
this.wtbl = "None";
}
else{
this.wtbl = wtKind;
}
}
public void setWtblTopMin( double wtbl_top_min ){
this.wtbl_top_min = wtbl_top_min;
this.hwt_lt_24 = (wtbl_top_min <= 61);
}
//Get Methods
/**
*
* @return
*/
public String getCokey() {
return this.cokey;
}
public Boolean isDeleted(){return this.Deleted;}
/**
*
* @return
*/
public String getName() {
return this.name;
}
/**
*
* @return
*/
public double getArea() {
return this.area;
}
/**
*
* @return
*/
public String getHsg() {
return this.hsg;
}
/**
*
* @return
*/
public String getTaxorder() {
return this.taxorder;
}
/**
*
* @return
*/
public double getSlope() {
return this.slope;
}
/**
*
* @return
*/
public double getKfactor() {
return this.kfactor;
}
/**
*
* @return
*/
public double getCoarseFrag() {
return this.coarseFrag;
}
/**
*
* @return
*/
public double getOrganicMatter() {
return this.organicMatter;
}
/**
*
* @return
*/
public double getHzdepth() {
return this.hzdepth;
}
/**
*
* @return
*/
public boolean getCracksgr24() {
return this.cracksgr24;
}
/**
*
* @return
*/
public boolean getSlopegr15() {
return this.slopegr15;
}
/**
*
* @return
*/
public boolean getHwt_lt_24() {
return this.hwt_lt_24;
}
public boolean getAoACompHwt(){return this.hwt_lt_24;}
public String getWTBL(){return this.wtbl;}
public double getWtbltopMin(){return this.wtbl_top_min;}
/**
*
* @param chkey
* @param chfragskey
* @param kwfact
* @param kwfact_b
* @param kffact
* @param kffact_b
* @param om_r
* @param hzthk_r
* @param hzdept_r
* @param hzdepb_r
*/
public void addHorizon( String chkey, String chfragskey, double kwfact, boolean kwfact_b, double kffact, boolean kffact_b, double om_r, double hzthk_r, Boolean hzthk_r_b, double hzdept_r, double hzdepb_r, double fragvol_r ){
// Each component can have mulitiple horizons...each horizon can have multiple fragment volumes...
V1_0.Component.horizon tHorizon;
if ( this.horizonMap.containsKey( chkey ) ){
tHorizon = this.horizonMap.get( chkey );
tHorizon.addFragKey( chfragskey, fragvol_r );
}
else{
tHorizon = new V1_0.Component.horizon( chkey, chfragskey, kwfact, kwfact_b, kffact, kffact_b, om_r, hzthk_r, hzthk_r_b, hzdept_r, hzdepb_r, fragvol_r );
this.chKeys.add( tHorizon );
this.horizonMap.put( chkey, tHorizon );
}
}
public void computeHorizonResults(){
double profile_thk = 0.0;
Boolean haveKFactor = false;
double comp_product = 0.0;
//If we remove the "order by" which includes hzdept_r in the first SQL statement in process(), then we need to sort this list before continuing...
//For now this "order by...hzdept_r" is currently in the SQL statement, so no sort is done here. If we find that the SQL statement takes longer with
//The order by clause, and the sort is quicker here, then this code will change.
//#Get first horizon organic matter
this.organicMatter = this.chKeys.get(0).getOm_r();
for( V1_0.Component.horizon horizon : this.chKeys ){
double horizonThickness = 0.0;
double horizonProduct = 0.0;
if ( !horizon.getHzthk_r_b() ){
this.hzdepth = horizon.getHzdepb_r() - horizon.getHzdept_r();
}
else{
this.hzdepth = horizon.getHzdept_r();
}
if ( this.hsg.equals("D") && this.taxorder.equals("Histosols") && horizon.getKffact_b() && horizon.getKwfact_b() ){
this.kfactor = 0.02;
}
else{
if ( !haveKFactor ){
if ( !horizon.getKffact_b() && horizon.getKwfact_b() ){
this.kfactor = horizon.getKffact();
haveKFactor = true;
}
else{
if( !horizon.getKwfact_b() && horizon.getKffact_b() ){
this.kfactor = horizon.getKwfact();
haveKFactor = true;
}
}
}
}
this.frag_vol_total += horizon.getFragVol();
if ( horizon.getHzthk_r_b() ){
horizonThickness = horizon.getHzdepb_r() - horizon.getHzdept_r();
}
else{
horizonThickness = horizon.getHzthk_r();
}
profile_thk += horizonThickness;
horizonProduct = horizonThickness * horizon.getFragVol();
comp_product += horizonProduct;
}
this.coarseFrag = comp_product / profile_thk;
}
class horizon implements Comparable<V1_0.Component.horizon> {
private final String chkey;
private final String chfragskey;
private final double kwfact;
private final Boolean kwfact_b;
private final double kffact;
private final Boolean kffact_b;
private final double om_r;
private final double hzthk_r;
private final double hzdept_r;
private final double hzdepb_r;
private final Boolean hzthk_r_b;
private double frag_vol_total;
private HashMap <String, Double> fragkeyMap;
horizon( String chkey, String chfragskey, double kwfact, boolean kwfact_b, double kffact, boolean kffact_b, double om_r, double hzthk_r, Boolean hzthk_r_b, double hzdept_r, double hzdepb_r, double fragvol_r ){
this.chkey = chkey;
this.chfragskey = chfragskey;
this.kwfact = kwfact;
this.kwfact_b = kwfact_b;
this.kffact = kffact;
this.kffact_b = kffact_b;
this.om_r = om_r;
this.hzthk_r = hzthk_r;
this.hzthk_r_b = hzthk_r_b;
this.hzdept_r = hzdept_r;
this.hzdepb_r = hzdepb_r;
this.fragkeyMap = new HashMap<>();
this.fragkeyMap.put(chfragskey, fragvol_r );
this.frag_vol_total = fragvol_r;
}
@Override
public int compareTo(V1_0.Component.horizon tHorizon ){
int ret_val = 0;
//TODO: Allow this to be sorted....by chkey:chfragskey:hzdept_r
// This might be needed if the "order by" clause of the SQL statement
// used to get this data runs faster without the "order by" that includes this hzdept_r value....
return ret_val;
}
public void addFragKey( String chfragskey, double fragvol_r ){
this.fragkeyMap.put( chfragskey, fragvol_r );
this.frag_vol_total += fragvol_r;
}
public double getFragVol(){ return this.frag_vol_total; }
public String getChkey(){ return this.chkey;}
public String getChfragsKey(){ return this.chfragskey;}
public double getKwfact(){ return this.kwfact;}
public boolean getKwfact_b(){ return this.kwfact_b;}
public double getKffact(){ return this.kffact;}
public boolean getKffact_b(){ return this.kffact_b;}
public double getOm_r(){ return this.om_r;}
public double getHzthk_r(){ return this.hzthk_r;}
public Boolean getHzthk_r_b(){ return this.hzthk_r_b;}
public double getHzdept_r(){ return this.hzdept_r;}
public double getHzdepb_r(){ return this.hzdepb_r;}
}
}
}