MSSQL_SOILS.java [src/soils/db] Revision: default Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package soils.db;
import csip.api.server.ServiceException;
import csip.SessionLogger;
import csip.utils.Validation;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngine;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.logging.Level;
import soils.Cocropyld;
import soils.Coecoclass;
import soils.Comonth;
import soils.Component;
import soils.Horizon;
import soils.MapUnit;
import soils.Mucropyld;
import soils.TextureGroup;
import soils.db.tables.TableCocropyld;
import soils.db.tables.TableCoecoclass;
import soils.db.tables.TableComonth;
import soils.db.tables.TableComponent;
import soils.db.tables.TableComponentCalculations;
import soils.db.tables.TableFragments;
import soils.db.tables.TableHorizon;
import soils.db.tables.TableLegend;
import soils.db.tables.TableMapUnit;
import soils.db.tables.TableMapUnitCalculations;
import soils.db.tables.TableMuaggatt;
import soils.db.tables.TableMucropyld;
import soils.db.tables.TableSaCatalog;
import soils.db.tables.TableSaSpatialVer;
import soils.db.tables.TableSaTabularVer;
import soils.db.tables.TableTexture;
import soils.db.tables.TableTextureGroup;
import soils.exceptions.SDMException;
import soils.exceptions.WEPPException;
import soils.exceptions.WEPP_WEPSException;
import soils.exceptions.WEPSException;
import soils.utils.EvalResult;
import soils.utils.GenericIFCData;
import soils.utils.SoilUtils;
import static soils.utils.SoilUtils.metricConversion;
import static soils.utils.SoilUtils.pctToFraction;
/**
*
* This interface class is meant to be used only internally within soilsdb. All
* software utilizing the soilsdb.jar file should access these internal
* functions ONLY through a wrapped function call, preferably located in the AoA
* class, or secondarily within some other wrapper class located in the soils
* directory of soilsdb. Implementations of this class should never be
* instantiated on their own outside of the soils package tree of the
* soilsdb.jar library.
* <p>
* Internally, the implementations of this interface should always be created
* through the SOILS_DB_FACTORY class, only.
*
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
public abstract class MSSQL_SOILS implements SOILS_DATA {
/**
* This value represents the SRID used in this database's geometry tables. Not
* all implementations of the geometry tables are using the same SRID's
* between databases. For instance SDM uses 4326 exclusively, while SSURGO
* uses 0 exclusively. [By the way 0 is not a valid SRID]
*/
protected String DB_GEOM_SRID;
protected SessionLogger LOG;
protected Connection connection;
protected String logPrefix;
protected final void Log(Level level, String msg, Throwable t) {
if ((null != LOG) && (LOG.isLoggable(level))) {
if (LOG.isLoggable(level)) {
LOG.log(level, logPrefix + ": " + msg, t);
}
}
}
protected final void Log(Level level, String msg) {
if ((null != LOG) && (LOG.isLoggable(level))) {
LOG.log(level, logPrefix + ": " + msg);
}
}
protected final void Log(Level level, String msg, Object... params) {
if ((null != LOG) && (LOG.isLoggable(level))) {
LOG.log(level, logPrefix + ": " + msg, params);
}
}
protected abstract String buildFindAllByShapeQuery(String WKT, boolean returnIntersectionShape) throws SDMException;
protected abstract String buildPlainComponentQuery(String mukey);
protected abstract String buildPlainCHFQuery(String mukey);
protected abstract String buildPlainNoFilterCHFQuery(HashMap<String, MapUnit> mapUnits) throws ServiceException;
protected abstract String buildBasicNoFilterCHFQuery(HashMap<String, MapUnit> mapUnits) throws ServiceException;
protected abstract String buildPlainNoFilterCHFQuery(HashMap<String, MapUnit> mapUnits, boolean includeMajComp) throws ServiceException;
protected abstract String buildBasicMukeyQuery(String mukey);
protected abstract String buildBasicNoFilterMukeyByCokeyQuery(String cokey);
protected abstract String buildBasicMukeyByCokeyQuery(String cokey);
protected abstract String buildBasicMukeyQueryByArea(String areaSymbol);
protected abstract String buildBasicMukeyQueryByAreaWithShape(String areaSymbol);
protected abstract String buildCHFQuery(String mukey, String filter);
protected abstract String buildCHQuery(String cokey, String filter);
protected abstract String buildCSMQuery(MapUnit mapUnit);
protected abstract String buildFindMapUnitsQuery(String WKTShape, boolean returnIntersectionShape);
protected abstract String buildFindMapUnitsByPolyKeyQuery(String mupolygonkey, boolean returnIntersectionShape);
protected abstract String buildMuCropYldQuery(HashMap<String, MapUnit> mapUnits, ArrayList<String> cropNames, ArrayList<String> yldUnits);
protected abstract String buildCoCropYldQuery(HashMap<String, MapUnit> mapUnits, ArrayList<String> cropNames, ArrayList<String> yldUnits);
protected abstract String buildCoEcoClassQuery(HashMap<String, MapUnit> mapUnits);
protected abstract String buildCoCropYldQuery(LinkedHashMap<String, Component> component);
protected abstract String buildCoEcoClassQuery(LinkedHashMap<String, Component> component);
protected abstract String buildCoMonthQuery(HashMap<String, MapUnit> mapUnits);
protected abstract String buildIsConusQuery(String lat, String lon);
protected abstract String buildMinResdept_rQuery(String cokey);
protected abstract String buildStateCountyByLocationQuery(String countyWKT);
protected abstract String buildStateAreaSymbolQuery(String stateAbbrev);
protected abstract String buildTextureDataQuery(HashMap<String, MapUnit> mapUnits);
protected abstract String buildTextureGroupsQuery(String chkey);
protected abstract String buildFragmentsQuery(String chkey);
protected abstract boolean isValidDb();
protected abstract String buildGenericMapUnitIntersectQuery();
protected abstract String buildValidateCokeyQuery(int cokey);
protected abstract String buildWeppWepsCHFQuery(String cokey, String filter);
@Override
public void close() throws SQLException {
if (null != connection) {
Log(Level.INFO, "Closing Database Connection.");
connection.close();
}
}
@Override
/**
*
*/
public HashMap<String, MapUnit> findAllByShape(GISObject shape, boolean returnIntersectionShape) throws SDMException, GISObjectException {
HashMap<String, MapUnit> ret_val = null;
if ((null != shape) && (shape.isValid())) {
String query = buildFindAllByShapeQuery(shape.toWKT(), returnIntersectionShape);
if ((null != query) && !query.isEmpty()) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
TableMapUnit mapUnit = new TableMapUnit();
TableMuaggatt muaggatt = new TableMuaggatt();
TableComponent component = new TableComponent();
TableFragments fragments = new TableFragments();
TableTexture texture = new TableTexture();
TableTextureGroup textureGroup = new TableTextureGroup();
ArrayList<String> usedColumns = new ArrayList<>();
usedColumns.addAll(mapUnit.getColumnList());
usedColumns.addAll(muaggatt.getColumnList());
usedColumns.addAll(component.getColumnList());
usedColumns.addAll(fragments.getColumnList());
usedColumns.addAll(texture.getColumnList());
usedColumns.addAll(textureGroup.getColumnList());
while (resultSet.next()) {
String mukey = resultSet.getString(TableComponent.MUKEY);
MapUnit tMapUnit = null;
if (null != ret_val) {
if (ret_val.containsKey(mukey)) {
tMapUnit = ret_val.get(mukey);
}
}
if (null == tMapUnit) {
tMapUnit = new MapUnit();
tMapUnit.setUsedColumns(usedColumns);
ret_val.put(mukey, tMapUnit);
tMapUnit.readFromSQL(resultSet);
}
String cokey = resultSet.getString(TableComponent.COKEY);
Component tComponent = null;
LinkedHashMap<String, Component> components = tMapUnit.components();
if (components.containsKey(cokey)) {
tComponent = components.get(cokey);
} else {
tComponent = new Component();
tComponent.setUsedColumns(usedColumns);
components.put(cokey, tComponent);
tComponent.readFromSQL(resultSet);
}
String chkey = resultSet.getString(TableHorizon.CHKEY_NAME);
Horizon tHorizon = null;
LinkedHashMap<String, Horizon> horizons = tComponent.horizons;
if (horizons.containsKey(chkey)) {
tHorizon = horizons.get(chkey);
} else {
tHorizon = new Horizon();
tHorizon.setUsedColumns(usedColumns);
horizons.put(chkey, tHorizon);
tHorizon.readFromSQL(resultSet);
}
String chtgkey = resultSet.getString(TableTextureGroup.CHTGKEY);
TextureGroup tTextureGroup = null;
LinkedHashMap<String, TextureGroup> textureGroups = tHorizon.textureGroups;
if (textureGroups.containsKey(chtgkey)) {
tTextureGroup = textureGroups.get(chtgkey);
} else {
tTextureGroup = new TextureGroup();
tTextureGroup.setUsedColumns(usedColumns);
textureGroups.put(chtgkey, tTextureGroup);
}
// This needs to be called each time to read all the textures into the textureGroup object.
// That is why this is outside of the the above "if" block.
tTextureGroup.readFromSQL(resultSet);
}
} catch (SQLException ex) {
throw new SDMException("SQLException: " + ex.getMessage(), ex);
} catch (ServiceException ex) {
throw new SDMException(ex);
}
}
}
return ret_val;
}
/**
* This function finds all of the comonth table data for each component found
* in this object's list of existing mapunits. It additionally computes the
* maximum ratings for flood and pond frequencies, which are stored in the
* TableComponentCalculations table of each Component object.
*
* @param map_units
* @return
* @throws ServiceException
*/
@Override
public synchronized boolean findAllComonthData(LinkedHashMap<String, MapUnit> map_units) throws ServiceException {
boolean ret_val = false;
if (null != map_units) {
String query = buildCoMonthQuery(map_units);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
Comonth.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableComonth.COKEY, TableComonth.COMONTH_KEY, TableComonth.FLOOD_FREQ_CL,
TableComonth.MONTH, TableComonth.MONTH_SEQ, TableComonth.POND_FREQ_CL
)));
while (resultSet.next()) {
synchronized (this) {
MapUnit tMapUnit = map_units.get(resultSet.getString(TableComponent.MUKEY));
if (null != tMapUnit) {
Component tComponent = tMapUnit.components().get(resultSet.getString(TableComonth.COKEY));
if (null != tComponent) {
Comonth tComonth = new Comonth();
tComonth.readFromSQL(resultSet);
tComponent.addComonth(tComonth);
ret_val = true;
} else {
ret_val = false;
break;
}
} else {
ret_val = false;
break;
}
}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findAllTextureData: " + ex.getMessage(), ex);
}
}
}
if (ret_val) {
if (null != map_units) {
for (MapUnit tMapUnit : map_units.values()) {
if (null != tMapUnit.components()) {
for (Component tComponent : tMapUnit.components().values()) {
tComponent.maxFloodFreq();
tComponent.maxPoolFreq();
}
}
}
}
}
return ret_val;
}
@Override
public synchronized boolean findAllTextureData(HashMap<String, MapUnit> mapUnits) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
String query = buildTextureDataQuery(mapUnits);
// Using these static functions prevents us from having to set the used
// columns each time we read a new row and create a new object.
// Normally, we would avoid using these static functions if we were dealing with exisitng objects.
ArrayList<String> textureGroupColumns = new ArrayList<>(Arrays.asList(
TableTextureGroup.CHKEY, TableTextureGroup.CHTGKEY,
TableTextureGroup.DESCRIPTION, TableTextureGroup.RVINDICATOR,
TableTextureGroup.STRATEXTSFLAG, TableTextureGroup.TEXTURE
));
ArrayList<String> textureColumns = new ArrayList<>(Arrays.asList(
TableTexture.CHTGKEY, TableTexture.CHTKEY,
TableTexture.LIEUTEX, TableTexture.TEXTURE_CL
));
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
while (resultSet.next()) {
//synchronized (this) {
MapUnit tMapUnit = mapUnits.get(resultSet.getString(TableMapUnit.MUKEY));
if (null != tMapUnit) {
Component tComponent = tMapUnit.components().get(resultSet.getString(TableComponent.COKEY));
if (null != tComponent) {
Horizon tHorizon = tComponent.horizons().get(resultSet.getString(TableHorizon.CHKEY_NAME));
if (null != tHorizon) {
// First time through this data result, the returned texture group pointers will be null
// Since there are duplicate texturegroup identifier potentials in the results this line of code
// prevents us from forming a new texturegroup object, when not needed and allows us to populate that
// texturegroup object's texture rows, which may be many.
TextureGroup tTextureGroup = tHorizon.textureGroups.get(resultSet.getString(TableTextureGroup.CHTGKEY));
// TextureGroup.readFromSQL() also reads any associated Texture data that is in the result set,
// and creates new Texture objects under this texture group as needed.
if (null != tTextureGroup) {
tTextureGroup.setUsedColumns(textureGroupColumns);
tTextureGroup.readFromSQL(resultSet, textureColumns);
ret_val = true;
} else {
//Creates a new texture group and reads its values from the result set.
tHorizon.setTextureGroups(resultSet, textureGroupColumns, textureColumns);
ret_val = true;
}
} else {
ret_val = false;
break;
}
} else {
ret_val = false;
break;
}
} else {
ret_val = false;
break;
}
//}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findAllTextureData: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
@Override
public ArrayList<String> findAreaSymbolsByState(String stateAbbrev) throws ServiceException {
ArrayList<String> ret_val = new ArrayList<>();
if (null != stateAbbrev) {
if (stateAbbrev.length() == 2) {
String query = buildStateAreaSymbolQuery(stateAbbrev);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
while (resultSet.next()) {
ret_val.add(resultSet.getString("areasymbol"));
}
} catch (SQLException ex) {
throw new ServiceException("Could not find any soil surveys, (areasymbol), for that state, " + stateAbbrev + ": " + ex.getMessage(), ex);
}
}
} else {
throw new ServiceException("State abbreviation value passed to findAreaSymbolsByState() had more than 2 characters. Cannot proceed; function requires a valid state abbreviation.");
}
} else {
throw new ServiceException("State abbreviation value was empty passed to findAreaSymbolsByState(). Cannot proceed; function requires a valid state abbreviation.");
}
if (ret_val.size() <= 0) {
throw new ServiceException("Could not find any soil surveys, (areasymbol), for this state: " + stateAbbrev + ".");
}
return ret_val;
}
@Override
public ArrayList<String> findAreaSymbolsByCounty(String countyWKT) throws ServiceException {
ArrayList<String> ret_val = new ArrayList<>();
if (null != countyWKT) {
String query = buildStateCountyByLocationQuery(countyWKT);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
while (resultSet.next()) {
ret_val.add(resultSet.getString("areasymbol"));
}
} catch (SQLException ex) {
throw new ServiceException("Could not find any soil surveys, (areasymbol), for that county shape: " + ex.getMessage(), ex);
}
}
} else {
throw new ServiceException("County shape value was empty passed to findAreaSymbolsByCounty(). Cannot proceed; function requires a valid WKT county shape.");
}
if (ret_val.size() <= 0) {
throw new ServiceException("Could not find any soil surveys, (areasymbol), for this county shape.");
}
return ret_val;
}
@Override
public synchronized boolean findEcoClassForMukeyList(HashMap<String, MapUnit> mapUnits) throws ServiceException {
return findEcoClassForMukeyList(mapUnits, null);
}
@Override
public synchronized boolean findEcoClassForMukeyList(HashMap<String, MapUnit> mapUnits, String addWhere) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
String query = buildCoEcoClassQuery(mapUnits);
if ((null != addWhere) && (!addWhere.isEmpty())) {
String preQuery = query.substring(0, query.lastIndexOf("ORDER BY"));
String postQuery = query.substring(query.lastIndexOf("ORDER BY"));
query = preQuery + " AND " + addWhere + " " + postQuery;
}
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
while (resultSet.next()) {
synchronized (this) {
MapUnit tMapUnit = mapUnits.get(resultSet.getString(TableMapUnit.MUKEY));
if (null != tMapUnit) {
Component tComponent = tMapUnit.components().get(resultSet.getString(TableComponent.COKEY));
if (null != tComponent) {
ArrayList<String> tList = Coecoclass.getDefaultUsedColumns();
// Using the static function here works because the component will create a new object of type Coecoclass
// as it reads each line of the returned data. If the object instance already existed, we would not use this funciton.
Coecoclass.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableCoecoclass.ECOCLASSTYPENAME, TableCoecoclass.ECOCLASSREF, TableCoecoclass.ECOCLASSID,
TableCoecoclass.ECOCLASSNAME, TableCoecoclass.COKEY, TableCoecoclass.COECOCLASSKEY,
TableCoecoclass.SOURCESDWPRIMARYKEY, TableCoecoclass.SOURCESDWTABLEPHYSICALNAME
)));
tComponent.readEcoClassFromSQL(resultSet);
// Restore previous used-list.
Coecoclass.setDefaultUsedColumns(tList);
//TableCoecoclass ecoClass = tComponent.getTableCoecoclass();
//ecoClass.readValuesFromSQL(resultSet);
ret_val = true;
}
}
}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findEcoClassForMukeyList: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
@Override
public synchronized boolean findCoCropYieldsByCropNameOrUnit(HashMap<String, MapUnit> mapUnits, ArrayList<String> cropNames,
ArrayList<String> yldUnits) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
String query = buildCoCropYldQuery(mapUnits, cropNames, yldUnits);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
Cocropyld.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableCocropyld.CROPNAME,
TableCocropyld.YLDUNITS,
TableCocropyld.NONIRRYIELD_L,
TableCocropyld.NONIRRYIELD_R,
TableCocropyld.NONIRRYIELD_H,
TableCocropyld.IRRYIELD_L,
TableCocropyld.IRRYIELD_R,
TableCocropyld.IRRYIELD_H,
TableCocropyld.CROPPRODINDEX,
TableCocropyld.VASOIPRDGRP,
TableCocropyld.COKEY,
TableCocropyld.COCROPYLDKEY
)));
while (resultSet.next()) {
synchronized (this) {
MapUnit tMapUnit = mapUnits.get(resultSet.getString(TableMapUnit.MUKEY));
if (null != tMapUnit) {
Component tComponent = tMapUnit.components().get(resultSet.getString(TableComponent.COKEY));
if (null != tComponent) {
tComponent.readCropYldFromSQL(resultSet);
ret_val = true;
}
}
}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findCoCropYldForMukeyList: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
@Override
public synchronized boolean findMuCropYieldsByCropNameOrUnit(HashMap<String, MapUnit> mapUnits, ArrayList<String> cropNames,
ArrayList<String> yldUnits) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
String query = buildMuCropYldQuery(mapUnits, cropNames, yldUnits);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
Mucropyld.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableMucropyld.CROPNAME,
TableMucropyld.YLDUNITS,
TableMucropyld.NONIRRYIELD_L,
TableMucropyld.NONIRRYIELD_R,
TableMucropyld.NONIRRYIELD_H,
TableMucropyld.IRRYIELD_L,
TableMucropyld.IRRYIELD_R,
TableMucropyld.IRRYIELD_H,
TableMucropyld.MUKEY,
TableMucropyld.MUCRPYLDKEY
)));
while (resultSet.next()) {
synchronized (this) {
MapUnit tMapUnit = mapUnits.get(resultSet.getString(TableMapUnit.MUKEY));
if (null != tMapUnit) {
tMapUnit.readCropYldFromSQL(resultSet);
ret_val = true;
}
}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMuCropYldForMukeyList: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
@Override
public boolean findCoCropYldForMukeyList(HashMap<String, MapUnit> mapUnits) throws ServiceException {
return findCoCropYieldsByCropNameOrUnit(mapUnits, null, null);
}
@Override
public boolean findMuCropYldForMukeyList(HashMap<String, MapUnit> mapUnits) throws ServiceException {
return findMuCropYieldsByCropNameOrUnit(mapUnits, null, null);
}
/**
* Looks up the mukey parameter in the database and finds the data associated
* with it. Specifically fills in the MapUnit object with the mukey, musym,
* muname, muacres, areasymbol, and areaname. This additionally has the
* side-effect in MapUnit of identifying if the MapUnit isPalouse. This
* function has a synchronized section because it temporarily rewrites the
* default used columns for MapUnit, which are static. It is synchronized to
* avoid causing difficulties elsewhere, where the used columns may also be in
* use in another thread.
*
* @param mukey
* @return Returns an instance of MapUnit.
* @throws ServiceException An exception is thrown if the lookup of the data
* associated with the mukey parameter is unsuccessful.
* @see MapUnit
*/
@Override
public synchronized MapUnit findMukeyData(String mukey) throws ServiceException {
MapUnit ret_val = null;
if ((null != mukey) && (!mukey.isEmpty())) {
Validation.checkMukey(mukey);
String query = buildBasicMukeyQuery(mukey);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
if (resultSet.next()) {
synchronized (this) {
//Temp storage for current used-list.
ArrayList<String> tList = MapUnit.getDefaultUsedColumns();
MapUnit.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnit.MUSYM, TableMapUnit.MUACRES, TableMapUnit.AREASYMBOL_NAME, TableMapUnit.AREA_NAME)));
ret_val = new MapUnit(mukey, resultSet, null);
// Restore previous used-list.
MapUnit.setDefaultUsedColumns(tList);
}
} else {
throw new ServiceException("Mukey not found in" + logPrefix + ".findMukeyData, for mukey: '" + mukey + "'");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMukeyData: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
/**
* Looks up the cokey parameter in the database and finds the mapunit data
* associated with it. Specifically fills in the MapUnit object with the
* mukey, musym, muname, muacres, areasymbol, and areaname. This additionally
* has the side-effect in MapUnit of identifying if the MapUnit isPalouse.
* This function has a synchronized section because it temporarily rewrites
* the default used columns for MapUnit, which are static. It is synchronized
* to avoid causing difficulties elsewhere, where the used columns may also be
* in use in another thread.
*
* @param component
* @return Returns an instance of MapUnit.
* @throws ServiceException An exception is thrown if the lookup of the data
* associated with the component parameter is unsuccessful.
* @see MapUnit
*/
@Override
public MapUnit findMukeyDataByCokey(Component component) throws ServiceException {
MapUnit ret_val = null;
String cokey;
if (null != component) {
cokey = component.cokey();
if (!cokey.isEmpty()) {
String query = buildBasicMukeyByCokeyQuery(cokey);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
if (resultSet.next()) {
synchronized (this) {
ret_val = new MapUnit();
ret_val.setUsedColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnit.MUSYM, TableMapUnit.MUACRES, TableMapUnit.AREASYMBOL_NAME, TableMapUnit.AREA_NAME)));
ret_val.readFromSQL(resultSet);
}
} else {
throw new ServiceException("Mukey not found in " + logPrefix + ".findMukeyDataByCokey, for cokey: '" + cokey + "' . This cokey may not be located in a non-MLRA area type.");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMukeyDataByCokey: " + ex.getMessage(), ex);
}
}
}
}
return ret_val;
}
@Override
public MapUnit findBasicNoFilterMukeyDataByCokey(Component component) throws ServiceException {
MapUnit ret_val = null;
String cokey;
if (null != component) {
cokey = component.cokey();
if (!cokey.isEmpty()) {
String query = buildBasicNoFilterMukeyByCokeyQuery(cokey);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
if (resultSet.next()) {
synchronized (this) {
TableMapUnit tmapUnit = new TableMapUnit();
ret_val = new MapUnit();
ArrayList<String> usedColumns = new ArrayList<>();
usedColumns.addAll(tmapUnit.getColumnList());
usedColumns.add(TableLegend.AREASYMBOL_NAME);
usedColumns.add(TableLegend.AREA_NAME);
usedColumns.add(TableSaCatalog.SA_VERSION);
usedColumns.add(TableSaCatalog.SA_VER_EST);
usedColumns.add(TableSaSpatialVer.SPATIAL_VERSION_EST);
usedColumns.add(TableSaSpatialVer.SPATIAL_VERSION);
usedColumns.add(TableSaSpatialVer.SPATIAL_VERSION_EST);
usedColumns.add(TableSaTabularVer.TABULAR_VERSION);
usedColumns.add(TableSaTabularVer.TABULAR_VERSION_EST);
ret_val.setUsedColumns(usedColumns);
ret_val.readFromSQL(resultSet);
}
} else {
throw new ServiceException("Mukey not found in " + logPrefix + ".findBasicNoFilterMukeyDataByCokey, for cokey: '" + cokey + "' . This cokey may not be located in a non-MLRA area type.");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findBasicNoFilterMukeyDataByCokey: " + ex.getMessage(), ex);
}
}
}
}
return ret_val;
}
/**
* Looks up the mukey parameter in the database and finds the data associated
* with it. Specifically fills in the MapUnit object with the mukey, musym,
* muname, muacres, areasymbol, and areaname. This additionally has the
* side-effect in MapUnit of identifying if the MapUnit isPalouse. This
* function has a synchronized section because it temporarily rewrites the
* default used columns for MapUnit, which are static. It is synchronized to
* avoid causing difficulties elsewhere, where the used columns may also be in
* use in another thread.
*
* @param mapUnit
* @return Returns an instance of MapUnit.
* @throws ServiceException An exception is thrown if the lookup of the data
* associated with the mukey parameter is unsuccessful.
* @see MapUnit
*/
@Override
public boolean findMukeyData(MapUnit mapUnit) throws ServiceException {
boolean ret_val = false;
String mukey;
if (null != mapUnit) {
mukey = mapUnit.mukey();
if (!mukey.isEmpty()) {
String query = buildBasicMukeyQuery(mukey);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
if (resultSet.next()) {
synchronized (this) {
mapUnit.setUsedColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnit.MUSYM, TableMapUnit.MUACRES, TableMapUnit.AREASYMBOL_NAME, TableMapUnit.AREA_NAME)));
mapUnit.readFromSQL(resultSet);
ret_val = true;
}
} else {
throw new ServiceException("Mukey not found in" + logPrefix + ".findMukeyData, for mukey: '" + mukey + "'");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMukeyData: " + ex.getMessage(), ex);
}
}
}
}
return ret_val;
}
/**
* Looks up the mukey parameter in the database and finds the data associated
* with it. Specifically fills in the MapUnit object with the mukey, musym,
* muname, muacres, areasymbol, and areaname. This additionally has the
* side-effect in MapUnit of identifying if the MapUnit isPalouse. This
* function has a synchronized section because it temporarily rewrites the
* default used columns for MapUnit, which are static. It is synchronized to
* avoid causing difficulties elsewhere, where the used columns may also be in
* use in another thread.
*
* @param areaSymbol
* @return Returns an instance of MapUnit.
* @throws ServiceException An exception is thrown if the lookup of the data
* associated with the mukey parameter is unsuccessful.
* @see MapUnit
*/
@Override
public synchronized HashMap<String, MapUnit> findMukeyDataByAreasymbol(String areaSymbol) throws ServiceException {
HashMap<String, MapUnit> ret_val = null;
if ((null != areaSymbol) && (!areaSymbol.isEmpty())) {
String query = buildBasicMukeyQueryByArea(areaSymbol);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
ret_val = new HashMap<>();
while (resultSet.next()) {
synchronized (this) {
MapUnit tMapUnit;
String mukey = resultSet.getString(TableMapUnit.MUKEY);
//Temp storage for current used-list.
ArrayList<String> tList = MapUnit.getDefaultUsedColumns();
MapUnit.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnit.MUSYM, TableMapUnit.MUACRES, TableMapUnit.AREASYMBOL_NAME, TableMapUnit.AREA_NAME)));
ret_val.put(mukey, new MapUnit(mukey, resultSet, null));
// Restore previous used-list.
MapUnit.setDefaultUsedColumns(tList);
}
}
if (ret_val.size() <= 0) {
throw new ServiceException("Data not found in" + logPrefix + ".findMukeyDataByAreasymbol, for areasymbol: '" + areaSymbol + "'");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMukeyDataByAreasymbol: " + ex.getMessage(), ex);
}
}
}
return ret_val;
}
@Override
public synchronized void findMukeyDataAndShapeByAreasymbol(ArrayList<String> areaSymbols, GISEngine gisEngine,
HashMap<String, MapUnit> mapUnits) throws ServiceException {
if (null != areaSymbols) {
for (String areaSymbol : areaSymbols) {
if (!areaSymbol.isEmpty()) {
String query = buildBasicMukeyQueryByAreaWithShape(areaSymbol);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
ArrayList<String> mapUnitColumns = new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnit.MUSYM, TableMapUnit.MUACRES, TableMapUnit.AREASYMBOL_NAME, TableMapUnit.AREA_NAME));
while (resultSet.next()) {
MapUnit tMapUnit = new MapUnit();
String mukey = resultSet.getString(TableMapUnit.MUKEY);
String WKT = resultSet.getString("muPoly");
GISObject muPoly = GISObjectFactory.createGISObject(WKT, gisEngine);
tMapUnit.mukey(mukey);
tMapUnit.setDefaultUsedColumns(mapUnitColumns);
tMapUnit.readFromSQL(resultSet);
tMapUnit.addShape(muPoly);
mapUnits.put(mukey, tMapUnit);
}
if (mapUnits.size() <= 0) {
throw new ServiceException("Data not found in" + logPrefix + ".findMukeyDataAndShapeByAreasymbol, for areasymbol: '" + areaSymbol + "'");
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findMukeyDataAndShapeByAreasymbol: " + ex.getMessage(), ex);
} catch (GISObjectException ex) {
throw new ServiceException("GIS Object creation error in " + logPrefix + ".findMukeyDataAndShapeByAreasymbol: " + ex.getMessage(), ex);
}
}
}
}
}
}
@Override
public boolean findComponentSoilMoisture(HashMap<String, MapUnit> mapUnits) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
for (String mukey : mapUnits.keySet()) {
MapUnit mapUnit = mapUnits.get(mukey);
Component component;
String query = buildCSMQuery(mapUnit);
if (query.length() > 0) {
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);) {
while (resultSet.next()) {
String tCokey = resultSet.getString(TableComponent.COKEY);
component = mapUnit.components().get(tCokey);
if (null != component) {
component.calculated_wtkind(EvalResult.getString(resultSet, "wtkind"));
if (component.calculated_wtkind().equals(EvalResult.getDefaultString())) {
component.calculated_wtkind("None");
component.calculated_wtbl_top_min(Double.NaN);
} else {
component.calculated_wtbl_top_min(EvalResult.getDouble(resultSet, "wtbl_top_min"));
}
component.calculated_hwt_lt_24((component.calculated_wtbl_top_min() <= 61));
} else {
throw new ServiceException("Database returned a cokey that was not requested.");
}
}
} catch (SQLException ex) {
throw new ServiceException("SQL error in " + logPrefix + ".findComponentSoilMoisture: " + ex.getMessage(), ex);
}
}
}
} else {
throw new ServiceException("NULL value passed to " + logPrefix + ".findComponentSoilMoisture for MapUnit list.");
}
return ret_val;
}
@Override
public Boolean findComponentsByMukey(MapUnit mapUnit) throws ServiceException {
Boolean ret_val = false;
if ((null != mapUnit) && (null != mapUnit.mukey()) && !mapUnit.mukey().isEmpty()) {
try (Statement statement = connection.createStatement();) {
String query = buildPlainComponentQuery(mapUnit.mukey());
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
ret_val = noFilterComponentData(results, mapUnit);
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the component lookups for this mapunit: " + ex.getMessage(), ex);
}
} else {
throw new ServiceException("No map unit key passed to the " + logPrefix + ".findComponentsByMukey() function.");
}
return ret_val;
}
@Override
@Deprecated
public Boolean findComponentsHorizonsFragsByMukey(MapUnit mapUnit, boolean computeLightleWeesieSlope, String filter) throws ServiceException {
Boolean ret_val = true;
if (filter.equalsIgnoreCase("WIND") || filter.equalsIgnoreCase("WATER")) {
if ((null != mapUnit) && (null != mapUnit.mukey()) && !mapUnit.mukey().isEmpty()) {
try (Statement statement = connection.createStatement();) {
String query = buildCHFQuery(mapUnit.mukey(), filter);
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
FilterResults filterResults = new FilterResults();
ret_val = filterComponentHorizonFragData(results, filterResults, mapUnit, filter, computeLightleWeesieSlope);
if (filter.equalsIgnoreCase("WATER") && !filterResults.foundKffact) {
ret_val = false;
Log(Level.WARNING, "No kffact found for this soil component in its horizon data.");
}
if ((mapUnit.components().size() <= 0)) {
ret_val = false;
Log(Level.WARNING, "No suitable soil components and/or horizon data found for this mapunit: " + mapUnit.mukey() + " .");
}
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the component lookups for this mapunit: " + ex.getMessage(), ex);
}
} else {
throw new ServiceException("No map unit key passed to the " + logPrefix + ".findComponentsHorizonsFragsByMukey() function.");
}
} else {
if (filter.equalsIgnoreCase("NONE")) {
if ((null != mapUnit) && (null != mapUnit.mukey()) && !mapUnit.mukey().isEmpty()) {
try (Statement statement = connection.createStatement();) {
String query = buildPlainCHFQuery(mapUnit.mukey());
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
ret_val = noFilterComponentHorizonFragData(results, mapUnit, computeLightleWeesieSlope);
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the component lookups for this mapunit: " + ex.getMessage(), ex);
}
} else {
throw new ServiceException("No map unit key passed to the " + logPrefix + ".findComponentsHorizonsFragsByMukey() function.");
}
} else {
throw new ServiceException("Invalid filter value, " + filter + ", passed to the " + logPrefix + ".findComponentsHorizonsFragsByMukey() function.");
}
}
return ret_val;
}
@Override
public boolean findAllBasicNoFilterComponentHorizonFragTextureData(HashMap<String, MapUnit> mapUnits) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
try (Statement statement = connection.createStatement();) {
String query = buildBasicNoFilterCHFQuery(mapUnits);
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
if (noFilterComponentHorizonFragData(results, mapUnits, true)) {
if (findAllTextureData(mapUnits)) {
ret_val = true;
} else {
throw new ServiceException("Could not get texture data those mapunits");
}
} else {
throw new ServiceException("Could not get component, horizon, fragments data for those mapunits");
}
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the basic component, horizon, frag, and textures lookups for these mapunits: " + ex.getMessage(), ex);
}
}
return ret_val;
}
@Override
public boolean findAllBasicComponentHorizonFragTextureData(HashMap<String, MapUnit> mapUnits, boolean includeNonMajComp) throws ServiceException {
boolean ret_val = false;
if (null != mapUnits) {
try (Statement statement = connection.createStatement();) {
String query = buildPlainNoFilterCHFQuery(mapUnits, includeNonMajComp);
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
if (noFilterComponentHorizonFragData(results, mapUnits, true)) {
if (findAllTextureData(mapUnits)) {
ret_val = true;
} else {
throw new ServiceException("Could not get texture data those mapunits");
}
} else {
throw new ServiceException("Could not get component, horizon, fragments data for those mapunits");
}
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the basic component, horizon, frag, and textures lookups for these mapunits: " + ex.getMessage(), ex);
}
}
return ret_val;
}
@Override
public boolean findAllBasicComponentHorizonFragTextureData(HashMap<String, MapUnit> mapUnits) throws ServiceException {
return findAllBasicComponentHorizonFragTextureData(mapUnits, false);
}
@Override
public boolean findComponentsHorizonsFragsForMukeyList(HashMap<String, MapUnit> mapUnits, boolean computeLightleWeesieSlope, String filter) throws ServiceException {
boolean ret_val = true;
for (String mukey : mapUnits.keySet()) {
ret_val = findComponentsHorizonsFragsByMukey(mapUnits.get(mukey), computeLightleWeesieSlope, filter);
if (!ret_val) {
mapUnits.get(mukey).setExclude(true, "No soil components for this mapunit were found having a sufficient set of parameters required for NRCS quality assessment (" + filter + ").");
}
}
return ret_val;
}
@Override
public ArrayList<ComponentsHorizonsFrags> findComponentsHorizonsFragsForMukeyList(ArrayList<String> mukeys, boolean computeLightleWeesieSlope, String filter) throws ServiceException {
ArrayList<ComponentsHorizonsFrags> ret_val = new ArrayList<>();
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean findComponentsForMukeyList(HashMap<String, MapUnit> mapUnits, boolean computeLightleWeesieSlope) throws ServiceException {
boolean ret_val = true;
for (String mukey : mapUnits.keySet()) {
ret_val = findComponentsHorizonsFragsByMukey(mapUnits.get(mukey), computeLightleWeesieSlope, "NONE");
if (!ret_val) {
mapUnits.get(mukey).setExclude(true, "No soil components for this mapunit were found having a sufficient set of parameters required for NRCS quality assessment (No Filter).");
}
}
return ret_val;
}
@Override
public MapUnit findBasicNoFilterDataByCokey(Component component) throws ServiceException {
MapUnit mapUnit = null;
HashMap<String, MapUnit> mapUnits;
if ((null != component) && (null != component.cokey()) && !component.cokey().isEmpty()) {
// Get mapUnit data
if (null == (mapUnit = findBasicNoFilterMukeyDataByCokey(component))) {
throw new ServiceException("Could not find any Mapunit information for the cokey, " + component.cokey() + ", provided.");
}
mapUnits = new HashMap<>();
mapUnits.put(mapUnit.mukey(), mapUnit);
mapUnit.putComponent(component);
findAllBasicNoFilterComponentHorizonFragTextureData(mapUnits);
} else {
throw new ServiceException("No component key passed to the " + logPrefix + ".findWEPPDataByCokey() function.");
}
return mapUnit;
}
@Override
public MapUnit findWEPPDataByCokey(Component component) throws ServiceException, WEPPException {
MapUnit mapUnit = null;
HashMap<String, MapUnit> mapUnits;
if ((null != component) && (null != component.cokey()) && !component.cokey().isEmpty()) {
// Get mapUnit data
if (null == (mapUnit = findMukeyDataByCokey(component))) {
throw new ServiceException("Could not find any Mapunit information for the cokey, " + component.cokey() + ", provided.");
}
mapUnits = new HashMap<>();
mapUnits.put(mapUnit.mukey(), mapUnit);
mapUnit.putComponent(component);
findAllBasicComponentHorizonFragTextureData(mapUnits);
component.updateCalculations();
try {
component.adjustForWEPP_WEPS("wepp");
} catch (SDMException | WEPP_WEPSException | WEPSException ex) {
throw new ServiceException(ex);
}
} else {
throw new ServiceException("No component key passed to the " + logPrefix + ".findWEPPDataByCokey() function.");
}
return mapUnit;
}
@Override
public MapUnit findWEPSDataByCokey(Component component, boolean adjustStratified, boolean organicChecks, boolean estimateNulls) throws ServiceException, WEPSException {
MapUnit mapUnit = null;
HashMap<String, MapUnit> mapUnits;
if ((null != component) && (null != component.cokey()) && !component.cokey().isEmpty()) {
// Get mapUnit data
if (null == (mapUnit = findMukeyDataByCokey(component))) {
throw new ServiceException("Could not find any Mapunit information for the cokey, " + component.cokey() + ", provided.");
}
mapUnits = new HashMap<>();
mapUnits.put(mapUnit.mukey(), mapUnit);
mapUnit.putComponent(component);
findAllBasicComponentHorizonFragTextureData(mapUnits);
try (Statement statement = connection.createStatement()) {
ResultSet results;
String query = buildMinResdept_rQuery(component.cokey());
results = statement.executeQuery(query);
if (results.next()) {
component.calculated_resdeptmin_r(EvalResult.getDouble(results, TableComponentCalculations.RESDEPTMIN_R));
} else {
component.calculated_resdeptmin_r(EvalResult.getDefaultDouble());
}
results.close();
} catch (SQLException ex) {
throw new ServiceException("Cannot execute the resdept_r query for this component: " + ex.getMessage(), ex);
}
component.updateCalculations();
try {
component.adjustForWEPP_WEPS("weps");
} catch (SDMException | WEPP_WEPSException | WEPPException ex) {
throw new ServiceException(ex);
}
//Clean up some values and set some final defaults if missing.
if (EvalResult.testDefaultInteger(mapUnit.brockdepmin())) {
mapUnit.brockdepmin(GenericIFCData.depthToBedrock);
} else {
mapUnit.brockdepmin(mapUnit.brockdepmin() * 10);
}
if (EvalResult.testDefaultDouble(component.calculated_resdeptmin_r())) {
} else {
component.calculated_resdeptmin_r(component.calculated_resdeptmin_r() * 10);
}
if (EvalResult.testDefaultDouble(component.slope_r())) {
component.slope_r(0.01);
} else {
component.slope_r(component.slope_r() / 100);
}
for (Horizon h : component.horizons.values()) {
if (!EvalResult.testDefaultDouble(h.hzdepb_r())) {
h.hzdepb_r(metricConversion(h.hzdepb_r(), SoilUtils.Metric.CM, SoilUtils.Metric.MM));
}
if (!EvalResult.testDefaultDouble(h.hzdept_r())) {
h.hzdept_r(metricConversion(h.hzdept_r(), SoilUtils.Metric.CM, SoilUtils.Metric.MM));
}
if (!EvalResult.testDefaultDouble(h.sandtotal_r())) {
h.sandtotal_r(pctToFraction(h.sandtotal_r()));
}
if (!EvalResult.testDefaultDouble(h.claytotal_r())) {
h.claytotal_r(pctToFraction(h.claytotal_r()));
}
if (!EvalResult.testDefaultDouble(h.silttotal_r())) {
h.silttotal_r(pctToFraction(h.silttotal_r()));
}
if (!EvalResult.testDefaultDouble(h.sandvc_r())) {
h.sandvc_r(pctToFraction(h.sandvc_r()));
}
if (!EvalResult.testDefaultDouble(h.sandco_r())) {
h.sandco_r(pctToFraction(h.sandco_r()));
}
if (!EvalResult.testDefaultDouble(h.sandmed_r())) {
h.sandmed_r(pctToFraction(h.sandmed_r()));
}
if (!EvalResult.testDefaultDouble(h.hzdepb_r())) {
h.sandfine_r(pctToFraction(h.sandfine_r()));
}
if (!EvalResult.testDefaultDouble(h.sandvf_r())) {
h.sandvf_r(pctToFraction(h.sandvf_r()));
}
if (!EvalResult.testDefaultDouble(h.om_r())) {
h.om_r(pctToFraction(h.om_r()));
}
if (!EvalResult.testDefaultDouble(h.caco3_r())) {
h.caco3_r(pctToFraction(h.caco3_r()));
}
}
} else {
throw new ServiceException("No component key passed to the " + logPrefix + ".findWEPPDataByCokey() function.");
}
return mapUnit;
}
//TODO: Add logging for ret_val's that get set to false during this function, after calling other functions that return a boolean assigned to it.
@Override
@Deprecated
public synchronized boolean findWEPSHorizonsForCokey(MapUnit mapUnit, Component component) throws ServiceException {
boolean ret_val = false;
// TextureGroup.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableTextureGroup.CHTGKEY, TableTextureGroup.TEXTURE,
// TableTextureGroup.STRATEXTSFLAG, TableTextureGroup.RVINDICATOR)));
// Fragments.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableFragments.CHFRAGSKEY, TableFragments.FRAGVOL_R, TableFragments.FRAGVOL_L,
// TableFragments.FRAGVOL_H, TableFragments.FRAGSIZE_R, TableFragments.FRAGSIZE_L, TableFragments.FRAGSIZE_H,
// TableFragments.FRAGHARD, TableFragments.FRAGSHP, TableFragments.FRAGROUND, TableFragments.FRAGKIND)));
if ((null != component) && (null != component.cokey()) && !component.cokey().isEmpty()) {
Validation.checkCokey(component.cokey());
try (Statement statement = connection.createStatement();) {
String query = buildCHQuery(component.cokey(), "WIND");
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
FilterResults filterResults = new FilterResults();
ret_val = filterWEPSComponentHorizonFragData(results, filterResults, mapUnit, component, true);
results.close();
// Fill-in the MapUnit object too
if ((!component.mukey().isEmpty()) && ret_val) {
mapUnit.mukey(component.mukey());
ret_val = findMukeyData(mapUnit);
}
if (!filterResults.foundSandLayer) {
ret_val = false;
Log(Level.WARNING, "No sand layer found for this soil component in its horizon data.");
}
//TODO: Verify this test still works in this case...
if ((mapUnit.components().size() <= 0)) {
ret_val = false;
Log(Level.WARNING, "No suitable soil horizon data found for this component: " + component.cokey() + " .");
} else {
query = buildMinResdept_rQuery(component.cokey());
Log(Level.INFO, " soils db query=" + query);
results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
if (results.next()) {
component.calculated_resdeptmin_r(EvalResult.getDouble(results, TableComponentCalculations.RESDEPTMIN_R));
} else {
component.calculated_resdeptmin_r(EvalResult.getDefaultDouble());
}
results.close();
ArrayList<String> textureGroupColumns = new ArrayList<>(Arrays.asList(TableTextureGroup.CHTGKEY, TableTextureGroup.TEXTURE,
TableTextureGroup.STRATEXTSFLAG, TableTextureGroup.RVINDICATOR));
ArrayList<String> fragmentsColumns = new ArrayList<>(Arrays.asList(TableFragments.CHFRAGSKEY, TableFragments.FRAGVOL_R, TableFragments.FRAGVOL_L,
TableFragments.FRAGVOL_H, TableFragments.FRAGSIZE_R, TableFragments.FRAGSIZE_L, TableFragments.FRAGSIZE_H,
TableFragments.FRAGHARD, TableFragments.FRAGSHP, TableFragments.FRAGROUND, TableFragments.FRAGKIND));
for (Horizon tHorizon : component.horizons.values()) {
query = buildTextureGroupsQuery(tHorizon.chkey());
Log(Level.INFO, " soils db query=" + query);
results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
// TextureGroup.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableTextureGroup.CHTGKEY, TableTextureGroup.TEXTURE,
// TableTextureGroup.STRATEXTSFLAG, TableTextureGroup.RVINDICATOR)));
while (results.next()) {
tHorizon.setTextureGroups(results, textureGroupColumns, new ArrayList<>());
}
query = buildFragmentsQuery(tHorizon.chkey());
Log(Level.INFO, " soils db query=" + query);
results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
// Fragments.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(TableFragments.CHFRAGSKEY, TableFragments.FRAGVOL_R, TableFragments.FRAGVOL_L,
// TableFragments.FRAGVOL_H, TableFragments.FRAGSIZE_R, TableFragments.FRAGSIZE_L, TableFragments.FRAGSIZE_H,
// TableFragments.FRAGHARD, TableFragments.FRAGSHP, TableFragments.FRAGROUND, TableFragments.FRAGKIND)));
tHorizon.setFragments(results, fragmentsColumns);
}
}
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the horizon lookups for this component: " + ex.getMessage(), ex);
}
} else {
throw new ServiceException("No component key passed to the " + logPrefix + ".findHorizonsFragsByCokey() function.");
}
return ret_val;
}
@Override
public boolean findHorizonsForCokey(MapUnit mapUnit, Component component) throws ServiceException {
boolean ret_val = false;
if ((null != component) && (null != component.cokey()) && !component.cokey().isEmpty()) {
Validation.checkCokey(component.cokey());
try (Statement statement = connection.createStatement();) {
String query = buildCHQuery(component.cokey(), "WATER");
Log(Level.INFO, " soils db query=" + query);
ResultSet results = statement.executeQuery(query);
Log(Level.INFO, " past the query execute");
FilterResults filterResults = new FilterResults();
ret_val = filterRusle2ComponentHorizonData(results, filterResults, mapUnit, component);
results.close();
// Fill-in the MapUnit object too
if (!component.mukey().isEmpty() && ret_val) {
ret_val = findMukeyData(mapUnit);
}
if (!filterResults.foundKffact) {
ret_val = false;
Log(Level.WARNING, "No kffact found for this soil component in its horizon data.");
}
//TODO: Verify this test still works in this case...
if ((mapUnit.components().size() <= 0)) {
ret_val = false;
Log(Level.WARNING, "No suitable soil horizon data found for this component: " + component.cokey() + " .");
}
} catch (SQLException ex) {
throw new ServiceException("Could not continue processing the horizon lookups for this component: " + ex.getMessage(), ex);
}
} else {
throw new ServiceException("No component key passed to the " + logPrefix + ".findHorizonsFragsByCokey() function.");
}
return ret_val;
}
@Override
public HashMap<String, MapUnit> findMapUnitsForGISObject(GISObject gisObject) throws ServiceException, GISObjectException {
return findMapUnitsForGISObject(gisObject, false, false);
}
@Override
public synchronized MapUnit findMapUnitsByMupolygonKey(String mupolygonkey, GISEngine gisEngine, boolean computeIntersectionArea, boolean returnIntersectionShape) throws ServiceException, GISObjectException {
MapUnit map_unit = null;
MapUnit.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableMapUnit.AREASYMBOL_NAME, TableMapUnit.MUKEY, TableMapUnit.MUSYM,
TableMapUnit.MUNAME, TableMapUnitCalculations.AREA_NAME, TableMuaggatt.BROCKDEPMIN, TableMapUnit.MUACRES,
TableSaCatalog.SA_VERSION, TableSaCatalog.SA_VER_EST,
TableSaSpatialVer.SPATIAL_VERSION, TableSaSpatialVer.SPATIAL_VERSION_EST,
TableSaTabularVer.TABULAR_VERSION, TableSaTabularVer.TABULAR_VERSION_EST
)));
if ((null != mupolygonkey) && (!mupolygonkey.isEmpty())) {
String query = buildFindMapUnitsByPolyKeyQuery(mupolygonkey, returnIntersectionShape);
try (Statement statement = connection.createStatement()) {
ResultSet results = statement.executeQuery(query);
while (results.next()) {
String mukey = results.getString(TableMapUnit.MUKEY);
map_unit = new MapUnit(mukey, results,
(returnIntersectionShape ? GISObjectFactory.createGISObject(results.getString("intersectionShape"), gisEngine) : null)
);
map_unit.aoaArea(map_unit.muacres());
}
} catch (SQLException ex) {
throw new ServiceException(logPrefix + ".findMapUnitsByMupolygonKey: SQL Exception encountered while finding map units for this shape.", ex);
} catch (GISObjectException ex) {
throw new ServiceException(logPrefix + ".findMapUnitsByMupolygonKey: GISObject Exception encountered while examining intersected shapes of map units for this shape.", ex);
}
}
return map_unit;
}
@Override
public synchronized HashMap<String, MapUnit> findMapUnitsForGISObject(GISObject gisObject, boolean computeIntersectionArea, boolean returnIntersectionShape) throws ServiceException, GISObjectException {
LinkedHashMap<String, MapUnit> map_units = new LinkedHashMap<>();
MapUnit.setDefaultUsedColumns(new ArrayList<>(Arrays.asList(
TableMapUnit.AREASYMBOL_NAME, TableMapUnit.MUKEY, TableMapUnit.MUSYM, TableMapUnit.AREA_NAME,
TableMapUnit.MUNAME, TableMapUnitCalculations.AREA_NAME, TableMuaggatt.BROCKDEPMIN, TableMapUnit.MUACRES,
TableSaCatalog.SA_VERSION, TableSaCatalog.SA_VER_EST,
TableSaSpatialVer.SPATIAL_VERSION, TableSaSpatialVer.SPATIAL_VERSION_EST,
TableSaTabularVer.TABULAR_VERSION, TableSaTabularVer.TABULAR_VERSION_EST
)));
if ((null != gisObject) && (gisObject.isValid())) {
String WKTShape = gisObject.toWKT();
double aoaArea = gisObject.areaInAcres();
String query = buildFindMapUnitsQuery(WKTShape, returnIntersectionShape);
try (Statement statement = connection.createStatement()) {
ResultSet results = statement.executeQuery(query);
while (results.next()) {
String mukey = results.getString(TableMapUnit.MUKEY);
MapUnit tMapUnit;
if (map_units.containsKey(mukey)) {
double addArea = results.getDouble("area");
tMapUnit = map_units.get(mukey);
tMapUnit.areaAdd(addArea);
if (returnIntersectionShape) {
tMapUnit.addShape(GISObjectFactory.createGISObject(results.getString("intersectionShape"), gisObject.getEngine()));
}
} else {
tMapUnit = new MapUnit(mukey, results,
(returnIntersectionShape ? GISObjectFactory.createGISObject(results.getString("intersectionShape"), gisObject.getEngine()) : null)
);
tMapUnit.aoaArea(aoaArea);
map_units.put(tMapUnit.mukey(), tMapUnit);
}
}
} catch (SQLException ex) {
throw new ServiceException(logPrefix + ".findMapUnitsForGISObject: SQL Exception encountered while finding map units for this shape.", ex);
} catch (GISObjectException ex) {
throw new ServiceException(logPrefix + ".findMapUnitsForGISObject: GISObject Exception encountered while examining intersected shapes of map units for this shape.", ex);
}
} else if (null == gisObject) {
throw new ServiceException("NULL gisObject value passed to " + logPrefix + ".findMapUnitsForGISObject.");
} else {
throw new ServiceException("Invalid gisObject value passed to " + logPrefix + ".findMapUnitsForGISObject.");
}
return map_units;
}
@Override
public HashMap<String, MapUnit> findMapUnitsForWKT(String wkt) throws ServiceException {
return findMapUnitsForWKT(wkt, false, false);
}
@Override
public HashMap<String, MapUnit> findMapUnitsForWKT(String wkt, boolean computeIntersectinArea, boolean returnIntersectionShape) throws ServiceException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Connection getConnection() {
return connection;
}
@Override
public boolean isCONUS(double lat, double lon) throws SQLException, ServiceException {
boolean ret_val = false;
String query = buildIsConusQuery(String.valueOf(lat), String.valueOf(lon));
try (Statement statement = connection.createStatement();) {
ResultSet results = statement.executeQuery(query);
if (results.next()) {
ret_val = results.getBoolean("CONUS");
} else {
throw new ServiceException("Cannot determine if the location provided is within CONUS. " + logPrefix + ".isCONUS query returned no results.");
}
}
return ret_val;
}
@Override
public boolean validateComponent(int cokey) throws SQLException {
boolean ret_val = false;
String query = buildValidateCokeyQuery(cokey);
try (Statement statement = connection.createStatement();) {
ResultSet results = statement.executeQuery(query);
if (results.next()) {
int tCokey = results.getInt("cokey");
ret_val = (tCokey == cokey);
}
}
return ret_val;
}
}