/* * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * User: rkambic * Date: Oct 13, 2010 * Time: 12:30:33 PM */ package thredds.server.radarServer; import thredds.catalog.query.Station; import ucar.unidata.geoloc.LatLonPointImpl; import ucar.unidata.geoloc.LatLonRect; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RadarServerUtil { public static final Pattern p_yymmdd_hhmm = Pattern.compile("(\\d{2})(\\d{4}_\\d{4})"); public static final Pattern p_yyyymmdd_hhmm = Pattern.compile("(\\d{8}_\\d{4})"); public static final String epic = "1970-01-01T00:00:00"; ////////////////////// Station utilities public static List<String> getStationNames( List<Station> stations ) { ArrayList<String> result = new ArrayList<String>(); for (Station s : stations) { result.add(s.getValue()); } return result; } public static List<String> convert4to3stations( List<String> stations ) { ArrayList<String> result = new ArrayList<String>(); for (String s : stations) { if( s.length() == 4 ) result.add(s.substring( 1 )); else result.add( s ); } return result; } /** * Get the list of station names that are contained within the bounding box. * * @param boundingBox lat/lon bounding box * @return list of station names contained within the bounding box * @throws java.io.IOException if read error */ public static List<String> getStationNames(LatLonRect boundingBox, List<Station> stations ) { LatLonPointImpl latlonPt = new LatLonPointImpl(); ArrayList<String> result = new ArrayList<String>(); for (Station s : stations) { latlonPt.set(s.getLocation().getLatitude(), s.getLocation().getLongitude()); if (boundingBox.contains(latlonPt)) { result.add(s.getValue()); } } return result; } /** * Find the station closest to the specified point. * The metric is (lat-lat0)**2 + (cos(lat0)*(lon-lon0))**2 * * @param lat latitude value * @param lon longitude value * @return name of station closest to the specified point * @throws java.io.IOException if read error */ public static String findClosestStation(double lat, double lon, List<Station> stations) { double cos = Math.cos(Math.toRadians(lat)); Station min_station = stations.get(0); double min_dist = Double.MAX_VALUE; for (Station s : stations) { double lat1 = s.getLocation().getLatitude(); double lon1 = LatLonPointImpl.lonNormal(s.getLocation().getLongitude(), lon); double dy = Math.toRadians(lat - lat1); double dx = cos * Math.toRadians(lon - lon1); double dist = dy * dy + dx * dx; if (dist < min_dist) { min_dist = dist; min_station = s; } } return min_station.getValue(); } /** * Determine if any of the given station names are actually in the dataset. * * @param stations List of station names * @return true if list is empty, ie no names are in the actual station list * @throws java.io.IOException if read error */ public static boolean isStationListEmpty(List<String> stations, DatasetRepository.RadarType radarType ) { if( stations.get( 0 ).toUpperCase().equals( "ALL") ) return false; for (String s : stations ) { if( isStation( s, radarType )) return false; } return true; } /** * returns true if a station * @param station * @param radarType * @return boolean isStation */ public static boolean isStation( String station, DatasetRepository.RadarType radarType ) { if( station.toUpperCase().equals( "ALL") ) return true; Station stn = null; // terminal level3 station if( station.length() == 3 && radarType.equals( DatasetRepository.RadarType.terminal ) ) { stn = DatasetRepository.terminalMap.get( "T"+ station ); } else if( station.length() == 3 ) { for( Station stn3 : DatasetRepository.nexradList ) { if( stn3.getValue().endsWith( station ) ) { stn = stn3; break; } } } else if( radarType.equals( DatasetRepository.RadarType.terminal ) ) { stn = DatasetRepository.terminalMap.get( station ); } else { stn = DatasetRepository.nexradMap.get( station ); } if( stn != null) return true; return false; } /** * returns station or null * @param station * @param radarType * @return station */ public static Station getStation( String station, DatasetRepository.RadarType radarType ) { Station stn = null; // terminal level3 station if( station.length() == 3 && radarType.equals( DatasetRepository.RadarType.terminal ) ) { stn = DatasetRepository.terminalMap.get( "T"+ station ); } else if( station.length() == 3 ) { for( Station stn3 : DatasetRepository.nexradList ) { if( stn3.getValue().endsWith( station ) ) { stn = stn3; break; } } } else if( radarType.equals( DatasetRepository.RadarType.terminal ) ) { stn = DatasetRepository.terminalMap.get( station ); } else { stn = DatasetRepository.nexradMap.get( station ); } return stn; } /////////////////// time utilities // returns ISO time extracted from a product public static String getObTimeISO( String product ) { String date; StringBuffer dsb = new StringBuffer(); Matcher m = p_yyyymmdd_hhmm.matcher( product ); if( m.find(0) ) { date = m.group( 1 ); } else { // try date w/o century Matcher mm = p_yymmdd_hhmm.matcher( product ); if( mm.find(0) ) { // add century, fails 2070 if( Integer.parseInt(mm.group( 1 )) > 69 ) { dsb.append("19").append( mm.group( 1 )).append( mm.group( 2 )); } else { dsb.append("20").append( mm.group( 1 )).append( mm.group( 2 )); } date = dsb.toString(); } else { return epic; } } dsb.setLength( 0 ); dsb.append( date.substring(0,4)).append( "-" ).append(date.substring(4,6)); dsb.append("-").append(date.substring(6,8)).append("T").append(date.substring(9, 11)); dsb.append(":").append( date.substring(11,13) ).append(":00"); return dsb.toString(); } // returns hhmm of datetime string public static String hhmm( String dateTime ) { StringBuffer sb = new StringBuffer( dateTime.substring( 11, 13 ) ); sb.append( dateTime.substring( 14, 16 )); return sb.toString(); } // returns if day is between dayStart and dayEnd public static boolean isValidDay( String day, String yyyymmddStart, String yyyymmddEnd ) { if ( day.equals( "all")) // for casestudy data return true; if( day.compareTo( yyyymmddStart ) >= 0 && day.compareTo( yyyymmddEnd ) <= 0 ) return true; return false; } // returns true if date is between dateStart and dateEnd public static boolean isValidDate( String dateReport, String dateStart, String dateEnd ) { Matcher m; m = p_yyyymmdd_hhmm.matcher( dateReport ); String date; if( m.find() ) { date = m.group( 1 ); } else { // try date w/o century m = p_yymmdd_hhmm.matcher( dateReport ); if( m.find() ) { // add century, fails 2070 StringBuffer dsb = new StringBuffer(); if( Integer.parseInt(m.group( 1 )) > 69 ) { dsb.append("19").append( m.group( 1 )).append( m.group( 2 )); } else { dsb.append("20").append( m.group( 1 )).append( m.group( 2 )); } date = dsb.toString(); } else { return false; } } // extract hhmm from product if( date.compareTo( dateStart ) >= 0 && date.compareTo( dateEnd ) <= 0 ) return true; return false; } }