WaterLocations_WqDataPortal.java [src/WaterLocations] Revision: default Date:
package WaterLocations;
import csip.api.client.ModelDataServiceCall;
import java.io.IOException;
import java.util.ArrayList;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import utils.WebPageUtils;
/**
* Last Updated: 3-January-2022
* @author Tyler Wible
* @since 20-November-2018
* The Water Quality Data Portal covers STORET, USGS, and STEWARDS databases, more information available here:
* https://www.waterqualitydata.us/webservices_documentation/
*/
public class WaterLocations_WqDataPortal implements WaterLocationsInterface {
String database = "STORET"; //This is currently only setup for STORET stations, so it needs expand to USGS and STEWARDS
private ArrayList<String> downloadStations_orig(String minLat, String maxLat, String minLong, String maxLong, boolean keepHistoricTF) throws WaterLocationsException {
//WQX discontinued support for the bounding box search function due to upgrades in Amazon's SQL software, this may someday work again, but now right now
//Specify station website from inputs
//https://www.waterqualitydata.us/data/Station/search?providers=STORET&bBox=-105.204340919673,40.4500296208208,-105.016200050561,40.6972465847942&mimeType=tsv
String stationUrl = "https://www.waterqualitydata.us/data/Station/search?providers=STORET&bBox=" +
minLong + "," +
minLat + "," +
maxLong + "," +
maxLat + "&mimeType=tsv";
//Fetch the monitoring stations webpage for current bounding box
ArrayList<String> webpageAll = new ArrayList<>();
try {
webpageAll = WebPageUtils.downloadWebpage(stationUrl);
} catch (IOException ex) {
throw new WaterLocationsException("The was an issue extracting " + database + " station locations from the specified URl: " + stationUrl + ". " + ex.getMessage());
}
return webpageAll;
}
@Override
public ArrayList<String> downloadStations(String minLat, String maxLat, String minLong, String maxLong, boolean keepHistoricTF) throws WaterLocationsException {
//Fetch stations by list of HUC8s until the bounding box function is fixed with WQX, tcw 20210608
JSONObject boundary = new JSONObject();
try {
JSONArray features = new JSONArray();
JSONObject feature = new JSONObject();
JSONObject geometry = new JSONObject();
JSONArray coordinates1 = new JSONArray();
JSONArray coordinates2 = new JSONArray();
JSONArray coordinates3 = new JSONArray();
double minLatd = Double.parseDouble(minLat);
double maxLatd = Double.parseDouble(maxLat);
double minLongd = Double.parseDouble(minLong);
double maxLongd = Double.parseDouble(maxLong);
JSONArray array1 = new JSONArray();
array1.put(minLongd);
array1.put(maxLatd);
JSONArray array2 = new JSONArray();
array2.put(maxLongd);
array2.put(maxLatd);
JSONArray array3 = new JSONArray();
array3.put(maxLongd);
array3.put(minLatd);
JSONArray array4 = new JSONArray();
array4.put(minLongd);
array4.put(minLatd);
coordinates3.put(array1);
coordinates3.put(array2);
coordinates3.put(array3);
coordinates3.put(array4);
coordinates3.put(array1);//close the shape back at the original point
coordinates2.put(coordinates3);
coordinates1.put(coordinates2);
geometry.put("coordinates", coordinates1);
geometry.put("type", "MultiPolygon");
feature.put("geometry", geometry);
JSONObject properties = new JSONObject();
feature.put("properties", properties);
feature.put("type", "Feature");
features.put(feature);
boundary.put("features", features);
boundary.put("type", "FeatureCollection");
} catch (JSONException ex) {
throw new WaterLocationsException("The was an issue generating the boundary for minLat:" + minLat + ", maxLat:" + maxLat + ", minLong:" + minLong + ", maxLong:" + maxLong + ". " + ex.getMessage());
}
//Call csip service for HUC8 boundaries
ModelDataServiceCall res;
try {
res = new ModelDataServiceCall()
.put("huc", 8)
.put("boundary", boundary)
.url("http://csip.engr.colostate.edu:8088/csip-huc/d/huc/extent/1.0")
.withDefaultLogger()
.call();
} catch (Exception ex) {
throw new RuntimeException("Fetching huc8 boundaries");
}
//Convert list of HUC8s into strings for the url query with WQX
String huc8list = "";
if (res.serviceFinished()) {
try {
JSONArray resultList = (JSONArray) res.get("result");
resultList = resultList.getJSONArray(0);
if(resultList.length() > 0){
JSONObject hucResult = resultList.getJSONObject(0);
huc8list = hucResult.getString("huc8");
for(int i=1; i<resultList.length(); i++){
hucResult = resultList.getJSONObject(i);
huc8list += ";" + hucResult.getString("huc8");
}
}
} catch (Exception ex) {
throw new RuntimeException("donwloading");
}
} else {
throw new RuntimeException(res.getError());
}
//Fetch stations by watershed(s)
ArrayList<String> webpageAll = new ArrayList<>();
if(!huc8list.isEmpty()){
webpageAll = downloadStations_huc(huc8list, false);
}
return webpageAll;
}
private ArrayList<String> downloadStations_huc(String huc8list, boolean keepHistoricTF) throws WaterLocationsException {
//WQX discontinued support for the bounding box search function due to upgrades in Amazon's SQL software, this may someday work again, but now right now
//Specify station website from inputs
//https://www.waterqualitydata.us/data/Station/search?providers=STORET&bBox=-105.204340919673,40.4500296208208,-105.016200050561,40.6972465847942&mimeType=tsv
String stationUrl = "https://www.waterqualitydata.us/data/Station/search?providers=STORET&huc=" +
huc8list + "&mimeType=tsv";
//Fetch the monitoring stations webpage for current bounding box
ArrayList<String> webpageAll = new ArrayList<>();
try {
webpageAll = WebPageUtils.downloadWebpage(stationUrl);
} catch (IOException ex) {
throw new WaterLocationsException("The was an issue extracting " + database + " station locations from the specified URl: " + stationUrl + ". " + ex.getMessage());
}
return webpageAll;
}
@Override
public ArrayList<Station> getStations(String minLat, String maxLat, String minLong, String maxLong, boolean keepHistoricTF) throws WaterLocationsException {
//Fetch monitoring stations web page for current bounding box
ArrayList<String> webpageAll = downloadStations(minLat, maxLat, minLong, maxLong, keepHistoricTF);
ArrayList<Station> stations = new ArrayList();
for(int i=1; i<webpageAll.size(); i++){//Skip header line
String[] columns = webpageAll.get(i).split("\t");
//Keep out only the desired data
//columns[0] = Org. ID
//columns[1] = Org. Name
//columns[2] = Station ID
//columns[3] = Station Name
//columns[4] = Station Type (River/Stream, Reservoir)
//columns[7] = Drainage Area
//columns[8] = Drainage Area Units
//columns[11] = Latitude
//columns[12] = Longitude
//columns[17] = Horizontal Datum
//columns[18] = Elevation
//columns[19] = Elevation Units
Station currentStation = new Station(database + "-" + columns[2]);
currentStation.SetOrgId(columns[0]);
currentStation.SetOrgName(columns[1]);
currentStation.SetStationId(columns[2]);
currentStation.SetStationName(columns[3]);
currentStation.SetStationType(columns[4]);
currentStation.SetDrainageArea(columns[7]);
currentStation.SetDrainageAreaUnits(columns[8]);
currentStation.SetLatitude(columns[11]);
currentStation.SetLongitude(columns[12]);
currentStation.SetHorizontalDatum(columns[17]);
currentStation.SetElevation(columns[18]);
currentStation.SetElevationUnits(columns[19]);
stations.add(currentStation);
}
return stations;
}
}