@@ -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++) { |