DEMSteepness.java [src/java/crp/utils] 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 crp.utils;

//import csip.Client;
import static csip.ModelDataService.KEY_METAINFO;
import static csip.ModelDataService.KEY_PARAMETER;
import csip.ServiceException;
import csip.utils.JSONUtils;
import data.interpretors.SlopeSteepness;
import static data.interpretors.SlopeSteepness.SLOP_VERSION_1;
import java.net.URI;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 *
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
public class DEMSteepness extends ServiceCall {

  private String metaInfo;
  private JSONObject[] aoa_geometry;
  private String resultFile;
  private SlopeSteepness slopes;
  private String slopeVersion = SLOP_VERSION_1;

  
  public DEMSteepness(String metaInfo, JSONObject _aoa_geometry, String URI) {
    super(URI);
    this.metaInfo = metaInfo;
    aoa_geometry = new JSONObject[1];
    aoa_geometry[0] = _aoa_geometry;

    errorPrefix = "DEMSteepnessServiceCall";
  }  
//  /**
//   *
//   * @param metaInfo
//   * @param _aoa_geometry
//   * @param URI
//   */
//  public DEMSteepness(JSONObject metaInfo, JSONObject _aoa_geometry, String URI, String version) {
//    super(URI);
//    this.metaInfo = metaInfo;
//    aoa_geometry = new JSONObject[1];
//    aoa_geometry[0] = _aoa_geometry;
//    if ((null != version) && !version.isEmpty()) {
//      slopeVersion = version;
//    }
//
//    errorPrefix = "DEMSteepnessServiceCall";
//  }
  public DEMSteepness(String metaInfo, ArrayList<JSONObject> _aoa_geometries, String URI) {
    super(URI);
    this.metaInfo = metaInfo;
    aoa_geometry = new JSONObject[_aoa_geometries.size()];

    for (int i = 0; i < _aoa_geometries.size(); i++) {
      aoa_geometry[i] = _aoa_geometries.get(i);
    }

    errorPrefix = "DEMSteepnessServiceCall";
  }
  public DEMSteepness(String metaInfo, ArrayList<JSONObject> _aoa_geometries, String URI, String version) {
    super(URI);
    this.metaInfo = metaInfo;
    aoa_geometry = new JSONObject[_aoa_geometries.size()];
    if ((null != version) && !version.isEmpty()) {
      slopeVersion = version;
    }
    for (int i = 0; i < _aoa_geometries.size(); i++) {
      aoa_geometry[i] = _aoa_geometries.get(i);
    }

    errorPrefix = "DEMSteepnessServiceCall";
  }

  public DEMSteepness(String metaInfo, ArrayList<JSONObject> _aoa_geometries, String URI, CheckedServiceResult<ServiceCallData> serviceCallback, String version) {
    super(URI, serviceCallback);
    this.metaInfo = metaInfo;
    if ((null != version) && !version.isEmpty()) {
      slopeVersion = version;
    }     
    aoa_geometry = new JSONObject[_aoa_geometries.size()];

    for (int i = 0; i < _aoa_geometries.size(); i++) {
      aoa_geometry[i] = _aoa_geometries.get(i);
    }

    errorPrefix = "DEMSteepnessServiceCall";
  }

  public String data() {
    return resultFile;
  }

  public SlopeSteepness slopes() {
    return slopes;
  }

  @Override
  protected void parseResults() throws ServiceException {
    //   Error checking has already been done on these results.
    // If we get to this function, no further error
    // checking is necessary, except to look at the "results" array in the output, if desired.
    if (null == callResultSection) {
      throwServiceCallException("Cannot find results in the call to " + this.URI + " .");
    }

    try {
      //  Get the climate file and store it.
      Map<String, JSONObject> resultMap = JSONUtils.getResults(results);
      String fileLink = JSONUtils.getStringParam(resultMap, "avg_slope_results.csv", "");
      if (!fileLink.isEmpty()) {
        URI cliURI = new URI(fileLink);

//        Client fileGet = new Client();
//        resultFile = fileGet.doGET(cliURI.toString());
        resultFile = IOUtils.toString(cliURI, "UTF-8");
        Logger.getLogger(DEMSteepness.class.getName()).log(Level.INFO, resultFile);

        if (null != resultFile) {
          slopes = new SlopeSteepness(resultFile, (this.URI.toString().contains("4.0") ? slopeVersion : "1.0"));
        }

      } else {
        throwServiceCallException("No  avg_slope_results.csv file link was found in the results from the average slope steepness service.");
      }

    } catch (Exception ex) {
      throwServiceCallException("Could not retrieve the slope_steepness file: ", ex);
    }
  }

  @Override
  protected void createRequest() throws ServiceException {
    JSONArray dataArray;
    JSONArray geoArray = new JSONArray();

    requestMetainfoObject = new JSONObject();
    request = new JSONObject();

    dataArray = new JSONArray();
    try {
      requestMetainfoObject.put("MultipartRequest", "Bundled Service Request From csip-crp MetaModeling CliWindSoil Service");
      requestMetainfoObject.put("CRPAssessment_Metainfo", new JSONObject(metaInfo));
      requestMetainfoObject.put("mode", "sync");
      request.put(KEY_METAINFO, requestMetainfoObject);

      if ((aoa_geometry.length == 1) && (aoa_geometry[0].toString().contains("FeatureCollection"))) {
        geoArray.put(aoa_geometry[0]);
        dataArray.put(JSONUtils.data("boundary", geoArray));
      } else {
        //Create a featurecollection from this one geometry.  (Later could be an array of geometries...
        geoArray.put(createFeatureCollection("DEMSteepnessServiceCall", aoa_geometry));
        dataArray.put(JSONUtils.data("boundary", geoArray));
      }

      dataArray.put(JSONUtils.data("DEM_RES", 10)); //  Use the "id" of each feature as its index into the result csv file.
      dataArray.put(JSONUtils.data("DInf", true)); //  Use the "id" of each feature as its index into the result csv file.

      dataArray.put(JSONUtils.data("result_ID", "id")); //  Use the "id" of each feature as its index into the result csv file.

      request.put(KEY_PARAMETER, dataArray);

    } catch (JSONException ex) {
      throwServiceCallException("Cannot create the JSON request.", ex);
    }
  }

  private JSONObject createFeature(int id, JSONObject geometry) throws JSONException {
    JSONObject feature = new JSONObject();
    JSONObject properties = new JSONObject();

    properties.put("ID", id);

    feature.put("type", "Feature");
    feature.put("properties", properties);
    feature.put("geometry", geometry);

    return feature;
  }

  private JSONArray createFeatureArray(JSONObject[] geometries) throws JSONException {
    JSONArray features = new JSONArray();

    for (int i = 0; i < geometries.length; i++) {
      features.put(createFeature(i + 1, geometries[i]));
    }

    return features;
  }

  private JSONObject createFeatureCollection(String name, JSONObject[] geometries) throws JSONException {
    JSONObject featureCollection = new JSONObject();
    JSONObject crs = new JSONObject();
    JSONObject crsProperties = new JSONObject();

    crsProperties.put("name", "urn:ogc:def:crs:OGC:1.3:CRS84");
    crs.put("type", "name");
    crs.put("properties", crsProperties);

    featureCollection.put("type", "FeatureCollection");
    featureCollection.put("name", name);
    featureCollection.put("crs", crs);
    featureCollection.put("features", createFeatureArray(geometries));

    return featureCollection;
  }
}