V2_0.java [src/java/m/rhem/rhem03_compEsd] Revision: 486856ad4de92338dc62853baf4a40ffa515614d  Date: Mon Feb 01 10:37:23 MST 2021
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package m.rhem.rhem03_compEsd;

import csip.Config;
import gisobjects.db.GISEngine;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import csip.ModelDataService;
import csip.ServiceException;
import csip.SessionLogger;
import csip.annotations.Polling;
import csip.annotations.Resource;
import csip.utils.JSONUtils;
import static gisobjects.db.GISEngineFactory.createGISEngine;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import java.util.List;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import rhem.utils.DBResources;
import static rhem.utils.DBResources.CRDB;
import rhem.utils.RHEMUtils;
import rhem.utils.RhemResources;
import soils.MapUnit;
import soils.db.SOILS_DATA;
import soils.db.SOILS_DB_Factory;

/**
 * RHEM-03: Get Soil Component, Ecological Site, Soil Component Surface Texture
 * Class, Soil Component Slope Length and Steepness for RHEM Evaluation Area
 *
 * @version 2.0
 * @author Rumpal Sidhu
 */
@Name("RHEM-03: Get Soil Component, Ecological Site, Soil Component Surface Texture Class, "
    + "Soil Component Slope Length and Steepness for RHEM Evaluation Area.")
@Description("Get map unit, soil component and ecological site information for "
    + "RHEM evaluation site. Get surface soil texture class relevant to "
    + "the soil component associated with a RHEM evaluation site within "
    + "an AoA. Get slope length and steepness relevant to the soil "
    + "component associated with a RHEM evaluation site within an AoA.")
