SNOTEL_Data.java [src/java/datadownload] Revision: default  Date:
package datadownload;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Last Updated: 29-December-2016
 * @author Tyler Wible
 * @since 7-July-2014
 */
public class SNOTEL_Data {
    /**
     * Finds data for the specified station out of the SNOWTEL Database
     * @param stationID  the station ID number for the SNOTEL station
     * @param state  the name of the state in which the SNOTEL station exists
     * @param dataType
     * @return  a String[][] containing column1 = date(if dataType = "daily": yyyy-MM-dd format, if dataType = "hourly": yyyy-MM-dd HH:mm format), column2 = flowValue
     * @throws Exception 
     */
    public static Object[] getSNOTELdata(String stationID, String state, String dataType) throws Exception {
         //Get the webpage of data for the USGS flow station
        ArrayList<String> webpageAll = DownloadSNOTELwebpage(stationID, state);
        
        //Pull out new arraylist of only the desired data from the arraylist to return as the web page result
        Iterator<String> iterate = webpageAll.iterator( );
        ArrayList<String> textData = new ArrayList<String>();
        int dataIndex = 0;
        while(iterate.hasNext()){
            String temp_pageData = (String) iterate.next();
            String[] f = temp_pageData.split(",");
            if(!temp_pageData.contains("#") && (f[0].equals("Date"))){
                //If in header of data, determine which column to get:
                //Date
                //Snow Water Equivalent (in)
                //Precipitation Accumulation (in)
                //Air Temperature Maximum (degF)
                //Air Temperature Minimum (degF)
                //Air Temperature Average (degF)
                //Precipitation Increment (in)
		for(int i=0; i<f.length; i++){
                    if(dataType.equalsIgnoreCase("snow") && f[i].contains("Snow Water Equivalent")){
                        dataIndex = i;
                    }else if(dataType.equalsIgnoreCase("precip_cummulative") && f[i].contains("Precipitation Accumulation")){
                        dataIndex = i;
                    }else if(dataType.equalsIgnoreCase("temp_max") && f[i].contains("Air Temperature Maximum")){
                        dataIndex = i;
                    }else if(dataType.equalsIgnoreCase("temp_min") && f[i].contains("Air Temperature Minimum")){
                        dataIndex = i;
                    }else if(dataType.equalsIgnoreCase("temp_ave") && f[i].contains("Air Temperature Average")){
                        dataIndex = i;
                    }else if(dataType.equalsIgnoreCase("precip_incremental") && f[i].contains("Precipitation Increment")){
                        dataIndex = i;
                    }
		}
                
            }else if(!temp_pageData.contains("#") && (!f[0].equals("Date"))){
                //Pull desired data
                if(dataIndex > 0 && f.length > dataIndex && !f[dataIndex].equalsIgnoreCase("")){
                    textData.add(f[0] + "\t" + f[dataIndex]);
                }
            }
        }

        //convert Array list into String[][] array (column1 = date, column2 = value)
        String[][] stringArray = new String[textData.size()][2];
        for(int i=0; i<stringArray.length; i++){
            String[] currentColumns = textData.get(i).split("\t");
            //currentColumns[0] = date
            //currentColumns[1] = value
            stringArray[i][0] = currentColumns[0];
            stringArray[i][1] = currentColumns[1];
        }
        
        //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 = {webpageAll, stringArray, start, end};
        return returnArray;
    }
    /**
     * Opens a web connection to USGS and returns the contents of a search for all flow data for the specific station and date range
     * @param stationID  the USGS station ID for the current station
     * @param state  the name of the state in which the SNOTEL station exists
     * @return an ArrayList<String> containing the results of the search for flow data using the above inputs
     * @throws IOException
     */
    public static ArrayList<String> DownloadSNOTELwebpage(String stationID, String state) throws IOException {
        //Specify flow website from inputs
        //https://www.wcc.sc.egov.usda.gov/reportGenerator/view_csv/customSingleStationReport/daily/946:AK:SNTL%7Cid=%22%22%7Cname/POR_BEGIN,POR_END/WTEQ::value,PREC::value,TMAX::value,TMIN::value,TAVG::value,PRCP::value
        state = changeStateCode(state, true);
        String website = "https://wcc.sc.egov.usda.gov/reportGenerator/view_csv/customSingleStationReport/daily/"
                + stationID + ":"
                + state + ":SNTL%7Cid=%22%22%7Cname/POR_BEGIN,POR_END/WTEQ::value,PREC::value,TMAX::value,TMIN::value,TAVG::value,PRCP::value";
        
        //Open the provided website
        URL webpage = new URL(website);
        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;
        ArrayList<String> pageData = new ArrayList<String>( );

        while((inputLine = in.readLine()) != null){
            pageData.add(inputLine);
        }
        in.close();

        return pageData;
    }
    private static String changeStateCode(String incomingState, boolean changeToStateCode){
        String[][] stateList = {{"Alaska", "ak"},
				{"Arizona", "az"},
				{"California", "ca"},
				{"Colorado", "co"},
				{"Idaho", "id"},
				{"Montana", "mt"},
				{"Nevada", "nv"},
				{"New Mexico", "nm"},
				{"Oregon", "or"},
				{"South Dakota", "sd"},
				{"Utah", "ut"},
				{"Washington", "wa"},
				{"Wyoming", "wy"}};
        
        String outgoingState = "";
        for(int i=0; i<stateList.length; i++){
            if(changeToStateCode){
                //Take the provided state and get it's state code
                if(stateList[i][0].equalsIgnoreCase(incomingState)){
                    outgoingState = stateList[i][1];
                    break;
                }
            }else{
                //Take the provided state code and get it's state name
                if(stateList[i][1].equalsIgnoreCase(incomingState)){
                    outgoingState = stateList[i][0];
                    break;
                }
            }
        }
        return outgoingState;
    }
}