TestAoA.java [test/soils] Revision: default  Date:
/*
 * 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.
 */
package soils;

import csip.api.server.ServiceException;
import csip.SessionLogger;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngine;
import gisobjects.db.GISEngineFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.codehaus.jettison.json.JSONException;
import static org.testng.Assert.*;
import org.testng.Reporter;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import soils.db.SOILS_DATA;
import soils.db.mssql_sdm;

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

    private static AoA aoa;
    private static SessionLogger Log = new SessionLogger();
    private static Connection conn, gisConn;
    private static SOILS_DATA soilsDb;
    private static GISEngine gisEngine;
    private static String shapeWKT;

    public TestAoA() throws Exception {
        //  Get a randomly sized, random location polygon (buffer) from the SDM database that we are using.        
        String query = "SELECT geography::STGeomFromText(mupolygon.mupolygongeo.STCentroid().STAsText(), 4326).MakeValid().STBuffer( (SELECT FLOOR(RAND()*(350-160)+160)) ).MakeValid().STAsText() as ShapeWKT\n"
                + "	FROM mupolygon\n"
                + "		WHERE mupolygon.mupolygonkey in  \n"
                + "		(\n"
                + "			SELECT TOP 1 mupolygonkey\n"
                + "				FROM mupolygon, legend, mapunit \n"
                + "					WHERE legend.lkey=mapunit.lkey AND mapunit.mukey=mupolygon.mukey AND legend.areatypename like 'Non-MLRA%' \n"
                + "					ORDER BY newid()\n"
                + "		);";

        Reporter.log("Attempting to generate random buffer polygon from SDM.");

        try (Connection tConn = createDataSource("SDM"); Statement statement = tConn.createStatement();) {
            ResultSet results = statement.executeQuery(query);
            if (results.next()) {
                shapeWKT = results.getString("ShapeWKT");
            }
        }

        System.out.println("Using WKT: " + shapeWKT);
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        conn = createDataSource("SDM");
        gisConn = createDataSource("CRDB");

        soilsDb = new mssql_sdm(conn, Log);
        gisEngine = GISEngineFactory.createGISEngine(gisConn);

        aoa = new AoA(soilsDb, Log);
        aoa.setGISObject(GISObjectFactory.createGISObject(shapeWKT, gisEngine));
        System.out.println("Shape acreage is: " + aoa.getArea());
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
        conn.close();
        gisConn.close();
    }

    /**
     * This function tests several features.
     *
     * @throws Exception
     */
    @Test(groups = "SetupMapUnitsWithShapesAndAreas")
    public void getMapUnitsAreasAndShapes() throws ServiceException, SQLException, GISObjectException {
        aoa.findIntersectedMapUnitsWithAreasAndShapes();
        assertTrue(aoa.map_units.size() > 0, "No Mapunits were found for the testing shape.");
    }

    /**
     * Just fills the component, horizon, fragmentation classes of each mapunit,
     * applying NO filter logic. Does not error out, per se, but could throw an
     * exception. The structures filled can be tested for content in other test
     * functions.
     *
     * @throws ServiceException
     */
    @Test(dependsOnGroups = "SetupMapUnitsWithShapesAndAreas")
    public void findAllComponents() throws ServiceException {
        aoa.findAllComponents();
        assertTrue(true);
    }

    /**
     * Just fills the component, horizon, fragmentation classes of each mapunit,
     * applying WIND and WATER filter logic. Does not error out, per se, but
     * could throw an exception. The structures filled can be tested for content
     * in other test functions.
     *
     * @throws ServiceException
     */
    @Test(groups = "SetupComponents", dependsOnGroups = "SetupMapUnitsWithShapesAndAreas")
    public void findAllComponentsApplyWindWaterFilters() throws ServiceException {
        aoa.findAllComponentsApplyWindWaterFilters();
        assertTrue(true);
    }

    /**
     * Tests to see if the mapunits recovered for the input polygon have areas
     * that add up to, or nearly to, the area of the AoA polygon shape, which
     * was randomly generated by the constructor. In almost all cases, they
     * should add-up.
     *
     * This tests the functionality of the getMapUnits functions to acquire the
     * shapes and areas of the intersected mapunit portions to the AoA polygon
     * (shape).
     */
    @Test(dependsOnGroups = "SetupMapUnitsWithShapesAndAreas")
    public void testAreas() {
        assertTrue(aoa.map_units != null, "This test requires that mapunits be found, and their areas calculated first.");

        double areaTotal = 0.0;
        for (String key : aoa.map_units.keySet()) {
            MapUnit mapunit = aoa.map_units.get(key);
            areaTotal += mapunit.area();
        }

        assertEquals(areaTotal, aoa.area, 0.00001);  //  This delta is approximately 4sqft.  May fail in some cases, if consistently failing, make it a larger number.     
    }

    @Test(dependsOnGroups = "SetupMapUnitsWithShapesAndAreas")
    public void testfindAllComponentsData_Basic(){
        System.out.println("Testing findAllComponentsData_Basic");
        
        assertTrue(aoa.map_units != null, "This test requires that mapunits be found, and their areas calculated first.");

        try {
            aoa.findAllComponentsData_Basic();
            for( MapUnit mapUnit:aoa.map_units.values()){
                System.out.println(mapUnit.toJSON(false, true).toString());
            }
        } catch (ServiceException ex) {
            assertTrue(false, "Could not find all components' data basic: " + ex.getMessage());
        } catch (JSONException ex) {
            assertTrue(false,"Could not create output JSON: " + ex.getMessage());
        }
        
    }
    
    private static synchronized Connection createDataSource(String type) throws Exception {
        Connection connection = null;

        Reporter.log("Attempting to load the database driver for: " + type);

        switch (type) {
            case "SDM":
                Class.forName("csip.sdm.SDMDriver");
                Reporter.log("Driver was loaded for: csip.sdm.SDMDriver");
                connection = DriverManager.getConnection("jdbc:sdm:rest://SDMDataAccess.sc.egov.usda.gov/Tabular/post.rest");
                Reporter.log("Connection to remote SDM REST Service was successful");
                break;

            case "CRDB":
                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                Reporter.log("Driver was loaded for: com.microsoft.sqlserver.jdbc.SQLServerDriver");
                connection = DriverManager.getConnection("jdbc:sqlserver://129.82.20.129:1433;databaseName=conservation_resources;user=sdmro;password=emHBcNq3");
                Reporter.log("Connection to the local Conservation Resources DB Service was successful");
                break;
        }
        return connection;
    }
}