AoA.java [src/soils] 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;
import csip.SessionLogger;
import csip.api.server.ServiceException;
import csip.api.server.ServiceResources;
import csip.utils.JSONUtils;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import static gisobjects.GISObjectFactory.createGISObject;
import static gisobjects.GISObjectFactory.setFixBadGeometries;
import gisobjects.db.GISEngine;
import static gisobjects.db.GISEngineFactory.createGISEngine;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import static soils.db.DBResources.SDM;
import static soils.db.DBResources.SDM_REST;
import soils.db.SOILS_DATA;
import soils.db.SOILS_DB_Factory;
import soils.db.tables.TableComponent;
import soils.db.tables.TableComponentCalculations;
import soils.db.tables.TableMapUnit;
import soils.db.tables.TableMapUnitCalculations;
import soils.filters.DataFilter;
import soils.utils.EvalResult;
/**
* AoA - This class is meant to be extended to meet your service needs. It
* contains the basics necessary to create an AoA geometry and find its
* associated mapunits, components, horizons, and frags. This class is coupled
* with the SOILS_DATA db object that you wish to use for your implementation.
* If you need to just store soils information, such as coming from an input
* JSON object, then you may use or extend this class or the SoilsData class
* contained in this package instead; it is not coupled with any database.
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
public class AoA extends SoilsData {
//Constants
public static final String AOA_ID = "AoAId";
public static final String AOA_GEOMETRY = "aoa_geometry";
public static final String NSLP = "aoa_nslp";
public static final String SRP = "aoa_srp";
public static final String AOA_DRAINED = "aoa_comp_drained";
public static final String EXCLUDED_LIST = "Excluded_Soil_Components";
public static final String CORRECTED_GEOMETRY = "corrected_geometry_WKT";
public static final String PSLP = "aoa_pslp";
public static final String PSSRP = "aoa_ssrp";
public static final String PSARP = "aoa_sarp";
protected boolean FIX_GEOMETRIES = true;
protected SessionLogger LOG;
protected double area = Double.NaN;
protected ArrayList<String> mukeyList = new ArrayList<>();
protected GISObject shape;
protected SOILS_DATA soilsDb;
protected static ArrayList<String> aoaRequiredInputs = new ArrayList<>();
protected TableAoA tableAoA = new TableAoA();
public AoA(ServiceResources resources, boolean useRemoteRest, SessionLogger Log) throws ServiceException, SQLException {
soilsDb = SOILS_DB_Factory.createEngine(resources.getJDBC(((useRemoteRest) ? SDM_REST : SDM)), Log);
LOG = Log;
}
public AoA(ServiceResources resources, boolean useRemoteRest) throws ServiceException, SQLException {
soilsDb = SOILS_DB_Factory.createEngine(resources.getJDBC(((useRemoteRest) ? SDM_REST : SDM)), null);
LOG = null;
}
public AoA(Map<String, JSONObject> params) throws ServiceException, JSONException {
super(JSONUtils.getJSONArrayParam(params, soils.SoilsData.MAP_UNIT_LIST));
tableAoA.setRequiredColumns(aoaRequiredInputs);
tableAoA.readValuesFromJSON(params);
}
public AoA(ServiceResources resources, boolean useRemoteRest, Connection gisDb, JSONObject aoa_geometry, SessionLogger Log) throws ServiceException, JSONException, GISObjectException, SQLException, IOException {
tableAoA.setRequiredColumns(aoaRequiredInputs);
this.LOG = Log;
this.soilsDb = SOILS_DB_Factory.createEngine(resources.getJDBC(((useRemoteRest) ? SDM_REST : SDM)), Log);
if ((null != soilsDb) && (null != gisDb)) {
setFixBadGeometries(FIX_GEOMETRIES);
}
if (null != aoa_geometry && (null != gisDb)) {
GISEngine tEngine = createGISEngine(gisDb);
shape = createGISObject(aoa_geometry, tEngine);
shape.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
setArea(shape.areaInAcres());
} else {
throw new ServiceException(((null == gisDb) ? ("No valid GIS database connection provided, but input geometry shape exists. Cannot create shape geometry.") : ("Missing " + AOA_GEOMETRY + " parameter in input JSON.")));
}
}
public AoA(ServiceResources resources, boolean useRemoteRest, Connection gisDb, JSONObject aoa_geometry) throws ServiceException, JSONException, GISObjectException, SQLException, IOException {
tableAoA.setRequiredColumns(aoaRequiredInputs);
this.LOG = null;
this.soilsDb = SOILS_DB_Factory.createEngine(resources.getJDBC(((useRemoteRest) ? SDM_REST : SDM)), null);
if ((null != soilsDb) && (null != gisDb)) {
setFixBadGeometries(FIX_GEOMETRIES);
}
if (null != aoa_geometry && (null != gisDb)) {
GISEngine tEngine = createGISEngine(gisDb);
shape = createGISObject(aoa_geometry, tEngine);
shape.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
setArea(shape.areaInAcres());
} else {
throw new ServiceException(((null == gisDb) ? ("No valid GIS database connection provided, but input geometry shape exists. Cannot create shape geometry.") : ("Missing " + AOA_GEOMETRY + " parameter in input JSON.")));
}
}
public AoA(SOILS_DATA soilsDb, Connection gisDb, JSONObject aoa_geometry, SessionLogger Log) throws ServiceException, JSONException, GISObjectException, SQLException, IOException {
tableAoA.setRequiredColumns(aoaRequiredInputs);
this.LOG = Log;
this.soilsDb = soilsDb;
if ((null != soilsDb) && (null != gisDb)) {
setFixBadGeometries(FIX_GEOMETRIES);
}
if (null != aoa_geometry && (null != gisDb)) {
GISEngine tEngine = createGISEngine(gisDb);
shape = createGISObject(aoa_geometry, tEngine);
shape.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
setArea(shape.areaInAcres());
} else {
throw new ServiceException(((null == gisDb) ? ("No valid GIS database connection provided, but input geometry shape exists. Cannot create shape geometry.") : ("Missing " + AOA_GEOMETRY + " parameter in input JSON.")));
}
}
public AoA(SOILS_DATA soilsDb, Connection gisDb, Map<String, JSONObject> params, SessionLogger Log) throws ServiceException, JSONException, GISObjectException, SQLException, IOException {
super(JSONUtils.getJSONArrayParam(params, soils.SoilsData.MAP_UNIT_LIST));
tableAoA.setRequiredColumns(aoaRequiredInputs);
tableAoA.readValuesFromJSON(params);
this.LOG = Log;
this.soilsDb = soilsDb;
if ((null != soilsDb) && (null != gisDb)) {
setFixBadGeometries(FIX_GEOMETRIES);
}
if (params.containsKey(AOA_GEOMETRY) && (null != gisDb)) {
GISEngine tEngine = createGISEngine(gisDb);
shape = createGISObject(params.get(AOA_GEOMETRY), tEngine);
shape.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
setArea(shape.areaInAcres());
} else {
throw new ServiceException(((null == gisDb) ? ("No valid GIS database connection provided, but input geometry shape exists. Cannot create shape geometry.") : ("Missing " + AOA_GEOMETRY + " parameter in input JSON.")));
}
}
public AoA(SOILS_DATA soilsDb, Map<String, JSONObject> params, SessionLogger Log) throws ServiceException, JSONException, GISObjectException, SQLException, IOException {
super(JSONUtils.getJSONArrayParam(params, soils.SoilsData.MAP_UNIT_LIST));
tableAoA.setRequiredColumns(aoaRequiredInputs);
tableAoA.readValuesFromJSON(params);
this.LOG = Log;
this.soilsDb = soilsDb;
if (null != soilsDb) {
//setGISObjectEngine(createGISEngine(this.soilsDb.getConnection()));
setFixBadGeometries(FIX_GEOMETRIES);
}
if (params.containsKey(AOA_GEOMETRY)) {
GISEngine tEngine = createGISEngine(soilsDb.getConnection());
shape = createGISObject(params.get(AOA_GEOMETRY), tEngine);
shape.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
setArea(shape.areaInAcres());
} else {
throw new ServiceException("Missing " + AOA_GEOMETRY + " parameter in input JSON.");
}
}
public AoA(JSONArray mapUnitArray) throws ServiceException {
super(mapUnitArray);
area = Double.NaN;
shape = null;
soilsDb = null;
LOG = null;
}
public AoA() throws ServiceException {
area = Double.NaN;
shape = null;
soilsDb = null;
LOG = null;
}
public AoA(SOILS_DATA soilsDb, GISObject gisShape, SessionLogger Log) throws GISObjectException, ServiceException, SQLException {
LOG = Log;
shape = gisShape;
setArea(gisShape.areaInAcres());
this.soilsDb = soilsDb;
if (null != soilsDb) {
//setGISObjectEngine(createGISEngine(this.soilsDb.getConnection()));
setFixBadGeometries(FIX_GEOMETRIES);
}
}
public AoA(SOILS_DATA soilsDb, SessionLogger Log) throws GISObjectException, SQLException {
LOG = Log;
area = Double.NaN;
shape = null;
this.soilsDb = soilsDb;
if (null != soilsDb) {
//setGISObjectEngine(createGISEngine(this.soilsDb.getConnection()));
setFixBadGeometries(FIX_GEOMETRIES);
}
}
public boolean hasGeomChanged() {
if (null != shape) {
return shape.hasChanged();
}
return false;
}
public String shapeWKT() {
if (null != shape) {
return shape.toWKT();
}
return "";
}
public GISObject shape() {
return shape;
}
public void merge(Map<String, JSONObject> soilComponentMap) throws JSONException, ServiceException {
TableAoA tempAoATable = new TableAoA();
tempAoATable.readValuesFromJSON(soilComponentMap);
this.tableAoA.merge(tempAoATable);
if (JSONUtils.checkKeyExistsB(soilComponentMap, soils.SoilsData.MAP_UNIT_LIST)) {
readMapUnitsFromJSON(JSONUtils.getJSONArrayParam(soilComponentMap, soils.SoilsData.MAP_UNIT_LIST), true);
}
}
public synchronized static void setRequiredInputs(ArrayList<String> aoaInputs, ArrayList<String> mapUnitInputs, ArrayList<String> componentInputs, ArrayList<String> horizonInputs) {
setRequiredInputs(mapUnitInputs, componentInputs, horizonInputs);
aoaRequiredInputs.clear();
if (null != aoaRequiredInputs) {
aoaRequiredInputs.addAll(aoaInputs);
}
}
public void computeTillageLayerClayTotals() {
for (MapUnit tMapUnit : map_units.values()) {
tMapUnit.computeTillageLayerClayTotals();
}
}
public String aoa_id() {
return tableAoA.aoa_id();
}
public void nutrient_slp(String nslp) {
tableAoA.aoa_nslp(nslp);
}
public String nutrient_slp() {
return tableAoA.aoa_nslp();
}
public void srp(String srp) {
tableAoA.aoa_srp(srp);
}
public String srp() {
return tableAoA.aoa_srp();
}
public String pslp() {
return tableAoA.aoa_pslp();
}
public void pslp(String pslp) {
tableAoA.aoa_pslp(pslp);
}
public String pssrp() {
return tableAoA.aoa_pssrp();
}
public void pssrp(String pssrp) {
tableAoA.aoa_pssrp(pssrp);
}
public String psarp() {
return tableAoA.aoa_psarp();
}
public void psarp(String psarp) {
tableAoA.aoa_psarp(psarp);
}
public void isDrained(boolean value) {
tableAoA.aoa_is_drained(value);
}
public boolean isDrained() {
return tableAoA.aoa_is_drained();
}
/**
* Gets all of the comonth table data for each component of each mapunit
* already existing in the AoA. Be sure to find the mapunits and component
* data for any given input shape for this class before calling this function.
* This function also computes the maximum values for the flodfreqcl and
* pondfreqcl for each component and its associated monthly records in the
* comonth table.
*
* @throws ServiceException
*/
public void getMaxFloodingPondingData() throws ServiceException {
if (null != soilsDb) {
if (!soilsDb.findAllComonthData(map_units)) {
throw new ServiceException("Unable to query SDM database for flooding and ponding information for these mapunits");
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
}
public void getSalinitySodicity() throws ServiceException {
if (null != soilsDb) {
if ((null != map_units) && (!map_units.isEmpty())) {
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computeSalinityAndSodicity();
}
}
}
}
} else {
throw new ServiceException("Unable to compute soil horizon salinity and sodicity values. No mapunit data has been collected yet.");
}
} else {
throw new ServiceException("Unable to compute soil horizon salinity and sodicity values. No soils database connection has been established.");
}
}
public void computePestSARP() {
double psarp_product = 0.0;
double calc_area = 0.0;
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computePestSARP(isDrained());
psarp_product += (component.psarp_number() * component.calculated_area());
calc_area += component.calculated_area();
}
}
}
}
double aoa_psarp_fract = ((calc_area != 0.0) ? (psarp_product / calc_area) : 0.0);
if (aoa_psarp_fract <= 1.50) {
psarp("LOW");
} else if (aoa_psarp_fract > 1.50 && aoa_psarp_fract <= 2.50) {
psarp("INTERMEDIATE");
} else {
psarp("HIGH");
}
}
public void computePestSSRP() {
double pssrp_product = 0.0;
double calc_area = 0.0;
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computePestSSRP(isDrained());
pssrp_product += (component.pssrp_number() * component.calculated_area());
calc_area += component.calculated_area();
}
}
}
}
double aoa_pssrp_fract = ((calc_area != 0.0) ? (pssrp_product / calc_area) : 0.0);
if (aoa_pssrp_fract <= 1.50) {
pssrp("LOW");
} else if (aoa_pssrp_fract > 1.50 && aoa_pssrp_fract <= 2.50) {
pssrp("INTERMEDIATE");
} else {
pssrp("HIGH");
}
}
public void computePestSLP() {
double cum_pslp_product = 0.0;
double aoa_pslp_fract;
double calc_area = 0.0;
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computePestSLP(isDrained());
cum_pslp_product += (component.pslp_number() * component.calculated_area());
calc_area += component.calculated_area();
}
}
}
}
aoa_pslp_fract = ((calc_area != 0.0) ? (cum_pslp_product / calc_area) : 0.0);
if (aoa_pslp_fract <= 1.50) {
pslp("VERY LOW");
} else if (aoa_pslp_fract > 1.50 && aoa_pslp_fract <= 2.50) {
pslp("LOW");
} else if (aoa_pslp_fract > 2.50 && aoa_pslp_fract <= 3.50) {
pslp("INTERMEDIATE");
} else {
pslp("HIGH");
}
}
public void computeComponentNSLP() throws ServiceException {
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computeNSLP();
}
}
}
}
}
public void computeAoANSLP() {
double cumNslpProduct = 0;
double aoaArea = 0;
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
cumNslpProduct += (component.calculated_nslp_number() * component.calculated_area());
aoaArea += component.calculated_area();
}
}
}
}
double aoaNslpFract = ((aoaArea != 0.0) ? (cumNslpProduct / aoaArea) : 0.0);
if (aoaNslpFract <= 0.50) {
nutrient_slp("LOW");
} else if (aoaNslpFract > 0.50 && aoaNslpFract <= 1.50) {
nutrient_slp("MODERATE");
} else if (aoaNslpFract > 1.50 && aoaNslpFract <= 2.50) {
nutrient_slp("MODERATELY HIGH");
} else {
nutrient_slp("HIGH");
}
}
public void computeComponentSedNutSRP(boolean isDrained) throws ServiceException {
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
component.computeSedNutSRP(isDrained);
}
}
}
}
}
//Compute weighted average nutrient soil leaching potential for the AoA
public void computeAoASRP() {
double srpProduct = 0;
double aoaArea = 0;
for (MapUnit mapUnit : map_units.values()) {
if (!mapUnit.isExcluded()) {
for (Component component : mapUnit.components().values()) {
if (!component.isExcluded()) {
srpProduct += (component.calculated_srp_number() * component.calculated_area());
aoaArea += component.calculated_area();
}
}
}
}
double aoaSrpFract = (aoaArea > 0.0) ? (srpProduct / aoaArea) : 0.0;
if (aoaSrpFract <= 0.50) {
srp("LOW");
} else if (aoaSrpFract > 0.50 && aoaSrpFract <= 1.50) {
srp("MODERATE");
} else if (aoaSrpFract > 1.50 && aoaSrpFract <= 2.50) {
srp("MODERATELY HIGH");
} else {
srp("HIGH");
}
}
protected void setMukeyList() {
if (!mukeyList.isEmpty()) {
mukeyList.clear();
}
map_units.keySet().stream().forEach((tMukey) -> {
mukeyList.add(tMukey);
});
}
/**
* Fills in the entire structures for all mapunits already stored in this AoA
* object. Consequently, this will complete all Component, Horizon, Fragments,
* and Texture data objects under each mapunit object stored here.<p>
* <b>This function does not apply any filtering to the database data. If you
* want the data filtered by soils SME filtering logic use one of the other
* functions in this AoA class.</b>
*
* @return
* @throws ServiceException
*/
public boolean findAllComponentsData_Basic() throws ServiceException {
boolean ret_val;
if (null != soilsDb) {
ret_val = soilsDb.findAllBasicComponentHorizonFragTextureData(map_units);
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllComponents() throws ServiceException {
boolean ret_val;
if (null != soilsDb) {
ret_val = soilsDb.findComponentsHorizonsFragsForMukeyList(map_units, true, "NONE");
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllComponentsApplyWaterFilter() throws ServiceException {
boolean ret_val;
boolean leftEarly = false;
if (null != soilsDb) {
for (String mukey : map_units.keySet()) {
if (!soilsDb.findComponentsHorizonsFragsByMukey(map_units.get(mukey), true, "WATER")) {
//leftEarly = true;
map_units.get(mukey).setExclude(true, "No soil components for this mapunit were found having a sufficient set of parameters required for NRCS quality assessment (water)");
}
}
ret_val = !leftEarly;
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllComponentsApplyWindFilter() throws ServiceException {
boolean ret_val;
boolean leftEarly = false;
if (null != soilsDb) {
for (String mukey : map_units.keySet()) {
if (!soilsDb.findComponentsHorizonsFragsByMukey(map_units.get(mukey), true, "WIND")) {
//leftEarly = true;
map_units.get(mukey).setExclude(true, "No soil components for this mapunit were found having a sufficient set of parameters required for NRCS quality assessment (wind)");
//map_units.get(mukey)
}
}
ret_val = !leftEarly;
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllComponentsApplyWindWaterFilters() throws ServiceException {
boolean ret_val;
boolean leftEarly = false;
if (null != soilsDb) {
if (findAllComponentsApplyWaterFilter()) {
if (!findAllComponentsApplyWindFilter()) {
leftEarly = true;
}
} else {
leftEarly = true;
}
ret_val = !leftEarly;
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllComponentCropYieldsByCropNameOrUnit(ArrayList<String> cropName, ArrayList<String> yldUnits) throws ServiceException {
boolean ret_val;
if (null != soilsDb) {
ret_val = soilsDb.findCoCropYieldsByCropNameOrUnit(map_units, cropName, yldUnits);
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findAllMapunitCropYieldsByCropNameOrUnit(ArrayList<String> cropName, ArrayList<String> yldUnits) throws ServiceException {
boolean ret_val;
if (null != soilsDb) {
ret_val = soilsDb.findMuCropYieldsByCropNameOrUnit(map_units, cropName, yldUnits);
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findComponentSoilMoistures() throws ServiceException {
boolean ret_val = false;
if (null != soilsDb) {
ret_val = soilsDb.findComponentSoilMoisture(map_units);
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findIntersectedMapUnits() throws ServiceException, GISObjectException {
boolean ret_val = false;
if (null != soilsDb) {
if (!map_units.isEmpty()) {
map_units.clear();
}
map_units.putAll(soilsDb.findMapUnitsForGISObject(shape));
setMukeyList();
if (map_units.isEmpty()) {
ret_val = true;
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findEcoClasses() throws ServiceException {
boolean ret_val = false;
if (null != soilsDb) {
ret_val = soilsDb.findEcoClassForMukeyList(map_units);
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findIntersectedMapUnitsWithAreas() throws ServiceException, GISObjectException {
boolean ret_val = false;
if (null != soilsDb) {
if (!map_units.isEmpty()) {
map_units.clear();
}
map_units.putAll(soilsDb.findMapUnitsForGISObject(shape, true, false));
setMukeyList();
if (!map_units.isEmpty()) {
ret_val = true;
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findIntersectedMapUnitsWithAreasAndShapes() throws ServiceException, GISObjectException {
boolean ret_val = false;
if (null != soilsDb) {
if (!map_units.isEmpty()) {
map_units.clear();
}
map_units.putAll(soilsDb.findMapUnitsForGISObject(shape, true, true));
setMukeyList();
if (!map_units.isEmpty()) {
ret_val = true;
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public boolean findIntersectedSoilsWithAreasAndShapesUsingFilter(DataFilter dataFilter) throws Exception {
if (null != soilsDb) {
if (!map_units.isEmpty()) {
map_units.clear();
}
map_units.putAll(soilsDb.findMapUnitsForGISObject(shape, true, true));
setMukeyList();
if (!map_units.isEmpty()) {
findAllComponentsData_Basic();
dataFilter.filter(map_units);
return true;
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return false;
}
public boolean findMapUnitsWithAreasAndShapesByMuPolygonKey(String mupolygonkey, GISEngine gisEngine) throws ServiceException, GISObjectException {
boolean ret_val = false;
if (null != soilsDb) {
if (!map_units.isEmpty()) {
map_units.clear();
}
MapUnit mapUnit = soilsDb.findMapUnitsByMupolygonKey(mupolygonkey, gisEngine, true, true);
if (null == mapUnit) {
throw new ServiceException("Could not find any mapunit information for that mupolygonkey");
}
map_units.put(mapUnit.mukey(), mapUnit);
setMukeyList();
if (!map_units.isEmpty()) {
ret_val = true;
}
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
/**
* Gets all components for this mapunit. No filtering is performed, and no
* components are excluded, therefore.
*
* @param mukey
* @throws ServiceException
*/
public void findComponentsByMapunit(String mukey) throws ServiceException {
MapUnit tMapUnit;
tMapUnit = soilsDb.findMukeyData(mukey);
if (null != tMapUnit) {
map_units.put(mukey, tMapUnit);
} // ELSE: If the lookup for the mukey fails, an exception will be thrown. No need to have an else here.
// Now get the component information
if (!soilsDb.findComponentsByMukey(tMapUnit)) {
throw new ServiceException("Could not find component data for this mapunit, " + mukey);
}
}
public void findMapunitsByAreaSymbol(String areaSymbol) throws ServiceException {
HashMap<String, MapUnit> tMapUnits;
tMapUnits = soilsDb.findMukeyDataByAreasymbol(areaSymbol);
if (null != tMapUnits) {
for (String key : tMapUnits.keySet()) {
map_units.put(key, tMapUnits.get(key));
}
} // ELSE: If the lookup for the mukey fails, an exception will be thrown. No need to have an else here.
}
public void findAllTextureData() throws ServiceException {
if (!soilsDb.findAllTextureData(map_units)) {
throw new ServiceException("Could not find any texture data for these mapunits.");
}
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
tableAoA.aoa_area(area);
}
public Connection getConnection() throws ServiceException {
Connection ret_val;
if (null != soilsDb) {
ret_val = soilsDb.getConnection();
} else {
throw new ServiceException("No soilsDb connection present in AoA object.");
}
return ret_val;
}
public void setGISObject(GISObject gisShape) throws ServiceException, GISObjectException {
if ((null != gisShape) && (null != soilsDb)) {
shape = gisShape;
setArea(gisShape.areaInAcres());
} else {
throw new ServiceException("Attempt to use a NULL value for " + ((null == soilsDb) ? "soilsDb" : "shape") + " in AoA class.");
}
}
@Override
public void toJSON(boolean selectedHorizonsOnly, JSONArray outArray) throws JSONException {
tableAoA.toJSON(outArray);
JSONArray mapUnitArray = new JSONArray();
super.toJSON(selectedHorizonsOnly, mapUnitArray);
outArray.put(JSONUtils.data(AoA.MAP_UNIT_LIST, mapUnitArray));
}
/**
* Use this ONLY to produce output JSON for listing the excluded mapUnits, AND
* do it last. This function will mark map units as excluded if ANY of their
* components are excluded, thus, this should only be done after all analysis,
* and calculations have been completed and the used map unit component
* combinations have already been output to the result JSON.
*
* @return
* @throws JSONException
* @throws ServiceException
*/
public JSONArray getExcluded() throws JSONException, ServiceException {
//Print out excluded MapUnits here, if neccessary.
JSONArray excludeds = new JSONArray();
JSONObject excludedObject = new JSONObject();
for (MapUnit mapUnit : map_units.values()) {
if (mapUnit.isExcluded() || mapUnit.hasExcludedComponents()) {
if (EvalResult.testDefaultDouble(mapUnit.aoaArea()) && mapUnit.aoaArea() > 0.0) {
mapUnit.area_pct((mapUnit.area() / mapUnit.aoaArea()) * 100.0);
}
if (!mapUnit.isExcluded() && mapUnit.hasExcludedComponents()) {
mapUnit.setExclude(true, "Components of this map unit were excluded. Please see below for the reasons each was excluded.");
}
mapUnit.setOutputColumns(new ArrayList<>(Arrays.asList(TableMapUnit.MUKEY, TableMapUnit.MUNAME, TableMapUnitCalculations.AREA_NAME, TableMapUnitCalculations.AREA_PCT)));
mapUnit.setComponentOutputColumns(new ArrayList<>(Arrays.asList(TableComponent.COKEY, TableComponent.COMPNAME, TableComponentCalculations.AREA_PCT_NAME)));
excludeds.put(mapUnit.toJSON(false, true));
}
}
return excludeds;
}
}