|
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WaterLevelObservationsGetter {
public static void main(String[] args) {
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=water_surface_height_above_reference_datum";
String saveToYourLocalDir = "C:\\temp\\sosdata\\";
String waterlevelDataType = "PreliminarySixMinute";
String stationsIds[] = {"1611400", "8311062", "8454049", "9034052", "9044020"};
String dates[] = {"2011-11-30", "2012-01-10"};
String datum = "";
String responseFormat = "csv";
String dateTimeStr;
String url;
URL dataUrl;
String fileName;
try {
List dtList = getDateTimeList(dates);
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.");
}
for (int j = 0, size = dtList.size(); j < size; j++) {
dateTimeStr = (String) dtList.get(j);
url = baseUrl + "&offering=urn:ioos:station:NOAA.NOS.CO-OPS:"
+ stationsIds[i] + "&responseFormat=" + urlEncode(responseMIMEType) + "&eventTime=" + dateTimeStr;
if (datum != null && datum.length() != 0) {
if (isValidVerticalDatum(datum)) {
url += "&result=VerticalDatum%3D%3D" + getDatumURN(datum);
} else {
throw new IOException(" Wrong Datum: please enter a valid datum string.");
}
}
if (waterlevelDataType != null && waterlevelDataType.length() != 0) {
if (isValidWaterLevelDataType(waterlevelDataType)) {
url += "&dataType=" + waterlevelDataType;
} else {
throw new IOException(" Wrong Water Level Data Type: please enter a valid data type string.");
}
}
dataUrl = new URL(url);
fileName = getFileName(stationsIds[i], dateTimeStr, responseFormat, waterlevelDataType, saveToYourLocalDir);
getResource(dataUrl, fileName);
}
}
} catch (Exception e) {
System.err.println("ERROR: ******* " + e.getMessage());
}
}
public static List getDateTimeList(String dates[]) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
String startTime = "00:00:00";
String endTime = "23:59:00";
int MAX_RETRIEVAL_DAYS = 31; long difference;
double diffDays;
Date start;
Date end;
Date tempStart;
Date tempEnd;
String dateTimeStr;
List dateTimeList = new ArrayList();
try {
start = sdf.parse(dates[0] + " " + startTime);
end = sdf.parse(dates[1] + " " + endTime);
if (end.before(start)) {
throw new java.text.ParseException(" Wrong dates order, end date must be later than begin date.", -1);
}
difference = end.getTime() - start.getTime();
diffDays = difference / (1000 * 60 * 60 * 24);
if (diffDays > MAX_RETRIEVAL_DAYS) {
tempStart = start;
for (int d = 0; d <= diffDays; d += MAX_RETRIEVAL_DAYS) {
tempEnd = sdf.parse(addDays(MAX_RETRIEVAL_DAYS - 1, tempStart) + " " + endTime);
if (tempEnd.after(end)) {
tempEnd = end;
}
dateTimeStr = sdf.format(tempStart).replace(" ", "T") + "Z" + "/" + sdf.format(tempEnd).replace(" ", "T") + "Z";
dateTimeList.add(dateTimeStr);
tempStart = sdf.parse(addDays(1, tempEnd) + " " + startTime);
}
} else {
dateTimeStr = sdf.format(start).replace(" ", "T") + "Z" + "/" + sdf.format(end).replace(" ", "T") + "Z";
dateTimeList.add(dateTimeStr);
}
} catch (ParseException ex) {
System.err.println("ERROR: ******* " + ex.toString());
}
return dateTimeList;
}
public static String addDays(int dayOffset, Date dateTime) {
Calendar calender = new GregorianCalendar();
calender.setTime(dateTime);
calender.add(Calendar.DATE, dayOffset);
int month = calender.get(Calendar.MONTH) + 1;
int day = calender.get(Calendar.DAY_OF_MONTH);
int year = calender.get(Calendar.YEAR);
StringBuilder buffer = new StringBuilder(15);
buffer.append(year);
buffer.append('-');
if (month < 10) {
buffer.append('0');
}
buffer.append(month);
buffer.append('-');
if (day < 10) {
buffer.append('0');
}
buffer.append(day);
return buffer.toString();
}
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;
}
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;
}
}
}
public static boolean isValidVerticalDatum(String datum) {
boolean isValidVDatum = false;
List acceptVDatums = new ArrayList();
acceptVDatums.add("IGLD");
acceptVDatums.add("MHHW");
acceptVDatums.add("MHW");
acceptVDatums.add("MLLW");
acceptVDatums.add("MLW");
acceptVDatums.add("MSL");
acceptVDatums.add("MTL");
acceptVDatums.add("NAVD");
acceptVDatums.add("STND");
if (datum != null) {
if (datum.length() == 0) {
isValidVDatum = false;
} else {
String s = datum.toUpperCase();
for (int i = 0, size = acceptVDatums.size(); i < size; i++) {
if (acceptVDatums.get(i).toString().equals(s)) {
isValidVDatum = true;
break;
}
}
}
}
return isValidVDatum;
}
public static boolean isValidWaterLevelDataType(String dataType) {
boolean isValidDataType = false;
List acceptWLDataType = new ArrayList();
acceptWLDataType.add("PreliminarySixMinute");
acceptWLDataType.add("PreliminaryOneMinute");
acceptWLDataType.add("VerifiedSixMinute");
acceptWLDataType.add("VerifiedHourlyHeight");
acceptWLDataType.add("VerifiedHighLow");
acceptWLDataType.add("VerifiedDailyMean");
if (dataType != null) {
for (int i = 0, size = acceptWLDataType.size(); i < size; i++) {
int matches = dataType.compareToIgnoreCase(acceptWLDataType.get(i).toString());
if (matches == 0) {
isValidDataType = true;
break;
}
}
}
return isValidDataType;
}
private static String urlEncode(String inString) {
if (inString != null) {
inString = inString.replace("/", "%2F");
inString = inString.replace("+", "%2B");
}
return inString;
}
public static String getFileName(String stationId, String dateTime, String responseFormat, String dataType, String saveToYourLocalDir) {
String dateTimeStr = dateTime.replace(":", "-").replace("/", "_");
if (dataType == null && dataType.length() == 0) {
dataType = "PreliminarySixMinute";
}
String fileName = saveToYourLocalDir + "water_level_" + dataType + "_" + stationId + "_" + dateTimeStr + "." + responseFormat.toLowerCase();
return fileName;
}
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());
}
}
}
private static String getDatumURN(String datum) {
String IOOS_VDATUM_PREFIX = "urn:ioos:def:datum:noaa::";
String datumUrn;
if (datum.equalsIgnoreCase("NAVD")) {
datumUrn = "urn:ogc:def:datum:epsg::5103";
} else {
datumUrn = IOOS_VDATUM_PREFIX + datum;
}
return datumUrn;
}
}
|