V1_0.java [src/java/d/soils/wwe02_wepssoilinput] Revision: default  Date:
/*
 * $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 d.soils.wwe02_wepssoilinput;

import static adb.DBResources.EROSION_SQLSVR;
import csip.Config;
import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Resource;
import csip.utils.Validation;
import d.util.IFCWriter;
import d.dataNodes.IFCData;
import d.dataNodes.NASIS;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import soils.Component;
import soils.MapUnit;
import soils.db.SOILS_DATA;
import soils.db.SOILS_DB_Factory;
import adb.DBResources;
import static adb.DBResources.R2GIS_SQLSVR;
import java.util.LinkedHashMap;
import java.util.Map;
import static soils.db.DBResources.SDM;

/**
 *
 * @author brad
 */
@Name("WWE-02:  WEPS Soil Input IFC (wepssoilinput)")
@Description("Gets data from the NRCS Soil Data Mart and generates a soil IFC input file for the WEPS model. (Wind Erosion Prediction System)")
@Path("d/wepssoilinput/1.0")
@Resource(from = DBResources.class)

public class V1_0 extends ModelDataService {

  static final String SSURGO = "ssurgo";
  static final String KEY_COKEY = "cokey";

  @Override
  protected Map<String, Object> getConfigInfo() {
    return new LinkedHashMap<String, Object>() {
      {
        put("soils.gis.database.source", resources().getResolved("soils.gis.database.source"));
        put(SDM, resources().getResolved(SDM));
        put(R2GIS_SQLSVR, resources().getResolved(R2GIS_SQLSVR));
        put("fpp.version", "wwe-02 1.0");
      }
    };
  }

  @Override
  protected void doProcess() throws Exception {
    String cokey = parameter().getString(KEY_COKEY);
    Validation.checkCokey(cokey);

    Component comp = new Component();
    comp.cokey(cokey);
    MapUnit mapUnit = getSoilMapUnit(comp);

    NASIS nas = new NASIS(10, LOG); // 10 is a default in the WEPS code so I will keep it until I understand more about it
    try (Connection c = resources().getJDBC(EROSION_SQLSVR)) {
      boolean foundSoil = nas.loadSQL(c, cokey);

      if (!foundSoil) {
        throw new ServiceException("No soils were found with a cokey " + cokey);
      }

      IFCData ifcData = new IFCData(nas, LOG);
      IFCWriter writer = new IFCWriter();
      File ifcFile = workspace().getFile(ifcData.getComponentName() + ".ifc");

      if (organicCheck(nas)) {
        writer.writeOrganicDefault(ifcFile.toString());
      } else {
        String warnings = writer.writeIFCfile(ifcData, ifcFile.toString());
        if (warnings != null) {
          metainfo().setWarning(warnings);
        }

      }

      if (ifcFile.exists()) {
        results().put(ifcFile);
      } else {
        throw new ServiceException("File " + ifcFile.getName() + "could not be created.");
      }
    }
  }

  private MapUnit getSoilMapUnit(Component comp) throws ServiceException, SQLException, Exception {
    MapUnit mapUnit = new MapUnit(comp);
    try (SOILS_DATA soilsDb = SOILS_DB_Factory.createEngine(getClass(), LOG, Config.getString("soils.gis.database.source"))) {
      if (soilsDb.validateComponent(Integer.parseInt(comp.cokey()))) {
        soilsDb.findHorizonsForCokey(mapUnit, comp);
      } else {
        throw new ServiceException("The cokey value provided does not exist in the SDM database.  Cannot continue.");
      }
    }
    return mapUnit;
  }

  private boolean organicCheck(NASIS nas) {
    if (nas.getTaxorder().equalsIgnoreCase("Histosols")) {
      return true;
    }

    // assuming the first horizon is the top because the sql orders by deptht_r
    if (nas.getHzdept()[0] == 0 && nas.getHzdepb()[0] > 10 && nas.getOm()[0] > 15) {
      return true;
    }

    return false;
  }
}