@Path("m/rhem/getrhemsoilcomponent/2.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
@Resource(from = soils.db.DBResources.class)
public class V2_0 extends ModelDataService {

  private int aoaId, rhemSiteId;
  private JSONObject rhemSiteGeometryPoint;
  private ArrayList<Mapunit> mapunitList = new ArrayList<>();
  private AoA aoa;


  @Override
  public void preProcess() throws ServiceException {
    aoaId = parameter().getInt("AoAID");
    rhemSiteId = parameter().getInt("rhem_site_id");
    rhemSiteGeometryPoint = parameter().getParamJSON("rhem_site_geometry");
  }


  @Override
  public void doProcess() throws Exception {
    try (SOILS_DATA soilsDb = SOILS_DB_Factory.createEngine(getClass(), LOG,
        RhemResources.soils_db);
        Connection crdb = resources().getJDBC(CRDB);) {
      try (GISEngine gisEngine = createGISEngine(crdb)) {
        GISObject geometry = GISObjectFactory.createGISObject(rhemSiteGeometryPoint, gisEngine);

        aoa = new AoA(soilsDb, geometry, LOG);
        aoa.findIntersectedMapUnits();
        aoa.findAllComponentsData_Basic();
        aoa.findEcoClasses();
        aoa.findAllTextureData();
        getData(crdb);
      }
    }
  }


  private void getData(Connection crdb) throws Exception {
    for (MapUnit mapUnit : aoa.getMapUnits().values()) {
      ArrayList<Component> componentList = new ArrayList<>();
      for (soils.Component component : mapUnit.components().values()) {
        Component comp = new Component(component.cokey(), component.compname(),
            component.comppct_r(), component.slope_l(), component.slope_r(), component.slope_h());

        ArrayList<EcologicalSite> ecoList = new ArrayList<>();
        for (soils.Coecoclass coEcoClass : component.ecoClasses().values()) {
          String ecoclassid = coEcoClass.ecoclassid();
          if (ecoclassid != null && ecoclassid.startsWith("R")) {
            try (Connection esdConnection = resources().getJDBC(DBResources.ESD);
                Statement esdStmt = esdConnection.createStatement();
                ResultSet resultSet = esdStmt.executeQuery(DBResources.RHEM03Query04(ecoclassid));) {
              while (resultSet.next()) {
                ecoList.add(new EcologicalSite(ecoclassid,
                    resultSet.getString("es_range_name")));
              }
            }
          }
        }
        comp.setEcoSiteList(ecoList);

        ArrayList<SurfaceTexture> surfaceTextureList = new ArrayList<>();
        for (soils.Horizon horizon : component.horizons.values()) {
          if (horizon.hzdept_r() == 0) {
            for (soils.TextureGroup textureGroup : horizon.textureGroups.values()) {
              for (soils.Texture texture : textureGroup.textures.values()) {
                String texcl = texture.texcl();
                try (Statement statement = crdb.createStatement();
                    ResultSet resultSet = statement.executeQuery(DBResources.RHEM03Query06(texcl));) {
                  while (resultSet.next()) {
                    int textureId = resultSet.getInt("texture_subclass_id");
                    String textureClass = resultSet.getString("text_abreviation");
                    String textureClassLabel = resultSet.getString("text_label");
                    surfaceTextureList.add(new SurfaceTexture(texcl,
                        textureId, textureClass, textureClassLabel));
                  }
                }
              }
            }
          }
        }
        comp.setSurfaceTextureList(surfaceTextureList);
        componentList.add(comp);
      }
      componentList.sort((o1, o2) -> Double.compare(o2.getComppctR(), o1.getComppctR()));
      mapunitList.add(new Mapunit(mapUnit.musym(), mapUnit.muname(), componentList));
    }
  }


  @Override
  public void postProcess() throws Exception {
    results().put("AoAID", this.aoaId, "Area of Analysis Identifier");
    results().put("rhem_site_id", this.rhemSiteId, "RHEM Evaluation Site Identifier");

    JSONArray mapUnitArray = new JSONArray();
    for (Mapunit mapunit : this.mapunitList) {
      JSONArray mapunitArr = new JSONArray();
      mapunitArr.put(JSONUtils.dataDesc("musym", mapunit.getMusym(), "Mapunit Symbol"));
      mapunitArr.put(JSONUtils.dataDesc("muname", mapunit.getMuname(), "Mapunit Name"));

      JSONArray componentArray = new JSONArray();
      for (Component component : mapunit.getComponentList()) {
        JSONArray componentArr = new JSONArray();
        componentArr.put(JSONUtils.dataDesc("cokey", component.getCokey(), "Soil Component Key"));
        componentArr.put(JSONUtils.dataDesc("compname", component.getCompName(), "Soil Component Name"));
        componentArr.put(JSONUtils.dataDesc("comppct_r", component.getComppctR(), "Soil Component Percentage Relative Value"));
        componentArr.put(JSONUtils.dataDesc("slopepct_l", component.getSlopePctL(), "Slope Percent – Low Value"));
        componentArr.put(JSONUtils.dataDesc("slopepct_r", component.getSlopePctR(), "Slope Percent – Representative Value"));
        componentArr.put(JSONUtils.dataDesc("slopepct_h", component.getSlopePctH(), "Slope Percent – High Value"));
        JSONArray ecoSiteArray = new JSONArray();
        for (EcologicalSite ecoSite : component.getEcoSiteList()) {
          JSONArray ecoSiteArr = new JSONArray();
          ecoSiteArr.put(JSONUtils.dataDesc("es_id", ecoSite.getEsId(), "Ecological Site Identifier"));
          ecoSiteArr.put(JSONUtils.dataDesc("es_range_name", ecoSite.getEsRangeName(), "Ecological Site Name"));
          ecoSiteArray.put(ecoSiteArr);
        }
        componentArr.put(JSONUtils.data("Ecological Site List", ecoSiteArray));

        JSONArray surfaceTestureArray = new JSONArray();
        for (SurfaceTexture texture : component.getSurfaceTextureList()) {
          JSONArray surfaceTextureArr = new JSONArray();
          surfaceTextureArr.put(JSONUtils.dataDesc("texcl", texture.getTexcl(), "Texture Class"));
          surfaceTextureArr.put(JSONUtils.dataDesc("rhem_texture_id ", texture.getTextureId(), "RHEM Texture Class Identifier"));
          surfaceTextureArr.put(JSONUtils.dataDesc("rhem_texture_class ", texture.getTextureClass(), "RHEM Texture Class"));
          surfaceTextureArr.put(JSONUtils.dataDesc("rhem_texture_class_label ", texture.getTextureClassLabel(), "RHEM Texture Class Label"));
          surfaceTestureArray.put(surfaceTextureArr);
        }
        componentArr.put(JSONUtils.data("Surface Texture Class List", surfaceTestureArray));
        componentArray.put(componentArr);
      }
      mapunitArr.put(JSONUtils.data("Components", componentArray));
      mapUnitArray.put(mapunitArr);
    }
    results().put("MapUnit List", mapUnitArray);
  }

  static class AoA extends soils.AoA {

    public AoA(SOILS_DATA soilsDb, GISObject aoaShape, SessionLogger Log) throws GISObjectException, ServiceException, SQLException {
      super(soilsDb, aoaShape, Log);
    }
  }

  static class Mapunit {

    protected String musym;
    protected String muname;
    protected List<Component> componentList;


    public Mapunit(String musym, String muname,
        List<Component> componentList) {
      this.musym = musym;
      this.muname = muname;
      this.componentList = componentList;
    }


    public String getMusym() {
      return musym;
    }


    public String getMuname() {
      return muname;
    }


    public List<Component> getComponentList() {
      return componentList;
    }
  }

  static class Component {

    protected String cokey;
    protected String compName;
    protected double comppctR;
    //slope length and steepness
    protected double slopePctL, slopePctR, slopePctH;

    protected List<EcologicalSite> ecoSiteList;
    protected List<SurfaceTexture> surfaceTextureList;


    public Component(String cokey, String compName, double comppctR,
        double slopePctL, double slopePctR, double slopePctH) {
      this.cokey = cokey;
      this.compName = compName;
      this.comppctR = comppctR;
      this.slopePctL = slopePctL;
      this.slopePctR = slopePctR;
      this.slopePctH = slopePctH;
    }


    public String getCokey() {
      return cokey;
    }


    public String getCompName() {
      return compName;
    }


    public double getComppctR() {
      return comppctR;
    }


    public double getSlopePctL() {
      return slopePctL;
    }


    public double getSlopePctR() {
      return slopePctR;
    }


    public double getSlopePctH() {
      return slopePctH;
    }


    public List<EcologicalSite> getEcoSiteList() {
      return ecoSiteList;
    }


    public List<SurfaceTexture> getSurfaceTextureList() {
      return surfaceTextureList;
    }


    public void setEcoSiteList(List<EcologicalSite> list) {
      ecoSiteList = list;
    }


    public void setSurfaceTextureList(List<SurfaceTexture> list) {
      surfaceTextureList = list;
    }

  }

  static class EcologicalSite {

    protected String esId;
    protected String esRangeName;


    public EcologicalSite(String esId, String esRangeName) {
      this.esId = esId;
      this.esRangeName = esRangeName;
    }


    public String getEsId() {
      return esId;
    }


    public String getEsRangeName() {
      return esRangeName;
    }
  }

  static class SurfaceTexture {

    protected String texcl;
    protected int textureId;
    protected String textureClass;
    protected String textureClassLabel;


    public SurfaceTexture(String texcl, int textureId, String textureClass,
        String textureClassLabel) {
      this.texcl = texcl;
      this.textureId = textureId;
      this.textureClass = textureClass;
      this.textureClassLabel = textureClassLabel;
    }


    public String getTexcl() {
      return texcl;
    }


    public int getTextureId() {
      return textureId;
    }


    public String getTextureClass() {
      return textureClass;
    }


    public String getTextureClassLabel() {
      return textureClassLabel;
    }
  }
}