GroundwaterData_USGSWell.java [src/WaterData] Revision: default  Date:
package WaterData;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import utils.WebPageUtils;

/**
* Last Updated: 20-November-2018
* @author Tyler Wible
* @since 3-November-2014
*/
public class GroundwaterData_USGSWell implements GroundwaterDataInterface{
    public String database = "USGSWell";

    @Override
    public ArrayList<String> extractWaterQualityData_raw(String stationId, String startDate, String endDate, String wqTest) throws WaterDataException {
        //Specify groundwater water quality website from inputs
        String wqUrl = "https://nwis.waterdata.usgs.gov/nwis/qwdata/?site_no=" + stationId + "&agency_cd=USGS&format=rdb";
        
        //Fetch the water quality data webpage for the current USGS station
        ArrayList<String> webpageAll = new ArrayList<>();
        try {
            webpageAll = WebPageUtils.downloadWebpage(wqUrl);
        } catch (IOException ex) {
            throw new WaterDataException("The was an issue extracting " + database + " water quality data from the specified URl: " + wqUrl + "." + ex.getMessage());
        }
        return webpageAll;
    }

    @Override
    public String[][] extractWaterQualityData_formatted(String stationId, String startDate, String endDate, String wqTest) throws WaterDataException {
        //Fetch water quality data
        ArrayList<String> webpageAll = extractWaterQualityData_raw(stationId, startDate, endDate, wqTest);
        
        //Extract data from the result webpage
        Iterator<String> iterate = webpageAll.iterator( );
        ArrayList<String> stationData = new ArrayList<>();
        while(iterate.hasNext()){
            String temp_pageData = (String) iterate.next();
            String[] f = temp_pageData.split("\t");

            if ( (f.length >= 15) && (f[0].equals("USGS")) ) {
                String WQSample_code = f[12];
                String WQSample_result = f[14];
                boolean A = WQSample_code.equals("");
                boolean B = WQSample_result.equals("");
                if (!A && !B){
                    //Count only the rows which contain the desired values of "agency_cd	...
                    //site_no	sample_dt	sample_tm	sample_end_dt	sample_end_tm	...
                    //sample_start_time_datum_cd	tm_datum_rlbty_cd	coll_ent_cd	...
                    //medium_cd	tu_id	body_part_id	parm_cd	remark_cd	result_va	...
                    //val_qual_tx	meth_cd	dqi_cd	rpt_lev_va	rpt_lev_cd	lab_std_va	anl_ent_cd"

                    //Pull out only the data needed to pass between sub-functions
                    //f[1] = stationId
                    //f[2] = date
                    //f[3] = time
                    //f[12] = water quality test code
                    //f[14] = water quality test value
                    stationData.add(f[2] + "\t" + f[12] + "\t" + f[14]);
                }
            }
        }
        
        //Extract just the 5 digit USGS water quality code from: "00600 Total nitrogen, water, unfiltered, milligrams per liter -- mg/L" (format: "5-digit test-name -- units")
        if(wqTest.length() > 5){
            wqTest = wqTest.substring(0,5);
        }

        //Determine which data to keep: 1) is it the requested wq test code 2) is it in the specified begin/end dates
        int ctr = 0;
        for(int i=0; i<stationData.size(); i++){
            String[] columns = stationData.get(i).split("\t");
            if(columns[1].equalsIgnoreCase(wqTest) &&
              (columns[0].compareTo(startDate) >= 0) && (columns[0].compareTo(endDate) <= 0)){
                ctr++;
            }
        }

        //Reformat data
        String[][] returnArray = new String[ctr][2];
        ctr=0;
        for(int i=0; i<stationData.size(); i++){
            String[] columns = stationData.get(i).split("\t");
            if(columns[1].equalsIgnoreCase(wqTest) &&
              (columns[0].compareTo(startDate) >= 0) && (columns[0].compareTo(endDate) <= 0)){
                returnArray[ctr][0] = columns[0];//date
                returnArray[ctr][1] = columns[2];//WQ test result value
                ctr++;
            }
        }
        return returnArray;
    }

    @Override
    public ArrayList<String> extractWaterTableElevation_raw(String stationId, String startDate, String endDate) throws WaterDataException {
        //Specify groundwater elevation (height) website from inputs
        //https://waterdata.usgs.gov/nwis/dv?cb_62611=on&format=rdb&site_no=404450103013501&referred_module=sw&period=&begin_date=1900-01-01&end_date=2015-08-20
        String elevUrl = "https://waterdata.usgs.gov/nwis/dv?cb_62611=on&format=rdb&site_no=" +
                stationId + "&referred_module=sw&period=&begin_date=" + startDate + "&end_date=" + endDate;
        
        //Fetch the groundwater elevation (height) data webpage for the current USGS station
        ArrayList<String> webpageAll = new ArrayList<>();
        try {
            webpageAll = WebPageUtils.downloadWebpage(elevUrl);
        } catch (IOException ex) {
            throw new WaterDataException("The was an issue extracting " + database + " water table elevation data from the specified URl: " + elevUrl + "." + ex.getMessage());
        }
        return webpageAll;
    }

