V2_1.java [src/java/m/crp/assessmenttool] Revision:   Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2019, 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.crp.assessmenttool;

import crp.utils.DBResources;
import static crp.utils.DBResources.LOCAL_SQLSERVER;
import crp.utils.SoilResult;
import csip.ServiceException;
import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Polling;
import csip.annotations.Resource;
import data.interpretors.SlopeSteepness;
import static data.interpretors.SlopeSteepness.SLOPE_VERSION_4_NO_ADJUSTMENTS;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngineFactory;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.ws.rs.Path;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
@Name("CRP Assessment")
@Description("This service consumes a JSON request containing a request identifier and "
    + "CRP Offer geometry and returns sheet/rill water and wind erosion rates for a "
    + "fallow management for up to the three most dominant soil components in a CRP "
    + "Offer area, plus a weighted average for each erosion rate.  "
    + "This version does allow a default slope value to be used if the DEM "
    + "average_slope service returns a 'none' value and also will error out if "
    + "the collective area in acres of all intersection polygons is 0.")
@Path("m/crpassessment/2.1")
@Polling(first = 2000, next = 1000)
@Resource(from = DBResources.class)
public class V2_1 extends V2_0 {

  @Override
  protected void init() {
    slopeVersion = SLOPE_VERSION_4_NO_ADJUSTMENTS;
  }

  @Override
  protected void getDEMSlopes(ArrayList<SoilResult> soils) throws ServiceException, SQLException, GISObjectException, JSONException, IOException {
    try (Connection connection = resources().getJDBC(LOCAL_SQLSERVER)) {
      gEngine = GISEngineFactory.createGISEngine(connection);
      for (SoilResult soilResult : soils) {
        double tSlope = Double.NaN;
        slopes = soilResult.slopes;

        if (slopes != null) {
          if (!slopes.badSlopeData() && slopes.slopeDataMessages().isEmpty()) {
            double wAvgSlope = 0.0;
            double totalAcres = 0.0;

            //Get overall average slope for these intersected polygons from the result file.
            for (int i = 0; i < slopes.numSlopes(); i++) {
              //Get slope by id used in creation of the featurecollection in 
              //  DEMSteepness (id's are String, and represent integer values starting at "1"
              SlopeSteepness.SlopeData tSlopeData = slopes.slope(String.valueOf(i + 1));
              if (null != tSlopeData) {
                JSONObject polyJSON = soilResult.polygonList.get(i);
                GISObject tVector = GISObjectFactory.createGISObject(polyJSON, gEngine);
                double tAvg = tSlopeData.mean();
                double tAcres = tVector.areaInAcres();
                wAvgSlope += tAcres * tAvg;
                totalAcres += tAcres;
              }
            }

            if (totalAcres != 0.0) {
              tSlope = (wAvgSlope / totalAcres);
//  DO NOT DEFAULT to any slope value...use what is calculated.
//              if (tSlope <= 0.0) {
//                tSlope = 0.01;
//              }
            } else {
              throw new ServiceException("Cannot calculate slope for this input shape.  Intersection areas are too small to total an area greater than 0 acres.");
//  Don't allow a zero area size to be used.
//              tSlope = 0.0;
//              Logger.getLogger(ServiceCall.class.getName()).log(Level.WARNING, "Total acres for this cokey''s,{0} mapunit intersections was zero.  Setting DEM slope to 0 .", soilResult.cokey);
            }
          } else {
            throw new ServiceException("The DEM returned slopes had bad data in the returned file. " + ((!slopes.slopeDataMessages().isEmpty()) ? " Bad data message: " + slopes.slopeDataMessages() : ""));
          }
        } else {
          throw new ServiceException("No data was returned from the DEM slope servcie for this cokey, " + soilResult.cokey + " and intersected mapunit polygons");
        }

        if (Double.isNaN(tSlope)) {
          throw new ServiceException("DEM slope calculation requested, but no DEM slope could be found for this soil: " + soilResult.cokey);
        }
        soilResult.slopeDEM = tSlope;
      }
    }
  }

}