Displaying differences for changeset
 
display as  

src/java/m/wqm/wqmsoilattributes/V1_0.java

@@ -7,6 +7,7 @@
  */
 import oms3.annotations.*;
 import csip.ModelDataService;
+import csip.ServiceException;
 import csip.annotations.*;
 import csip.utils.JSONUtils;
 import org.codehaus.jettison.json.JSONArray;
@@ -39,6 +40,8 @@
     //mapunit/ssurgo polygon intersect URI
     private final String SSURGO_INTERSECT_URI = "http://csip.engr.colostate.edu:8090/csip-erosion/d/soils/1.2";        
     private final Double minimumPercentage = 0.05;
+    static final int JSON_LATITUDE = 1;
+    static final int JSON_LONGITUDE = 0;     
     
     //Request
     private String aoaId;
@@ -51,43 +54,50 @@
     private String error_msg = "";
     private Connection conn = null;
     private Statement statement = null; 
-    private V1_0.ServiceCall intersectCall = null;
+    //private V1_0.ServiceCall intersectCall = null;
+    private wqm.utils.WQMTools.PolygonLatLon polygonData;       
     
     @Override
-    protected void preProcess() throws Exception {
+    protected void preProcess(){
         this.error_msg = "";
-        
-        JSONArray request = getRequest().optJSONArray("parameter");
-        
-        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") ){
-            this.aoaId = getStringParam("AoAId");
-            //Get the entire aoa_geometry group as it matches the input payload for the ServiceCall class
-            this.aoaGeometry = getJSONParam("aoa_geometry");
-            this.intersectCall = new ServiceCall( this.SSURGO_INTERSECT_URI );            
-            
-            try {
-                this.conn = wqm.utils.WQMTools.getConnection( "ssurgo", LOG );
-                this.statement = this.conn.createStatement();
+    this.polygonData = null;
 
-            } catch (SQLException se) {
-                LOG.info("Did not open database for WQM-02");
-                LOG.info(se.getMessage());
-                this.error_msg = "Could not open the database connection required. ";
-            }                                     
-        }
-        else{
-            //  No valid input stream for this service
-            this.error_msg = "No valid input parameters were found.  Check your input JSON.";
-        }                 
+    try {
+        JSONArray request = getRequest().optJSONArray("parameter");
+
+        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") ){
+        this.aoaId = getStringParam("AoAId");
+        //Get the entire aoa_geometry group as it matches the input payload for the ServiceCall class
+        this.aoaGeometry = getJSONParam("aoa_geometry");
+        JSONArray features = this.aoaGeometry.optJSONArray("features");
+        if ( this.buildPolygon( features ) ){                            
+            //this.intersectCall = new ServiceCall( this.SSURGO_INTERSECT_URI );            
+
+            this.conn = wqm.utils.WQMTools.getConnection( "ssurgo", LOG );
+            this.statement = this.conn.createStatement();                                      
+        }
+        }
+        else{
+        //  No valid input stream for this service
+        this.error_msg = "No valid input parameters were found.  Check your input JSON.";
+        }                     
+    } catch (JSONException | ServiceException | SQLException se) {
+        LOG.info("Could not proceed with preprocessing of request JSON for WQM-02");
+        LOG.info(se.getMessage());
+        this.error_msg = "Could not proceed with preprocessing of the request JSON. " + se.getMessage();
+    }           
     }
 
     @Override
