V2_2.java [src/java/d/soils/wwe01_wwesoilparams] Revision: default  Date:
package d.soils.wwe01_wwesoilparams;

import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import csip.annotations.VersionInfo;
import csip.api.server.PayloadResults;
import static d.soils.wwe01_wwesoilparams.SoilParamsAoAFactory.WWE_SOIL_PARAMS_2_2;
import gisobjects.GISObject;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import javax.ws.rs.Path;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import static soils.AoA.CORRECTED_GEOMETRY;
import static soils.AoA.EXCLUDED_LIST;
import soils.Component;
import soils.MapUnit;
import soils.SoilsData;
import soils.db.DBResources;
import soils.db.tables.TableMapUnit;
import soils.db.tables.TableMapUnitCalculations;
import soils.db.tables.TableSaCatalog;
import soils.db.tables.TableSaSpatialVer;
import soils.db.tables.TableSaTabularVer;
import static soils.utils.EvalResult.writeDouble;

/*
 * 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.
 */
/**
 * REST Web Service. Front end callable.
 *
 * @author wlloyd, od, Shaun Case
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
@Name("WWE-01:  Erosion Soil Parameters (wwesoilparams)")
@Description("Intersects area of analysis (AoA) geometry with NRCS Soil Data Mart "
    + "(SDM) mapunit geometry, derives a list of distinct soil components, horizons, "
    + "and texture data for the AoA, and gets parameters from SDM tables for "
    + "populating application UI data fields and computing erosion rates and other "
    + "resource analysis output.  This version includes the component long_name and "
    + "returns the maptunit intersection polygons")
@VersionInfo("2.2")
@Path("d/wwesoilparams/2.2")

@Resource(from = DBResources.class)
public class V2_2 extends SoilParamsService {

  public V2_2() {
    super(WWE_SOIL_PARAMS_2_2);
  }

  @Override
  protected void postProcess() throws Exception {
    PayloadResults result = results();
    result.put("AoA Area", writeDouble(aoiArea, "%.3f"), "acres");
    result.put(SoilsData.MAP_UNIT_LIST, results);
    result.put(EXCLUDED_LIST, excludeds);
    if (!newWKT.isEmpty()) {
      result.put(CORRECTED_GEOMETRY, newWKT, "If this section is present, the input geometry was invalid.  This service attempted to correct it, and was successful in creating a new geometry that could be utilized.  Please check this corrected geometry to be sure it represents what you originally intended.  If it does, please contact the source of your original geometry to have it corrected.  You may use this WKT to do so.");
    }

    //CREATE geoJSON output file for mapunit level information including the intersected polygons
    //put result link to the geoJSON file
    try (
        FileOutputStream outFile = new FileOutputStream(workspace().getFile("geoJSON.json"));
        BufferedWriter jWriter = new BufferedWriter(new OutputStreamWriter(outFile));) {

      JSONObject fCollection = new JSONObject();
      JSONObject crs = new JSONObject();
      JSONArray features = new JSONArray();

      crs.put("type", "name");
      crs.put("properties", (new JSONObject()).put("name", "urn:ogc:def:crs:EPSG:7.9.8:4326"));
      fCollection.put("type", "FeatureCollection");
      fCollection.put("crs", crs);

      for (MapUnit mapUnit : mapunits) {
        ArrayList<GISObject> polys = mapUnit.getIntersectionPolygons();
        if (polys.size() > 0) {
          ArrayList<Component> components = new ArrayList<>();
          components.addAll(mapUnit.components().values());
          String domCokey = getDominantCokey(components);
          
          JSONObject feature = new JSONObject();
          JSONObject geometry = new JSONObject();

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

          if (polys.size() > 1) {
            JSONArray geometries = new JSONArray();
            geometry.put("type", "GeometryCollection");
            for (GISObject gisObject : polys) {
              geometries.put(gisObject.toJSON());
            }
            geometry.put("geometries", geometries);

          } else {
            geometry = polys.get(0).toJSON();
          }

          feature.put("geometry", geometry);
          JSONObject properties = new JSONObject();

          properties.put(TableMapUnit.MUKEY, mapUnit.mukey());
          properties.put(TableMapUnit.MUSYM, mapUnit.musym());
          properties.put(TableMapUnit.MUNAME, mapUnit.muname());
          properties.put(TableMapUnit.AREA_NAME, mapUnit.areaname());
          properties.put(TableMapUnit.AREASYMBOL_NAME, mapUnit.areasymbol());
          properties.put(TableMapUnitCalculations.AREA_NAME, mapUnit.area());
          properties.put("dominant_cokey", domCokey);
          properties.put(TableSaCatalog.SA_VERSION, mapUnit.saVersion());
          properties.put(TableSaCatalog.SA_VER_EST, mapUnit.saVersionEst());
          properties.put(TableSaSpatialVer.SPATIAL_VERSION, mapUnit.saSpatialVersion());
          properties.put(TableSaSpatialVer.SPATIAL_VERSION_EST, mapUnit.saSpatialVersionEst());
          properties.put(TableSaTabularVer.TABULAR_VERSION, mapUnit.saTabularVersion());
          properties.put(TableSaTabularVer.TABULAR_VERSION_EST, mapUnit.saTabularVersionEst());

          feature.put("properties", properties);
          features.put(feature);
        }

      }
      fCollection.put("features", features);
      
      jWriter.write(fCollection.toString());
      jWriter.flush();
    }

    File resultFile = workspace().getFile("geoJSON.json");
    if (resultFile.exists() && resultFile.isFile()) {
      result.put(resultFile);
    } else {
      result.put("geoJSON", "None", "No polygons found");
    }
  }
  
  protected String getDominantCokey(ArrayList<Component> components){
    double area_pct = 0.0;
    String cokey = "";
    
    for( Component component: components){
      if ( component.area_pct() > area_pct){
        area_pct = component.area_pct();
        cokey = component.cokey();
      }
    }
    
    return cokey;
  }
}