NOAA Web Site Link Tides and Currents Home Page Transparent placeholder image
CO-OPS         IOOS Data Portal         Take Our Survey
banner graphic

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HarmonicConstituentsGetter {

    public static void main(String[] args) {
        //CO-OPS Sensor Observation Service (SOS) URL
        String sosUrl = "https://opendap.co-ops.nos.noaa.gov/ioos-dif-sos/SOS";
        String baseUrl = sosUrl + "?service=SOS&request=GetObservation&version=1.0.0&observedProperty=harmonic_constituents";

        /*
         * The user can modify the local directory where the downloaded data files can be stored, 
         * the stations IDs, the unit, the time zone, and the preferred format of those data files.
         *
         */
        //Local directory that data files will be stored to
        String saveToYourLocalDir = "C:\\temp\\sosdata\\";
        //Station Ids
        String stationsIds[] = {"8454049", "8637689", "9754228", "9759394"};
        //Data unit options: Meters, Feet, also can be null
        String unit = "";
        //Time zone options: GMT, LST, also can be null
        String timeZone = "";        
        //Response format options: csv, tsv, xml, kml 
        String responseFormat = "csv";

        String url;
        URL dataUrl;
        String fileName;

        try {
            String responseMIMEType = getResponseMIMEType(responseFormat);
            for (int i = 0; i < stationsIds.length; i++) {
                if (!isValidNwlonStationId(stationsIds[i])) {
                    throw new IOException(" Wrong Station ID: " + stationsIds[i] + ", please enter a valid station ID.");
                }

                url = baseUrl + "&offering=urn:ioos:station:NOAA.NOS.CO-OPS:" + stationsIds[i]
                        + "&responseFormat=" + urlEncode(responseMIMEType);

                if (unit != null && unit.length() != 0) {
                    if (unit.equalsIgnoreCase("Meters") || unit.equalsIgnoreCase("Feet")) {
                        url += "&unit=" + unit;
                    } else {
                        throw new IOException(" Wrong Unit: please enter a valid unit string.");
                    }
                }

                if (timeZone != null && timeZone.length() != 0) {
                    if (timeZone.equalsIgnoreCase("GMT") || timeZone.equalsIgnoreCase("LST")) {
                        url += "&timeZone=" + timeZone;
                    } else {
                        throw new IOException(" Wrong Time Zone: Please enter a valid time zone string.");
                    }
                }

                /*
                 * The end result of that URL should look like this;
                 * https://opendap.co-ops.nos.noaa.gov/ioos-dif-sos/SOS?service=SOS&request=GetObservation&version=1.0.0
                 * &observedProperty=harmonic_constituents&offering=urn:ioos:station:NOAA.NOS.CO-OPS:8454049
                 * &responseFormat=text%2Fcsv&unit=Meters&timeZone=GMT
                 */

                dataUrl = new URL(url);
                fileName = getFileName(stationsIds[i], responseFormat, saveToYourLocalDir);
                getResource(dataUrl, fileName);
            }
        } catch (Exception e) {
            System.err.println("ERROR: ******* " + e.getMessage());
        }
    }

    /**
     * Check if string is a valid NWLON station ID (consist of 7 digits).
     *
     * @param stationId string to check
     * @return boolean if consists only of numbers
     */
    public static boolean isValidNwlonStationId(String stationId) {
        Pattern regexWL = Pattern.compile("^[1-9][0-9]{6}$");

        if (stationId == null) {
            return false;
        } else {
            stationId = stationId.trim();
            Matcher mWL = regexWL.matcher(stationId);

            if (mWL.matches()) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * Get the MIME type of response format.
     *
     * @param formatOption response format
     * @return MIME Type of response format
     */
    private static String getResponseMIMEType(String formatOption) throws IOException {
        String responseMIMEType = "text/csv";
        if (formatOption.equalsIgnoreCase("csv")) {
            responseMIMEType = "text/csv";
        } else if (formatOption.equalsIgnoreCase("tsv")) {
            responseMIMEType = "text/tab-separated-values";
        } else if (formatOption.equalsIgnoreCase("kml")) {
            responseMIMEType = "application/vnd.google-earth.kml+xml";
        } else if (formatOption.equalsIgnoreCase("xml")) {
            responseMIMEType = "text/xml;schema=\"ioos/0.6.1\"";
        } else {
            throw new IOException(" Wrong Response Format: please enter a valid response format string.");
        }
        return responseMIMEType;
    }

    /**
     * Encode a URL string.
     *
     * @param inString string to encode
     * @return encoded string
     */
    private static String urlEncode(String inString) {
        if (inString != null) {
            inString = inString.replace("/", "%2F");
            inString = inString.replace("+", "%2B");
        }
        return inString;
    }

    /**
     * Get the name of data file that will be saved to local hard disk.
     *
     * @param stationId station ID
     * @param responseFormat response format
     * @param saveToYourLocalDir local directory that data files will be stored
     * to
     * @return new file name to be created on local hard disk
     */
    public static String getFileName(String stationId, String responseFormat, String saveToYourLocalDir) {
        String fileName = saveToYourLocalDir + "harmonic_constituents_" + stationId + "." + responseFormat.toLowerCase();
        return fileName;
    }

    /**
     * Fetch the files from the http connection and write it to a local file.
     *
     * @param url URL to fetch data
     * @param fileName new file to be created on local hard disk
     */
    public static void getResource(URL url, String fileName) {
        HttpURLConnection huc = null;
        BufferedInputStream in = null;
        FileOutputStream file;
        BufferedOutputStream out = null;

        try {
            huc = (HttpURLConnection) url.openConnection();
            huc.setAllowUserInteraction(false);
            huc.setDoInput(true);
            huc.setDoOutput(false);
            huc.setUseCaches(false);
            huc.setReadTimeout(30000);
            huc.connect();

            in = new BufferedInputStream(huc.getInputStream());
            file = new FileOutputStream(fileName);
            out = new BufferedOutputStream(file);

            int len;
            byte[] data = new byte[1024];
            while ((len = in.read(data, 0, 1024)) >= 0) {
                out.write(data, 0, len);
            }

            out.flush();
            out.close();
            in.close();
            huc.disconnect();
            Thread.sleep(4000);
        } catch (InterruptedException iex) {
            System.err.println("ERROR: ******* " + iex.toString());
        } catch (IOException ex) {
            System.err.println("ERROR: ******* " + ex.toString());
        } finally {
            try {
                in.close();
                out.close();
                huc.disconnect();
            } catch (IOException ex) {
                System.err.println("ERROR: ******* " + ex.toString());
            }
        }
    }
}

 
Web site owner: Center for Operational Oceanographic Products and Services (CO-OPS)          Privacy Policy         Take Our Survey