CDSN_Data.java [src/java/m/cfa] Revision: 8270e78a57e94b386f731fcde8b76e6c9ef568d9 Date: Thu Sep 15 13:55:14 MDT 2016
package m.cfa;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
/**
* Last Updated: 13-September-2016
* @author Tyler Wible
* @since 19-April-2016
*/
public class CDSN_Data {
/**
* Interfaces with the Colorado Data Sharing Network (CDSN) restful web services
* for a set of search parameters for available stations
* @param resultSummaryTF a boolean flag for whether a result summary
* should be included with the station search
* @param minLat the minimum latitude for the station search
* @param maxLat the maximum latitude for the station search
* @param minLong the minimum longitude the station search
* @param maxLong the maximum longitude for the station search
* @return an ArrayList<String> containing the web service result(s)
*/
private static ArrayList<String> downloadCDSNstations(boolean resultSummaryTF,
String minLat,
String maxLat,
String minLong,
String maxLong) throws IOException{
//Specify station search url from inputs
//http://awqmsws.goldsystems.com/api/MonitoringLocationsVer1?ContentType=json&CountyName=BROADWATER
String cdsnStationWebsite = "http://awqmsws.goldsystems.com/api/MonitoringLocationsVer1?ContentType=json&IncludeResultSummary="+ String.valueOf(resultSummaryTF) +
"&MonitoringLocationType=River%" + //Comment out this line to search for more than river/stream stations
"&MinimumLatitude=" + minLat + "&MaximumLatitude=" + maxLat + "&MinimumLongitude=" + minLong + "&MaximumLongitude=" + maxLong;
//ContentType (xml, json)
//CountyName
//Huc8
//Huc12
//IncludeResultSummary (true, false)
//MinimumLatitude
//MaximumLatitude
//MinimumLongitude
//MaximumLongitude
//MonitoringLocationIdentifiersCsv
//MonitoringLocationType (River/Stream, Landfill, and lots more)
//OrganizationIdentifiersCsv
//StateCode (CO)
//WatershedManagementUnit (?)
//Open the provided website
ArrayList<String> pageData = new ArrayList<>();
try{
URL webpage = new URL(cdsnStationWebsite);
URLConnection yc = webpage.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
//Read out all of the webpage out into an ArrayList<String>
String inputLine;
while((inputLine = in.readLine()) != null){
pageData.add(inputLine);
}
in.close();
}catch(FileNotFoundException e){
//Leave array blank for later error messages pasted onto the user
}
return pageData;
}
/**
* Interfaces with the Colorado Data Sharing Network (CDSN) restful web services
* for a set of search parameters for available stations
* @param resultSummaryTF a boolean flag for whether a result summary
* should be included with the station search
* @param minLat the minimum latitude for the station search
* @param maxLat the maximum latitude for the station search
* @param minLong the minimum longitude the station search
* @param maxLong the maximum longitude for the station search
* @return JSONArray of CDSN stations within the bounding lat/long box
* @throws IOException
* @throws org.codehaus.jettison.json.JSONException
*/
public static JSONArray getCDSNstations(boolean resultSummaryTF,
String minLat,
String maxLat,
String minLong,
String maxLong) throws IOException, JSONException {
//Get CDSN stations
ArrayList<String> stationList = downloadCDSNstations(resultSummaryTF, minLat, maxLat, minLong, maxLong);
JSONArray stations = new JSONArray("[]");
if(stationList.size() > 0){
//parse the json string into a JSONArray and the object(s) within it
stations = new JSONArray(stationList.get(0));
}
return stations;
}
/**
* Interfaces with the Colorado Data Sharing Network (CDSN) restful web services
* for a set of search parameters for available stations
* @param organizationID The ID for the supervising organization for the station within STORET
* @param stationID station ID of the current station, used to search the STORET databes
* @param wq_test The word 'flow' or the formatted name for the water quality test being used, Format is: '00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L' = '5-digit-USGS-water-quality-test-code test-name -- units'
* @param beginDate the used defined begin date of search (yyyy-mm-dd)
* @param endDate the user defined end date of search (yyyy-mm-dd)
* @return an ArrayList<String> containing the web service result(s)
*/
private static ArrayList<String> downloadCDSNdata(String organizationID,
String stationID,
String wq_test,
String beginDate,
String endDate) throws IOException, ParseException{
//If no date input, make it the maximum of available data
if(beginDate == null || beginDate.equalsIgnoreCase("")){
beginDate = "1900-01-01";
}
if(endDate == null || endDate.equalsIgnoreCase("")){
// Pull current date for upper limit of data search
DateFormat desiredDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date currentDate = new Date();
endDate = desiredDateFormat.format(currentDate);
}
//Reformat dates for CDSN format only
String minDate = beginDate.substring(5,7) + "-" + beginDate.substring(8) + "-" + beginDate.substring(0,4);
String maxDate = endDate.substring(5,7) + "-" + endDate.substring(8) + "-" + endDate.substring(0,4);
//Specify data search url from inputs
//http://awqmsws.goldsystems.com/api/ResultsVer1?ContentType=json&OrganizationIdentifiersCsv=CITYFTCO_WQX&MonitoringLocationIdentifiersCsv=1EFF&MinDate=01-01-1900&MaxDate=04-25-2016&Characteristic=Ammonia-nitrogen
String cdsnDataWebsite = "http://awqmsws.goldsystems.com/api/ResultsVer1?ContentType=json" +
"&OrganizationIdentifiersCsv=" + organizationID + "&MonitoringLocationIdentifiersCsv=" + stationID +
"&MinDate=" + minDate + "&MaxDate=" + maxDate;
if(!wq_test.equalsIgnoreCase("All")){
String characteristic_name = wq_test;
if(wq_test.length() > 5){
//extract "Ammonia-nitrogen as N" from "00625 Ammonia-nitrogen as N -- mg/L"
characteristic_name = wq_test.substring(6, wq_test.indexOf("--") - 1);
}
cdsnDataWebsite = cdsnDataWebsite + "&Characteristic=" + characteristic_name;
}
//ActivityType (lots)
//Characteristic (lots)
//ContentType (xml, json)
//CountyName
//Huc8
//Huc12
//MaxDate (mm/dd/yyyy or mm-dd-yyyy)
//MediaName (Air, Water, Biological, Soil, Sediment, Other, Tissue, Habitat)
//Media SubdivisionName (lots)
//MinDate (mm/dd/yyyy or mm-dd-yyyy)
//MonitoringLocationIdentifiersCsv ("id1, id2, id3")
//MonitoringLocationType (lots)
//OrganizationIdentifiersCsv ("id1, id2, id3")
//ProjectIdentifier (lots)
//StateCode (CO)
//WaterBodyName (lots)
//WatershedManagementUnit (lots)
ArrayList<String> pageData = new ArrayList<>();
try{
//Open the provided website
URL webpage = new URL(cdsnDataWebsite);
URLConnection yc = webpage.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
//Read out all of the webpage out into an ArrayList<String>
String inputLine;
while((inputLine = in.readLine()) != null){
pageData.add(inputLine);
}
in.close();
}catch (FileNotFoundException e){
//Leave array blank for later error messages pasted onto the user
}
return pageData;
}
/**
* Interfaces with the STORET download website and searches for the data for a specific station and
* read it out into a variable depending on what data was requested
* @param organizationID The ID for the supervising organization for the station within STORET
* @param stationID station ID of the current station, used to search the STORET databes
* @param wq_test The word 'flow' or the formatted name for the water quality test being used, Format is: '00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L' = '5-digit-USGS-water-quality-test-code test-name -- units'
* @param beginDate the used defined begin date of search (yyyy-mm-dd)
* @param endDate the user defined end date of search (yyyy-mm-dd)
* @return a Object[][] containing:
* [0] = an ArrayList containing the data query from the web service
* [1] = a String[][] containing flow or water quality data: column1 = date(yyyy-mm-dd), column2 = flowValue
* [2] = start data of the data (yyyy-mm-dd)
* [3] = end data of the data (yyyy-mm-dd)
* @throws java.io.IOException
* @throws java.text.ParseException
* @throws org.codehaus.jettison.json.JSONException
*/
public static Object[] getCDSNdata(String organizationID,
String stationID,
String wq_test,
String beginDate,
String endDate) throws IOException, ParseException, JSONException {
//Get CDSN station data
ArrayList<String> dataList = downloadCDSNdata(organizationID, stationID, wq_test, beginDate, endDate);
//http://awqmsws.goldsystems.com/api/ResultsVer1?ContentType=json&OrganizationIdentifiersCsv=CITYFTCO_WQX&MonitoringLocationIdentifiersCsv=1EFF&Characteristic=Ammonia-nitrogen&MinDate=01-01-1900&MaxDate=04-25-2016
//Parse results
ArrayList<String> resultFileContents = new ArrayList<>();
if(dataList.size() > 0){
resultFileContents.add("OrganizationIdentifier\tMonitoringLocationIdentifier\tMediaSubdivisionName\tActivityIdentifier\tStartDate\tStartTime\tMediaName\tActivityType\tCharacteristicName\tSampleFraction\tValueType\tStatus\tResultValue\tResultUnit\tAnalyticalMethodContext\tAnalyticalMethodIdentifier\tDetectionCondition\tQualifierCode");
//parse the json string into a JSONArray and the object(s) within it
JSONArray cdsnResponse = new JSONArray(dataList.get(0));
for(int i=0; i<cdsnResponse.length(); i++){
JSONObject currentActivity = cdsnResponse.getJSONObject(i);
String orgID = currentActivity.getString("OrganizationIdentifier");
//String stationID = currentActivity.getString("MonitoringLocationIdentifier");
String mediaSubdivision = currentActivity.getString("MediaSubdivisionName");
String activityID = currentActivity.getString("ActivityIdentifier");
String date = currentActivity.getString("StartDate");
String time = currentActivity.getString("StartTime");
String mediaName = currentActivity.getString("MediaName");
String activityType = currentActivity.getString("ActivityType");
//Parse 'result' JSONArray within each 'activity' JSONObject
JSONArray resultArray = currentActivity.getJSONArray("Results");
for(int j=0; j<resultArray.length(); j++){
JSONObject currentResult = resultArray.getJSONObject(j);
String characteristic = currentResult.getString("CharacteristicName");
String fraction = currentResult.getString("SampleFraction");
String valueType = currentResult.getString("ValueType");
String status = currentResult.getString("Status");
String resultValue = currentResult.getString("ResultValue");
String units = currentResult.getString("ResultUnit");
String methodContext = currentResult.getString("AnalyticalMethodContext");
String methodIdentifier = currentResult.getString("AnalyticalMethodIdentifier");
String detectionCondition = currentResult.getString("DetectionCondition");
String QualifierCode = currentResult.getString("QualifierCode");
//Save results
resultFileContents.add(orgID + "\t"+stationID+"\t"+mediaSubdivision+"\t"+activityID+"\t"+
date+"\t"+time+"\t"+mediaName+"\t"+activityType+"\t"+characteristic+"\t"+
fraction+"\t"+valueType+"\t"+status+"\t"+resultValue+"\t"+units+"\t"+
methodContext+"\t"+methodIdentifier+"\t"+detectionCondition+"\t"+QualifierCode);
}
}
}else{
resultFileContents.add("No " + wq_test + " data found for CDSN Station: " + stationID + " by: " + organizationID);
}
//convert Array list into String[][] array (column1 = date, column2 = value)
String[][] stringArray = new String[resultFileContents.size() - 1][2];
for(int i=1; i<resultFileContents.size(); i++){
String[] currentColumns = resultFileContents.get(i).split("\t");
stringArray[i-1][0] = currentColumns[4]; //date
stringArray[i-1][1] = currentColumns[12]; //value
}
//Save analysis results
String start = "-1";
String end = "-1";
if(stringArray.length > 0){
start = stringArray[0][0];
end = stringArray[stringArray.length - 1][0];
}
Object[] returnArray = {resultFileContents, stringArray, start, end};
return returnArray;
}
}