-    protected String process() throws Exception {       
-        if ( ( null != this.intersectCall ) && ( !this.intersectCall.getError() ) ){
-            HashMap<String, Double> aoa_mukeyList;               
-            aoa_mukeyList = this.intersectCall.intersect( this.aoaGeometry );
+    protected String process() throws Exception { 
+    if ( (null != this.polygonData ) && (this.error_msg.isEmpty()) ){
+        //if ( ( null != this.intersectCall ) && ( !this.intersectCall.getError() ) ){
+            HashMap<String, Double> aoa_mukeyList;     
+        
+            aoa_mukeyList = this.ssurgoIntersect( this.polygonData.toWKT() );
+        //aoa_mukeyList = this.intersectCall.intersect( this.aoaGeometry );
             try{
-                if ( (!this.intersectCall.getError() ) && ( null != aoa_mukeyList) && ( aoa_mukeyList.size() > 0) ){   
+                if ( (this.error_msg.isEmpty()) && ( null != aoa_mukeyList) && ( aoa_mukeyList.size() > 0) ){   
                     ResultSet resultSet;
                     String query;
                     this.componentList = new ArrayList<>();   
@@ -250,6 +260,136 @@
         }
         putResult("soil_component_list", resultArray);
     }
+    
+    private Boolean buildPolygon( JSONArray features ) throws JSONException{
+    Boolean ret_val = false;
+    
+    if ( null != features ){
+        if ( features.length() > 0 ){
+        JSONObject feature = features.getJSONObject( 0 ).optJSONObject( "geometry" ) ;
+        if ( this.isGeometryPolygonType( feature ) ){
+            JSONArray polygon = feature.optJSONArray( "coordinates" );
+            if ( null != polygon ){                   
+            if ( polygon.length() > 0 ){
+                this.polygonData = readPolygonCoordinates( polygon.getJSONArray( 0 ) );
+                if ( null != this.polygonData ){
+                if ( !this.polygonData.isValid() ){
+                    this.error_msg += "Invalid latitude and/or longitude data contained in this polygon.  Cannot proceed with processing of this request. ";            
+                }
+                else{
+                    ret_val = true;
+                }
+                }//No else needed here, the error message will be built in readPolygonCoordinates()
+            }
+            else{
+                this.error_msg = "No coordinates found associated with the polygon specified in feature collection number:  1 . ";               
+               }               
+            }
+            else{
+            this.error_msg = "No coordinates found associated with the polygon specified in feature collection number:  1 . ";
+            }            
+        }//No else needed here, the error message will be built in isGeometryPolygonType()
+        }
+        else{
+        this.error_msg = "No geometry found associated with this feature. ";        
+        }
+    }
+    else{
+        this.error_msg = "Cannot process request JSON, missing features. ";
+    }    
+
+    return ret_val;
+    }
+    
+    private Boolean isGeometryPolygonType( JSONObject geometry ){
+    Boolean ret_val = false;
+    
+    if ( null != geometry ){
+        String geometryType;
+
+        geometryType = geometry.optString( "type" );
+        if ( !geometryType.isEmpty() ){
+        if ( geometryType.toLowerCase().equals( "polygon" ) ){
+            ret_val = true;
+        }
+        else{
+            this.error_msg = "No valid geometry type found in the feature collection number:  1 .  Looking for 'Polygon'. ";            
+        }
+        }
+        else{
+        this.error_msg = "No geometry type specified in the feature collection number:  1 . ";                    
+        }                
+    }
+    else{
+        this.error_msg = "No geometry found in the feature collection number:  1 . ";
+    }    
+    
+    return ret_val;
+    }
+    
+    private wqm.utils.WQMTools.PolygonLatLon readPolygonCoordinates( JSONArray shape ) throws JSONException{
+    wqm.utils.WQMTools.PolygonLatLon tPolygon = new wqm.utils.WQMTools.PolygonLatLon();
+    
+    if ( null != shape ){
+        for ( int k = 0; k < shape.length(); k++ ){
+        JSONArray jPoint = shape.getJSONArray( k );
+        tPolygon.add(  jPoint.getDouble( V1_0.JSON_LATITUDE ), jPoint.getDouble( V1_0.JSON_LONGITUDE ) );
+        }                    
+    }
+    else{
+        this.error_msg = "Cannot find the latitude and longitude values for this polygon. ";
+        tPolygon = null;
+    }    
+        
+    return tPolygon;
+    }
+    
+ // Returns the intersected mukey with the largest area.
+    private HashMap<String, Double> ssurgoIntersect( String WKTPolygon ){
+    String polygonText = " ST_PolygonFromText(" + WKTPolygon + ") ";
+    String query;
+    HashMap<String, Double> ret_val = null;
+    
+    try{
+        if ( null != WKTPolygon ){
+        ret_val = new HashMap<>();
+
+        query = "SELECT m.areasymbol, m.musym, m.mukey,"
+            + "st_area(st_transform(st_intersection(ST_PolygonFromTexT(" + WKTPolygon + ", 4326), m.the_geom::geography::geometry ),3541))/43560 as sizeIntersectionAcres "
+            + " FROM ssurgo.soilmu_a as m "
+            + " WHERE ST_Intersects(" + polygonText + ", m.the_geom ) "
+            + " AND st_isvalid( m.the_geom) AND st_isvalid(" + polygonText + ");";
+
+        ResultSet results = this.statement.executeQuery( query );
+
+        if ( null != results ){
+            while ( results.next() ){
+            String tKey = results.getString( "mukey" );
+            Double mapunitArea = results.getDouble( "sizeIntersectionAcres" );
+            if (!ret_val.containsKey(tKey)){
+                ret_val.put( tKey, mapunitArea );
+            }
+            }
+        }
+        else{
+            this.error_msg += "No results from the intersect query for this geometry. ";
+            if ( null != ret_val ){
+            ret_val.clear();
+            ret_val = null;
+            }
+        }
+        }
+    }
+    catch( Exception ex ){
+        this.error_msg += "Cannot continue processing this request in the intersect procedure:  " + ex.getMessage();    
+        if ( null != ret_val ){
+        ret_val.clear();
+        ret_val = null;
+        }        
+    }
+        
+    return ret_val;
+    }    
         
     
     //Inner Classes
@@ -302,7 +442,7 @@
                             HashMap<String, Double> tempMap = new HashMap<>();                
                             String mukey;
                             double aoaArea;
-                            ArrayList<String> keys = new ArrayList<String>();
+                            ArrayList<String> keys = new ArrayList<>();
                             JSONArray mukeyArray = intersectResult.getJSONArray(1).getJSONArray(0);
                             
                             for (int i = 0; i < mukeyArray.length(); i++) {