V1_0.java [src/java/m/nadp/clip] Revision: default  Date:
package m.nadp.clip;

import csip.annotations.Description;
import csip.annotations.Name;
import csip.annotations.Resource;
import csip.api.server.Executable;
import csip.api.server.PayloadParameter;
import csip.api.server.PayloadResults;
import csip.api.server.ServiceException;
import csip.ModelDataService;
import static csip.annotations.ResourceType.REFERENCE;
import gisobjects.GISObject;
import static gisobjects.GISObjectFactory.createGISObject;
import gisobjects.db.GISEngine;
import static gisobjects.db.GISEngineFactory.createGISEngine;
import gisobjects.vector.GIS_FeatureCollection;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.util.ArrayList;
import javax.ws.rs.Path;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import utils.DBResources_nadp;
import static utils.DBResources_nadp.nadp_ID;

/**
* Last Updated: 6-June-2019
* @author Tyler Wible
* @since 31-March-2016
*/
@Name("nadp_clip")
@Description("NADP Atmospheric Wet Depostion Clipping Service")
@Path("m/clip/1.0")
@Resource(file = "gdalwarp", type = REFERENCE, id = "gdalwarp")
@Resource(from = DBResources_nadp.class)
public class V1_0 extends ModelDataService {

    protected int year;
    protected String dbType;
    protected GISObject aoaBoundary;
    protected ArrayList<File> result;
    
    private File getNADPImageFile(int year, String dbType) {
//      Format: /mnt/csip-raster/clean/deposition/{year}/{dbType}/{dbType}_dep_{year}.tif
        return new File(String.format("/mnt/csip-raster/clean/deposition/%1$s/%2$s/%2$s_dep_%1$s.tif",year, dbType));

    }

    @Override
    protected void preProcess() throws Exception {
        PayloadParameter inputPayload = parameter();
        year = inputPayload.getInt("year", 2018);
        dbType = inputPayload.getString("dataType", "N");
        
        //Import user specified clipping boundary
        JSONObject boundary = inputPayload.getJSONArray("boundary").getJSONObject(0);
        try (Connection gisDb = resources().getJDBC(nadp_ID);) {
            GISEngine tEngine = createGISEngine(gisDb);
            aoaBoundary = createGISObject(boundary, tEngine);
            aoaBoundary.makeValid(GISObject.UsePurpose.all_purposes, GISObject.GISType.all_types);
        }
        result = new ArrayList<>();
    }

    @Override
    protected void doProcess() throws Exception {
        File ws = workspace().getDir();
        File nadpRaster = this.getNADPImageFile(year, dbType);
        
        if (GISObject.GISObjectType.featurecollection == aoaBoundary.getType()) {
            for (int i = 0; i < ((GIS_FeatureCollection) aoaBoundary).getFeatureCount(); i++) {
                // get polygon translation
                GISObject newPolygon = ((GIS_FeatureCollection) aoaBoundary).getGeometry(i);
                
                //Clip the raster to the current polygon
                String boundaryFile = writeWKTtoFile(ws.getPath(), newPolygon, i);
                String resultName = ws.getAbsolutePath()+"/nadp_"+dbType+"_"+year+"_"+i+"_"+getSUID().substring(0,8)+".tif";
                clipRaster(boundaryFile, nadpRaster, resultName);
            }
        }else{
            //Clip the raster the provided boundary
            String boundaryFile = writeWKTtoFile(ws.getPath(), aoaBoundary, 0);
            String resultName = ws.getAbsolutePath()+"/nadp_"+dbType+"_"+year+"_0_"+getSUID().substring(0,8)+".tif";
            clipRaster(boundaryFile, nadpRaster, resultName);
        }
    }


    @Override
    protected void postProcess() throws Exception {
        PayloadResults resultPayload = results();
        for (File f : result) {
            resultPayload.put(f);
        }
    }
    
    private String writeWKTtoFile(String directory, GISObject boundary, int i) throws IOException, JSONException{
        //open the file writer and set path
        String path = directory + File.separator + "boundary_" + i + ".txt";
        FileWriter writer =  new FileWriter(path, false);
        PrintWriter print_line = new PrintWriter(writer);
        
        //Print the needed values
        print_line.printf("%s", boundary.toJSON().toString());
      
        // Close the file writer 
        print_line.close();
        writer.close();
        LOG.info("Boundary text file located at:\t" + path);
        
        return path;
    }

    private void clipRaster(String boundaryFile, File srcRaster, String resultName) throws ServiceException, IOException {
        Executable e = resources().getExe("gdalwarp");
        e.addArguments("-cutline", boundaryFile, "-crop_to_cutline", "-of", "GTiff", srcRaster.toString(), resultName);
        LOG.info(e.getArguments().toString());
        StringWriter writer = new StringWriter();
        e.redirectOutput(writer);
        e.redirectError(writer);
        e.exec();
        LOG.info(writer.toString());
        result.add(new File(resultName));
    }
}