    @Override
    public String[][] extractWaterTableElevation_formatted(String stationId, String startDate, String endDate) throws WaterDataException {
        //Fetch water quality data
        ArrayList<String> webpageAll = extractWaterTableElevation_raw(stationId, startDate, endDate);
        
        //Extract data from the result webpage
        Iterator<String> iterate = webpageAll.iterator( );
        ArrayList<String> textData = new ArrayList<String>();
        while(iterate.hasNext()){
            String temp_pageData = (String) iterate.next();
            String[] f = temp_pageData.split("\t");

            if ((f.length >= 8) && ("USGS".equals(f[0]))) {
                boolean Ice = f[7].equalsIgnoreCase("Ice");
                boolean Ssn = f[7].equalsIgnoreCase("Ssn");
                boolean Dis = f[7].equalsIgnoreCase("Dis");
                boolean rat = f[7].equalsIgnoreCase("Rat");
                boolean eqp = f[7].equalsIgnoreCase("Eqp");
                boolean other = f[7].equalsIgnoreCase("***");
                boolean blank = f[7].equalsIgnoreCase("");
                if (!Ice && !Ssn && !Dis && !rat && !eqp && !other && !blank) {
                    //Pull out only the data needed to pass between sub-functions
                    //f[1] = StationId
                    //f[2] = Date
                    //f[3] = FlowValue
                    textData.add(f[1] + "\t" + f[2] + "\t" + f[7]);
                }
            }
        }

        //Reformat data
        String[][] returnArray = new String[textData.size()][2];
        for(int i=0; i<returnArray.length; i++){
            String[] currentColumns = textData.get(i).split("\t");
            //currentColumns[0] = stationId
            //currentColumns[1] = date
            //currentColumns[2] = value
            returnArray[i][0] = currentColumns[1];
            returnArray[i][1] = currentColumns[2];
        }
        return returnArray;
    }

    @Override
    public ArrayList<String> extractDepthToWaterTable_raw(String stationId, String startDate, String endDate) throws WaterDataException {
        //Specify depth to groundwater  website from inputs
        //https://waterdata.usgs.gov/nwis/dv?cb_72019=on&format=rdb&site_no=404915077500801&referred_module=sw&period=&begin_date=1900-01-01&end_date=2015-08-20
        String depthUrl = "https://waterdata.usgs.gov/nwis/dv?cb_72019=on&format=rdb&site_no=" +
                stationId + "&referred_module=sw&period=&begin_date=" + startDate + "&end_date=" + endDate;
        
        //Fetch the depth to groundwater webpage for the current USGS station
        ArrayList<String> webpageAll = new ArrayList<>();
        try {
            webpageAll = WebPageUtils.downloadWebpage(depthUrl);
        } catch (IOException ex) {
            throw new WaterDataException("The was an issue extracting " + database + " water table elevation data from the specified URl: " + depthUrl + "." + ex.getMessage());
        }
        return webpageAll;
    }

    @Override
    public String[][] extractDepthToWaterTable_formatted(String stationId, String startDate, String endDate) throws WaterDataException {
        //Fetch water quality data
        ArrayList<String> webpageAll = extractDepthToWaterTable_raw(stationId, startDate, endDate);
        
        //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<>();
        while(iterate.hasNext()){
            String temp_pageData = (String) iterate.next();
            String[] f = temp_pageData.split("\t");

            if ((f.length >= 4) && ("USGS".equals(f[0]))) {
                boolean Ice = f[3].equalsIgnoreCase("Ice");
                boolean Ssn = f[3].equalsIgnoreCase("Ssn");
                boolean Dis = f[3].equalsIgnoreCase("Dis");
                boolean rat = f[3].equalsIgnoreCase("Rat");
                boolean eqp = f[3].equalsIgnoreCase("Eqp");
                boolean other = f[3].equalsIgnoreCase("***");
                boolean blank = f[3].equalsIgnoreCase("");
                if (!Ice && !Ssn && !Dis && !rat && !eqp && !other && !blank) {
                    //Pull out only the data needed to pass between sub-functions
                    //f[1] = StationId
                    //f[2] = Date
                    //f[3] = FlowValue
                    textData.add(f[1] + "\t" + f[2] + "\t" + f[3]);
                }
            }
        }

        //Reformat data
        String[][] returnArray = new String[textData.size()][2];
        for(int i=0; i<returnArray.length; i++){
            String[] currentColumns = textData.get(i).split("\t");
            //currentColumns[0] = stationId
            //currentColumns[1] = date
            //currentColumns[2] = value
            returnArray[i][0] = currentColumns[1];
            returnArray[i][1] = currentColumns[2];
        }
        return returnArray;
    }
}