V1_0.java [src/java/m/svap/svap09_svapgradient] Revision: default Date:
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API, and application suite.
*
* 2012-2017, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package m.svap.svap09_svapgradient;
import com.vividsolutions.jts.geom.Coordinate;
import csip.Config;
import csip.annotations.Polling;
import csip.annotations.Resource;
import csip.ModelDataService;
import csip.ServiceException;
import gisobjects.GISObject;
import gisobjects.GISObjectException;
import gisobjects.GISObjectFactory;
import gisobjects.db.GISEngine;
import static gisobjects.db.GISEngineFactory.createGISEngine;
import gisobjects.vector.GIS_FeatureCollection;
import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONException;
import svap.utils.DBResources;
import static svap.utils.DBResources.CRDB;
import svap.utils.ExternalService;
import svap.utils.SVAPUtils;
/**
* SVAP-09: Calculate Stream Gradient for Field Assessment
*
* @author Rumpal Sidhu
* @version 1.0
*/
@Name("SVAP-09: Calculate Stream Gradient for Field Assessment")
@Description("This service computes the gradient of the USGS NHD stream flowline"
+ " nearest the point representing the stream reach to be evaluated by SVAP.")
@Path("m/svap/svapgradient/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
public class V1_0 extends ModelDataService {
private JSONObject assessmentLocation;
private int assessmentId;
private GISObject streamGISGeometry;
private double streamLength;
private double startElevation;
private double endElevation;
private double gradient;
@Override
protected void preProcess() throws ServiceException {
assessmentLocation = parameter().getJSON("assessment_location");
assessmentId = parameter().getInt("assessment_id");
}
@Override
protected void doProcess() throws ServiceException, JSONException, URISyntaxException, IOException, SQLException, GISObjectException, Exception {
JSONObject huc12Response = SVAPUtils.getHUC12Data(assessmentLocation, "json");
String hucGeometry = huc12Response.getJSONArray("features").getJSONObject(0).getJSONObject("geometry").toString();
JSONObject nhdFlowlineResponse = SVAPUtils.getNHDFlowlineData(hucGeometry, "geojson", "FCODE = 46000 OR FCODE = 46003 OR FCODE = 46006 OR FCODE = 46007");
findNearestStreamSegment(nhdFlowlineResponse);
if (streamGISGeometry == null) {
throw new ServiceException("Problem in finding the nearest stream segment.");
} else {
Coordinate[] coordArray = streamGISGeometry.getGeometry().getCoordinates();
startElevation = getElevation(coordArray[0].y, coordArray[0].x);
endElevation = getElevation(coordArray[coordArray.length - 1].y, coordArray[coordArray.length - 1].x);
gradient = Math.abs(startElevation - endElevation) / (streamLength);
}
}
private void findNearestStreamSegment(JSONObject streamGeometry) throws SQLException, GISObjectException, JSONException, IOException, ServiceException {
try (Connection connection = resources().getJDBC(CRDB);
GISEngine gisEngine = createGISEngine(connection);) {
GISObject assessmentPoint = GISObjectFactory.createGISObject(assessmentLocation, gisEngine);
GISObject gisStreamGeometry = GISObjectFactory.createGISObject(streamGeometry, gisEngine);
if (GISObject.GISObjectType.featurecollection == gisStreamGeometry.getType()) {
SortedMap<Double, Integer> distanceMap = new TreeMap();
GIS_FeatureCollection gfc = (GIS_FeatureCollection) gisStreamGeometry;
for (int i = 0; i < gfc.getFeatureCount(); i++) {
GISObject stream = gfc.getGeometry(i);
double distance = assessmentPoint.distanceTo(stream);
distanceMap.put(distance, i);
}
int index = distanceMap.get(distanceMap.firstKey());
streamGISGeometry = gfc.getGeometry(index);
streamLength = Double.parseDouble(gfc.getFeatureAttribute(index, "LENGTHKM")) * 1000.0;
}
}
}
private double getElevation(double latitude, double longitude) throws Exception {
String requestUrl = Config.getString("service.csip.epqs.url") + "x=" + longitude + "&y=" + latitude + "&units=Meters&output=json";
JSONObject responseObj = new JSONObject(new ExternalService().doGET(requestUrl));
return responseObj.getJSONObject("USGS_Elevation_Point_Query_Service").getJSONObject("Elevation_Query").getDouble("Elevation");
}
@Override
protected void postProcess() throws ServiceException {
results().put("assessment_id", assessmentId, "Assessment Identifier");
results().put("stream_geometry", streamGISGeometry.toWKT(), "Stream Geometry");
results().put("stream_length", streamLength, "Stream flowline length", "m");
results().put("elevation_1", startElevation, "Elevation of Stream Flowline Endpoint", "m");
results().put("elevation_2", endElevation, "Elevation of Stream Flowline Endpoint", "m");
results().put("gradient", gradient, "Gradient of the Stream");
}
}