diff --git a/cave/com.raytheon.uf.viz.aviation.advisory/src/com/raytheon/uf/viz/aviation/advisory/adapter/AirmetDataAdapter.java b/cave/com.raytheon.uf.viz.aviation.advisory/src/com/raytheon/uf/viz/aviation/advisory/adapter/AirmetDataAdapter.java index a5515384e3..bc1f6010f0 100644 --- a/cave/com.raytheon.uf.viz.aviation.advisory/src/com/raytheon/uf/viz/aviation/advisory/adapter/AirmetDataAdapter.java +++ b/cave/com.raytheon.uf.viz.aviation.advisory/src/com/raytheon/uf/viz/aviation/advisory/adapter/AirmetDataAdapter.java @@ -59,13 +59,13 @@ public class AirmetDataAdapter extends AbstractAdvisoryDataAdapter { private static final String LABEL_FORMAT = "%d%s"; private static final String INSPECT_FORMAT = "Valid UNTIL %02d%02d%02d\n%s"; - + private static final String REPORT_INDICATOR = "AIRMET"; private static final String SEGMENT_SEPERATOR = "\n. \n"; private static final float LINE_WIDTH = 1.5f; - + private static final LineStyle LINE_STYLE = LineStyle.SOLID; @XmlAttribute @@ -89,7 +89,8 @@ public class AirmetDataAdapter extends AbstractAdvisoryDataAdapter { if (airmetRecord.getAirmetReport() != null) { for (AirmetReport report : airmetRecord.getAirmetReport()) { if (isValidReport(report)) { - AdvisoryRecord oRecord = convertReport(report); + AdvisoryRecord oRecord = convertReport(airmetRecord, + report); if (oRecord != null) { result.add(oRecord); } @@ -100,17 +101,17 @@ public class AirmetDataAdapter extends AbstractAdvisoryDataAdapter { return result; } - public AdvisoryRecord convertReport(AirmetReport report) { + public AdvisoryRecord convertReport(AirmetRecord parent, AirmetReport report) { Set locations = report.getAirmetLocation(); if (locations == null || locations.size() == 0) { return null; } Coordinate[] coords = new Coordinate[locations.size()]; for (AirmetLocation loc : locations) { - coords[loc.getIndex() - 1] = new Coordinate(loc.getLongitude(), loc - .getLatitude()); + coords[loc.getIndex() - 1] = new Coordinate(loc.getLongitude(), + loc.getLatitude()); } - int updateNumber = report.getParentID().getUpdateNumber(); + int updateNumber = parent.getUpdateNumber(); String sequenceId = report.getSequenceID(); if (sequenceId == null) { sequenceId = ""; @@ -166,7 +167,7 @@ public class AirmetDataAdapter extends AbstractAdvisoryDataAdapter { public float getLineWidth() { return LINE_WIDTH; } - + @Override public LineStyle getLineStyle() { return LINE_STYLE; diff --git a/edexOsgi/build.edex/esb/conf/modes.xml b/edexOsgi/build.edex/esb/conf/modes.xml index 05b14d7454..90fec075c8 100644 --- a/edexOsgi/build.edex/esb/conf/modes.xml +++ b/edexOsgi/build.edex/esb/conf/modes.xml @@ -47,20 +47,23 @@ ncgrib-ingest.xml aww-ingest.xml + ncairep-ingest.xml ncccfp-ingest.xml ncgrib-distribution.xml ncep-util-on-edex-ingest - ncep-util-on-edex-ingestGrib - h5uair-ingest.xml - h5scd-ingest.xml - pafm-ingest.xml - uair-ingest.xml + ncep-util-on-edex-ingestGrib + ncscd-ingest.xml + ncpafm-ingest.xml + ncpirep-ingest.xml + nctaf-ingest.xml + ncuair-ingest.xml .*request.* grib-ingest.xml + ncairep-ingest.xml ncgrib-ingest.xml ffmp-ingest.*.xml scan-ingest.*.xml @@ -77,11 +80,12 @@ ncccfp-ingest.xml ncgrib-distribution.xml ncep-util-on-edex-ingest - ncep-util-on-edex-ingestGrib - h5uair-ingest.xml - h5scd-ingest.xml - pafm-ingest.xml - uair-ingest.xml + ncep-util-on-edex-ingestGrib + ncscd-ingest.xml + ncpafm-ingest.xml + ncpirep-ingest.xml + nctaf-ingest.xml + ncuair-ingest.xml diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/createNcepStnsTables.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/createNcepStnsTables.sql index 705bc1394b..50c9fa4b06 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/createNcepStnsTables.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/createNcepStnsTables.sql @@ -22,11 +22,11 @@ pkey SERIAL PRIMARY KEY, DROP TABLE IF EXISTS stns.BUOYS CASCADE; CREATE TABLE stns.BUOYS ( PKEY SERIAL PRIMARY KEY, - STNUM int, + STATION_NUM int, NAME varchar(32), COUNTRY char(2), - LAT double precision, - LON double precision + LATITUDE double precision, + LONGITUDE double precision ); -- Create cities table @@ -43,6 +43,20 @@ pkey SERIAL PRIMARY KEY, priority smallint NOT NULL ); +-- Create climo_data table +DROP TABLE IF EXISTS stns.climo_data CASCADE; +CREATE TABLE stns.climo_data( +pkey SERIAL PRIMARY KEY, + station_id varchar(8) NOT NULL, + month smallint NOT NULL, + day smallint NOT NULL, + TDYF double precision, + TNTF double precision, + PPNT double precision, + PPDY double precision, + PP24 double precision +); + -- Create climreg table DROP TABLE IF EXISTS stns.climreg CASCADE; CREATE TABLE stns.climreg( @@ -114,13 +128,13 @@ pkey SERIAL PRIMARY KEY, DROP TABLE IF EXISTS stns.countynam CASCADE; CREATE TABLE stns.countynam ( PKEY SERIAL PRIMARY KEY, - STID varchar(8), - STNUM int, + STATION_ID varchar(8), + STATION_NUM int, NAME varchar(32), STATE char(2), COUNTRY char(2), - LAT double precision, - LON double precision, + LATITUDE double precision, + LONGITUDE double precision, WFO varchar(3) ); @@ -142,13 +156,13 @@ pkey SERIAL PRIMARY KEY, DROP TABLE IF EXISTS stns.CPCSTNS CASCADE; CREATE TABLE stns.CPCSTNS ( PKEY SERIAL PRIMARY KEY, - STID varchar(4), - STNUM int, + STATION_ID varchar(4), + STATION_NUM int, NAME varchar(32), STATE char(2), COUNTRY char(2), - LAT double precision, - LON double precision, + LATITUDE double precision, + LONGITUDE double precision, ELEV int, PRI int ); @@ -156,13 +170,13 @@ CREATE TABLE stns.CPCSTNS ( DROP TABLE IF EXISTS stns.DLWX CASCADE; CREATE TABLE stns.DLWX ( PKEY SERIAL PRIMARY KEY, - STID varchar(4), - STNUM int, + STATION_ID varchar(4), + STATION_NUM int, NAME varchar(32), STATE char(2), COUNTRY char(2), - LAT double precision, - LON double precision, + LATITUDE double precision, + LONGITUDE double precision, ELEV int, PRI int ); @@ -170,26 +184,26 @@ CREATE TABLE stns.DLWX ( DROP TABLE IF EXISTS stns.FFGZON CASCADE; CREATE TABLE stns.FFGZON ( PKEY SERIAL PRIMARY KEY, - STID varchar(8), - STNUM int, + STATION_ID varchar(8), + STATION_NUM int, NAME varchar(32), STATE char(2), COUNTRY char(2), - LAT double precision, - LON double precision, + LATITUDE double precision, + LONGITUDE double precision, WFO varchar(8) ); -- Create firezones table DROP TABLE IF EXISTS stns.FIREZONES CASCADE; CREATE TABLE stns.FIREZONES ( PKEY SERIAL PRIMARY KEY, - STID varchar(8), - STNUM int, + STATION_ID varchar(8), + STATION_NUM int, NAME varchar(32), STATE char(2), COUNTRY char(2), - LAT double precision, - LON double precision, + LATITUDE double precision, + LONGITUDE double precision, WFO varchar(8) ); @@ -578,28 +592,28 @@ pkey SERIAL PRIMARY KEY, DROP TABLE IF EXISTS stns.SNWORLD CASCADE; CREATE TABLE stns.SNWORLD ( PKEY SERIAL PRIMARY KEY, - STID varchar(4) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(4) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL, PRI int NOT NULL ); -- Create spcwatch table DROP TABLE IF EXISTS stns.SPCWATCH CASCADE; CREATE TABLE stns.SPCWATCH ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL ); -- Create state table DROP TABLE IF EXISTS stns.STATE CASCADE; @@ -612,53 +626,53 @@ CREATE TABLE stns.STATE ( DROP TABLE IF EXISTS stns.STNS_II90 CASCADE; CREATE TABLE stns.STNS_II90 ( PKEY SERIAL PRIMARY KEY, - STNUM int NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL , + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL , PRI int NOT NULL ); -- Create systns table DROP TABLE IF EXISTS stns.SYSTNS CASCADE; CREATE TABLE stns.SYSTNS ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL ); -- Create syworld table DROP TABLE IF EXISTS stns.SYWORLD CASCADE; CREATE TABLE stns.SYWORLD ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL ); -- Create tafstn table DROP TABLE IF EXISTS stns.TAFSTN CASCADE; CREATE TABLE stns.TAFSTN ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL, PRI int NOT NULL, MISC char(3) NOT NULL ); @@ -666,13 +680,13 @@ CREATE TABLE stns.TAFSTN ( DROP TABLE IF EXISTS stns.TCABKPT CASCADE; CREATE TABLE stns.TCABKPT ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL , TBCHRS varchar(20) NOT NULL ); @@ -680,39 +694,39 @@ CREATE TABLE stns.TCABKPT ( DROP TABLE IF EXISTS stns.TCABKPT_ISLAND CASCADE; CREATE TABLE stns.TCABKPT_ISLAND ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL ); -- Create tcabkpt_land table DROP TABLE IF EXISTS stns.TCABKPT_LAND CASCADE; CREATE TABLE stns.TCABKPT_LAND ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL ); -- Create tcabkptlz table DROP TABLE IF EXISTS stns.TCABKPTLZ CASCADE; CREATE TABLE stns.TCABKPTLZ ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL, TBCHRS varchar(20) NOT NULL ); @@ -720,26 +734,26 @@ CREATE TABLE stns.TCABKPTLZ ( DROP TABLE IF EXISTS stns.TCABKPT_OVL CASCADE; CREATE TABLE stns.TCABKPT_OVL ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL ); -- Create tcabkpt_water table DROP TABLE IF EXISTS stns.TCABKPT_WATER CASCADE; CREATE TABLE stns.TCABKPT_WATER ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, PRI int NOT NULL ); -- Create tpc_countries table @@ -750,8 +764,8 @@ CREATE TABLE stns.TPC_COUNTRIES ( FIPS int NOT NULL, NAME varchar(32) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL ); -- Create tpc_states table DROP TABLE IF EXISTS stns.TPC_STATES CASCADE; @@ -762,98 +776,98 @@ CREATE TABLE stns.TPC_STATES ( NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL ); -- Create volcano table DROP TABLE IF EXISTS stns.VOLCANO CASCADE; CREATE TABLE stns.VOLCANO ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL, LOCATION varchar(20) NOT NULL ); -- Create volcano_small table DROP TABLE IF EXISTS stns.VOLCANO_SMALL CASCADE; CREATE TABLE stns.VOLCANO_SMALL ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL ); -- Create vors table DROP TABLE IF EXISTS stns.VORS CASCADE; CREATE TABLE stns.VORS ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL ); -- Create wfo table DROP TABLE IF EXISTS stns.WFO CASCADE; CREATE TABLE stns.WFO ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL ); -- Create wrqpf table DROP TABLE IF EXISTS stns.WRQPF CASCADE; CREATE TABLE stns.WRQPF ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL, PRI int NOT NULL ); -- Create xrainsort table DROP TABLE IF EXISTS stns.XRAINSORT CASCADE; CREATE TABLE stns.XRAINSORT ( PKEY SERIAL PRIMARY KEY, - STID varchar(4) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(4) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, - ELEV int NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, + ELEVATION int NOT NULL, PRI int NOT NULL ); -- Create zones table DROP TABLE IF EXISTS stns.ZONES CASCADE; CREATE TABLE stns.ZONES ( PKEY SERIAL PRIMARY KEY, - STID varchar(8) NOT NULL, - STNUM int NOT NULL, + STATION_ID varchar(8) NOT NULL, + STATION_NUM int NOT NULL, NAME varchar(32) NOT NULL, STATE char(2) NOT NULL, COUNTRY char(2) NOT NULL, - LAT double precision NOT NULL, - LON double precision NOT NULL, + LATITUDE double precision NOT NULL, + LONGITUDE double precision NOT NULL, WFO char(3) NOT NULL ); diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/initializeNcepDb.sh b/edexOsgi/build.edex/opt/db/ddl/ncep/initializeNcepDb.sh index 820de79491..7a9eb6a10c 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/initializeNcepDb.sh +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/initializeNcepDb.sh @@ -43,6 +43,10 @@ for shp in `find ${4}/shapefiles -name "*.shp"` ; do || $base == 'Asctropfirs' \ || $base == 'Asctweb' \ || $base == 'Ascwrzones' \ + || $base == 'Awcartcc' \ + || $base == 'Awcccfcan' \ + || $base == 'Awcfaarea' \ + || $base == 'Atlbasin' \ || $base == 'Bwus_bnd' \ || $base == 'Bwus_label' \ || $base == 'Bwx1224' \ @@ -57,6 +61,7 @@ for shp in `find ${4}/shapefiles -name "*.shp"` ; do || $base == 'Firbnds' \ || $base == 'Firebnds' \ || $base == 'FireWxAOR' \ + || $base == 'FirKzoaAwc' \ || $base == 'G2t_atl_bnd' \ || $base == 'G2t_nwc' \ || $base == 'G2t_pac_bnd' \ @@ -74,6 +79,7 @@ for shp in `find ${4}/shapefiles -name "*.shp"` ; do || $base == 'Npsabnds' \ || $base == 'Opcbnds' \ || $base == 'Opcbnds_nomex' \ + || $base == 'PacBasin' \ || $base == 'Pfzbnds' \ || $base == 'Rfcbnds' \ || $base == 'Sig_high' \ diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadBuoys.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadBuoys.sql index 93babf757c..f0f7425104 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadBuoys.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadBuoys.sql @@ -1,4 +1,4 @@ -COPY stns.BUOYS(PKEY, STNUM, NAME, COUNTRY, LAT, LON) FROM stdin with delimiter as ','; +COPY stns.BUOYS(PKEY, STATION_NUM, NAME, COUNTRY, LATITUDE, LONGITUDE) FROM stdin with delimiter as ','; 1,44004,Hotel,US,38.5,-70.7 2,41001,East_Hatteras,US,34.7,-72.6 3,41002,South_Hatteras,US,32.3,-75.2 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadCountynam.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadCountynam.sql index ce7b66dc5c..6e462ea313 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadCountynam.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadCountynam.sql @@ -1,4 +1,4 @@ -COPY stns.countynam(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, WFO) FROM stdin with delimiter as ','; +COPY stns.countynam(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, WFO) FROM stdin with delimiter as ','; 1,Saipan,69110,Saipan,GU,US,15.19,145.76,GUM 2,Northern,69085,Northern_Islands,GU,US,18.11,145.76,GUM 3,Tinian,69120,Tinian,GU,US,15.01,145.63,GUM diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadCpcstns.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadCpcstns.sql index 9622b643f2..a4d9b2056e 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadCpcstns.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadCpcstns.sql @@ -1,4 +1,4 @@ -COPY stns.CPCSTNS(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.CPCSTNS(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; 1,ABI,72266,ABILENE,TX,US,32.5,-99.7,0,0 2,ABQ,72365,ALBUQUERQUE_INTL,NM,US,35.05,-106.62,1620,0 3,ADK,70454,ADAK_NAS/MITCHELL,AK,US,51.88,-176.65,4,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadDlwx.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadDlwx.sql index bd30d62465..72b988a87c 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadDlwx.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadDlwx.sql @@ -1,4 +1,4 @@ -COPY stns.DLWX(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.DLWX(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; 1,EYW,722010,KEY_WEST_INTL_ARPT_(ASOS),FL,US,24.55,-81.75,6,99 2,MIA,722020,MIAMI_INTL_AIRPORT_(ASOS),FL,US,25.82,-80.28,4,99 3,MCO,722050,ORLANDO_JETPORT___(ASOS),FL,US,28.43,-81.32,32,99 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadFfgzon.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadFfgzon.sql index 10420db159..85935543c4 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadFfgzon.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadFfgzon.sql @@ -1,4 +1,4 @@ -COPY stns.FFGZON(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, WFO) FROM stdin with delimiter as ','; +COPY stns.FFGZON(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, WFO) FROM stdin with delimiter as ','; 1,ALZ001,10010,Lauderdale,AL,US,34.89,-87.78, BMX 2,ALZ002,10020,Colbert,AL,US,34.65,-87.83, BMX 3,ALZ003,10030,Franklin,AL,US,34.43,-87.84, BMX diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadFirezones.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadFirezones.sql index 8f6362a3a4..0b06af4f57 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadFirezones.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadFirezones.sql @@ -1,4 +1,4 @@ -COPY stns.FIREZONES(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, WFO) FROM stdin with delimiter as ','; +COPY stns.FIREZONES(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, WFO) FROM stdin with delimiter as ','; 1,AKZ191,21910,Western_Aleutians,AK,US,51.51,179.05,AFC 2,GUZ004,540040,Saipan,GU,US,15.19,145.76,GUM 3,GUZ003,540030,Tinian,GU,US,15.01,145.63,GUM diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadNcepStns.sh b/edexOsgi/build.edex/opt/db/ddl/ncep/loadNcepStns.sh index 5c2ef44ea7..d0559747f9 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadNcepStns.sh +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadNcepStns.sh @@ -12,6 +12,7 @@ ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadAirepWaypnts.sql >> ${5} 2>&1 ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadBuoys.sql >> ${5} 2>&1 ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadClimReg.sql >> ${5} 2>&1 +${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadClimodata.sql >> ${5} 2>&1 ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadCities.sql >> ${5} 2>&1 ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadCntyclst.sql >> ${5} 2>&1 ${1}/bin/psql -d ncep -U ${3} -q -p ${2} -f ${4}/loadCoastal.sql >> ${5} 2>&1 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSnworld.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSnworld.sql index 116b633ced..9a086e2357 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSnworld.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSnworld.sql @@ -1,4 +1,4 @@ -COPY stns.SNWORLD(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.SNWORLD(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; 1,ENJA,1001,JAN MAYEN ISLAN, ,NO,70.93,-8.67,9,1 2,ENBJ,1028,BJORNOYA ISLAND, ,NO,74.52,19.02,14,1 3,ENBO,1152,BODO VI, ,NO,67.27,14.37,13,1 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSpcwatch.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSpcwatch.sql index aab1e2bd05..24b29ff6aa 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSpcwatch.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSpcwatch.sql @@ -1,4 +1,4 @@ -COPY stns.SPCWATCH (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV) FROM stdin with delimiter as ','; +COPY stns.SPCWATCH (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION) FROM stdin with delimiter as ','; 1,EPM,504,EASTPORT,ME,US,44.92,-67.02,0 2,HUL,501,HOULTON,ME,US,46.12,-67.8,0 3,CAR,500,CARIBOU,ME,US,46.87,-68.02,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadState.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadState.sql index 50f0553e72..8d19db7f7e 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadState.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadState.sql @@ -1,60 +1,60 @@ COPY stns.STATE (STATEID , STATENAME) FROM stdin with delimiter as ','; -AL,ALABAMA -AK,ALASKA -AZ,ARIZONA -AR,ARKANSAS -CA,CALIFORNIA -CO,COLORADO -CT,CONNECTICUT -DE,DELAWARE -DC,DISTRICT OF COLUMBIA -FL,FLORIDA -GA,GEORGIA -HI,HAWAII -ID,IDAHO -IL,ILLINOIS -IN,INDIANA -IA,IOWA -KS,KANSAS -KY,KENTUCKY -LA,LOUISIANA -ME,MAINE -MD,MARYLAND -MA,MASSACHUSETTS -MI,MICHIGAN -MN,MINNESOTA -MS,MISSISSIPPI -MO,MISSOURI -MT,MONTANA -NE,NEBRASKA -NV,NEVADA -NH,NEW HAMPSHIRE -NJ,NEW JERSEY -NM,NEW MEXICO -NY,NEW YORK -NC,NORTH CAROLINA -ND,NORTH DAKOTA -OH,OHIO -OK,OKLAHOMA -OR,OREGON -PA,PENNSYLVANIA -RI,RHODE ISLAND -SC,SOUTH CAROLINA -SD,SOUTH DAKOTA -TN,TENNESSEE -TX,TEXAS -UT,UTAH -VT,VERMONT -VA,VIRGINIA -WA,WASHINGTON -WV,WEST VIRGINIA -WI,WISCONSIN -WY,WYOMING -LH,LAKE HURON -LO,LAKE ONTARIO -LM,LAKE MICHIGAN -LE,LAKE ERIE -LS,LAKE SUPERIOR -CW,COASTAL WATERS -PR,PUERTO RICO +AL,ALABAMA +AK,ALASKA +AZ,ARIZONA +AR,ARKANSAS +CA,CALIFORNIA +CO,COLORADO +CT,CONNECTICUT +DE,DELAWARE +DC,DISTRICT OF COLUMBIA +FL,FLORIDA +GA,GEORGIA +HI,HAWAII +ID,IDAHO +IL,ILLINOIS +IN,INDIANA +IA,IOWA +KS,KANSAS +KY,KENTUCKY +LA,LOUISIANA +ME,MAINE +MD,MARYLAND +MA,MASSACHUSETTS +MI,MICHIGAN +MN,MINNESOTA +MS,MISSISSIPPI +MO,MISSOURI +MT,MONTANA +NE,NEBRASKA +NV,NEVADA +NH,NEW HAMPSHIRE +NJ,NEW JERSEY +NM,NEW MEXICO +NY,NEW YORK +NC,NORTH CAROLINA +ND,NORTH DAKOTA +OH,OHIO +OK,OKLAHOMA +OR,OREGON +PA,PENNSYLVANIA +RI,RHODE ISLAND +SC,SOUTH CAROLINA +SD,SOUTH DAKOTA +TN,TENNESSEE +TX,TEXAS +UT,UTAH +VT,VERMONT +VA,VIRGINIA +WA,WASHINGTON +WV,WEST VIRGINIA +WI,WISCONSIN +WY,WYOMING +LH,LAKE HURON +LO,LAKE ONTARIO +LM,LAKE MICHIGAN +LE,LAKE ERIE +LS,LAKE SUPERIOR +CW,COASTAL WATERS +PR,PUERTO RICO \. diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadStns_II90.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadStns_II90.sql index a453c82cce..a8a3408ce6 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadStns_II90.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadStns_II90.sql @@ -1,4 +1,4 @@ -COPY stns.STNS_II90 (PKEY, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.STNS_II90 (PKEY, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; 1,69002, HUNTER_LIGGET/TUSI&,CA,US,36,-121.23,310,0 2,69007, FORT_ORD/FRITZSCHE&,CA,US,36.68,-121.77,41,0 3,69008, CAMP_ROBERTS,CA,US,35.75,-120.7,220,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSystns.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSystns.sql index 076abf0fe0..55c9f4689b 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSystns.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSystns.sql @@ -1,4 +1,4 @@ -COPY stns.SYSTNS (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV) FROM stdin with delimiter as ','; +COPY stns.SYSTNS (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION) FROM stdin with delimiter as ','; 1,BRW,70026,BARROW/POST-ROGERS,AK,US,7130,-15678,4 2,OME,70200,NOME,AK,US,6450,-16543,7 3,MCG,70231,MCGRATH,AK,US,6297,-15562,103 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSyworld.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSyworld.sql index a284c168f6..b3512b489e 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadSyworld.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadSyworld.sql @@ -1,4 +1,4 @@ -COPY stns.SYWORLD (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV) FROM stdin with delimiter as ','; +COPY stns.SYWORLD (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION) FROM stdin with delimiter as ','; 1,ENJA,1001,JAN MAYEN(NOR-NAVY, ,NO,70.93,-8.67,9 2,ENSB,1008,SVALBARD/LONGYEAR, ,NO,78.25,15.47,29 3,ENAN,1010,ANDOYA/ANDENES(AFB, ,NO,69.3,16.15,14 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTafstn.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTafstn.sql index 1e125769a9..7d4d16e63c 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTafstn.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTafstn.sql @@ -1,4 +1,4 @@ -COPY stns.TAFSTN (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI, MISC) FROM stdin with delimiter as ','; +COPY stns.TAFSTN (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI, MISC) FROM stdin with delimiter as ','; 1,KDYS,690190,DYESS_AFB/ABILENE_&,TX,US,32.43,-99.85,545,0, 2,KNUW,690230,WHIDBEY_ISLAND_NAS&,WA,US,48.35,-122.65,14,0, 3,KNYL,699604,YUMA_MCAS_________&,AZ,US,32.65,-114.62,65,0, diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt.sql index adb3f99665..35f0108031 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPT (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI, TBCHRS) FROM stdin with delimiter as ','; +COPY stns.TCABKPT (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI, TBCHRS) FROM stdin with delimiter as ','; 1,MTH_RIO,100100,Mouth_of_the_Rio_Grande_River,TX,US,25.96,-97.15,10, TX061 G150 2,"",100112,"",TX,US,26.06,-97.17,12, G130G170 3,PORT_ISA,100120,Port_Isabel,TX,US,26.07,-97.21,19,"" diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_island.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_island.sql index 17aa106301..65c9024668 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_island.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_island.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPT_ISLAND (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI ) FROM stdin with delimiter as ','; +COPY stns.TCABKPT_ISLAND (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI ) FROM stdin with delimiter as ','; 1,ANTIGUA/,500100,Antigua/Barbuda,--,AD,17.35,-61.8,50 2,ARUBA\,_B,500200,Aruba\,_Bonaire\,_Curacao,--,AC,12.35,-69,50 3,BAHAMA_C,500300,Bahamas_(Central),--,BA,24,-75.5,50 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_land.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_land.sql index e53787576a..5327210d39 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_land.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_land.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPT_LAND (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI) FROM stdin with delimiter as ','; +COPY stns.TCABKPT_LAND (PKEY, STATION_ID ,STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI) FROM stdin with delimiter as ','; 1,MTH_RIO,100100,Mouth_of_the_Rio_Grande_River,TX,US,25.96,-97.15,10 2,PT_MANSF,100200,Port_Mansfield,TX,US,26.6,-97.29,10 3,BAFFN_BY,100300,Baffin_Bay,TX,US,27.29,-97.38,10 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_ovl.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_ovl.sql index 985d9ecef9..3f8bd37fd7 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_ovl.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_ovl.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPT_OVL (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI ) FROM stdin with delimiter as ','; +COPY stns.TCABKPT_OVL (PKEY, STATION_ID ,STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI ) FROM stdin with delimiter as ','; 1,MTH_RIO,100100,Mouth_of_the_Rio_Grande_River,TX,US,25.96,-97.15,10 2,PT_MANSF,100200,Port_Mansfield,TX,US,26.6,-97.29,10 3,BAFFN_BY,100300,Baffin_Bay,TX,US,27.29,-97.37,10 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_water.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_water.sql index 39fff6c79c..e644af05dc 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_water.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkpt_water.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPT_WATER (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI) FROM stdin with delimiter as ','; +COPY stns.TCABKPT_WATER (PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI) FROM stdin with delimiter as ','; 1,FLA_BAY,800010,Florida_Bay,FL,US,24.95,-80.9,80 2,L_MAUREP,808080,Lake_Maurepas,LA,US,30.25,-90.54,80 3,L_OKEECH,800020,Lake_Okeechobee,FL,US,26.95,-80.8,80 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkptlz.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkptlz.sql index 8725938a2c..916ee76f28 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkptlz.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTcabkptlz.sql @@ -1,4 +1,4 @@ -COPY stns.TCABKPTLZ (PKEY, STID ,STNUM, NAME, STATE, COUNTRY, LAT, LON, PRI, TBCHRS) FROM stdin with delimiter as ','; +COPY stns.TCABKPTLZ (PKEY, STATION_ID ,STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, PRI, TBCHRS) FROM stdin with delimiter as ','; 1,MTH_RIO,100100,Mouth_of_the_Rio_Grande_River,TX,US,25.96,-97.15,10,TX256 2,--,100112,--,TX,US,26.06,-97.17,12,"" 3,PORT_ISA,100120,Port_Isabel,TX,US,26.07,-97.21,19,"" diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_countries.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_countries.sql index 90c4cbad38..bd436a6738 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_countries.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_countries.sql @@ -1,4 +1,4 @@ -COPY stns.TPC_COUNTRIES (PKEY, ALPHA ,FIPS, NAME, COUNTRY, LAT, LON) FROM stdin with delimiter as ','; +COPY stns.TPC_COUNTRIES (PKEY, ALPHA ,FIPS, NAME, COUNTRY, LATITUDE, LONGITUDE) FROM stdin with delimiter as ','; 1,PR,72,Puerto Rico,PR,18.9,-65 2,BA,101,Bahamas,BA,24.5,-73.8 3,BE,102,Bermuda,BE,32,-63.7 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_states.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_states.sql index 013557a320..f6d66a5307 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_states.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadTpc_states.sql @@ -1,4 +1,4 @@ -COPY stns.TPC_STATES (PKEY, ALPHA ,FIPS, NAME, STATE, COUNTRY, LAT, LON) FROM stdin with delimiter as ','; +COPY stns.TPC_STATES (PKEY, ALPHA ,FIPS, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE) FROM stdin with delimiter as ','; 1,AL,1,Alabama,AL,US,32.5,-86.5 2,AK,2,Alaska,AK,US,63,-150 3,AZ,4,Arizona,AZ,US,34.5,-111 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano.sql index 63dd34ba70..e0e5d51d1f 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano.sql @@ -1,4 +1,4 @@ -COPY stns.VOLCANO(PKEY, STID, STNUM, NAME, LAT, LON, ELEV, LOCATION) FROM stdin with delimiter as ','; +COPY stns.VOLCANO(PKEY, STATION_ID, STATION_NUM, NAME, LATITUDE, LONGITUDE, ELEVATION, LOCATION) FROM stdin with delimiter as ','; 1,1402-08,999999,Acatenango,14.5,-90.88,3976,Guatemala 2,1201-04,999999,Adams,46.13,-121.29,3742,US-Washington 3,0803-17,999999,Adatara,37.62,140.28,1718,Honshu-Japan diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano_small.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano_small.sql index d20a5d9854..3ad1cb7df6 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano_small.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVolcano_small.sql @@ -1,4 +1,4 @@ -COPY stns.VOLCANO_SMALL(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV) FROM stdin with delimiter as ','; +COPY stns.VOLCANO_SMALL(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION) FROM stdin with delimiter as ','; 1,AVACHINS,999999,AVACHINSKY,--,BY,53.25,158.83,0 2,BEZYMIAN,999999,BEZYMIANNY,--,BY,55.97,160.58,0 3,KARYMSKY,999999,KARYMSKY,--,BY,54.05,159.43,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVors.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVors.sql index 458123633f..23a2e65e5f 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadVors.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadVors.sql @@ -1,4 +1,4 @@ -COPY stns.VORS(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON) FROM stdin with delimiter as ','; +COPY stns.VORS(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE) FROM stdin with delimiter as ','; 1,YSJ,395,ST_JOHN,NB,CN,45.32,-65.88 2,HUL,341,HOULTON,ME,US,46.04,-67.83 3,PQI,367,PRESQUE_ISLE,ME,US,46.77,-68.09 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadWfo.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadWfo.sql index d645c0570b..99aef40f7d 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadWfo.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadWfo.sql @@ -1,4 +1,4 @@ -COPY stns.WFO(PKEY, STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV) FROM stdin with delimiter as ','; +COPY stns.WFO(PKEY, STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION) FROM stdin with delimiter as ','; 1,ABQ,50,ALBUQUERQUE,NM,US,35.03,-106.62,0 2,ABR,76,ABERDEEN,SD,US,45.45,-98.41,0 3,AFC,112,ANCHORAGE,AK,US,61.15,-149.98,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadWrqpf.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadWrqpf.sql index fd9159414b..b924780f99 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadWrqpf.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadWrqpf.sql @@ -1,4 +1,4 @@ -COPY stns.WRQPF(STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.WRQPF(STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; 0E4,999999,PAYSON,AZ,US,34.14,-111.2,4913,1 4BK,999999,BROOKINGS-2SE,OR,US,42.03,-124.25,46,1 4HV,999999,HANKSVILLE,UT,US,38.22,-110.43,4308,1 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadXrainsort.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadXrainsort.sql index bdfbfa0835..70ea81ac64 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadXrainsort.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadXrainsort.sql @@ -1,4 +1,4 @@ -COPY stns.XRAINSORT(STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, ELEV, PRI) FROM stdin with delimiter as ','; +COPY stns.XRAINSORT(STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, ELEVATION, PRI) FROM stdin with delimiter as ','; PASY,704140,SHEMYA_AFB,AK,US,52.72,174.12,30,0 YYT,718010,SAINT_JOHN'S_ARPT,NF,CN,47.62,-52.73,140,0 XSW,715870,ST.-JOHN'S-WEST_CDA_CS,NF,CN,47.52,-52.79,114,0 diff --git a/edexOsgi/build.edex/opt/db/ddl/ncep/loadZones.sql b/edexOsgi/build.edex/opt/db/ddl/ncep/loadZones.sql index b7566c8cba..866d126fd3 100644 --- a/edexOsgi/build.edex/opt/db/ddl/ncep/loadZones.sql +++ b/edexOsgi/build.edex/opt/db/ddl/ncep/loadZones.sql @@ -1,4 +1,4 @@ -COPY stns.ZONES(STID, STNUM, NAME, STATE, COUNTRY, LAT, LON, WFO) FROM stdin with delimiter as ','; +COPY stns.ZONES(STATION_ID, STATION_NUM, NAME, STATE, COUNTRY, LATITUDE, LONGITUDE, WFO) FROM stdin with delimiter as ','; AKZ187,21870,Central_Aleutians,AK,US,52.22,-174.23,AFC AKZ213,22130,St_Lawrence_I_and_Bering_St_Cst,AK,US,63.36,-170.27,AFG AKZ195,21950,Pribilof_Islands,AK,US,57.18,-170.26,AFC diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject old mode 100755 new mode 100644 diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/component-deploy.xml old mode 100755 new mode 100644 index c3412a6be6..747a87e201 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/component-deploy.xml @@ -1,11 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetLocation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetLocation.java old mode 100755 new mode 100644 index b892c2e117..38a2e80669 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetLocation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetLocation.java @@ -1,210 +1,192 @@ -/** - * AirmetLocation - * - * This java class defines the getters and setters for the - * airmet location table. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 39 L. Lin Initial creation - * 07/2009 39 L. Lin Migration to TO11 - * 09/2009 39 L. Lin Add latitude/longitude to location table - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.airmet; - -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -import java.io.Serializable; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "airmet_location") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class AirmetLocation implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Integer recordId = null; - - // The consigmet record this object belongs to - @ManyToOne - @JoinColumn(name = "parentID", nullable = false) - private AirmetReport parentID; - - // Collection of locations - @Column(length = 480) - @XmlElement - @DynamicSerializeElement - private String locationLine; - - // Each location of a airmet forecast area - @Column(length = 48) - @XmlElement - @DynamicSerializeElement - private String location; - - // Each latitude of an airmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double latitude; - - // Each longitude of an airmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double longitude; - - // Index for the order of a complete location set - @Column - @XmlElement - @DynamicSerializeElement - private Integer index; - - /** - * No-Arg Convstructor. - */ - public AirmetLocation() { - this.locationLine = ""; - this.location = ""; - this.index = IDecoderConstantsN.INTEGER_MISSING; - } - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @return the parentID - */ - public AirmetReport getParentID() { - return parentID; - } - - /** - * @param parentID - * to set - */ - public void setParentID(AirmetReport parentID) { - this.parentID = parentID; - } - - /** - * @return the index - */ - public Integer getIndex() { - return index; - } - - /** - * @param index - * to set - */ - public void setIndex(Integer index) { - this.index = index; - } - - /** - * @return the locationLine - */ - public String getLocationLine() { - return locationLine; - } - - /** - * @param locationLine - * to set - */ - public void setLocationLine(String locationLine) { - this.locationLine = locationLine; - } - - /** - * @return the location - */ - public String getLocation() { - return location; - } - - /** - * @param location - * to set - */ - public void setLocation(String location) { - this.location = location; - } - - /** - * @return the latitude - */ - public double getLatitude() { - return latitude; - } - - /** - * @param latitude - * to set - */ - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - /** - * @return the longitude - */ - public double getLongitude() { - return longitude; - } - - /** - * @param longitude - * to set - */ - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - /** - * Get the record id. - * - * @return The recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * Set the record id. - * - * @param record - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - -} +/** + * AirmetLocation + * + * This java class defines the getters and setters for the + * airmet location table. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 39 L. Lin Initial creation + * 07/2009 39 L. Lin Migration to TO11 + * 09/2009 39 L. Lin Add latitude/longitude to location table + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.airmet; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + + +@Entity +@Table(name="airmet_location") +@DynamicSerialize +public class AirmetLocation implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Integer recordId = null; + + + // Collection of locations + @Column(length=480) + @DynamicSerializeElement + private String locationLine; + + // Each location of a airmet forecast area + @Column(length=48) + @DynamicSerializeElement + private String location; + + // Each latitude of an airmet forecast area + @Column + @DynamicSerializeElement + private double latitude; + + // Each longitude of an airmet forecast area + @Column + @DynamicSerializeElement + private double longitude; + + // Index for the order of a complete location set + @Column + @DynamicSerializeElement + private Integer index; + + /** + * No-Arg Convstructor. + */ + public AirmetLocation() { + this.locationLine=""; + this.location=""; + this.index=IDecoderConstantsN.INTEGER_MISSING; + } + + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * @return the parentID + * + public AirmetReport getParentID() { + return parentID; + }*/ + + /** + * @param parentID to set + * + public void setParentID(AirmetReport parentID) { + this.parentID = parentID; + }*/ + + /** + * @return the index + */ + public Integer getIndex() { + return index; + } + + /** + * @param index to set + */ + public void setIndex(Integer index) { + this.index = index; + } + + /** + * @return the locationLine + */ + public String getLocationLine() { + return locationLine; + } + + /** + * @param locationLine to set + */ + public void setLocationLine(String locationLine) { + this.locationLine = locationLine; + } + + /** + * @return the location + */ + public String getLocation() { + return location; + } + + /** + * @param location to set + */ + public void setLocation(String location) { + this.location = location; + } + + /** + * @return the latitude + */ + public double getLatitude() { + return latitude; + } + + /** + * @param latitude to set + */ + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + /** + * @return the longitude + */ + public double getLongitude() { + return longitude; + } + + /** + * @param longitude to set + */ + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + /** + * Get the record id. + * + * @return The recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * Set the record id. + * @param record + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetRecord.java old mode 100755 new mode 100644 index e8884574ec..543cccdc6c --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetRecord.java @@ -1,341 +1,322 @@ -/** - * AirmetRecord - * - * This java class performs the mapping to the database table for AIRMET - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 L. Lin Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 39 L. Lin Initial coding - * 07/2009 39 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.airmet; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import org.hibernate.annotations.Index; - -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "airmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class AirmetRecord extends PluginDataObject { - - /** - * - */ - private static final long serialVersionUID = 1L; - - // reportType is AIRMET. - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String reportType; - - // reportName will be SIERRA, TANGO, or ZULU - @Column(length = 32) - @DataURI(position = 1) - @XmlElement - @DynamicSerializeElement - private String reportName; - - // WMO header - @Column(length = 32) - @DataURI(position = 2) - @XmlElement - @DynamicSerializeElement - private String wmoHeader; - - // The issue office where the report from - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String issueOffice; - - // Update number as: 1, 2, 3, ... - @Column - @DataURI(position = 3) - @XmlElement - @DynamicSerializeElement - private Integer updateNumber; - - // Issue time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar issueTime; - - // The designator - @Column(length = 8) - @XmlElement - @DynamicSerializeElement - private String designatorBBB; - - // CorrectionFlag is a flag: 0 for normal, 1 for COR or CC, 2 for AMD, and 3 - // for TEST - /* - * CorrectionFlag is a flag: 0 for normal, 1 for COR or CC, 2 for AMD, 3 for - * TEST, and 4 for NIL report - */ - @Column - @XmlElement - @DynamicSerializeElement - private Integer correctionFlag; - - // The entire report - @Column(length = 15000) - @XmlElement - @DynamicSerializeElement - private String bullMessage; - - /** - * Airmet report - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @Index(name = "airmet_report_parentid_idex") - private Set airmetReport = new HashSet(); - - /** - * Default Convstructor - */ - public AirmetRecord() { - this.issueOffice = ""; - this.wmoHeader = ""; - this.bullMessage = ""; - this.designatorBBB = ""; - this.updateNumber = 0; - this.reportType = ""; - this.reportName = null; - this.correctionFlag = 0; - } - - /** - * Convstructs an airmet record from a dataURI - * - * @param uri - * The dataURI - */ - public AirmetRecord(String uri) { - super(uri); - } - - @Override - public IDecoderGettable getDecoderGettable() { - // TODO Auto-generated method stub - return null; - } - - /** - * @return the issueOffice - */ - public String getIssueOffice() { - return issueOffice; - } - - /** - * @param issueOffice - * to set - */ - public void setIssueOffice(String issueOffice) { - this.issueOffice = issueOffice; - } - - /** - * @return the wmoHeader - */ - public String getWmoHeader() { - return wmoHeader; - } - - /** - * @param wnoHeader - * to set - */ - public void setWmoHeader(String wmoHeader) { - this.wmoHeader = wmoHeader; - } - - /** - * @return the issueTime - */ - public Calendar getIssueTime() { - return issueTime; - } - - /** - * @param issueTime - * to set - */ - public void setIssueTime(Calendar issueTime) { - this.issueTime = issueTime; - } - - /** - * @return the reportType - */ - public String getReportType() { - return reportType; - } - - /** - * @param reportType - * to set - */ - public void setReportType(String reportType) { - this.reportType = reportType; - } - - /** - * @return the designatorBBB - */ - public String getDesignatorBBB() { - return designatorBBB; - } - - /** - * @param designatorBBB - * to set - */ - public void setDesignatorBBB(String designatorBBB) { - this.designatorBBB = designatorBBB; - } - - /** - * @return the correctionFlag - */ - public Integer getCorrectionFlag() { - return correctionFlag; - } - - /** - * @param correctionFlag - * to set - */ - public void setCorrectionFlag(Integer correctionFlag) { - this.correctionFlag = correctionFlag; - } - - /** - * @return the updateNumber - */ - public Integer getUpdateNumber() { - return updateNumber; - } - - /** - * @param updateNumber - * to set - */ - public void setUpdateNumber(Integer updateNumber) { - this.updateNumber = updateNumber; - } - - /** - * @return the bullMessage - */ - public String getBullMessage() { - return bullMessage; - } - - /** - * @param bullMessage - * to set - */ - public void setBullMessage(String bullMessage) { - this.bullMessage = bullMessage; - } - - /** - * @return the reportName - */ - public String getReportName() { - return reportName; - } - - /** - * @param reportName - * to set - */ - public void setReportName(String reportName) { - this.reportName = reportName; - } - - /** - * @return the set of AIRMET report - */ - public Set getAirmetReport() { - return airmetReport; - } - - /** - * @param airmet - * the report to set - */ - public void setAirmetReport(Set curReport) { - this.airmetReport = curReport; - } - - /** - * @param add - * AirmetReport to set - */ - public void addAirmetReport(AirmetReport curReport) { - airmetReport.add(curReport); - curReport.setParentID(this); - } - - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - if (this.getAirmetReport() != null && this.getAirmetReport().size() > 0) { - for (Iterator iter = this.getAirmetReport() - .iterator(); iter.hasNext();) { - AirmetReport cs = iter.next(); - cs.setParentID(this); - } - } - - } - -} +/** + * AirmetRecord + * + * This java class performs the mapping to the database table for AIRMET + * + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 L. Lin Initial creation + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 39 L. Lin Initial coding + * 07/2009 39 L. Lin Migration to TO11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.airmet; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; + +import javax.persistence.CascadeType; +import javax.persistence.Column; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Index; + +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +@Entity +@Table(name = "airmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) +@DynamicSerialize + + +public class AirmetRecord extends PluginDataObject{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + // reportType is AIRMET. + @Column(length=32) + @DynamicSerializeElement + private String reportType; + + // reportName will be SIERRA, TANGO, or ZULU + @Column(length=32) + @DataURI(position=1) + @DynamicSerializeElement + private String reportName; + + // WMO header + @Column(length=32) + @DataURI(position=2) + @DynamicSerializeElement + private String wmoHeader; + + // The issue office where the report from + @Column(length=32) + @DynamicSerializeElement + private String issueOffice; + + // Update number as: 1, 2, 3, ... + @Column + @DataURI(position=3) + @DynamicSerializeElement + private Integer updateNumber; + + // Issue time of the report + @Column + @DynamicSerializeElement + private Calendar issueTime; + + // The designator + @Column(length=8) + @DynamicSerializeElement + private String designatorBBB; + + // CorrectionFlag is a flag: 0 for normal, 1 for COR or CC, 2 for AMD, and 3 for TEST + /* + * CorrectionFlag is a flag: + * 0 for normal, 1 for COR or CC, 2 for AMD, 3 for TEST, and 4 for NIL report + */ + @Column + @DynamicSerializeElement + private Integer correctionFlag; + + // The entire report + @Column(length=15000) + @DynamicSerializeElement + private String bullMessage; + + + /** + * Airmet report + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "airmetReport_parentid_idex") + private Set airmetReport = new HashSet(); + + + /** + * Default Convstructor + */ + public AirmetRecord() { + this.issueOffice=""; + this.wmoHeader=""; + this.bullMessage=""; + this.designatorBBB=""; + this.updateNumber=0; + this.reportType=""; + this.reportName=null; + this.correctionFlag=0; + } + + /** + * Convstructs an airmet record from a dataURI + * + * @param uri The dataURI + */ + public AirmetRecord(String uri) { + super(uri); + } + + + @Override + public IDecoderGettable getDecoderGettable() { + // TODO Auto-generated method stub + return null; + } + + /** + * @return the issueOffice + */ + public String getIssueOffice(){ + return issueOffice; + } + + /** + * @param issueOffice to set + */ + public void setIssueOffice(String issueOffice){ + this.issueOffice=issueOffice; + } + + /** + * @return the wmoHeader + */ + public String getWmoHeader(){ + return wmoHeader; + } + + /** + * @param wnoHeader to set + */ + public void setWmoHeader(String wmoHeader){ + this.wmoHeader=wmoHeader; + } + + /** + * @return the issueTime + */ + public Calendar getIssueTime(){ + return issueTime; + } + + /** + * @param issueTime to set + */ + public void setIssueTime(Calendar issueTime){ + this.issueTime=issueTime; + } + + /** + * @return the reportType + */ + public String getReportType() { + return reportType; + } + + /** + * @param reportType to set + */ + public void setReportType(String reportType) { + this.reportType = reportType; + } + + /** + * @return the designatorBBB + */ + public String getDesignatorBBB() { + return designatorBBB; + } + + /** + * @param designatorBBB to set + */ + public void setDesignatorBBB(String designatorBBB) { + this.designatorBBB = designatorBBB; + } + + /** + * @return the correctionFlag + */ + public Integer getCorrectionFlag() { + return correctionFlag; + } + + /** + * @param correctionFlag to set + */ + public void setCorrectionFlag(Integer correctionFlag) { + this.correctionFlag = correctionFlag; + } + + /** + * @return the updateNumber + */ + public Integer getUpdateNumber() { + return updateNumber; + } + + /** + * @param updateNumber to set + */ + public void setUpdateNumber(Integer updateNumber) { + this.updateNumber = updateNumber; + } + + /** + * @return the bullMessage + */ + public String getBullMessage() { + return bullMessage; + } + + /** + * @param bullMessage to set + */ + public void setBullMessage(String bullMessage) { + this.bullMessage = bullMessage; + } + + /** + * @return the reportName + */ + public String getReportName() { + return reportName; + } + + /** + * @param reportName to set + */ + public void setReportName(String reportName) { + this.reportName = reportName; + } + + /** + * @return the set of AIRMET report + */ + public Set getAirmetReport() { + return airmetReport; + } + + /** + * @param airmet the report to set + */ + public void setAirmetReport(Set curReport) { + this.airmetReport = curReport; + } + + /** + * @param add AirmetReport to set + */ + public void addAirmetReport(AirmetReport curReport){ + airmetReport.add(curReport); + //curReport.setParentID(this); + } + + /** + * Override existing set method to modify any + * classes that use the dataURI as a foreign key + */ + @Override + public void setIdentifier(Object dataURI) + { + + this.identifier = dataURI; + /* + if(this.getAirmetReport() != null && this.getAirmetReport().size() > 0) + { + for (Iterator iter = this.getAirmetReport().iterator(); iter.hasNext();) { + AirmetReport cs = iter.next(); + cs.setParentID(this); + } + }*/ + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetReport.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetReport.java old mode 100755 new mode 100644 index 01a48fc106..723e4b8f76 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetReport.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/AirmetReport.java @@ -1,350 +1,328 @@ -/** - * AirmetReport - * - * This java class defines the getters and setters for the - * AIRMET report table. - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 L. Lin Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.airmet; - -import java.io.Serializable; -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -import org.hibernate.annotations.Index; - -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "airmet_report") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class AirmetReport implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Integer recordId = null; - - // The AIRMET record this object belongs to - @ManyToOne - @JoinColumn(name = "parentID", nullable = false) - private AirmetRecord parentID; - - /* - * hazard type as: Instrument Flight Rules(IR), Mountain Obscuration(MO), - * Turbulence(TB), Icing(IC), Sustained SFC Winds(SW), Low Level Wind - * Shear(LLWS), or CANCEL. If a report is outlook, then an "OUTLOOK: will be - * added. - */ - @Column(length = 40) - @XmlElement - @DynamicSerializeElement - private String hazardType; - - // The report indicator will be AIRMET or OUTLOOK. - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String reportIndicator; - - // Sequence ID of an AIRMET report - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String sequenceID; - - // Start time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar startTime; - - // End time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar endTime; - - // Flight level 1 - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String flightLevel1; - - // Flight level 2 - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String flightLevel2; - - // cancelFlag is a flag indicating a cancellation (0 or 1) - @Column - @XmlElement - @DynamicSerializeElement - private Integer cancelFlag; - - // The information of a complete report - @Column(length = 1440) - @XmlElement - @DynamicSerializeElement - private String segment; - - /** - * Airmet location - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @Index(name = "airmet_location_parentid_idex") - private Set airmetLocation = new HashSet(); - - /** - * No-Arg Convstructor - */ - public AirmetReport() { - this.flightLevel1 = null; - this.flightLevel2 = null; - this.segment = null; - this.hazardType = null; - this.reportIndicator = null; - this.sequenceID = null; - this.cancelFlag = 0; - } - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @return the sequenceID - */ - public String getSequenceID() { - return sequenceID; - - } - - /** - * @return the sequenceID - */ - public void setSequenceID(String sequenceID) { - this.sequenceID = sequenceID; - } - - /** - * @return the set of airmet location - */ - public Set getAirmetLocation() { - return airmetLocation; - } - - /** - * @param airmet - * the location to set - */ - public void setAirmetLocation(Set curLocation) { - this.airmetLocation = curLocation; - } - - /** - * @param add - * airmet location to set - */ - public void addAirmetLocation(AirmetLocation plocation) { - airmetLocation.add(plocation); - } - - /** - * @return the parentID - */ - // public String getParentID() { - public AirmetRecord getParentID() { - - return parentID; - } - - /** - * @param parentID - * the parentID to set - */ - public void setParentID(AirmetRecord parentID) { - this.parentID = parentID; - if (this.getAirmetLocation() != null - && this.getAirmetLocation().size() > 0) { - for (Iterator iter = this.getAirmetLocation() - .iterator(); iter.hasNext();) { - AirmetLocation cond = iter.next(); - cond.setParentID(this); - } - } - } - - /** - * @return the report - */ - public String getSegment() { - return segment; - } - - /** - * @param segment - * to set - */ - public void setSegment(String segment) { - this.segment = segment; - } - - /** - * @return the startTime - */ - public Calendar getStartTime() { - return startTime; - } - - /** - * @param startTime - * to set - */ - public void setStartTime(Calendar startTime) { - this.startTime = startTime; - } - - /** - * @return the endTime - */ - public Calendar getEndTime() { - return endTime; - } - - /** - * @param endTIme - * to set - */ - public void setEndTime(Calendar endTime) { - this.endTime = endTime; - } - - /** - * @return the flightLevel1 - */ - public String getFlightLevel1() { - return flightLevel1; - } - - /** - * @param flightLevel1 - * to set - */ - public void setFlightLevel1(String flightLevel1) { - this.flightLevel1 = flightLevel1; - } - - /** - * @return the flightLevel2 - */ - public String getFlightLevel2() { - return flightLevel2; - } - - /** - * @param flightLevel2 - * to set - */ - public void setFlightLevel2(String flightLevel2) { - this.flightLevel2 = flightLevel2; - } - - /** - * Get the record id. - * - * @return The recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * Set the record id. - * - * @param record - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - - /** - * @return the cancelFlag - */ - public Integer getCancelFlag() { - return cancelFlag; - } - - /** - * @param cancelFlag - * to set - */ - public void setCancelFlag(Integer cancelFlag) { - this.cancelFlag = cancelFlag; - } - - /** - * @return the hazardType - */ - public String getHazardType() { - return hazardType; - } - - /** - * @param hazardType - * to set - */ - public void setHazardType(String hazardType) { - this.hazardType = hazardType; - } - - /** - * @return the reportIndicator - */ - public String getReportIndicator() { - return reportIndicator; - } - - /** - * @param reportIndicator - * to set - */ - public void setReportIndicator(String reportIndicator) { - this.reportIndicator = reportIndicator; - } - -} +/** + * AirmetReport + * + * This java class defines the getters and setters for the + * AIRMET report table. + * + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 L. Lin Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.airmet; + +import java.io.Serializable; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.hibernate.annotations.Index; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +@Entity +@Table(name="airmet_report") +@DynamicSerialize +public class AirmetReport implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Integer recordId = null; + + // The AIRMET record this object belongs to + //@ManyToOne + //@JoinColumn(name="parentID", nullable=false) + // private AirmetRecord parentID; + + /* + * hazard type as: Instrument Flight Rules(IR), Mountain Obscuration(MO), + * Turbulence(TB), Icing(IC), Sustained SFC Winds(SW), + * Low Level Wind Shear(LLWS), or CANCEL. If a report is outlook, then + * an "OUTLOOK: will be added. + */ + @Column(length=40) + @DynamicSerializeElement + private String hazardType; + + //The report indicator will be AIRMET or OUTLOOK. + @Column(length=16) + @DynamicSerializeElement + private String reportIndicator; + + // Sequence ID of an AIRMET report + @Column(length=16) + @DynamicSerializeElement + private String sequenceID; + + // Start time of the report + @Column + @DynamicSerializeElement + private Calendar startTime; + + // End time of the report + @Column + @DynamicSerializeElement + private Calendar endTime; + + // Flight level 1 + @Column(length=16) + @DynamicSerializeElement + private String flightLevel1; + + // Flight level 2 + @Column(length=16) + @DynamicSerializeElement + private String flightLevel2; + + // cancelFlag is a flag indicating a cancellation (0 or 1) + @Column + @DynamicSerializeElement + private Integer cancelFlag; + + // The information of a complete report + @Column(length=1440) + @DynamicSerializeElement + private String segment; + + + /** + * Airmet location + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "airmetLocation_parentid_idex") + private Set airmetLocation = new HashSet(); + + + /** + * No-Arg Convstructor + */ + public AirmetReport() { + this.flightLevel1 = null; + this.flightLevel2=null; + this.segment=null; + this.hazardType=null; + this.reportIndicator=null; + this.sequenceID=null; + this.cancelFlag=0; + } + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * @return the sequenceID + */ + public String getSequenceID() { + return sequenceID; + + } + + /** + * @return the sequenceID + */ + public void setSequenceID(String sequenceID) { + this.sequenceID = sequenceID; + } + + /** + * @return the set of airmet location + */ + public Set getAirmetLocation() { + return airmetLocation; + } + + /** + * @param airmet the location to set + */ + public void setAirmetLocation(Set curLocation) { + this.airmetLocation = curLocation; + } + + /** + * @param add airmet location to set + */ + public void addAirmetLocation(AirmetLocation plocation){ + airmetLocation.add(plocation); + } + + /** + * @return the parentID + * + //public String getParentID() { + public AirmetRecord getParentID() { + + return parentID; + }*/ + + /** + * @param parentID the parentID to set + * + public void setParentID(AirmetRecord parentID) { + //this.parentID = parentID; + if(this.getAirmetLocation() != null && this.getAirmetLocation().size() > 0) + { + for (Iterator iter = this.getAirmetLocation().iterator(); iter.hasNext();) { + AirmetLocation cond = iter.next(); + cond.setParentID(this); + } + } + }*/ + + /** + * @return the report + */ + public String getSegment() { + return segment; + } + + /** + * @param segment to set + */ + public void setSegment(String segment) { + this.segment = segment; + } + + /** + * @return the startTime + */ + public Calendar getStartTime() { + return startTime; + } + + /** + * @param startTime to set + */ + public void setStartTime(Calendar startTime) { + this.startTime = startTime; + } + + /** + * @return the endTime + */ + public Calendar getEndTime() { + return endTime; + } + + /** + * @param endTIme to set + */ + public void setEndTime(Calendar endTime) { + this.endTime = endTime; + } + + /** + * @return the flightLevel1 + */ + public String getFlightLevel1() { + return flightLevel1; + } + + /** + * @param flightLevel1 to set + */ + public void setFlightLevel1(String flightLevel1) { + this.flightLevel1 = flightLevel1; + } + + /** + * @return the flightLevel2 + */ + public String getFlightLevel2() { + return flightLevel2; + } + + /** + * @param flightLevel2 to set + */ + public void setFlightLevel2(String flightLevel2) { + this.flightLevel2 = flightLevel2; + } + + /** + * Get the record id. + * + * @return The recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * Set the record id. + * @param record + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + + /** + * @return the cancelFlag + */ + public Integer getCancelFlag() { + return cancelFlag; + } + + /** + * @param cancelFlag to set + */ + public void setCancelFlag(Integer cancelFlag) { + this.cancelFlag = cancelFlag; + } + + /** + * @return the hazardType + */ + public String getHazardType() { + return hazardType; + } + + /** + * @param hazardType to set + */ + public void setHazardType(String hazardType) { + this.hazardType = hazardType; + } + + /** + * @return the reportIndicator + */ + public String getReportIndicator() { + return reportIndicator; + } + + /** + * @param reportIndicator to set + */ + public void setReportIndicator(String reportIndicator) { + this.reportIndicator = reportIndicator; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/AirmetDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/AirmetDao.java index 3dbadd4965..157991d2b4 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/AirmetDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/AirmetDao.java @@ -1,31 +1,13 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ package gov.noaa.nws.ncep.common.dataplugin.airmet.dao; import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; - import java.util.List; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; /** * TODO Add Description @@ -36,6 +18,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 23, 2009 jkorman Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @@ -43,7 +27,7 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * @version 1.0 */ -public class AirmetDao extends NcepDefaultPluginDao { +public class AirmetDao extends PluginDao { /** * Creates a new ReccoDao @@ -92,4 +76,11 @@ public class AirmetDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/package-info.java old mode 100755 new mode 100644 index 9756d21d53..a14f1d767a --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/dao/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains data access object for airmet data. -*/ -package gov.noaa.nws.ncep.common.dataplugin.airmet.dao; +/** +* Contains data access object for airmet data. +*/ +package gov.noaa.nws.ncep.common.dataplugin.airmet.dao; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/package-info.java old mode 100755 new mode 100644 index 0834c431c0..8841b360da --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.airmet/src/gov/noaa/nws/ncep/common/dataplugin/airmet/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains table record for decoder plug-ins -*/ -package gov.noaa.nws.ncep.common.dataplugin.airmet; +/** +* Contains table record for decoder plug-ins +*/ +package gov.noaa.nws.ncep.common.dataplugin.airmet; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/component-deploy.xml index f3c931e65e..fe90b37851 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/component-deploy.xml @@ -1,11 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/src/gov/noaa/nws/ncep/common/dataplugin/atcf/dao/AtcfDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/src/gov/noaa/nws/ncep/common/dataplugin/atcf/dao/AtcfDao.java index a2dbda62eb..b8a7dd66b9 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/src/gov/noaa/nws/ncep/common/dataplugin/atcf/dao/AtcfDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.atcf/src/gov/noaa/nws/ncep/common/dataplugin/atcf/dao/AtcfDao.java @@ -12,64 +12,64 @@ * * @author fjyen * @version 1.0 - **/ -package gov.noaa.nws.ncep.common.dataplugin.atcf.dao; - -import java.util.List; - -import gov.noaa.nws.ncep.common.dataplugin.atcf.AtcfRecord; + **/ +package gov.noaa.nws.ncep.common.dataplugin.atcf.dao; + +import java.util.List; + +import gov.noaa.nws.ncep.common.dataplugin.atcf.AtcfRecord; import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; -import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.edex.database.DataAccessLayerException; - -public class AtcfDao extends NcepDefaultPluginDao { - - - /** - * Creates a new ReccoDao - * @throws PluginException - */ - public AtcfDao(String pluginName) throws PluginException { - super(pluginName); - } - - /** - * Retrieves a atcf report using the datauri . - * - * @param dataURI - * The dataURI to match against. - * @return The report record if it exists. - */ - public AtcfRecord queryByDataURI(String dataURI) { - AtcfRecord report = null; - List obs = null; - try { - obs = queryBySingleCriteria("dataURI", dataURI); - } catch (DataAccessLayerException e) { - e.printStackTrace(); - } - if((obs != null)&&(obs.size() > 0)) { - report = (AtcfRecord) obs.get(0); - } - return report; - } - - /** - * Queries for to determine if a given data uri exists on the ATCF table. - * - * @param dataUri - * The DataURI to find. - * @return An array of objects. If not null, there should only be a single - * element. - */ - public Object[] queryDataUriColumn(final String dataUri) { - - String sql = "select datauri from awips.atcf where datauri='" - + dataUri + "';"; - - Object[] results = executeSQLQuery(sql); - - return results; - } -} + +public class AtcfDao extends NcepDefaultPluginDao { + + + /** + * Creates a new ReccoDao + * @throws PluginException + */ + public AtcfDao(String pluginName) throws PluginException { + super(pluginName); + } + + /** + * Retrieves a atcf report using the datauri . + * + * @param dataURI + * The dataURI to match against. + * @return The report record if it exists. + */ + public AtcfRecord queryByDataURI(String dataURI) { + AtcfRecord report = null; + List obs = null; + try { + obs = queryBySingleCriteria("dataURI", dataURI); + } catch (DataAccessLayerException e) { + e.printStackTrace(); + } + if((obs != null)&&(obs.size() > 0)) { + report = (AtcfRecord) obs.get(0); + } + return report; + } + + /** + * Queries for to determine if a given data uri exists on the ATCF table. + * + * @param dataUri + * The DataURI to find. + * @return An array of objects. If not null, there should only be a single + * element. + */ + public Object[] queryDataUriColumn(final String dataUri) { + + String sql = "select datauri from awips.atcf where datauri='" + + dataUri + "';"; + + Object[] results = executeSQLQuery(sql); + + return results; + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/component-deploy.xml index 3812f979b6..cc9e2864ea 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/component-deploy.xml @@ -1,11 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwFips.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwFips.java index 9375ee152d..849a81eeb0 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwFips.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwFips.java @@ -8,6 +8,8 @@ * Date Author Description * ------------ ---------- ----------- -------------------------- * 12/2008 L. Lin Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -20,12 +22,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -33,7 +30,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="aww_fips") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwFips implements Serializable, ISerializableObject { @@ -44,19 +40,17 @@ public class AwwFips implements Serializable, ISerializableObject { private Integer recordId = null; // The AWW record this object belongs to. - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private AwwUgc parentID; + //@ManyToOne + //@JoinColumn(name="parentID", nullable=false) + //private AwwUgc parentID; // The county FIPS @Column(length=16) - @XmlElement @DynamicSerializeElement private String fips; // The universal geographic code @Column(length=640) - @XmlElement @DynamicSerializeElement private String ugc; @@ -94,19 +88,7 @@ public class AwwFips implements Serializable, ISerializableObject { this.recordId = recordId; } - /** - * @return the parentID - */ - public AwwUgc getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(AwwUgc parentID) { - this.parentID = parentID; - } + /** * @return the fips diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwHVtec.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwHVtec.java index aa1c5dc546..be1f89791d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwHVtec.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwHVtec.java @@ -9,6 +9,8 @@ * ------------ ---------- ----------- -------------------------- * 12/2008 L. Lin Initial creation * 04/2009 L. Lin Convert to to10 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -23,12 +25,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -36,7 +33,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="aww_hvtec") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwHVtec implements Serializable, ISerializableObject { @@ -47,55 +43,47 @@ public class AwwHVtec implements Serializable, ISerializableObject { private Integer recordId = null; // The AWW HVTEC record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private AwwVtec parentID; + //@ManyToOne + //@JoinColumn(name="parentID", nullable=false) + //private AwwVtec parentID; // NWS location Identifier @Column(length=16) - @XmlElement @DynamicSerializeElement private String locationIdentifier; // Flood severity such as 0, N, 1, 2, 3, U @Column(length=16) - @XmlElement @DynamicSerializeElement private String floodSeverity; // Immediate Cause such as ER, SM, ...etc @Column(length=16) - @XmlElement @DynamicSerializeElement private String immediateCause; // Flood record such as NO, NR, UU, OO @Column(length=32) - @XmlElement @DynamicSerializeElement private String floodRecord; // HVTEC event start time @Column - @XmlElement @DynamicSerializeElement private Calendar eventStartTime; // HVTEC event crest time @Column - @XmlElement @DynamicSerializeElement private Calendar eventCrestTime; // HVTEC event end time @Column - @XmlElement @DynamicSerializeElement private Calendar eventEndTime; // Text information for HVTEC line @Column(length=128) - @XmlElement @DynamicSerializeElement private String hvtecLine; @@ -139,19 +127,7 @@ public class AwwHVtec implements Serializable, ISerializableObject { this.recordId = recordId; } - /** - * @return the parentID - */ - public AwwVtec getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(AwwVtec parentID) { - this.parentID = parentID; - } + /** * @return the floodSeverity diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwLatlons.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwLatlons.java index fe0e7d18be..542bd0d566 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwLatlons.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwLatlons.java @@ -9,6 +9,8 @@ * ------------ ---------- ----------- -------------------------- * 12/2008 L. Lin Initial creation * 04/2009 L. Lin Convert to to10 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -17,18 +19,11 @@ package gov.noaa.nws.ncep.common.dataplugin.aww; import java.io.Serializable; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; -import gov.noaa.nws.ncep.common.dataplugin.aww.AwwRecord; - import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -36,7 +31,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="aww_latlons") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwLatlons implements Serializable, ISerializableObject { @@ -46,26 +40,19 @@ public class AwwLatlons implements Serializable, ISerializableObject { @GeneratedValue private Integer recordId = null; - // The AWW Latlons record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private AwwUgc parentID; - + // Latitude @Column - @XmlElement @DynamicSerializeElement private Float lat; // longitude @Column - @XmlElement @DynamicSerializeElement private Float lon; // Index for the order of a complete "lat/lon" set @Column - @XmlElement @DynamicSerializeElement private int index; @@ -104,19 +91,7 @@ public class AwwLatlons implements Serializable, ISerializableObject { this.recordId = recordId; } - /** - * @return the parentID - */ - public AwwUgc getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(AwwUgc parentID) { - this.parentID = parentID; - } + /** * @return the latitude diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java index 5cfbf51672..081ff93ae5 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwRecord.java @@ -21,6 +21,8 @@ * when the aww record is inserted into relational DB * The reason mndTime is used is because the combination * of original 5 elements is not unique in some scenarios. + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * This code has been developed by the SIB for use in the AWIPS2 system. @@ -40,6 +42,7 @@ import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -48,6 +51,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.hibernate.annotations.Index; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; @@ -57,8 +61,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name = "aww", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwRecord extends PluginDataObject{ @@ -101,69 +103,60 @@ public class AwwRecord extends PluginDataObject{ */ @Column(length=40) @DataURI(position=1) - @XmlElement @DynamicSerializeElement private String reportType; // The issue office where the report from @Column(length=32) @DataURI(position=2) - @XmlElement @DynamicSerializeElement private String issueOffice; // The collection of watch numbers in the report @Column(length=160) @DataURI(position=5) - @XmlElement @DynamicSerializeElement private String watchNumber; // WMO header @Column(length=32) - @XmlElement @DynamicSerializeElement private String wmoHeader; // Issue time of the report @Column @DataURI(position=3) - @XmlElement @DynamicSerializeElement private Calendar issueTime; // The designator @Column(length=8) @DataURI(position=4) - @XmlElement @DynamicSerializeElement private String designatorBBB; // The designator @Column(length=72) @DataURI(position=6) - @XmlElement @DynamicSerializeElement private String mndTime; // Attention WFO @Column(length=72) - @XmlElement @DynamicSerializeElement private String attentionWFO; // The entire report @Column(length=40000) - @XmlElement @DynamicSerializeElement private String bullMessage; // AWW UGC Table @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "awwUGC_parentid_idex") private Set awwUGC = new HashSet(); @@ -258,7 +251,7 @@ public class AwwRecord extends PluginDataObject{ */ public void addAwwUGC(AwwUgc pugc){ awwUGC.add(pugc); - pugc.setParentID(this); + //pugc.setParentID(this); } /** @@ -270,13 +263,7 @@ public class AwwRecord extends PluginDataObject{ this.identifier = dataURI; - if(this.getAwwUGC() != null && this.getAwwUGC().size() > 0) - { - for (Iterator iter = this.getAwwUGC().iterator(); iter.hasNext();) { - AwwUgc cond = iter.next(); - cond.setParentID(this); - } - } + } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwUgc.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwUgc.java index 2333274836..9754660ca5 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwUgc.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwUgc.java @@ -9,6 +9,8 @@ * ------------ ---------- ----------- -------------------------- * 12/2008 L. Lin Initial creation * 04/2009 L. Lin Convert to to10 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -24,7 +26,6 @@ import gov.noaa.nws.ncep.common.dataplugin.aww.AwwLatlons; import java.util.HashSet; import java.util.Set; -import java.util.Iterator; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -35,22 +36,15 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.Index; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="aww_ugc") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwUgc implements Serializable, ISerializableObject { @@ -61,31 +55,27 @@ public class AwwUgc implements Serializable, ISerializableObject { private Integer recordId = null; // The AWW record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private AwwRecord parentID; + //@ManyToOne + //@JoinColumn(name="parentID", nullable=false) + //private AwwRecord parentID; // The universal geographic code @Column(length=640) - @XmlElement @DynamicSerializeElement private String ugc; // The product purge time @Column - @XmlElement @DynamicSerializeElement private Calendar prodPurgeTime; // A collection of VTEC event tracking numbers under this UGC @Column(length=40) - @XmlElement @DynamicSerializeElement private String eventTrackingNumber; // Text information for this segment @Column(length=12000) - @XmlElement @DynamicSerializeElement private String segment; @@ -93,27 +83,27 @@ public class AwwUgc implements Serializable, ISerializableObject { * AWW VTEC Table */ @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "awwVtecLine_parentid_idex") private Set awwVtecLine = new HashSet(); /** * Aww FIPS Table */ @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "awwFIPS_parentid_idex") private Set awwFIPS = new HashSet(); /** * Aww LatLon Table */ @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "awwLatLon_parentid_idex") private Set awwLatLon = new HashSet(); /** @@ -152,44 +142,7 @@ public class AwwUgc implements Serializable, ISerializableObject { return serialVersionUID; } - /** - * @return the parentID - */ - public AwwRecord getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(AwwRecord parentID) { - this.parentID = parentID; - - if(this.getAwwVtecLine() != null && this.getAwwVtecLine().size() > 0) - { - for (Iterator iter = this.getAwwVtecLine().iterator(); iter.hasNext();) { - AwwVtec cond = iter.next(); - cond.setParentID(this); - } - } - - if (this.getAwwFIPS() !=null && this.getAwwFIPS().size() >0 ) - { - for (Iterator iter = this.getAwwFIPS().iterator(); iter.hasNext();) { - AwwFips cond = iter.next(); - cond.setParentID(this); - cond.setUgc(ugc); - } - } - - if (this.getAwwLatLon() !=null && this.getAwwLatLon().size() >0 ) - { - for (Iterator iter = this.getAwwLatLon().iterator(); iter.hasNext();) { - AwwLatlons cond = iter.next(); - cond.setParentID(this); - } - } - } + /** * @return the ugc diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwVtec.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwVtec.java index ac68f47286..59031bc6d6 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwVtec.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/AwwVtec.java @@ -9,6 +9,8 @@ * ------------ ---------- ----------- -------------------------- * 12/2008 L. Lin Initial creation * 04/2009 L. Lin Convert to to10. + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ @@ -19,7 +21,6 @@ import java.io.Serializable; import java.util.Calendar; import java.util.HashSet; import java.util.Set; -import java.util.Iterator; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -30,14 +31,9 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.Index; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; @@ -45,7 +41,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="aww_vtec") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class AwwVtec implements Serializable, ISerializableObject { @@ -56,61 +51,52 @@ public class AwwVtec implements Serializable, ISerializableObject { private Integer recordId = null; // The AWW VTEC record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private AwwUgc parentID; + //@ManyToOne + //@JoinColumn(name="parentID", nullable=false) + //private AwwUgc parentID; // VTEC office ID @Column(length=16) - @XmlElement @DynamicSerializeElement private String officeID; // Action such as NEW, CON, CAN, EXT, .... @Column(length=16) - @XmlElement @DynamicSerializeElement private String action; // VTEC event start time @Column - @XmlElement @DynamicSerializeElement private Calendar eventStartTime; // VTEC event end time @Column - @XmlElement @DynamicSerializeElement private Calendar eventEndTime; // VTEC event tracking number @Column(length=16) - @XmlElement @DynamicSerializeElement private String eventTrackingNumber; // Significance such as W-warning, A-watch, Y-advisory, S-statement @Column(length=16) - @XmlElement @DynamicSerializeElement private String significance; // product class such as O-operational product, T-test product, E-experimental... @Column(length=16) - @XmlElement @DynamicSerializeElement private String productClass; // phenomena - two character string PP @Column(length=16) - @XmlElement @DynamicSerializeElement private String phenomena; // Text information for VTEC @Column(length=128) - @XmlElement @DynamicSerializeElement private String vtecLine; @@ -118,9 +104,9 @@ public class AwwVtec implements Serializable, ISerializableObject { * AWW HVTEC Table */ @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "awwHVtecLine_parentid_idex") private Set awwHVtecLine = new HashSet(); /** @@ -163,26 +149,7 @@ public class AwwVtec implements Serializable, ISerializableObject { this.recordId = recordId; } - /** - * @return the parentID - */ - public AwwUgc getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(AwwUgc parentID) { - this.parentID = parentID; - if (this.getAwwHVtecLine() != null && this.getAwwHVtecLine().size() > 0) - { - for (Iterator iter = this.getAwwHVtecLine().iterator(); iter.hasNext();) { - AwwHVtec cond = iter.next(); - cond.setParentID(this); - } - } - } + /** * @return the vtecLine diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/dao/AwwDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/dao/AwwDao.java index 19b6c3c350..962d8a7bb7 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/dao/AwwDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.aww/src/gov/noaa/nws/ncep/common/dataplugin/aww/dao/AwwDao.java @@ -8,20 +8,23 @@ * Date Author Description * ------------ ---------- ----------- -------------------------- * 05/2010 L. Lin Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * This code has been developed by the SIB for use in the AWIPS2 system. */ package gov.noaa.nws.ncep.common.dataplugin.aww.dao; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; - import java.util.List; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; -public class AwwDao extends NcepDefaultPluginDao { +public class AwwDao extends PluginDao { /** * Creates a new AwwDao @@ -70,4 +73,11 @@ public class AwwDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject old mode 100755 new mode 100644 diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/component-deploy.xml old mode 100755 new mode 100644 index be412e1f79..2b151fd65d --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/component-deploy.xml @@ -1,11 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetLocation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetLocation.java old mode 100755 new mode 100644 index a4449d8251..4a900182ec --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetLocation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetLocation.java @@ -1,204 +1,178 @@ -/** - * ConvsigmetLocation - * - * This java class defines the getters and setters for the - * convective sigmet location table. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 06/2009 87/114 L. Lin Enlarge size of locationLine and location. - * 07/2009 87/114 L. Lin Migration to TO11 - * 09/2009 87/114 L. Lin Add latitude/longitude to location table - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ -package gov.noaa.nws.ncep.common.dataplugin.convsigmet; - -import java.io.Serializable; - -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -@Entity -@Table(name="convsigmet_location") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class ConvSigmetLocation implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Integer recordId = null; - - // The consigmet record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private ConvSigmetSection parentID; - - // Collection of locations - @Column(length=480) - @XmlElement - @DynamicSerializeElement - private String locationLine; - - // Each location of a convective sigmet forecast area - @Column(length=48) - @XmlElement - @DynamicSerializeElement - private String location; - - // Each latitude of a convective sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double latitude; - - // Each longitude of a convective sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double longitude; - - // Index for the order of a complete location set - @Column - @XmlElement - @DynamicSerializeElement - private Integer index; - - /** - * No-Arg Convstructor. - */ - public ConvSigmetLocation() { - this.locationLine=""; - this.location=""; - this.index=IDecoderConstantsN.INTEGER_MISSING; - } - - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @return the parentID - */ - public ConvSigmetSection getParentID() { - return parentID; - } - - /** - * @param parentID to set - */ - public void setParentID(ConvSigmetSection parentID) { - this.parentID = parentID; - } - - /** - * @return the index - */ - public Integer getIndex() { - return index; - } - - /** - * @param index to set - */ - public void setIndex(Integer index) { - this.index = index; - } - - /** - * @return the locationLine - */ - public String getLocationLine() { - return locationLine; - } - - /** - * @param locationLine to set - */ - public void setLocationLine(String locationLine) { - this.locationLine = locationLine; - } - - /** - * @return the location - */ - public String getLocation() { - return location; - } - - /** - * @param location to set - */ - public void setLocation(String location) { - this.location = location; - } - - /** - * @return the latitude - */ - public double getLatitude() { - return latitude; - } - - /** - * @param latitude to set - */ - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - /** - * @return the longitude - */ - public double getLongitude() { - return longitude; - } - - /** - * @param longitude to set - */ - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - - /** - * Get the record id. - * - * @return The recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * Set the record id. - * @param record - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - -} +/** + * ConvsigmetLocation + * + * This java class defines the getters and setters for the + * convective sigmet location table. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 03/2009 87/114 L. Lin Initial coding + * 06/2009 87/114 L. Lin Enlarge size of locationLine and location. + * 07/2009 87/114 L. Lin Migration to TO11 + * 09/2009 87/114 L. Lin Add latitude/longitude to location table + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ +package gov.noaa.nws.ncep.common.dataplugin.convsigmet; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +@Entity +@Table(name="convsigmet_location") +@DynamicSerialize +public class ConvSigmetLocation implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Integer recordId = null; + + + // Collection of locations + @Column(length=480) + @DynamicSerializeElement + private String locationLine; + + // Each location of a convective sigmet forecast area + @Column(length=48) + @DynamicSerializeElement + private String location; + + // Each latitude of a convective sigmet forecast area + @Column + @DynamicSerializeElement + private double latitude; + + // Each longitude of a convective sigmet forecast area + @Column + @DynamicSerializeElement + private double longitude; + + // Index for the order of a complete location set + @Column + @DynamicSerializeElement + private Integer index; + + /** + * No-Arg Convstructor. + */ + public ConvSigmetLocation() { + this.locationLine=""; + this.location=""; + this.index=IDecoderConstantsN.INTEGER_MISSING; + } + + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + + /** + * @return the index + */ + public Integer getIndex() { + return index; + } + + /** + * @param index to set + */ + public void setIndex(Integer index) { + this.index = index; + } + + /** + * @return the locationLine + */ + public String getLocationLine() { + return locationLine; + } + + /** + * @param locationLine to set + */ + public void setLocationLine(String locationLine) { + this.locationLine = locationLine; + } + + /** + * @return the location + */ + public String getLocation() { + return location; + } + + /** + * @param location to set + */ + public void setLocation(String location) { + this.location = location; + } + + /** + * @return the latitude + */ + public double getLatitude() { + return latitude; + } + + /** + * @param latitude to set + */ + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + /** + * @return the longitude + */ + public double getLongitude() { + return longitude; + } + + /** + * @param longitude to set + */ + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + + /** + * Get the record id. + * + * @return The recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * Set the record id. + * @param record + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java old mode 100755 new mode 100644 index b8ce874bb0..2e720ca28a --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetRecord.java @@ -1,311 +1,287 @@ -/** - * ConvsigmetRecord - * - * This java class performs the mapping to the database table for CONVSIGMET - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 07/2009 87/114 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.convsigmet; - -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import org.hibernate.annotations.Index; - -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "convsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class ConvSigmetRecord extends PluginDataObject { - - /** - * - */ - private static final long serialVersionUID = 1L; - - // reportType is "convective sigmet". - @Column(length = 32) - @DataURI(position = 1) - @XmlElement - @DynamicSerializeElement - private String reportType; - - // WMO header - @Column(length = 32) - @DataURI(position = 2) - @XmlElement - @DynamicSerializeElement - private String wmoHeader; - - // forecastRegion as: SIGW, SIGC, or SIGE - @Column(length = 8) - @DataURI(position = 3) - @XmlElement - @DynamicSerializeElement - private String forecastRegion; - - // The issue office where the report from - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String issueOffice; - - // Issue time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar issueTime; - - // The designator - @Column(length = 8) - @XmlElement - @DynamicSerializeElement - private String designatorBBB; - - // CorrectionFlag is a flag indicating a cancellation (0 or 1) - @Column - @XmlElement - @DynamicSerializeElement - private Integer correctionFlag; - - // The entire report - @Column(length = 15000) - @XmlElement - @DynamicSerializeElement - private String bullMessage; - - /** - * Convsigmet section - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @Index(name = "convsigmet_section_parentid_idex") - private Set convSigmetSection = new HashSet(); - - /** - * Default Convstructor - */ - public ConvSigmetRecord() { - this.issueOffice = ""; - this.wmoHeader = ""; - this.bullMessage = ""; - this.designatorBBB = ""; - this.forecastRegion = ""; - this.reportType = ""; - this.correctionFlag = IDecoderConstantsN.INTEGER_MISSING; - } - - /** - * Convstructs a consigmet record from a dataURI - * - * @param uri - * The dataURI - */ - public ConvSigmetRecord(String uri) { - super(uri); - } - - @Override - public IDecoderGettable getDecoderGettable() { - // TODO Auto-generated method stub - return null; - } - - /** - * @return the issueOffice - */ - public String getIssueOffice() { - return issueOffice; - } - - /** - * @param issueOffice - * to set - */ - public void setIssueOffice(String issueOffice) { - this.issueOffice = issueOffice; - } - - /** - * @return the wmoHeader - */ - public String getWmoHeader() { - return wmoHeader; - } - - /** - * @param wnoHeader - * to set - */ - public void setWmoHeader(String wmoHeader) { - this.wmoHeader = wmoHeader; - } - - /** - * @return the issueTime - */ - public Calendar getIssueTime() { - return issueTime; - } - - /** - * @param issueTime - * to set - */ - public void setIssueTime(Calendar issueTime) { - this.issueTime = issueTime; - } - - /** - * @return the reportType - */ - public String getReportType() { - return reportType; - } - - /** - * @param reportType - * to set - */ - public void setReportType(String reportType) { - this.reportType = reportType; - } - - /** - * @return the designatorBBB - */ - public String getDesignatorBBB() { - return designatorBBB; - } - - /** - * @param designatorBBB - * to set - */ - public void setDesignatorBBB(String designatorBBB) { - this.designatorBBB = designatorBBB; - } - - /** - * @return the correctionFlag - */ - public Integer getCorrectionFlag() { - return correctionFlag; - } - - /** - * @param correctionFlag - * to set - */ - public void setCorrectionFlag(Integer correctionFlag) { - this.correctionFlag = correctionFlag; - } - - /** - * @return the forecastRegion - */ - public String getForecastRegion() { - return forecastRegion; - } - - /** - * @param forecastRegion - * to set - */ - public void setForecastRegion(String forecastRegion) { - this.forecastRegion = forecastRegion; - } - - /** - * @return the bullMessage - */ - public String getBullMessage() { - return bullMessage; - } - - /** - * @param bullMessage - * to set - */ - public void setBullMessage(String bullMessage) { - this.bullMessage = bullMessage; - } - - /** - * @return the set of convective Sigmet section - */ - public Set getConvSigmetSection() { - return convSigmetSection; - } - - /** - * @param convsigmet - * the section to set - */ - public void setConvSigmetSection(Set convSection) { - this.convSigmetSection = convSection; - } - - /** - * @param add - * convective Sigmet Section to set - */ - public void addConvSigmetSection(ConvSigmetSection psection) { - convSigmetSection.add(psection); - psection.setParentID(this); - } - - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - if (this.getConvSigmetSection() != null - && this.getConvSigmetSection().size() > 0) { - for (Iterator iter = this.getConvSigmetSection() - .iterator(); iter.hasNext();) { - ConvSigmetSection cs = iter.next(); - cs.setParentID(this); - } - } - - } - -} +/** + * ConvsigmetRecord + * + * This java class performs the mapping to the database table for CONVSIGMET + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 03/2009 87/114 L. Lin Initial coding + * 07/2009 87/114 L. Lin Migration to TO11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.convsigmet; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; + +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +import javax.persistence.CascadeType; +import javax.persistence.Column; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Index; + +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +@Entity +@Table(name = "convsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) +@DynamicSerialize + + +public class ConvSigmetRecord extends PluginDataObject{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + // reportType is "convective sigmet". + @Column(length=32) + @DataURI(position=1) + @DynamicSerializeElement + private String reportType; + + // WMO header + @Column(length=32) + @DataURI(position=2) + @DynamicSerializeElement + private String wmoHeader; + + // forecastRegion as: SIGW, SIGC, or SIGE + @Column(length=8) + @DataURI(position=3) + @DynamicSerializeElement + private String forecastRegion; + + // The issue office where the report from + @Column(length=32) + @DynamicSerializeElement + private String issueOffice; + + // Issue time of the report + @Column + @DynamicSerializeElement + private Calendar issueTime; + + // The designator + @Column(length=8) + @DynamicSerializeElement + private String designatorBBB; + + // CorrectionFlag is a flag indicating a cancellation (0 or 1) + @Column + @DynamicSerializeElement + private Integer correctionFlag; + + // The entire report + @Column(length=15000) + @DynamicSerializeElement + private String bullMessage; + + + /** + * Convsigmet section + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "convSigmetSection_parentid_idex") + private Set convSigmetSection = new HashSet(); + + + /** + * Default Convstructor + */ + public ConvSigmetRecord() { + this.issueOffice=""; + this.wmoHeader=""; + this.bullMessage=""; + this.designatorBBB=""; + this.forecastRegion=""; + this.reportType=""; + this.correctionFlag=IDecoderConstantsN.INTEGER_MISSING; + } + + /** + * Convstructs a consigmet record from a dataURI + * + * @param uri The dataURI + */ + public ConvSigmetRecord(String uri) { + super(uri); + } + + + @Override + public IDecoderGettable getDecoderGettable() { + // TODO Auto-generated method stub + return null; + } + + /** + * @return the issueOffice + */ + public String getIssueOffice(){ + return issueOffice; + } + + /** + * @param issueOffice to set + */ + public void setIssueOffice(String issueOffice){ + this.issueOffice=issueOffice; + } + + /** + * @return the wmoHeader + */ + public String getWmoHeader(){ + return wmoHeader; + } + + /** + * @param wnoHeader to set + */ + public void setWmoHeader(String wmoHeader){ + this.wmoHeader=wmoHeader; + } + + /** + * @return the issueTime + */ + public Calendar getIssueTime(){ + return issueTime; + } + + /** + * @param issueTime to set + */ + public void setIssueTime(Calendar issueTime){ + this.issueTime=issueTime; + } + + /** + * @return the reportType + */ + public String getReportType() { + return reportType; + } + + /** + * @param reportType to set + */ + public void setReportType(String reportType) { + this.reportType = reportType; + } + + /** + * @return the designatorBBB + */ + public String getDesignatorBBB() { + return designatorBBB; + } + + /** + * @param designatorBBB to set + */ + public void setDesignatorBBB(String designatorBBB) { + this.designatorBBB = designatorBBB; + } + + /** + * @return the correctionFlag + */ + public Integer getCorrectionFlag() { + return correctionFlag; + } + + /** + * @param correctionFlag to set + */ + public void setCorrectionFlag(Integer correctionFlag) { + this.correctionFlag = correctionFlag; + } + + /** + * @return the forecastRegion + */ + public String getForecastRegion() { + return forecastRegion; + } + + /** + * @param forecastRegion to set + */ + public void setForecastRegion(String forecastRegion) { + this.forecastRegion = forecastRegion; + } + + /** + * @return the bullMessage + */ + public String getBullMessage() { + return bullMessage; + } + + /** + * @param bullMessage to set + */ + public void setBullMessage(String bullMessage) { + this.bullMessage = bullMessage; + } + + + /** + * @return the set of convective Sigmet section + */ + public Set getConvSigmetSection() { + return convSigmetSection; + } + + /** + * @param convsigmet the section to set + */ + public void setConvSigmetSection(Set convSection) { + this.convSigmetSection = convSection; + } + + /** + * @param add convective Sigmet Section to set + */ + public void addConvSigmetSection(ConvSigmetSection psection){ + convSigmetSection.add(psection); + + } + + /** + * Override existing set method to modify any + * classes that use the dataURI as a foreign key + */ + @Override + public void setIdentifier(Object dataURI) + { + + this.identifier = dataURI; + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetSection.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetSection.java old mode 100755 new mode 100644 index 1c64860c13..0a508f87f2 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetSection.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/ConvSigmetSection.java @@ -1,397 +1,343 @@ -/** - * ConvsigmetSection - * - * This java class defines the getters and setters for the - * convective sigmet section table. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 07/2009 87/114 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.convsigmet; - -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -import java.io.Serializable; -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -import org.hibernate.annotations.Index; - -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "convsigmet_section") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class ConvSigmetSection implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Integer recordId = null; - - // The CONVSIGMET record this object belongs to - @ManyToOne - @JoinColumn(name = "parentID", nullable = false) - private ConvSigmetRecord parentID; - - // Class type such as: LINE, AREA, ISOL, CS, and OUTLOOK - @Column(length = 8) - @XmlElement - @DynamicSerializeElement - private String classType; - - // Sequence ID of a convective sigmet report - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String sequenceID; - - // Start time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar startTime; - - // End time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar endTime; - - /* - * Intensity is DMSHG (weakening), DSIPTG (ending) INTSFYG (strengthening), - * DVLPG (beginning/growing) - */ - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String intensity; - - // To where flight level from tops - @Column - @XmlElement - @DynamicSerializeElement - private int flightLevel; - - // TOPS TO or TOPS ABV for flight level - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String cloudTop; - - // Direction of weather report heads to - @Column - @XmlElement - @DynamicSerializeElement - private int direction; - - // wind speed in knots - @Column - @XmlElement - @DynamicSerializeElement - private int speed; - - // Distance is the Distance or Area diameter of the area or line - @Column - @XmlElement - @DynamicSerializeElement - private int distance; - - // The information of a complete section - @Column(length = 720) - @XmlElement - @DynamicSerializeElement - private String segment; - - /** - * Convsigmet location - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @Index(name = "convsigmet_location_parentid_idex") - private Set convSigmetLocation = new HashSet(); - - /** - * No-Arg Convstructor - */ - public ConvSigmetSection() { - this.intensity = null; - this.cloudTop = null; - this.segment = null; - this.classType = null; - this.sequenceID = null; - - this.direction = IDecoderConstantsN.INTEGER_MISSING; - this.speed = IDecoderConstantsN.INTEGER_MISSING; - this.distance = IDecoderConstantsN.INTEGER_MISSING; - this.flightLevel = IDecoderConstantsN.INTEGER_MISSING; - } - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @return the sequenceID - */ - public String getSequenceID() { - return sequenceID; - - } - - /** - * @return the sequenceID - */ - public void setSequenceID(String sequenceID) { - this.sequenceID = sequenceID; - } - - /** - * @return the intensity - */ - public String getIntensity() { - return intensity; - } - - /** - * @param intensity - * to set - */ - public void setIntensity(String intensity) { - this.intensity = intensity; - } - - /** - * @return the direction - */ - public int getDirection() { - return direction; - } - - /** - * @param direction - * to set - */ - public void setDirection(int direction) { - this.direction = direction; - } - - /** - * @return the speed - */ - public int getSpeed() { - return speed; - } - - /** - * @param speed - * to set - */ - public void setSpeed(int speed) { - this.speed = speed; - } - - /** - * @return the distance - */ - public int getDistance() { - return distance; - } - - /** - * @param distance - * to set - */ - public void setDistance(int distance) { - this.distance = distance; - } - - /** - * @return the set of convective sigmet location - */ - public Set getConvSigmetLocation() { - return convSigmetLocation; - } - - /** - * @param convsigmet - * the location to set - */ - public void setConvSigmetLocation(Set convLocation) { - this.convSigmetLocation = convLocation; - } - - /** - * @param add - * conv Sigmet location to set - */ - public void addConvSigmetLocation(ConvSigmetLocation plocation) { - convSigmetLocation.add(plocation); - } - - /** - * @return the parentID - */ - // public String getParentID() { - public ConvSigmetRecord getParentID() { - - return parentID; - } - - /** - * @param parentID - * the parentID to set - */ - public void setParentID(ConvSigmetRecord parentID) { - this.parentID = parentID; - if (this.getConvSigmetLocation() != null - && this.getConvSigmetLocation().size() > 0) { - for (Iterator iter = this - .getConvSigmetLocation().iterator(); iter.hasNext();) { - ConvSigmetLocation cond = iter.next(); - cond.setParentID(this); - } - } - } - - /** - * @return the classType - */ - public String getClassType() { - return classType; - } - - /** - * @param classType - * to set - */ - public void setClassType(String classType) { - this.classType = classType; - } - - /** - * @return the section - */ - public String getSegment() { - return segment; - } - - /** - * @param segment - * to set - */ - public void setSegment(String segment) { - this.segment = segment; - } - - /** - * @return the startTime - */ - public Calendar getStartTime() { - return startTime; - } - - /** - * @param startTime - * to set - */ - public void setStartTime(Calendar startTime) { - this.startTime = startTime; - } - - /** - * @return the endTime - */ - public Calendar getEndTime() { - return endTime; - } - - /** - * @param endTIme - * to set - */ - public void setEndTime(Calendar endTime) { - this.endTime = endTime; - } - - /** - * @return the cloudTop - */ - public String getCloudTop() { - return cloudTop; - } - - /** - * @param cloudTop - * to set - */ - public void setCloudTop(String cloudTop) { - this.cloudTop = cloudTop; - } - - /** - * @return the flightLevel - */ - public int getFlightLevel() { - return flightLevel; - } - - /** - * @param flightLevel - * to set - */ - public void setFlightLevel(int flightLevel) { - this.flightLevel = flightLevel; - } - - /** - * Get the record id. - * - * @return The recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * Set the record id. - * - * @param record - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - -} +/** + * ConvsigmetSection + * + * This java class defines the getters and setters for the + * convective sigmet section table. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 03/2009 87/114 L. Lin Initial coding + * 07/2009 87/114 L. Lin Migration to TO11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.convsigmet; + +import java.io.Serializable; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import org.hibernate.annotations.Index; +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +@Entity +@Table(name="convsigmet_section") +@DynamicSerialize +public class ConvSigmetSection implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Integer recordId = null; + + + // Class type such as: LINE, AREA, ISOL, CS, and OUTLOOK + @Column(length=8) + @DynamicSerializeElement + private String classType; + + // Sequence ID of a convective sigmet report + @Column(length=16) + @DynamicSerializeElement + private String sequenceID; + + // Start time of the report + @Column + @DynamicSerializeElement + private Calendar startTime; + + // End time of the report + @Column + @DynamicSerializeElement + private Calendar endTime; + + /* + * Intensity is DMSHG (weakening), DSIPTG (ending) + * INTSFYG (strengthening), DVLPG (beginning/growing) + */ + @Column(length=32) + @DynamicSerializeElement + private String intensity; + + // To where flight level from tops + @Column + @DynamicSerializeElement + private int flightLevel; + + // TOPS TO or TOPS ABV for flight level + @Column(length=16) + @DynamicSerializeElement + private String cloudTop; + + // Direction of weather report heads to + @Column + @DynamicSerializeElement + private int direction; + + // wind speed in knots + @Column + @DynamicSerializeElement + private int speed; + + // Distance is the Distance or Area diameter of the area or line + @Column + @DynamicSerializeElement + private int distance; + + // The information of a complete section + @Column(length=720) + @DynamicSerializeElement + private String segment; + + + /** + * Convsigmet location + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "convSigmetLocation_parentid_idex") + private Set convSigmetLocation = new HashSet(); + + + /** + * No-Arg Convstructor + */ + public ConvSigmetSection() { + this.intensity = null; + this.cloudTop=null; + this.segment=null; + this.classType=null; + this.sequenceID=null; + + this.direction=IDecoderConstantsN.INTEGER_MISSING; + this.speed=IDecoderConstantsN.INTEGER_MISSING; + this.distance=IDecoderConstantsN.INTEGER_MISSING; + this.flightLevel=IDecoderConstantsN.INTEGER_MISSING; + } + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * @return the sequenceID + */ + public String getSequenceID() { + return sequenceID; + + } + + /** + * @return the sequenceID + */ + public void setSequenceID(String sequenceID) { + this.sequenceID = sequenceID; + } + + /** + * @return the intensity + */ + public String getIntensity() { + return intensity; + } + + /** + * @param intensity to set + */ + public void setIntensity(String intensity) { + this.intensity = intensity; + } + + /** + * @return the direction + */ + public int getDirection() { + return direction; + } + + /** + * @param direction to set + */ + public void setDirection(int direction) { + this.direction = direction; + } + + /** + * @return the speed + */ + public int getSpeed() { + return speed; + } + + /** + * @param speed to set + */ + public void setSpeed(int speed) { + this.speed = speed; + } + + /** + * @return the distance + */ + public int getDistance() { + return distance; + } + + /** + * @param distance to set + */ + public void setDistance(int distance) { + this.distance = distance; + } + + /** + * @return the set of convective sigmet location + */ + public Set getConvSigmetLocation() { + return convSigmetLocation; + } + + /** + * @param convsigmet the location to set + */ + public void setConvSigmetLocation(Set convLocation) { + this.convSigmetLocation = convLocation; + } + + /** + * @param add conv Sigmet location to set + */ + public void addConvSigmetLocation(ConvSigmetLocation plocation){ + convSigmetLocation.add(plocation); + } + + + + /** + * @return the classType + */ + public String getClassType() { + return classType; + } + + /** + * @param classType to set + */ + public void setClassType(String classType) { + this.classType = classType; + } + + /** + * @return the section + */ + public String getSegment() { + return segment; + } + + /** + * @param segment to set + */ + public void setSegment(String segment) { + this.segment = segment; + } + + /** + * @return the startTime + */ + public Calendar getStartTime() { + return startTime; + } + + /** + * @param startTime to set + */ + public void setStartTime(Calendar startTime) { + this.startTime = startTime; + } + + /** + * @return the endTime + */ + public Calendar getEndTime() { + return endTime; + } + + /** + * @param endTIme to set + */ + public void setEndTime(Calendar endTime) { + this.endTime = endTime; + } + + /** + * @return the cloudTop + */ + public String getCloudTop() { + return cloudTop; + } + + /** + * @param cloudTop to set + */ + public void setCloudTop(String cloudTop) { + this.cloudTop = cloudTop; + } + + /** + * @return the flightLevel + */ + public int getFlightLevel() { + return flightLevel; + } + + /** + * @param flightLevel to set + */ + public void setFlightLevel(int flightLevel) { + this.flightLevel = flightLevel; + } + + /** + * Get the record id. + * + * @return The recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * Set the record id. + * @param record + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/dao/ConvSigmetDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/dao/ConvSigmetDao.java index ee358ce469..d901628cb1 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/dao/ConvSigmetDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/dao/ConvSigmetDao.java @@ -1,31 +1,14 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ package gov.noaa.nws.ncep.common.dataplugin.convsigmet.dao; import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; import java.util.List; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; /** * TODO Add Description @@ -36,6 +19,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 23, 2009 jkorman Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @@ -43,7 +28,7 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * @version 1.0 */ -public class ConvSigmetDao extends NcepDefaultPluginDao { +public class ConvSigmetDao extends PluginDao { /** * Creates a new ReccoDao @@ -92,4 +77,11 @@ public class ConvSigmetDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/package-info.java old mode 100755 new mode 100644 index f6e6ae41a7..a50a714f00 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.convsigmet/src/gov/noaa/nws/ncep/common/dataplugin/convsigmet/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains table record for decoder plug-ins -*/ -package gov.noaa.nws.ncep.common.dataplugin.convsigmet; +/** +* Contains table record for decoder plug-ins +*/ +package gov.noaa.nws.ncep.common.dataplugin.convsigmet; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/component-deploy.xml index b2c5c9b902..743055d90d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/component-deploy.xml @@ -1,10 +1,8 @@ - - - - - + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgPrecip.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgPrecip.java index 219c0061ea..c7e806fa54 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgPrecip.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgPrecip.java @@ -13,6 +13,8 @@ * 03/2009 14 T. Lee Migration to TO10 * 11/2009 14 T. Lee Migration to TO11D6 * 05/2010 14 T. Lee Migration to TO11DR11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -26,21 +28,15 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import gov.noaa.nws.ncep.common.dataplugin.ffg.FfgRecord; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @Entity @Table(name="ffg_precip") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FfgPrecip implements Serializable, ISerializableObject { @@ -50,11 +46,6 @@ public class FfgPrecip implements Serializable, ISerializableObject { @GeneratedValue private Integer recordId = null; - /** The FFG record this object belongs to **/ - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private FfgRecord parentID; - /** The zone ID **/ @Column(length=32) @XmlElement @@ -113,17 +104,17 @@ public class FfgPrecip implements Serializable, ISerializableObject { /** * @return the parentID - */ + * public FfgRecord getParentID() { return parentID; - } + }*/ /** * @param parentID the parentID to set - */ + * public void setParentID(FfgRecord parentID) { this.parentID = parentID; - } + }*/ /** * @return the zoneID diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java index 5b07795a16..c535b728d7 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/FfgRecord.java @@ -13,6 +13,8 @@ * 12/2008 14 T. Lee Initialized variable * 03/2009 14 T. Lee Migration to TO10 * 07/2009 14 T. Lee Migration to TO11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -23,23 +25,17 @@ package gov.noaa.nws.ncep.common.dataplugin.ffg; import java.util.Calendar; import java.util.HashSet; -import java.util.Iterator; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import javax.xml.bind.annotation.XmlRootElement; - -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.Index; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.IDecoderGettable; @@ -49,67 +45,57 @@ import gov.noaa.nws.ncep.common.dataplugin.ffg.FfgPrecip; @Entity @Table(name = "ffg", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class FfgRecord extends PluginDataObject { private static final long serialVersionUID = 1L; /** Report type */ - @Column(length=32) - @XmlElement + @Column(length=32) @DynamicSerializeElement private String reportType; /** FFG AWIPS identifier */ @Column(length=32) - @DataURI(position=1) - @XmlElement + @DataURI(position=1) @DynamicSerializeElement private String awipsID; /** Bulletin insurance time */ - @Column - @XmlElement + @Column @DynamicSerializeElement private Calendar issueTime; /** Station ID */ - @Column(length=32) - @XmlElement + @Column(length=32) @DynamicSerializeElement private String issueOffice; /** Designator BBB */ - @Column(length=8) - @XmlElement + @Column(length=8) @DynamicSerializeElement private String designatorBBB; /** Bulletin messages */ - @Column(length=10000) - @XmlElement + @Column(length=10000) @DynamicSerializeElement private String bullMessage; /** Mass News Disseminator (MND) */ - @Column(length=72) - @XmlElement + @Column(length=72) @DynamicSerializeElement private String mndTime; /** WMO header */ - @Column(length=32) - @XmlElement + @Column(length=32) @DynamicSerializeElement private String wmoHeader; /** FFG precipitation */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "ffgP_parentid_idex") private Set ffgP = new HashSet(); /** @@ -270,7 +256,7 @@ public class FfgRecord extends PluginDataObject { */ public void addPrecip(FfgPrecip precip){ ffgP.add(precip); - precip.setParentID (this); + //precip.setParentID (this); } /** @@ -281,11 +267,11 @@ public class FfgRecord extends PluginDataObject { public void setIdentifier(Object dataURI) { this.identifier = dataURI; - if (this.getFfgP() != null && this.getFfgP().size() > 0) { + /*if (this.getFfgP() != null && this.getFfgP().size() > 0) { for (Iterator iter = this.getFfgP().iterator(); iter.hasNext();) { FfgPrecip fp = iter.next(); - fp.setParentID(this); + //fp.setParentID(this); } - } + }*/ } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/dao/FfgDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/dao/FfgDao.java index 01d8b865bf..1767d2828d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/dao/FfgDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/dao/FfgDao.java @@ -10,6 +10,8 @@ * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 05/2010 14 T. Lee Migration to TO11DR11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -19,15 +21,14 @@ package gov.noaa.nws.ncep.common.dataplugin.ffg.dao; import gov.noaa.nws.ncep.common.dataplugin.ffg.FfgRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; - import java.util.List; - -import com.raytheon.edex.db.dao.DefaultPluginDao; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; -public class FfgDao extends NcepDefaultPluginDao { +public class FfgDao extends PluginDao { /** * FfgDao constructor. @@ -76,4 +77,11 @@ public class FfgDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/package-info.java index bed1d1531f..87ecb1c61d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ffg/src/gov/noaa/nws/ncep/common/dataplugin/ffg/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains table record for decoder plug-ins -*/ -package gov.noaa.nws.ncep.common.dataplugin.ffg; +/** +* Contains table record for decoder plug-ins +*/ +package gov.noaa.nws.ncep.common.dataplugin.ffg; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/component-deploy.xml index ff7d39f18e..8e3725a52f 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/component-deploy.xml @@ -1,11 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/src/gov/noaa/nws/ncep/common/dataplugin/idft/dao/IdftDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/src/gov/noaa/nws/ncep/common/dataplugin/idft/dao/IdftDao.java index bb6d27b6f3..1f3ca5dd41 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/src/gov/noaa/nws/ncep/common/dataplugin/idft/dao/IdftDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.idft/src/gov/noaa/nws/ncep/common/dataplugin/idft/dao/IdftDao.java @@ -12,64 +12,64 @@ * * @author fjyen * @version 1.0 - **/ -package gov.noaa.nws.ncep.common.dataplugin.idft.dao; - -import java.util.List; - -import gov.noaa.nws.ncep.common.dataplugin.idft.IdftRecord; + **/ +package gov.noaa.nws.ncep.common.dataplugin.idft.dao; + +import java.util.List; + +import gov.noaa.nws.ncep.common.dataplugin.idft.IdftRecord; import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; -import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.edex.database.DataAccessLayerException; - -public class IdftDao extends NcepDefaultPluginDao { - - - /** - * Creates a new ReccoDao - * @throws PluginException - */ - public IdftDao(String pluginName) throws PluginException { - super(pluginName); - } - - /** - * Retrieves a idft report using the datauri . - * - * @param dataURI - * The dataURI to match against. - * @return The report record if it exists. - */ - public IdftRecord queryByDataURI(String dataURI) { - IdftRecord report = null; - List obs = null; - try { - obs = queryBySingleCriteria("dataURI", dataURI); - } catch (DataAccessLayerException e) { - e.printStackTrace(); - } - if((obs != null)&&(obs.size() > 0)) { - report = (IdftRecord) obs.get(0); - } - return report; - } - - /** - * Queries for to determine if a given data uri exists on the IDFT table. - * - * @param dataUri - * The DataURI to find. - * @return An array of objects. If not null, there should only be a single - * element. - */ - public Object[] queryDataUriColumn(final String dataUri) { - - String sql = "select datauri from awips.idft where datauri='" - + dataUri + "';"; - - Object[] results = executeSQLQuery(sql); - - return results; - } -} + +public class IdftDao extends NcepDefaultPluginDao { + + + /** + * Creates a new ReccoDao + * @throws PluginException + */ + public IdftDao(String pluginName) throws PluginException { + super(pluginName); + } + + /** + * Retrieves a idft report using the datauri . + * + * @param dataURI + * The dataURI to match against. + * @return The report record if it exists. + */ + public IdftRecord queryByDataURI(String dataURI) { + IdftRecord report = null; + List obs = null; + try { + obs = queryBySingleCriteria("dataURI", dataURI); + } catch (DataAccessLayerException e) { + e.printStackTrace(); + } + if((obs != null)&&(obs.size() > 0)) { + report = (IdftRecord) obs.get(0); + } + return report; + } + + /** + * Queries for to determine if a given data uri exists on the IDFT table. + * + * @param dataUri + * The DataURI to find. + * @return An array of objects. If not null, there should only be a single + * element. + */ + public Object[] queryDataUriColumn(final String dataUri) { + + String sql = "select datauri from awips.idft where datauri='" + + dataUri + "';"; + + Object[] results = executeSQLQuery(sql); + + return results; + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject old mode 100755 new mode 100644 diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/component-deploy.xml old mode 100755 new mode 100644 index f7b7d81d0c..f96032c7e9 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetLocation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetLocation.java old mode 100755 new mode 100644 index 1df67890ab..8d41fb86ee --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetLocation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetLocation.java @@ -1,205 +1,179 @@ -/** - * IntlsigmetLocation - * - * This java class defines the getters and setters for the - * international sigmet location table. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 113 L. Lin Initial creation - * 07/2009 113 L. Lin Migration to TO11 - * 09/2009 113 L. Lin modify lat/lon float to latitude/longitude double - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; - -import java.io.Serializable; - -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -@Entity -@Table(name="intlsigmet_location") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class IntlSigmetLocation implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Integer recordId = null; - - // The intlsigmet record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private IntlSigmetRecord parentID; - - // Collection of locations - @Column(length=480) - @XmlElement - @DynamicSerializeElement - private String locationLine; - - // Each location of an international sigmet forecast area - @Column(length=48) - @XmlElement - @DynamicSerializeElement - private String locationName; - - // Each latitude of an international sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double latitude; - - // Each longitude of an international sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double longitude; - - // Index for the order of a complete location set - @Column - @XmlElement - @DynamicSerializeElement - private Integer index; - - /** - * No-Arg Convstructor. - */ - public IntlSigmetLocation() { - this.locationLine=null; - this.locationName=null; - this.latitude=IDecoderConstantsN.FLOAT_MISSING; - this.longitude=IDecoderConstantsN.FLOAT_MISSING; - this.index=IDecoderConstantsN.INTEGER_MISSING; - } - - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @return the parentID - */ - public IntlSigmetRecord getParentID() { - return parentID; - } - - /** - * @param parentID to set - */ - public void setParentID(IntlSigmetRecord parentID) { - this.parentID = parentID; - } - - /** - * @return the index - */ - public Integer getIndex() { - return index; - } - - /** - * @param index to set - */ - public void setIndex(Integer index) { - this.index = index; - } - - /** - * @return the locationLine - */ - public String getLocationLine() { - return locationLine; - } - - /** - * @param locationLine to set - */ - public void setLocationLine(String locationLine) { - this.locationLine = locationLine; - } - - /** - * @return the location - */ - public String getLocationName() { - return locationName; - } - - /** - * @param location to set - */ - public void setLocationName(String location) { - this.locationName = location; - } - - /** - * Get the record id. - * - * @return The recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * Set the record id. - * @param record - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - - /** - * @return the latitude - */ - public double getLatitude() { - return latitude; - } - - /** - * @param latitude to set - */ - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - /** - * @return the longitude - */ - public double getLongitude() { - return longitude; - } - - /** - * @param longitude to set - */ - public void setLongitude(double longitude) { - this.longitude = longitude; - } - -} +/** + * IntlsigmetLocation + * + * This java class defines the getters and setters for the + * international sigmet location table. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 113 L. Lin Initial creation + * 07/2009 113 L. Lin Migration to TO11 + * 09/2009 113 L. Lin modify lat/lon float to latitude/longitude double + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +@Entity +@Table(name="intlsigmet_location") +@DynamicSerialize +public class IntlSigmetLocation implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Integer recordId = null; + + + // Collection of locations + @Column(length=480) + @DynamicSerializeElement + private String locationLine; + + // Each location of an international sigmet forecast area + @Column(length=48) + @DynamicSerializeElement + private String locationName; + + // Each latitude of an international sigmet forecast area + @Column + @DynamicSerializeElement + private double latitude; + + // Each longitude of an international sigmet forecast area + @Column + @DynamicSerializeElement + private double longitude; + + // Index for the order of a complete location set + @Column + @DynamicSerializeElement + private Integer index; + + /** + * No-Arg Convstructor. + */ + public IntlSigmetLocation() { + this.locationLine=null; + this.locationName=null; + this.latitude=IDecoderConstantsN.FLOAT_MISSING; + this.longitude=IDecoderConstantsN.FLOAT_MISSING; + this.index=IDecoderConstantsN.INTEGER_MISSING; + } + + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + + /** + * @return the index + */ + public Integer getIndex() { + return index; + } + + /** + * @param index to set + */ + public void setIndex(Integer index) { + this.index = index; + } + + /** + * @return the locationLine + */ + public String getLocationLine() { + return locationLine; + } + + /** + * @param locationLine to set + */ + public void setLocationLine(String locationLine) { + this.locationLine = locationLine; + } + + /** + * @return the location + */ + public String getLocationName() { + return locationName; + } + + /** + * @param location to set + */ + public void setLocationName(String location) { + this.locationName = location; + } + + /** + * Get the record id. + * + * @return The recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * Set the record id. + * @param record + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + + /** + * @return the latitude + */ + public double getLatitude() { + return latitude; + } + + /** + * @param latitude to set + */ + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + /** + * @return the longitude + */ + public double getLongitude() { + return longitude; + } + + /** + * @param longitude to set + */ + public void setLongitude(double longitude) { + this.longitude = longitude; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java old mode 100755 new mode 100644 index b6ab63624a..96ce811903 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/IntlSigmetRecord.java @@ -1,591 +1,558 @@ -/** - * IntlsigmetRecord - * - * This java class performs the mapping to the database table for ITNLSIGMET - * - * HISTORY - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 113 L. Lin Initial coding - * 07/2009 113 L. Lin Migration to TO11 - * 05/2010 113 L. Lin Migration to TO11DR11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -import javax.persistence.CascadeType; -import javax.persistence.Column; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; - -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "intlsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize - - -public class IntlSigmetRecord extends PluginDataObject{ - - /** - * - */ - private static final long serialVersionUID = 1L; - - // reportType is "international sigmet". - @Column(length=32) - @DataURI(position=1) - @XmlElement - @DynamicSerializeElement - private String reportType; - - // hazardType is weather phenomena. - @Column(length=48) - @DataURI(position=2) - @XmlElement - @DynamicSerializeElement - private String hazardType; - - // WMO header - @Column(length=32) - @XmlElement - @DynamicSerializeElement - private String wmoHeader; - - // The issue office where the report from - @Column(length=32) - @XmlElement - @DynamicSerializeElement - private String issueOffice; - - // Issue time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar issueTime; - - // Start time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar startTime; - - // End time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar endTime; - - // The message ID - @Column(length=16) - @DataURI(position=3) - @XmlElement - @DynamicSerializeElement - private String messageID; - - // The sequence number - @Column(length=8) - @DataURI(position=4) - @XmlElement - @DynamicSerializeElement - private String sequenceNumber; - - // The air traffic services unit - @Column(length=16) - @XmlElement - @DynamicSerializeElement - private String atsu; - - // The location indicator of the meteorological watch office originator - @Column(length=16) - @XmlElement - @DynamicSerializeElement - private String omwo; - - // Flight level 1 - @Column - @XmlElement - @DynamicSerializeElement - private Integer flightlevel1; - - // Flight level 2 - @Column - @XmlElement - @DynamicSerializeElement - private Integer flightlevel2; - - // Distance - @Column - @XmlElement - @DynamicSerializeElement - private Integer distance; - - // Direction - @Column(length=16) - @XmlElement - @DynamicSerializeElement - private String direction; - - // Speed - @Column - @XmlElement - @DynamicSerializeElement - private Integer speed; - - /* - * the name of the storm, where applicable, or location of the - * volcano, where applicable, or the word, OTHER, for reports - * not from CONUS, Hawaii, Guam, Japan, UK, Tahiti, and Cuba - - */ - @Column(length=48) - @XmlElement - @DynamicSerializeElement - private String nameLocation; - - /* - * remarks such as: correction, remarks, ...etc. - */ - @Column(length=32) - @XmlElement - @DynamicSerializeElement - private String remarks; - - // The changes in intensity; using as "INTSF", "WKN", or "NC". - @Column(length=16) - @XmlElement - @DynamicSerializeElement - private String intensity; - - // The polygon indicator as "WI", "WTN", "EITHER SIDE", or "E OF". - @Column(length=16) - @XmlElement - @DynamicSerializeElement - private String polygonExtent; - - // The entire report - @Column(length=5000) - @XmlElement - @DynamicSerializeElement - private String bullMessage; - - - /** - * Intlsigmet location - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) - private Set intlSigmetLocation = new HashSet(); - - - /** - * Default Convstructor - */ - public IntlSigmetRecord() { - this.issueOffice=null; - this.wmoHeader=null; - this.bullMessage=null; - this.hazardType=null; - this.messageID=null; - this.reportType="INTLSIGMET"; - this.sequenceNumber=null; - this.atsu=null; - this.omwo=null; - this.nameLocation=null; - this.intensity=null; - this.remarks=null; - this.flightlevel1=IDecoderConstantsN.INTEGER_MISSING; - this.flightlevel2=IDecoderConstantsN.INTEGER_MISSING; - this.direction=null; - this.distance=IDecoderConstantsN.INTEGER_MISSING; - this.speed=IDecoderConstantsN.INTEGER_MISSING; - this.polygonExtent=null; - } - - /** - * Convstructs a consigmet record from a dataURI - * - * @param uri The dataURI - */ - public IntlSigmetRecord(String uri) { - super(uri); - } - - - @Override - public IDecoderGettable getDecoderGettable() { - // TODO Auto-generated method stub - return null; - } - - /** - * @return the issueOffice - */ - public String getIssueOffice(){ - return issueOffice; - } - - /** - * @param issueOffice to set - */ - public void setIssueOffice(String issueOffice){ - this.issueOffice=issueOffice; - } - - /** - * @return the wmoHeader - */ - public String getWmoHeader(){ - return wmoHeader; - } - - /** - * @param wnoHeader to set - */ - public void setWmoHeader(String wmoHeader){ - this.wmoHeader=wmoHeader; - } - - /** - * @return the issueTime - */ - public Calendar getIssueTime(){ - return issueTime; - } - - /** - * @param issueTime to set - */ - public void setIssueTime(Calendar issueTime){ - this.issueTime=issueTime; - } - - /** - * @return the reportType - */ - public String getReportType() { - return reportType; - } - - /** - * @param reportType to set - */ - public void setReportType(String reportType) { - this.reportType = reportType; - } - - /** - * @return the bullMessage - */ - public String getBullMessage() { - return bullMessage; - } - - /** - * @param bullMessage to set - */ - public void setBullMessage(String bullMessage) { - this.bullMessage = bullMessage; - } - - /** - * @return the set of hazard - */ - public String getHazardType() { - return hazardType; - } - - /** - * @param hazardType to set - */ - public void setHazardType(String hazardType) { - this.hazardType = hazardType; - } - - /** - * @return the startTime - */ - public Calendar getStartTime() { - return startTime; - } - - /** - * @param startTime to set - */ - public void setStartTime(Calendar startTime) { - this.startTime = startTime; - } - - /** - * @return the endTime - */ - public Calendar getEndTime() { - return endTime; - } - - /** - * @param endTime to set - */ - public void setEndTime(Calendar endTime) { - this.endTime = endTime; - } - - public String getMessageID() { - return messageID; - } - - /** - * @param messageID to set - */ - public void setMessageID(String messageID) { - this.messageID = messageID; - } - - /** - * @return the sequenceNumber - */ - public String getSequenceNumber() { - return sequenceNumber; - } - - /** - * @param sequenceNumber to set - */ - public void setSequenceNumber(String sequenceNumber) { - this.sequenceNumber = sequenceNumber; - } - - /** - * @return the atsu - */ - public String getAtsu() { - return atsu; - } - - /** - * @param atsu to set - */ - public void setAtsu(String atsu) { - this.atsu = atsu; - } - - /** - * @return the omwo - */ - public String getOmwo() { - return omwo; - } - - /** - * @param omwo to set - */ - public void setOmwo(String omwo) { - this.omwo = omwo; - } - - /** - * @return the flightLevel1 - */ - public Integer getFlightlevel1() { - return flightlevel1; - } - - /** - * @param flightLevel1 to set - */ - public void setFlightlevel1(Integer flightlevel1) { - this.flightlevel1 = flightlevel1; - } - - /** - * @return flightLevel2 - */ - public Integer getFlightlevel2() { - return flightlevel2; - } - - /** - * @param flightLevel2 to set - */ - public void setFlightlevel2(Integer flightlevel2) { - this.flightlevel2 = flightlevel2; - } - - /** - * @return distacne - */ - public Integer getDistance() { - return distance; - } - - /** - * @param distance to set - */ - public void setDistance(Integer distance) { - this.distance = distance; - } - - /** - * @return direction - */ - public String getDirection() { - return direction; - } - - /** - * @param direction to set - */ - public void setDirection(String direction) { - this.direction = direction; - } - - /** - * @return the speed - */ - public Integer getSpeed() { - return speed; - } - - /** - * @param speed to set - */ - public void setSpeed(Integer speed) { - this.speed = speed; - } - - /** - * @return the nameLocation - */ - public String getNameLocation() { - return nameLocation; - } - - /** - * @param nameLocation to set - */ - public void setNameLocation(String nameLocation) { - this.nameLocation = nameLocation; - } - - /** - * @return the remarks - */ - public String getRemarks() { - return remarks; - } - - /** - * @param remarks to set - */ - public void setRemarks(String remarks) { - this.remarks = remarks; - } - - /** - * @return the intensity - */ - public String getIntensity() { - return intensity; - } - - /** - * @param intensity to set - */ - public void setIntensity(String intensity) { - this.intensity = intensity; - } - - /** - * @return the polygonExtent - */ - public String getPolygonExtent() { - return polygonExtent; - } - - /** - * @param polygonExtent to set - */ - public void setPolygonExtent(String polygonExtent) { - this.polygonExtent = polygonExtent; - } - - /** - * @return the intlSigmetLocation - */ - public Set getIntlSigmetLocation() { - return intlSigmetLocation; - } - - /** - * @param intlSigmetLocation to set - */ - public void setIntlSigmetLocation(Set intlSigmetLocation) { - this.intlSigmetLocation = intlSigmetLocation; - } - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } - - /** - * @param add international sigmet Location to set - */ - public void addIntlSigmetLocation(IntlSigmetLocation psection){ - intlSigmetLocation.add(psection); - psection.setParentID(this); - } - - /** - * Override existing set method to modify any - * classes that use the dataURI as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) - { - - this.identifier = dataURI; - - if(this.getIntlSigmetLocation() != null && this.getIntlSigmetLocation().size() > 0) - { - for (Iterator iter = this.getIntlSigmetLocation().iterator(); iter.hasNext();) { - IntlSigmetLocation cs = iter.next(); - cs.setParentID(this); - } - } - - } - -} +/** + * IntlsigmetRecord + * + * This java class performs the mapping to the database table for ITNLSIGMET + * + * HISTORY + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 113 L. Lin Initial coding + * 07/2009 113 L. Lin Migration to TO11 + * 05/2010 113 L. Lin Migration to TO11DR11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +import javax.persistence.CascadeType; +import javax.persistence.Column; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Index; +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +@Entity +@Table(name = "intlsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) +@DynamicSerialize + + +public class IntlSigmetRecord extends PluginDataObject{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + // reportType is "international sigmet". + @Column(length=32) + @DataURI(position=1) + @DynamicSerializeElement + private String reportType; + + // hazardType is weather phenomena. + @Column(length=48) + @DataURI(position=2) + @DynamicSerializeElement + private String hazardType; + + // WMO header + @Column(length=32) + @DynamicSerializeElement + private String wmoHeader; + + // The issue office where the report from + @Column(length=32) + @DynamicSerializeElement + private String issueOffice; + + // Issue time of the report + @Column + @DynamicSerializeElement + private Calendar issueTime; + + // Start time of the report + @Column + @DynamicSerializeElement + private Calendar startTime; + + // End time of the report + @Column + @DynamicSerializeElement + private Calendar endTime; + + // The message ID + @Column(length=16) + @DataURI(position=3) + @DynamicSerializeElement + private String messageID; + + // The sequence number + @Column(length=8) + @DataURI(position=4) + @DynamicSerializeElement + private String sequenceNumber; + + // The air traffic services unit + @Column(length=16) + @DynamicSerializeElement + private String atsu; + + // The location indicator of the meteorological watch office originator + @Column(length=16) + @DynamicSerializeElement + private String omwo; + + // Flight level 1 + @Column + @DynamicSerializeElement + private Integer flightlevel1; + + // Flight level 2 + @Column + @DynamicSerializeElement + private Integer flightlevel2; + + // Distance + @Column + @DynamicSerializeElement + private Integer distance; + + // Direction + @Column(length=16) + @DynamicSerializeElement + private String direction; + + // Speed + @Column + @DynamicSerializeElement + private Integer speed; + + /* + * the name of the storm, where applicable, or location of the + * volcano, where applicable, or the word, OTHER, for reports + * not from CONUS, Hawaii, Guam, Japan, UK, Tahiti, and Cuba + + */ + @Column(length=48) + @DynamicSerializeElement + private String nameLocation; + + /* + * remarks such as: correction, remarks, ...etc. + */ + @Column(length=32) + @DynamicSerializeElement + private String remarks; + + // The changes in intensity; using as "INTSF", "WKN", or "NC". + @Column(length=16) + @DynamicSerializeElement + private String intensity; + + // The polygon indicator as "WI", "WTN", "EITHER SIDE", or "E OF". + @Column(length=16) + @DynamicSerializeElement + private String polygonExtent; + + // The entire report + @Column(length=5000) + @DynamicSerializeElement + private String bullMessage; + + + /** + * Intlsigmet location + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "intlSigmetLocation_parentid_idex") + private Set intlSigmetLocation = new HashSet(); + + + /** + * Default Convstructor + */ + public IntlSigmetRecord() { + this.issueOffice=null; + this.wmoHeader=null; + this.bullMessage=null; + this.hazardType=null; + this.messageID=null; + this.reportType="INTLSIGMET"; + this.sequenceNumber=null; + this.atsu=null; + this.omwo=null; + this.nameLocation=null; + this.intensity=null; + this.remarks=null; + this.flightlevel1=IDecoderConstantsN.INTEGER_MISSING; + this.flightlevel2=IDecoderConstantsN.INTEGER_MISSING; + this.direction=null; + this.distance=IDecoderConstantsN.INTEGER_MISSING; + this.speed=IDecoderConstantsN.INTEGER_MISSING; + this.polygonExtent=null; + } + + /** + * Convstructs a consigmet record from a dataURI + * + * @param uri The dataURI + */ + public IntlSigmetRecord(String uri) { + super(uri); + } + + + @Override + public IDecoderGettable getDecoderGettable() { + // TODO Auto-generated method stub + return null; + } + + /** + * @return the issueOffice + */ + public String getIssueOffice(){ + return issueOffice; + } + + /** + * @param issueOffice to set + */ + public void setIssueOffice(String issueOffice){ + this.issueOffice=issueOffice; + } + + /** + * @return the wmoHeader + */ + public String getWmoHeader(){ + return wmoHeader; + } + + /** + * @param wnoHeader to set + */ + public void setWmoHeader(String wmoHeader){ + this.wmoHeader=wmoHeader; + } + + /** + * @return the issueTime + */ + public Calendar getIssueTime(){ + return issueTime; + } + + /** + * @param issueTime to set + */ + public void setIssueTime(Calendar issueTime){ + this.issueTime=issueTime; + } + + /** + * @return the reportType + */ + public String getReportType() { + return reportType; + } + + /** + * @param reportType to set + */ + public void setReportType(String reportType) { + this.reportType = reportType; + } + + /** + * @return the bullMessage + */ + public String getBullMessage() { + return bullMessage; + } + + /** + * @param bullMessage to set + */ + public void setBullMessage(String bullMessage) { + this.bullMessage = bullMessage; + } + + /** + * @return the set of hazard + */ + public String getHazardType() { + return hazardType; + } + + /** + * @param hazardType to set + */ + public void setHazardType(String hazardType) { + this.hazardType = hazardType; + } + + /** + * @return the startTime + */ + public Calendar getStartTime() { + return startTime; + } + + /** + * @param startTime to set + */ + public void setStartTime(Calendar startTime) { + this.startTime = startTime; + } + + /** + * @return the endTime + */ + public Calendar getEndTime() { + return endTime; + } + + /** + * @param endTime to set + */ + public void setEndTime(Calendar endTime) { + this.endTime = endTime; + } + + public String getMessageID() { + return messageID; + } + + /** + * @param messageID to set + */ + public void setMessageID(String messageID) { + this.messageID = messageID; + } + + /** + * @return the sequenceNumber + */ + public String getSequenceNumber() { + return sequenceNumber; + } + + /** + * @param sequenceNumber to set + */ + public void setSequenceNumber(String sequenceNumber) { + this.sequenceNumber = sequenceNumber; + } + + /** + * @return the atsu + */ + public String getAtsu() { + return atsu; + } + + /** + * @param atsu to set + */ + public void setAtsu(String atsu) { + this.atsu = atsu; + } + + /** + * @return the omwo + */ + public String getOmwo() { + return omwo; + } + + /** + * @param omwo to set + */ + public void setOmwo(String omwo) { + this.omwo = omwo; + } + + /** + * @return the flightLevel1 + */ + public Integer getFlightlevel1() { + return flightlevel1; + } + + /** + * @param flightLevel1 to set + */ + public void setFlightlevel1(Integer flightlevel1) { + this.flightlevel1 = flightlevel1; + } + + /** + * @return flightLevel2 + */ + public Integer getFlightlevel2() { + return flightlevel2; + } + + /** + * @param flightLevel2 to set + */ + public void setFlightlevel2(Integer flightlevel2) { + this.flightlevel2 = flightlevel2; + } + + /** + * @return distacne + */ + public Integer getDistance() { + return distance; + } + + /** + * @param distance to set + */ + public void setDistance(Integer distance) { + this.distance = distance; + } + + /** + * @return direction + */ + public String getDirection() { + return direction; + } + + /** + * @param direction to set + */ + public void setDirection(String direction) { + this.direction = direction; + } + + /** + * @return the speed + */ + public Integer getSpeed() { + return speed; + } + + /** + * @param speed to set + */ + public void setSpeed(Integer speed) { + this.speed = speed; + } + + /** + * @return the nameLocation + */ + public String getNameLocation() { + return nameLocation; + } + + /** + * @param nameLocation to set + */ + public void setNameLocation(String nameLocation) { + this.nameLocation = nameLocation; + } + + /** + * @return the remarks + */ + public String getRemarks() { + return remarks; + } + + /** + * @param remarks to set + */ + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + /** + * @return the intensity + */ + public String getIntensity() { + return intensity; + } + + /** + * @param intensity to set + */ + public void setIntensity(String intensity) { + this.intensity = intensity; + } + + /** + * @return the polygonExtent + */ + public String getPolygonExtent() { + return polygonExtent; + } + + /** + * @param polygonExtent to set + */ + public void setPolygonExtent(String polygonExtent) { + this.polygonExtent = polygonExtent; + } + + /** + * @return the intlSigmetLocation + */ + public Set getIntlSigmetLocation() { + return intlSigmetLocation; + } + + /** + * @param intlSigmetLocation to set + */ + public void setIntlSigmetLocation(Set intlSigmetLocation) { + this.intlSigmetLocation = intlSigmetLocation; + } + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * @param add international sigmet Location to set + */ + public void addIntlSigmetLocation(IntlSigmetLocation psection){ + intlSigmetLocation.add(psection); + + } + + /** + * Override existing set method to modify any + * classes that use the dataURI as a foreign key + */ + @Override + public void setIdentifier(Object dataURI) + { + + this.identifier = dataURI; + + + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/dao/IntlSigmetDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/dao/IntlSigmetDao.java index 0b2a46a5da..b983f6e92c 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/dao/IntlSigmetDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/dao/IntlSigmetDao.java @@ -1,31 +1,13 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ package gov.noaa.nws.ncep.common.dataplugin.intlsigmet.dao; import java.util.List; import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; - import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; /** * Set of DAO methods for AIREP Observation data. @@ -37,6 +19,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 20080103 384 jkorman Initial Coding. + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author jkorman @@ -59,7 +43,7 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * @version 1.0 */ -public class IntlSigmetDao extends NcepDefaultPluginDao { +public class IntlSigmetDao extends PluginDao { /** * Creates a new ReccoDao @@ -108,4 +92,11 @@ public class IntlSigmetDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/package-info.java old mode 100755 new mode 100644 index 109d80eeaf..2062041916 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.intlsigmet/src/gov/noaa/nws/ncep/common/dataplugin/intlsigmet/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains table record for decoder plug-ins -*/ -package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; +/** +* Contains table record for decoder plug-ins +*/ +package gov.noaa.nws.ncep.common.dataplugin.intlsigmet; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/component-deploy.xml index a7eca9a40c..d31c582841 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/areaName.sql b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/areaName.sql index faac86f375..bffdcea1cb 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/areaName.sql +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/areaName.sql @@ -199,6 +199,11 @@ INSERT INTO awips.mcidas_area_names VALUES (324,'VAAC|SouthWestAtlantic'); INSERT INTO awips.mcidas_area_names VALUES (325,'VAAC|SouthEastPacific'); INSERT INTO awips.mcidas_area_names VALUES (326,'VAAC|Mexico-CentralAmerica'); INSERT INTO awips.mcidas_area_names VALUES (327,'VAAC|SouthEastPacific'); +INSERT INTO awips.mcidas_area_names VALUES (328,'VAAC|CentralPacific'); +INSERT INTO awips.mcidas_area_names VALUES (329,'VAAC|CentralPacific'); +INSERT INTO awips.mcidas_area_names VALUES (330,'VAAC|CentralPacific'); +INSERT INTO awips.mcidas_area_names VALUES (331,'VAAC|CentralPacific'); +INSERT INTO awips.mcidas_area_names VALUES (332,'VAAC|CentralPacific'); INSERT INTO awips.mcidas_area_names VALUES (1805,'WashDC'); INSERT INTO awips.mcidas_area_names VALUES (1810,'NAtlantic'); INSERT INTO awips.mcidas_area_names VALUES (1815,'US'); @@ -295,7 +300,7 @@ INSERT INTO awips.mcidas_area_names VALUES (8065,'World-10km'); INSERT INTO awips.mcidas_area_names VALUES (8066,'World'); INSERT INTO awips.mcidas_area_names VALUES (8067,'World-T'); INSERT INTO awips.mcidas_area_names VALUES (8069,'World'); -INSERT INTO awips.mcidas_area_names VALUES (8070,'World'); +INSERT INTO awips.mcidas_area_names VALUES (8070,'NHem'); INSERT INTO awips.mcidas_area_names VALUES (8072,'NPS-65E'); INSERT INTO awips.mcidas_area_names VALUES (8073,'NPS-45W'); INSERT INTO awips.mcidas_area_names VALUES (8074,'NPS-155W'); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/imageType.sql b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/imageType.sql index b9ea69c97c..436a7b02e4 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/imageType.sql +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/imageType.sql @@ -129,3 +129,9 @@ INSERT INTO awips.mcidas_image_type VALUES (167, 'VIS', '1', '85'); INSERT INTO awips.mcidas_image_type VALUES (168, 'IR', '2', '85'); INSERT INTO awips.mcidas_image_type VALUES (169, 'WV', '8', '85'); INSERT INTO awips.mcidas_image_type VALUES (170, 'IR2', '16', '85'); +INSERT INTO awips.mcidas_image_type VALUES (171, 'VIS', '1', '184'); +INSERT INTO awips.mcidas_image_type VALUES (172, 'IR2', '2', '184'); +INSERT INTO awips.mcidas_image_type VALUES (173, 'WV', '4', '184'); +INSERT INTO awips.mcidas_image_type VALUES (174, 'IR', '8', '184'); +INSERT INTO awips.mcidas_image_type VALUES (175, 'IR3', '128', '184'); +INSERT INTO awips.mcidas_image_type VALUES (176, 'IR4', '16', '184'); \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/satelliteName.sql b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/satelliteName.sql index 453941558c..d58f95273c 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/satelliteName.sql +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/res/scripts/satelliteName.sql @@ -7,6 +7,7 @@ INSERT INTO awips.mcidas_satellite_names VALUES (31,'GOES6'); INSERT INTO awips.mcidas_satellite_names VALUES (32,'GOES7'); INSERT INTO awips.mcidas_satellite_names VALUES (33,'GOES7'); INSERT INTO awips.mcidas_satellite_names VALUES (35,'FYC'); +INSERT INTO awips.mcidas_satellite_names VALUES (36,'FYC'); INSERT INTO awips.mcidas_satellite_names VALUES (51,'METEOSAT8'); INSERT INTO awips.mcidas_satellite_names VALUES (52,'METEOSAT9'); INSERT INTO awips.mcidas_satellite_names VALUES (53,'METEOSAT10'); @@ -25,3 +26,4 @@ INSERT INTO awips.mcidas_satellite_names VALUES (83,'GMS'); INSERT INTO awips.mcidas_satellite_names VALUES (84,'MTS'); INSERT INTO awips.mcidas_satellite_names VALUES (85,'MTSAT2'); INSERT INTO awips.mcidas_satellite_names VALUES (180,'GOES13'); +INSERT INTO awips.mcidas_satellite_names VALUES (184,'GOES15'); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasAreaProjection.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasAreaProjection.java index 1006cdbc2c..71f9a3c9b5 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasAreaProjection.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasAreaProjection.java @@ -223,7 +223,7 @@ public class McidasAreaProjection extends MapProjection { static final ParameterDescriptorGroup PARAMETERS = new DefaultParameterDescriptorGroup( "MCIDAS_AREA_NAV", - new ParameterDescriptor[] { SEMI_MAJOR, SEMI_MINOR, NAV_BLOCK_BASE64 } + new ParameterDescriptor[] { SEMI_MAJOR, SEMI_MINOR, CENTRAL_MERIDIAN, NAV_BLOCK_BASE64 } ); /** diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasMapCoverage.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasMapCoverage.java index 5352474dda..cc7ffaa469 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasMapCoverage.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasMapCoverage.java @@ -11,9 +11,9 @@ * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 10/2009 144 T. Lee Created - * 12/2009 144 T. Lee Migrated to TO11D6 - * 01/2010 201 M. Li Split into dataplugin project - * 05/2010 144 L. Lin Migration to TO11DR11. + * 12/2009 144 T. Lee Migrated to TO11D6 + * 01/2010 201 M. Li Split into dataplugin project + * 05/2010 144 L. Lin Migration to TO11DR11. * * */ @@ -43,9 +43,9 @@ import org.hibernate.annotations.Type; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.ProjectedCRS; -import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; import com.raytheon.uf.common.geospatial.ISpatialObject; -import com.raytheon.uf.common.serialization.adapters.GeometryAdapter; +import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; +import com.raytheon.uf.common.serialization.adapters.GeometryAdapter; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.vividsolutions.jts.geom.Geometry; @@ -56,18 +56,16 @@ import com.vividsolutions.jts.geom.Polygon; @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize -public class McidasMapCoverage extends PersistableDataObject implements - ISpatialObject { +public class McidasMapCoverage extends PersistableDataObject implements ISpatialObject { private static final long serialVersionUID = 1; - @Id private int pid; /** - * The projection of the map coverage 1 = Mercator, 3 = Lambert Conformal or - * TANC 5 = Polar Stereographic 7585 = native satellite navigation e.g. - * GVAR, ... + * The projection of the map coverage 1 = Mercator, 3 = Lambert Conformal or TANC + * 5 = Polar Stereographic + * 7585 = native satellite navigation e.g. GVAR, ... */ @Column @XmlAttribute @@ -85,7 +83,7 @@ public class McidasMapCoverage extends PersistableDataObject implements @XmlAttribute @DynamicSerializeElement private Integer ny; - + /** The pixel resolution of the image */ @Column @XmlAttribute @@ -105,11 +103,10 @@ public class McidasMapCoverage extends PersistableDataObject implements private Float clon; /** - * The standard latitude 1. For the Lambert Conformal projection this is the - * latitude of the proection cone intersects the earth. For the Polar - * Stereographic this is the latitude at which projection plan intersects - * the earth. For Mercator this is the latitude at which the Mercator - * projection cylinder intersects the earth. + * The standard latitude 1. For the Lambert Conformal projection this is the latitude + * of the proection cone intersects the earth. For the Polar Stereographic this is the + * latitude at which projection plan intersects the earth. For Mercator this is the + * latitude at which the Mercator projection cylinder intersects the earth. */ @Column @XmlAttribute @@ -117,14 +114,14 @@ public class McidasMapCoverage extends PersistableDataObject implements private Float stdlat1; /** - * The standard latitude 2 is the second latitude of a secant cone which - * intersects the earth for the Lambert Conformal projection. + * The standard latitude 2 is the second latitude of a secant cone which intersects the + * earth for the Lambert Conformal projection. */ @Column @XmlAttribute @DynamicSerializeElement private Float stdlat2; - + /** The latitude of the lower-left corner */ @Column @XmlAttribute @@ -148,31 +145,31 @@ public class McidasMapCoverage extends PersistableDataObject implements @XmlAttribute @DynamicSerializeElement private Float urlon; - + /** image element coordinate of area line 0, element 0 */ @Column @XmlAttribute @DynamicSerializeElement private int upperLeftElement; - + /** image line coordinate of area line 0, element 0 */ @Column @XmlAttribute @DynamicSerializeElement private int upperLeftLine; - + /** element resolution */ @Column @XmlAttribute @DynamicSerializeElement private int elementRes; - + /** line resolution */ @Column @XmlAttribute @DynamicSerializeElement private int lineRes; - + @Column(length = 5120) @XmlAttribute @DynamicSerializeElement @@ -223,10 +220,9 @@ public class McidasMapCoverage extends PersistableDataObject implements * @param geometry * The geometry */ - public McidasMapCoverage(Integer projection, Integer nx, Integer ny, - Float dx, Float dy, Float clon, Float stdlat1, Float stdlat2, - Float lllat, Float lllon, Float urlat, Float urlon, - CoordinateReferenceSystem crs, Geometry geometry) { + public McidasMapCoverage(Integer projection, Integer nx, Integer ny, Float dx, + Float dy, Float clon, Float stdlat1, Float stdlat2, Float lllat, Float lllon, + Float urlat,Float urlon, CoordinateReferenceSystem crs, Geometry geometry) { this.projection = projection; this.nx = nx; this.ny = ny; @@ -253,27 +249,19 @@ public class McidasMapCoverage extends PersistableDataObject implements * Constructs a new SatMapCoverage Object for native satellite navigation * * @param mapProjection - * @param nx - * The number of horizontal scan lines - * @param ny - * The number vertical scan lines - * @param reflon - * Reference Longitude - * @param upperLeftElement - * image element coordinate of area line 0, element 0 - * @param upperLeftLine - * image line coordinate of area line 0, element 0 - * @param xres - * Element resolution - * @param yres - * Line resolution - * @param crs - * The coordinate reference system + * @param nx The number of horizontal scan lines + * @param ny The number vertical scan lines + * @param reflon Reference Longitude + * @param upperLeftElement image element coordinate of area line 0, element 0 + * @param upperLeftLine image line coordinate of area line 0, element 0 + * @param xres Element resolution + * @param yres Line resolution + * @param crs The coordinate reference system * @param geometry */ public McidasMapCoverage(Integer projection, Integer nx, Integer ny, - Float reflon, int upperLeftElement, int upperLeftLine, int xres, - int yres, ProjectedCRS crs, Geometry geometry) { + Float reflon, int upperLeftElement, int upperLeftLine, int xres, + int yres, ProjectedCRS crs, Geometry geometry) { this.projection = projection; this.nx = nx; this.ny = ny; @@ -294,10 +282,10 @@ public class McidasMapCoverage extends PersistableDataObject implements this.crsWKT = crsObject.toWKT(); this.location = (Polygon) geometry; pid = this.hashCode(); - } + } @Override - public int hashCode() { + public int hashCode() { HashCodeBuilder hashBuilder = new HashCodeBuilder(); hashBuilder.append(projection); hashBuilder.append(nx); @@ -329,41 +317,39 @@ public class McidasMapCoverage extends PersistableDataObject implements if (crsObject == null) { try { crsObject = CRS.parseWKT(crsWKT); - // ReferencingFactoryFinder.getCRSFactory(null).createFromWKT(crsWKT); + // ReferencingFactoryFinder.getCRSFactory(null).createFromWKT(crsWKT); } catch (Exception e) { - /* - * parseWKT() doesn't recognize PROJCS PARAMETERS whose value is - * a "String" (it assumes all PARAMETER values are doubles.) If - * this crsWKT is a MCIDAS NAV, use McidasSpatialFactory - * instead. - */ - // e.printStackTrace(); - Pattern p = Pattern - .compile("PROJCS\\[\"MCIDAS\\sAREA\\s(.*)\""); + /* + * parseWKT() doesn't recognize PROJCS PARAMETERS whose value is a "String" (it + * assumes all PARAMETER values are doubles.) + * If this crsWKT is a MCIDAS NAV, use McidasSpatialFactory instead. + */ + //e.printStackTrace(); + Pattern p = Pattern.compile("PROJCS\\[\"MCIDAS\\sAREA\\s(.*)\""); Matcher m = p.matcher(crsWKT); m.find(); - if (m.groupCount() == 1) { - String type = m.group(1); - // System.out.println("FOUND PROJCS:"+m.group(0)+":"+type); - p = Pattern - .compile("\\[\"NAV_BLOCK_BASE64\",\\s\"(.*)\"\\]"); - m = p.matcher(crsWKT); - boolean found = m.find(); + if ( m.groupCount() == 1 ) { + String type = m.group(1); + //System.out.println("FOUND PROJCS:"+m.group(0)+":"+type); + p = Pattern.compile("\\[\"NAV_BLOCK_BASE64\",\\s\"(.*)\"\\]"); + m = p.matcher(crsWKT); + boolean found = m.find(); - // System.out.println(m.group()); - // System.out.println(m.groupCount()+m.group(1)); - if (found) { - String navBlock = m.group(1); - crsObject = McidasSpatialFactory.getInstance() - .constructCRS(type, navBlock); - } else { - crsObject = null; - } - } else { - crsObject = null; + //System.out.println(m.group()); + //System.out.println(m.groupCount()+m.group(1)); + if ( found ) { + String navBlock = m.group(1); + crsObject = McidasSpatialFactory.getInstance().constructCRS(type, navBlock); + } + else { + crsObject = null; + } } - + else { + crsObject = null; + } + } } return crsObject; @@ -400,7 +386,7 @@ public class McidasMapCoverage extends PersistableDataObject implements public void setStdlat1(Float stdlat1) { this.stdlat1 = stdlat1; } - + public Float getStdlat2() { return stdlat2; } @@ -475,78 +461,73 @@ public class McidasMapCoverage extends PersistableDataObject implements this.ny = ny; } + /** - * @return the upperLeftElement - */ - public int getUpperLeftElement() { - return upperLeftElement; - } + * @return the upperLeftElement + */ + public int getUpperLeftElement() { + return upperLeftElement; + } - /** - * @param upperLeftElement - * the upperLeftElement to set - */ - public void setUpperLeftElement(int upperLeftElement) { - this.upperLeftElement = upperLeftElement; - } + /** + * @param upperLeftElement the upperLeftElement to set + */ + public void setUpperLeftElement(int upperLeftElement) { + this.upperLeftElement = upperLeftElement; + } - /** - * @return the upperLeftLine - */ - public int getUpperLeftLine() { - return upperLeftLine; - } + /** + * @return the upperLeftLine + */ + public int getUpperLeftLine() { + return upperLeftLine; + } - /** - * @param upperLeftLine - * the upperLeftLine to set - */ - public void setUpperLeftLine(int upperLeftLine) { - this.upperLeftLine = upperLeftLine; - } + /** + * @param upperLeftLine the upperLeftLine to set + */ + public void setUpperLeftLine(int upperLeftLine) { + this.upperLeftLine = upperLeftLine; + } - /** - * @return the elementRes - */ - public int getElementRes() { - return elementRes; - } + /** + * @return the elementRes + */ + public int getElementRes() { + return elementRes; + } - /** - * @param elementRes - * the elementRes to set - */ - public void setElementRes(int elementRes) { - this.elementRes = elementRes; - } + /** + * @param elementRes the elementRes to set + */ + public void setElementRes(int elementRes) { + this.elementRes = elementRes; + } - /** - * @return the lineRes - */ - public int getLineRes() { - return lineRes; - } + /** + * @return the lineRes + */ + public int getLineRes() { + return lineRes; + } - /** - * @param lineRes - * the lineRes to set - */ - public void setLineRes(int lineRes) { - this.lineRes = lineRes; - } + /** + * @param lineRes the lineRes to set + */ + public void setLineRes(int lineRes) { + this.lineRes = lineRes; + } - public String getCrsWKT() { + public String getCrsWKT() { return crsWKT; } public void setCrsWKT(String crsWKT) { - // TODO new 2.6 version of geotools adds \r\n to long String parameters - // in WKT format - // this temp hack removes the extraneous characters, but we may want to - // investigate - // using a specific formatter to keep this consistent and in our control + //TODO new 2.6 version of geotools adds \r\n to long String parameters in WKT format + // this temp hack removes the extraneous characters, but we may want to investigate + // using a specific formatter to keep this consistent and in our control this.crsWKT = crsWKT.replaceAll("\r\n", ""); - // this.crsWKT = crsWKT; + //this.crsWKT = crsWKT; } public Polygon getLocation() { diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasRecord.java index c18ab15b11..67ba6ebd83 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasRecord.java @@ -19,53 +19,53 @@ * @version 1 */ -package gov.noaa.nws.ncep.common.dataplugin.mcidas; - -import java.util.Calendar; +package gov.noaa.nws.ncep.common.dataplugin.mcidas; + +import java.util.Calendar; import java.util.Date; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.ManyToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import javax.persistence.UniqueConstraint; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.dataplugin.persist.IPersistable; -import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject; import com.raytheon.uf.common.geospatial.ISpatialEnabled; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import gov.noaa.nws.ncep.common.dataplugin.mcidas.McidasMapCoverage; - -@Entity + +@Entity @Table(name = "mcidas", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class McidasRecord extends PersistablePluginDataObject implements - IPersistable, ISpatialEnabled { - - private static final long serialVersionUID = 1L; - - /** The satellite name */ - @Column(length = 32) - @DataURI(position = 1) - @XmlAttribute - @DynamicSerializeElement - private String satelliteName; +@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +@DynamicSerialize +public class McidasRecord extends PersistablePluginDataObject implements + IPersistable, ISpatialEnabled { + + private static final long serialVersionUID = 1L; + + /** The satellite name */ + @Column(length = 32) + @DataURI(position = 1) + @XmlAttribute + @DynamicSerializeElement + private String satelliteName; /** The area name */ @Column(length = 64) @@ -95,29 +95,29 @@ public class McidasRecord extends PersistablePluginDataObject implements @XmlAttribute @DynamicSerializeElement private Calendar creationTime; - - /** - * The image time - */ - @Column - @XmlAttribute - @DynamicSerializeElement - private Calendar imageTime; + + /** + * The image time + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private Calendar imageTime; - /** - * Size of logical records in bytes for product. - */ - @Column - @XmlAttribute - @DynamicSerializeElement - private Integer sizeRecords; - - /** Satellite projection */ + /** + * Size of logical records in bytes for product. + */ + @Column + @XmlAttribute + @DynamicSerializeElement + private Integer sizeRecords; + + /** Satellite projection */ @Column(length=16) @XmlAttribute - @DynamicSerializeElement - private String projection; - + @DynamicSerializeElement + private String projection; + /** The report type */ @Column(length=16) @XmlAttribute @@ -157,53 +157,53 @@ public class McidasRecord extends PersistablePluginDataObject implements * File name ingested to the end point. */ private String inputFileName; - - @ManyToOne - @PrimaryKeyJoinColumn - @XmlElement - @DynamicSerializeElement + + @ManyToOne + @PrimaryKeyJoinColumn + @XmlElement + @DynamicSerializeElement private McidasMapCoverage coverage; - + /** Area file header block */ @Transient private byte[] headerBlock; - - @Override - public McidasMapCoverage getSpatialObject() { - return coverage; - } - - public McidasMapCoverage getCoverage() { - return coverage; - } - - public void setCoverage(McidasMapCoverage coverage) { - this.coverage = coverage; - } - - /** - * No-arg constructor. - */ + + @Override + public McidasMapCoverage getSpatialObject() { + return coverage; + } + + public McidasMapCoverage getCoverage() { + return coverage; + } + + public void setCoverage(McidasMapCoverage coverage) { + this.coverage = coverage; + } + + /** + * No-arg constructor. + */ public McidasRecord() { satelliteName = null; imageType = null; resolution = null; projection = null; imageTime = null; - areaName = null; - } - - /** - * Constructs a McIDAS satellite record from a dataURI - * - * @param uri - * The dataURI - */ - public McidasRecord(String uri) { - super(uri); - } - - + areaName = null; + } + + /** + * Constructs a McIDAS satellite record from a dataURI + * + * @param uri + * The dataURI + */ + public McidasRecord(String uri) { + super(uri); + } + + /** * Get the time to use for persisting this data. * @@ -218,48 +218,48 @@ public class McidasRecord extends PersistablePluginDataObject implements return c.getTime(); } - - /** - * Set the time to be used for the persistence time for this object. - * - * @param persistTime - * The persistence time to be used. - */ - public void setPersistenceTime(Calendar persistTime) { - setInsertTime(persistTime); - } - - public Integer getSizeRecords() { - return sizeRecords; - } - - public void setSizeRecords(Integer sizeRecords) { - this.sizeRecords = sizeRecords; - } - - /** - * Get the IDecoderGettable reference for this record. - * - * @return The IDecoderGettable reference for this record. Null for this - * class. - */ - @Override - public IDecoderGettable getDecoderGettable() { - return null; - } - - public String getReportType() { - return reportType; - } - - public void setReportType(String reportType) { - this.reportType = reportType; - } - - public String getSatelliteName() { - return satelliteName; - } - + + /** + * Set the time to be used for the persistence time for this object. + * + * @param persistTime + * The persistence time to be used. + */ + public void setPersistenceTime(Calendar persistTime) { + setInsertTime(persistTime); + } + + public Integer getSizeRecords() { + return sizeRecords; + } + + public void setSizeRecords(Integer sizeRecords) { + this.sizeRecords = sizeRecords; + } + + /** + * Get the IDecoderGettable reference for this record. + * + * @return The IDecoderGettable reference for this record. Null for this + * class. + */ + @Override + public IDecoderGettable getDecoderGettable() { + return null; + } + + public String getReportType() { + return reportType; + } + + public void setReportType(String reportType) { + this.reportType = reportType; + } + + public String getSatelliteName() { + return satelliteName; + } + public Calendar getCreationTime() { return creationTime; } @@ -284,17 +284,17 @@ public class McidasRecord extends PersistablePluginDataObject implements this.projection = projection; } - public void setSatelliteName(String satelliteName) { - this.satelliteName = satelliteName; - } - - public String getImageType() { - return imageType; - } - - public void setImageType(String imageType) { - this.imageType = imageType; - } + public void setSatelliteName(String satelliteName) { + this.satelliteName = satelliteName; + } + + public String getImageType() { + return imageType; + } + + public void setImageType(String imageType) { + this.imageType = imageType; + } public Integer getResolution() { return resolution; @@ -372,5 +372,5 @@ public class McidasRecord extends PersistablePluginDataObject implements public void setPersistenceTime(Date persistTime) { // TODO Auto-generated method stub - } + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasSpatialFactory.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasSpatialFactory.java index f806d55e68..1996694e6e 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasSpatialFactory.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.mcidas/src/gov/noaa/nws/ncep/common/dataplugin/mcidas/McidasSpatialFactory.java @@ -411,6 +411,7 @@ public class McidasSpatialFactory { */ pvg.parameter("semi_major").setValue(1.0); pvg.parameter("semi_minor").setValue(1.0); + pvg.parameter("central_meridian").setValue(0.0); //pvg.parameter("scale_factor").setValue(1.0); pvg.parameter("NAV_BLOCK_BASE64").setValue(encoded); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/component-deploy.xml index 8a8bc35063..5a4431877b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/component-deploy.xml @@ -1,10 +1,10 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/NcccfpLocation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/NcccfpLocation.java index 5879076583..78c3724a5a 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/NcccfpLocation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/NcccfpLocation.java @@ -1,3 +1,4 @@ + package gov.noaa.nws.ncep.common.dataplugin.ncccfp; import javax.persistence.Column; @@ -10,8 +11,8 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.hibernate.annotations.Type; import org.opengis.referencing.crs.CoordinateReferenceSystem; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.geospatial.ISpatialObject; +import com.raytheon.uf.common.dataplugin.annotations.DataURI; import com.raytheon.uf.common.serialization.adapters.GeometryAdapter; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -43,18 +44,18 @@ public class NcccfpLocation implements ISpatialObject { private static final long serialVersionUID = 8890315829188793187L; - @DataURI(position = 0) + @DataURI(position=0) @Column(name = "location", columnDefinition = "geometry") @Type(type = "com.raytheon.edex.db.objects.hibernate.GeometryType") @XmlJavaTypeAdapter(value = GeometryAdapter.class) @DynamicSerializeElement private Geometry geometry; - - @Column(length = 600) + + @Column(length=600) @DynamicSerializeElement @XmlElement private String locationAll; - + @Column @DynamicSerializeElement @XmlElement @@ -64,7 +65,7 @@ public class NcccfpLocation implements ISpatialObject { @DynamicSerializeElement @XmlElement private double boxLong; - + @Override public CoordinateReferenceSystem getCrs() { return null; @@ -104,12 +105,12 @@ public class NcccfpLocation implements ISpatialObject { public void setGeometry(Geometry geometry) { this.geometry = geometry; } - - public void setLocationAll(String locationAll) { - this.locationAll = locationAll; + + public void setLocationAll (String locationAll) { + this.locationAll = locationAll; } - - public String getLocationAll() { - return locationAll; + + public String getLocationAll () { + return locationAll; } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/dao/NcccfpDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/dao/NcccfpDao.java index d222125aea..d8f8117a29 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/dao/NcccfpDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncccfp/src/gov/noaa/nws/ncep/common/dataplugin/ncccfp/dao/NcccfpDao.java @@ -12,64 +12,64 @@ * * @author fjyen * @version 1.0 - **/ -package gov.noaa.nws.ncep.common.dataplugin.ncccfp.dao; - -import java.util.List; - -import gov.noaa.nws.ncep.common.dataplugin.ncccfp.NcccfpRecord; + **/ +package gov.noaa.nws.ncep.common.dataplugin.ncccfp.dao; + +import java.util.List; + +import gov.noaa.nws.ncep.common.dataplugin.ncccfp.NcccfpRecord; import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; -import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.edex.database.DataAccessLayerException; - -public class NcccfpDao extends NcepDefaultPluginDao { - - - /** - * Creates a new ReccoDao - * @throws PluginException - */ - public NcccfpDao(String pluginName) throws PluginException { - super(pluginName); - } - - /** - * Retrieves a NCCCFP report using the datauri . - * - * @param dataURI - * The dataURI to match against. - * @return The report record if it exists. - */ - public NcccfpRecord queryByDataURI(String dataURI) { - NcccfpRecord report = null; - List obs = null; - try { - obs = queryBySingleCriteria("dataURI", dataURI); - } catch (DataAccessLayerException e) { - e.printStackTrace(); - } - if((obs != null)&&(obs.size() > 0)) { - report = (NcccfpRecord) obs.get(0); - } - return report; - } - - /** - * Queries for to determine if a given data uri exists on the NCCCFP table. - * - * @param dataUri - * The DataURI to find. - * @return An array of objects. If not null, there should only be a single - * element. - */ - public Object[] queryDataUriColumn(final String dataUri) { - - String sql = "select datauri from awips.ncccfp where datauri='" - + dataUri + "';"; - - Object[] results = executeSQLQuery(sql); - - return results; - } -} + +public class NcccfpDao extends NcepDefaultPluginDao { + + + /** + * Creates a new ReccoDao + * @throws PluginException + */ + public NcccfpDao(String pluginName) throws PluginException { + super(pluginName); + } + + /** + * Retrieves a NCCCFP report using the datauri . + * + * @param dataURI + * The dataURI to match against. + * @return The report record if it exists. + */ + public NcccfpRecord queryByDataURI(String dataURI) { + NcccfpRecord report = null; + List obs = null; + try { + obs = queryBySingleCriteria("dataURI", dataURI); + } catch (DataAccessLayerException e) { + e.printStackTrace(); + } + if((obs != null)&&(obs.size() > 0)) { + report = (NcccfpRecord) obs.get(0); + } + return report; + } + + /** + * Queries for to determine if a given data uri exists on the NCCCFP table. + * + * @param dataUri + * The DataURI to find. + * @return An array of objects. If not null, there should only be a single + * element. + */ + public Object[] queryDataUriColumn(final String dataUri) { + + String sql = "select datauri from awips.ncccfp where datauri='" + + dataUri + "';"; + + Object[] results = executeSQLQuery(sql); + + return results; + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/META-INF/MANIFEST.MF index 2e4e99b19a..68b97e8882 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/META-INF/MANIFEST.MF @@ -22,9 +22,11 @@ Require-Bundle: javax.measure, gov.noaa.nws.ncep.common;bundle-version="1.0.0", gov.noaa.nws.ncep.edex.common;bundle-version="1.0.0" Import-Package: com.raytheon.uf.common.dataplugin.level, + com.raytheon.uf.common.derivparam.tree, com.raytheon.uf.common.geospatial Export-Package: gov.noaa.nws.ncep.common.dataplugin.ncgrib, gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception, + gov.noaa.nws.ncep.common.dataplugin.ncgrib.ncdatatree, gov.noaa.nws.ncep.common.dataplugin.ncgrib.request, gov.noaa.nws.ncep.common.dataplugin.ncgrib.spatial.projections, gov.noaa.nws.ncep.common.dataplugin.ncgrib.subgrid, diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/component-deploy.xml index f07db9f2de..acd0a67839 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcGenProcess.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcGenProcess.java index d84ed37d7e..b42e2bd75b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcGenProcess.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcGenProcess.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribModel.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribModel.java index ebcd4e229e..fb6e6c0699 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribModel.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribModel.java @@ -61,6 +61,8 @@ import gov.noaa.nws.ncep.common.dataplugin.ncgrib.util.NcgridModel; * ------------ ---------- ----------- -------------------------- * 4/7/09 1994 bphillip Initial Creation * 1/31/11 M. Li Add eventName for dynamic model name + * 9/08/11 X. Guo Check file size to create hash code + * 11/17/11 X. Guo Fixed hash generator problem * * * @@ -316,8 +318,12 @@ public class NcgribModel extends PersistableDataObject { public int hashCode(String afileName) { HashCodeBuilder builder = new HashCodeBuilder(); - String[] tokens = afileName.split("\\."); - builder.append(modelName + "_" + tokens[0] + "_"+ tokens[1] + "_" + tokens[3]); +// String[] tokens = afileName.split("\\."); + String tmp = afileName; + if ( tmp.contains(".")) { + tmp = tmp.replace(".", "_"); + } + builder.append(modelName + "_" + tmp); builder.append(eventName); builder.append(parameterName); builder.append(parameterAbbreviation); diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribPathProvider.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribPathProvider.java index dfac4debac..7a4ad26489 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribPathProvider.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribPathProvider.java @@ -37,6 +37,8 @@ import com.raytheon.uf.common.dataplugin.persist.IPersistable; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 4/24/09 1994 bphillip Initial Creation + * 1/12/12 xguo Create new HDF5 file name + * yyyy-MM-dd-HH-fhrs-ensNumber.h5 * * * @@ -46,7 +48,7 @@ import com.raytheon.uf.common.dataplugin.persist.IPersistable; public class NcgribPathProvider extends DefaultPathProvider { private static final SimpleDateFormat gribHdf5FileNameFormat = new SimpleDateFormat( - "yyyy-MM-dd-HHmm"); + "yyyy-MM-dd-HH"); static { gribHdf5FileNameFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } @@ -102,11 +104,18 @@ public class NcgribPathProvider extends DefaultPathProvider { StringBuffer sb = new StringBuffer(); Date refTime = pdo.getDataTime().getRefTime(); + int fhrs = pdo.getDataTime().getFcstTime()/3600; String refTimeString = null; synchronized (gribHdf5FileNameFormat) { refTimeString = gribHdf5FileNameFormat.format(refTime); } + int pbNum = 0; + if ( pdo.getModelInfo().getPerturbationNumber() != null){ + pbNum = pdo.getModelInfo().getPerturbationNumber(); + } sb.append(refTimeString); + sb.append(String.format("-%d", fhrs)); + sb.append(String.format("-%d", pbNum)); sb.append(".h5"); return sb.toString(); } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribRecord.java index aedfda1d81..0a48fd40bf 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/NcgribRecord.java @@ -86,36 +86,36 @@ public class NcgribRecord extends PersistablePluginDataObject implements @DynamicSerializeElement private int masterTableVersion; - /** + /** * Version number of GRIB local tables used to augment Master Tables (See * Table 1.1) 0 - local tables not used, only table entries and templates - * the current master table are valid. (Currently 1) + * the current master table are valid. (Currently 1) */ @Column @XmlAttribute @DynamicSerializeElement private int localTableVersion; - /** - * Significance of reference time (See Table 1.2) 0 for analysis, 1 for - * forecast, 2 for verifying time, and 3 for observation time + /** Significance of reference time (See Table 1.2) + * 0 for analysis, 1 for forecast, 2 for verifying time, + * and 3 for observation time */ @Column @XmlAttribute @DynamicSerializeElement private int refTimeSignificance; - /** - * Processed data type in this GRIB message (See Table 1.4) 0 for analysis, - * 1 for forecast, 2 for both, .... or PDT in table 4.3 This refers to PDT# - * in GEMPAK output + /** Processed data type in this GRIB message (See Table 1.4) + * 0 for analysis, 1 for forecast, 2 for both, .... + * or PDT in table 4.3 + * This refers to PDT# in GEMPAK output */ @Column @XmlAttribute @DynamicSerializeElement private int processedDataType; - - /** Denotes if local section is present (currently false) */ + + /** Denotes if local section is present (currently false)*/ @Column @XmlAttribute @DynamicSerializeElement @@ -160,7 +160,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements @DynamicSerializeElement private float[] hybridCoordList; - /** The model information in ncgrib_models child table */ + /** The model information in ncgrib_models child table*/ @ManyToOne(cascade = { CascadeType.REFRESH }, fetch = FetchType.EAGER) @PrimaryKeyJoinColumn @Fetch(FetchMode.SELECT) @@ -171,12 +171,13 @@ public class NcgribRecord extends PersistablePluginDataObject implements private boolean isVector = false; - /** - * The short model name (i.e.NAM80) This should be interpreted from the - * generating process number and grid id : 96 for gfs, 114 for NAEFS, 84 for - * meso NAM 12KM, 86 for RUC, 81 for GFS analysis, 82 for analysis GDAS, - * etc... information form ON388 - table A Generating Process or Model from - * originating center 7 which is NCEP + /** The short model name (i.e.NAM80) This should be interpreted from + * the generating process number and grid id : 96 for gfs, + * 114 for NAEFS, 84 for meso NAM 12KM, 86 for RUC, 81 for GFS analysis, + * 82 for analysis GDAS, etc... + * information form ON388 - table A + * Generating Process or Model from originating center 7 + * which is NCEP */ @Column @XmlAttribute @@ -190,34 +191,32 @@ public class NcgribRecord extends PersistablePluginDataObject implements @DataURI(position = 3) private int gridVersion = 0; - /** - * The name of ingested file + /** The name of ingested file */ @Column @XmlAttribute @DynamicSerializeElement @DataURI(position = 4) private String fileName; - - /** - * The name of event such as Hurricane or Volcano + + /** The name of event such as Hurricane or + * Volcano */ @Column @XmlAttribute @DynamicSerializeElement private String eventName; - - /** - * Type of Generating Process + + /** Type of Generating Process */ @Column @XmlAttribute @DynamicSerializeElement @DataURI(position = 7) private int processType; - - /** - * Resolution and componet flags (See Table 3.3) + + /** Resolution and componet flags + * (See Table 3.3) */ @Column @XmlAttribute @@ -225,9 +224,10 @@ public class NcgribRecord extends PersistablePluginDataObject implements private Integer resCompFlags; /** - * Indicate the discipline of the processed data contained within a GRIB - * message - 0 for Meteorological products in table 0.0 This refers to DIS# - * in GEMPAK output + * Indicate the discipline of the processed + * data contained within a GRIB message - + * 0 for Meteorological products in table 0.0 + * This refers to DIS# in GEMPAK output */ @Column @XmlAttribute @@ -235,8 +235,8 @@ public class NcgribRecord extends PersistablePluginDataObject implements private int discipline; /** - * Parameter category by product discipline 0 for temperature in table 4.1 - * by discipline 0 + * Parameter category by product discipline + * 0 for temperature in table 4.1 by discipline 0 */ @Column @XmlAttribute @@ -244,27 +244,29 @@ public class NcgribRecord extends PersistablePluginDataObject implements private int category; /** - * Parameter number by product discipline and parameter category 9 for - * temperature anomaly in table 4.2-0-0 for discipline 0 and category 0 This - * refers to ID# in GEMPAK output + * Parameter number by product discipline and parameter category + * 9 for temperature anomaly in table 4.2-0-0 for discipline 0 + * and category 0 + * This refers to ID# in GEMPAK output */ @Column @XmlAttribute @DynamicSerializeElement private int parameterId; - - /** - * pdt - Product definition template number. + + /** pdt - Product definition template number. */ @Column @XmlAttribute @DynamicSerializeElement private int pdt; - + /** - * Fixed surface types or vertical coordinate ID 1 2 for cloud base level - * and 100 for isobaric surface in table 4.5 or VCRDGRID1.TBL for NCEP This - * refers to VCD# in GEMPAK output The location in pds[9] + * Fixed surface types or vertical coordinate ID 1 + * 2 for cloud base level and 100 for isobaric surface + * in table 4.5 or VCRDGRID1.TBL for NCEP + * This refers to VCD# in GEMPAK output + * The location in pds[9] */ @Column @XmlAttribute @@ -272,9 +274,11 @@ public class NcgribRecord extends PersistablePluginDataObject implements private int vcrdId1; /** - * Fixed surface types or vertical coordinate ID 2 2 for cloud base level - * and 100 for isobaric surface in table 4.5 or VCRDGRID1.TBL for NCEP This - * refers to VCD# in GEMPAK output The location in pds[12] + * Fixed surface types or vertical coordinate ID 2 + * 2 for cloud base level and 100 for isobaric surface + * in table 4.5 or VCRDGRID1.TBL for NCEP + * This refers to VCD# in GEMPAK output + * The location in pds[12] */ @Column @XmlAttribute @@ -282,23 +286,27 @@ public class NcgribRecord extends PersistablePluginDataObject implements private int vcrdId2; /** - * Scaled value of first fixed surface in GRIB2- TEMPLATE 4.1 This refers to - * LEVEL1 in GEMPAK output + * Scaled value of first fixed surface in GRIB2- TEMPLATE 4.1 + * This refers to LEVEL1 in GEMPAK output */ @Column @XmlAttribute @DynamicSerializeElement private int glevel1; + + private float decodedLevel1; /** - * Scaled value of second fixed surface in GRIB2- TEMPLATE 4.1 This refers - * to LEVEL2 in GEMPAK output + * Scaled value of second fixed surface in GRIB2- TEMPLATE 4.1 + * This refers to LEVEL2 in GEMPAK output */ @Column @XmlAttribute @DynamicSerializeElement private int glevel2; + private float decodedLevel2; + /** * The gempak vertical coordinate grid name */ @@ -307,7 +315,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements @DynamicSerializeElement @DataURI(position = 6) private String vcord; - + /** * The gempak abbreviation grid name */ @@ -316,7 +324,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements @DynamicSerializeElement @DataURI(position = 5) private String parm; - + /** * The gempak scale for decoding the grid field */ @@ -324,7 +332,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements @XmlAttribute @DynamicSerializeElement private String scale; - + /** * The forecast interval */ @@ -332,7 +340,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements @XmlAttribute @DynamicSerializeElement private int interval; - + /** * Creates an empty NcgribRecord */ @@ -399,7 +407,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements this.pdt = recordToCopy.pdt; this.vcrdId1 = recordToCopy.vcrdId1; this.vcrdId2 = recordToCopy.vcrdId2; - this.vcord = vcord; + this.vcord = recordToCopy.vcord; this.glevel1 = recordToCopy.glevel1; this.glevel2 = recordToCopy.glevel2; this.parm = recordToCopy.parm; @@ -438,10 +446,10 @@ public class NcgribRecord extends PersistablePluginDataObject implements } /** - * public void setSpatialObject(NcgridCoverage location) { - * modelInfo.setLocation(location); } - */ - + public void setSpatialObject(NcgridCoverage location) { + modelInfo.setLocation(location); + }*/ + /** * Gets the model information * @@ -645,7 +653,7 @@ public class NcgribRecord extends PersistablePluginDataObject implements this.gridVersion = gridVersion; } - public Integer getResCompFlags() { + public Integer getResCompFlags() { return resCompFlags; } @@ -654,131 +662,159 @@ public class NcgribRecord extends PersistablePluginDataObject implements } public String getModelName() { - return modelName; - } + return modelName; + } - public void setModelName(String modelName) { - this.modelName = modelName; - } + public void setModelName(String modelName) { + this.modelName = modelName; + } - public int getDiscipline() { - return discipline; - } + public int getDiscipline() { + return discipline; + } - public void setDiscipline(int discipline) { - this.discipline = discipline; - } + public void setDiscipline(int discipline) { + this.discipline = discipline; + } - public int getCategory() { - return category; - } + public int getCategory() { + return category; + } - public void setCategory(int category) { - this.category = category; - } + public void setCategory(int category) { + this.category = category; + } - public int getParameterId() { - return parameterId; - } + public int getParameterId() { + return parameterId; + } - public void setParameterId(int parameterId) { - this.parameterId = parameterId; - } + public void setParameterId(int parameterId) { + this.parameterId = parameterId; + } - public int getPdt() { - return pdt; - } + public int getPdt() { + return pdt; + } - public void setPdt(int pdt) { - this.pdt = pdt; - } + public void setPdt(int pdt) { + this.pdt = pdt; + } - public String getFileName() { - return fileName; - } + public String getFileName() { + return fileName; + } - public void setFileName(String fileName) { - this.fileName = fileName; - } + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getEventName() { + return eventName; + } - public String getEventName() { - return eventName; - } + public void setEventName(String eventName) { + this.eventName = eventName; + } - public void setEventName(String eventName) { - this.eventName = eventName; - } + public int getProcessType() { + return processType; + } - public int getProcessType() { - return processType; - } + public void setProcessType(int processType) { + this.processType = processType; + } + + public int getVcrdId1() { + return vcrdId1; + } - public void setProcessType(int processType) { - this.processType = processType; - } + public void setVcrdId1(int vcrdId1) { + this.vcrdId1 = vcrdId1; + } - public int getVcrdId1() { - return vcrdId1; - } + public int getVcrdId2() { + return vcrdId2; + } - public void setVcrdId1(int vcrdId1) { - this.vcrdId1 = vcrdId1; - } + public void setVcrdId2(int vcrdId2) { + this.vcrdId2 = vcrdId2; + } - public int getVcrdId2() { - return vcrdId2; - } + public int getGlevel1() { + return glevel1; + } - public void setVcrdId2(int vcrdId2) { - this.vcrdId2 = vcrdId2; - } + public void setGlevel1(int glevel1) { + this.glevel1 = glevel1; + } - public int getGlevel1() { - return glevel1; - } + public int getGlevel2() { + return glevel2; + } - public void setGlevel1(int glevel1) { - this.glevel1 = glevel1; - } + public void setGlevel2(int glevel2) { + this.glevel2 = glevel2; + } - public int getGlevel2() { - return glevel2; - } + public String getVcord() { + return vcord; + } - public void setGlevel2(int glevel2) { - this.glevel2 = glevel2; - } + public void setVcord(String vcord) { + this.vcord = vcord; + } - public String getVcord() { - return vcord; - } + public String getParm() { + return parm; + } - public void setVcord(String vcord) { - this.vcord = vcord; - } + public void setParm(String parm) { + this.parm = parm; + } - public String getParm() { - return parm; - } + public String getScale() { + return scale; + } - public void setParm(String parm) { - this.parm = parm; - } + public void setScale(String scale) { + this.scale = scale; + } - public String getScale() { - return scale; - } + public int getInterval() { + return interval; + } - public void setScale(String scale) { - this.scale = scale; - } + public void setInterval(int interval) { + this.interval = interval; + } - public int getInterval() { - return interval; - } + /** + * @return the decodedLevel1 + */ + public float getDecodedLevel1() { + return decodedLevel1; + } - public void setInterval(int interval) { - this.interval = interval; - } + /** + * @param decodedLevel1 the decodedLevel1 to set + */ + public void setDecodedLevel1(float decodedLevel1) { + this.decodedLevel1 = decodedLevel1; + } + + /** + * @return the decodedLevel2 + */ + public float getDecodedLevel2() { + return decodedLevel2; + } + + /** + * @param decodedLevel2 the decodedLevel2 to set + */ + public void setDecodedLevel2(float decodedLevel2) { + this.decodedLevel2 = decodedLevel2; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/request/GetNcCoverageRequest.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/request/GetNcCoverageRequest.java index 5fd344c78d..c92c758c2b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/request/GetNcCoverageRequest.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/request/GetNcCoverageRequest.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/LatLonNcgridCoverage.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/LatLonNcgridCoverage.java index d2af97f5fd..e5d95b31c3 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/LatLonNcgridCoverage.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/LatLonNcgridCoverage.java @@ -60,6 +60,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 4/7/09 1994 bphillip Initial Creation + * 9/08/11 X. Guo Skip correct Lon value after add new column * * * @@ -154,10 +155,16 @@ public class LatLonNcgridCoverage extends NcgridCoverage { @Override public void initialize() throws GribException { + double maxLon; double minLat = MapUtil.correctLat(la1); double maxLat = MapUtil.correctLat(la2); double minLon = MapUtil.correctLon(lo1); - double maxLon = MapUtil.correctLon(lo2); + if ( lo2 >= 360.0) { + maxLon = lo2; + } + else { + maxLon = MapUtil.correctLon(lo2); + } if (maxLon < minLon) { maxLon += 360.0; } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/NcgridCoverage.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/NcgridCoverage.java index b870754954..8c19122842 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/NcgridCoverage.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/spatial/projections/NcgridCoverage.java @@ -20,9 +20,6 @@ package gov.noaa.nws.ncep.common.dataplugin.ncgrib.spatial.projections; -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.subgrid.SubNcgrid; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @@ -41,6 +38,8 @@ import org.hibernate.annotations.Type; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.subgrid.SubNcgrid; import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject; import com.raytheon.uf.common.geospatial.ISpatialObject; import com.raytheon.uf.common.geospatial.MapUtil; @@ -167,12 +166,10 @@ public abstract class NcgridCoverage extends PersistableDataObject implements */ public abstract NcgridCoverage trim(SubNcgrid subGrid); - @Override public Polygon getGeometry() { return geometry; } - @Override public CoordinateReferenceSystem getCrs() { if (crs == null) { try { diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgribModelLookup.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgribModelLookup.java index b626ff7986..c59a38ee36 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgribModelLookup.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgribModelLookup.java @@ -45,6 +45,7 @@ import com.raytheon.uf.common.serialization.SerializationUtil; * ------------ ---------- ----------- -------------------------- * 3/12/10 4758 bphillip Initial creation * 10/13/10 276 llin Modified for NC GRIB. + * 11/02/11 xguo Updated gridid * * * @author njensen @@ -173,7 +174,7 @@ public class NcgribModelLookup { modelsByName.put(model.getName(), model); Integer center = model.getCenter(); Integer subCenter = Integer.parseInt(model.getSubCenter()); - String grid = String.valueOf(model.getGrid()); + String grid = model.getGrid(); for (int process : model.getProcess()) { models.put(toHash(center, subCenter, grid, process), model); } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgridModel.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgridModel.java index 07c71f7b22..29d5944068 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgridModel.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncgrib/src/gov/noaa/nws/ncep/common/dataplugin/ncgrib/util/NcgridModel.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ @@ -45,7 +45,7 @@ public class NcgridModel implements ISerializableObject { /** The NCEP grid associated with this model */ @XmlElement - private Integer grid; + private String grid; @XmlElement private String subcenter; @@ -80,11 +80,11 @@ public class NcgridModel implements ISerializableObject { this.name = name; } - public Integer getGrid() { + public String getGrid() { return grid; } - public void setGrid(Integer grid) { + public void setGrid(String grid) { this.grid = grid; } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/component-deploy.xml index 30469198f1..472e38d65d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/component-deploy.xml @@ -1,10 +1,8 @@ - - - + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/dao/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/dao/package-info.java index b8855f6780..82e6dddf92 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/dao/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncscat/src/gov/noaa/nws/ncep/common/dataplugin/ncscat/dao/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains data access object for airmet data. -*/ -package gov.noaa.nws.ncep.common.dataplugin.ncscat.dao; +/** +* Contains data access object for airmet data. +*/ +package gov.noaa.nws.ncep.common.dataplugin.ncscat.dao; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject old mode 100755 new mode 100644 diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/component-deploy.xml old mode 100755 new mode 100644 index 861a4f99bb..dc1df1b812 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetLocation.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetLocation.java old mode 100755 new mode 100644 index ae6ac7e47a..fafe385dce --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetLocation.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetLocation.java @@ -1,185 +1,161 @@ -/** - * NonConvsigmetLocation - * - * This java class defines the getters and setters for the - * convective sigmet location table. - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 Uma Josyula Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; - -import java.io.Serializable; - -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - - - -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -@Entity -@Table(name="nonconvsigmet_location") -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class NonConvSigmetLocation implements Serializable, ISerializableObject { - - private static final long serialVersionUID = 1L; - @Id - @GeneratedValue - private Integer recordId = null; - - // The nonconvsigmet record this object belongs to - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private NonConvSigmetRecord parentID; - - // Collection of locations - @Column(length=120) - @XmlElement - @DynamicSerializeElement - private String locationLine; - - // Each location of a nonconvective sigmet forecast area - @Column(length=40) - @XmlElement - @DynamicSerializeElement - private String location; - - // Each latitude of a nonconvective sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double latitude; - - // Each longitude of a nonconvective sigmet forecast area - @Column - @XmlElement - @DynamicSerializeElement - private double longitude; - - // Index for the order of a complete location set - @Column - @XmlElement - @DynamicSerializeElement - private Integer index; - - /** - * No-Arg Convstructor. - */ - public NonConvSigmetLocation() { - this.locationLine=""; - this.location=""; - this.index=IDecoderConstantsN.INTEGER_MISSING; - } - - /** - * @return the recordId. If not set returns null. - */ - public Integer getRecordId() { - return recordId; - } - - /** - * @param recordId to set - */ - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } - - /** - * @return the parentID - */ - public NonConvSigmetRecord getParentID() { - return parentID; - } - - /** - * @param parentID to set - */ - public void setParentID(NonConvSigmetRecord parentID) { - this.parentID = parentID; - } - - /** - * @return the locationLine - */ - public String getLocationLine() { - return locationLine; - } - - /** - * @param locationLine to set - */ - public void setLocationLine(String locationLine) { - this.locationLine = locationLine; - } - - /** - * @return the location - */ - public String getLocation() { - return location; - } - - /** - * @param location to set - */ - public void setLocation(String location) { - this.location = location; - } - - /** - * @return the index - */ - public Integer getIndex() { - return index; - } - - /** - * @param index to set - */ - public void setIndex(Integer index) { - this.index = index; - } - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - /** - * @return the serialVersionUID - */ - public static long getSerialVersionUID() { - return serialVersionUID; - } +/** + * NonConvsigmetLocation + * + * This java class defines the getters and setters for the + * convective sigmet location table. + * + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 Uma Josyula Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + + + +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +@Entity +@Table(name="nonconvsigmet_location") +@DynamicSerialize +public class NonConvSigmetLocation implements Serializable, ISerializableObject { + + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue + private Integer recordId = null; + + + + // Collection of locations + @Column(length=120) + @DynamicSerializeElement + private String locationLine; + + // Each location of a nonconvective sigmet forecast area + @Column(length=40) + @DynamicSerializeElement + private String location; + + // Each latitude of a nonconvective sigmet forecast area + @Column + @DynamicSerializeElement + private double latitude; + + // Each longitude of a nonconvective sigmet forecast area + @Column + @DynamicSerializeElement + private double longitude; + + // Index for the order of a complete location set + @Column + @DynamicSerializeElement + private Integer index; + + /** + * No-Arg Convstructor. + */ + public NonConvSigmetLocation() { + this.locationLine=""; + this.location=""; + this.index=IDecoderConstantsN.INTEGER_MISSING; + } + + /** + * @return the recordId. If not set returns null. + */ + public Integer getRecordId() { + return recordId; + } + + /** + * @param recordId to set + */ + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } + + + + /** + * @return the locationLine + */ + public String getLocationLine() { + return locationLine; + } + + /** + * @param locationLine to set + */ + public void setLocationLine(String locationLine) { + this.locationLine = locationLine; + } + + /** + * @return the location + */ + public String getLocation() { + return location; + } + + /** + * @param location to set + */ + public void setLocation(String location) { + this.location = location; + } + + /** + * @return the index + */ + public Integer getIndex() { + return index; + } + + /** + * @param index to set + */ + public void setIndex(Integer index) { + this.index = index; + } + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + /** + * @return the serialVersionUID + */ + public static long getSerialVersionUID() { + return serialVersionUID; + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java old mode 100755 new mode 100644 index 2c8cc8532c..39b31aa410 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/NonConvSigmetRecord.java @@ -1,548 +1,546 @@ -/** - * NonConvsigmetRecord - * - * This java class performs the mapping to the database table for NONCONVSIGMET - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 Uma Josyula Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; - -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; - -@Entity -@Table(name = "nonconvsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -@DynamicSerialize -public class NonConvSigmetRecord extends PluginDataObject { - - /** - * - */ - private static final long serialVersionUID = 1L; - - // reportType is "non-convective sigmet". - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String reportType; - - // WMO header - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String wmoHeader; - - // forecastRegion as: SL - @Column(length = 8) - @DataURI(position = 2) - @XmlElement - @DynamicSerializeElement - private String forecastRegion; - - // The issue office where the report from - @Column(length = 32) - @DataURI(position = 1) - @XmlElement - @DynamicSerializeElement - private String issueOffice; - - // Issue time of the report - @Column - @DataURI(position = 3) - @XmlElement - @DynamicSerializeElement - private Calendar issueTime; - - // The designator - @Column(length = 8) - @XmlElement - @DynamicSerializeElement - private String designatorBBB; - - // CorrectionFlag is a flag with values (1 or 2 or 3) - @Column(length = 8) - @XmlElement - @DynamicSerializeElement - private String correctionRemarks; - - // The awipsId from the report - @Column(length = 32) - @DataURI(position = 4) - @XmlElement - @DynamicSerializeElement - private String awipsId; - - // The state list from the report - @Column(length = 256) - @XmlElement - @DynamicSerializeElement - private String stateList; - - // Start time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar startTime; - - // End time of the report - @Column - @XmlElement - @DynamicSerializeElement - private Calendar endTime; - - // The type of the hazard from the report - @Column(length = 16) - @XmlElement - @DynamicSerializeElement - private String hazardType; - - // The intensity of the hazard from the report - @Column(length = 64) - @XmlElement - @DynamicSerializeElement - private String hazardIntensity; - - // The cause for the hazard from the report - @Column(length = 128) - @XmlElement - @DynamicSerializeElement - private String hazardCause; - - // The conditions stated about the hazard from the report - @Column(length = 128) - @XmlElement - @DynamicSerializeElement - private String hazardCondition; - - // The lower flight level from the report - @Column - @XmlElement - @DynamicSerializeElement - private int flightLevel1; - - // The upper flight level from the report - @Column - @XmlElement - @DynamicSerializeElement - private int flightLevel2; - - // The sigmet Identifier from the report - @Column(length = 32) - @XmlElement - @DynamicSerializeElement - private String sigmetId; - - // The entire report - @Column(length = 3000) - @XmlElement - @DynamicSerializeElement - private String bullMessage; - - /** - * Convsigmet location - */ - @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - private Set nonConvSigmetLocation = new HashSet(); - - /** - * Default Constructor - */ - public NonConvSigmetRecord() { - this.issueOffice = ""; - this.wmoHeader = ""; - this.bullMessage = ""; - this.designatorBBB = ""; - this.forecastRegion = ""; - this.reportType = ""; - this.correctionRemarks = ""; - this.awipsId = ""; - this.flightLevel1 = IDecoderConstantsN.INTEGER_MISSING; - this.flightLevel2 = IDecoderConstantsN.INTEGER_MISSING; - this.hazardCause = ""; - this.hazardCondition = ""; - this.hazardIntensity = ""; - this.hazardType = "UNKNOWN"; - this.stateList = ""; - this.sigmetId = ""; - } - - /** - * Convstructs a non-consigmet record from a dataURI - * - * @param uri - * The dataURI - */ - public NonConvSigmetRecord(String uri) { - super(uri); - } - - @Override - public IDecoderGettable getDecoderGettable() { - // TODO Auto-generated method stub - return null; - } - - /** - * @return the reportType - */ - public String getReportType() { - return reportType; - } - - /** - * @param reportType - * to set - */ - public void setReportType(String reportType) { - this.reportType = reportType; - } - - /** - * @return the wmoHeader - */ - public String getWmoHeader() { - return wmoHeader; - } - - /** - * @param wmoHeader - * to set - */ - public void setWmoHeader(String wmoHeader) { - this.wmoHeader = wmoHeader; - } - - /** - * @return the forecastRegion - */ - public String getForecastRegion() { - return forecastRegion; - } - - /** - * @param forecastRegion - * to set - */ - public void setForecastRegion(String forecastRegion) { - this.forecastRegion = forecastRegion; - } - - /** - * @return the issueOffice - */ - public String getIssueOffice() { - return issueOffice; - } - - /** - * @param issueOffice - * to set - */ - public void setIssueOffice(String issueOffice) { - this.issueOffice = issueOffice; - } - - /** - * @return the issueTime - */ - public Calendar getIssueTime() { - return issueTime; - } - - /** - * @param issueTime - * to set - */ - public void setIssueTime(Calendar issueTime) { - this.issueTime = issueTime; - } - - /** - * @return the designatorBBB - */ - public String getDesignatorBBB() { - return designatorBBB; - } - - /** - * @param designatorBBB - * to set - */ - public void setDesignatorBBB(String designatorBBB) { - this.designatorBBB = designatorBBB; - } - - /** - * @return the correctionFlag - */ - public String getCorrectionRemarks() { - return correctionRemarks; - } - - /** - * @param correctionFlag - * to set - */ - public void setCorrectionRemarks(String correctionRemarks) { - this.correctionRemarks = correctionRemarks; - } - - /** - * @return the awipsId - */ - public String getAwipsId() { - return awipsId; - } - - /** - * @param awipsId - * to set - */ - public void setAwipsId(String awipsId) { - this.awipsId = awipsId; - } - - /** - * @return the stateList - */ - public String getStateList() { - return stateList; - } - - /** - * @param stateList - * to set - */ - public void setStateList(String stateList) { - this.stateList = stateList; - } - - /** - * @return the startTime - */ - public Calendar getStartTime() { - return startTime; - } - - /** - * @param startTime - * to set - */ - public void setStartTime(Calendar startTime) { - this.startTime = startTime; - } - - /** - * @return the endTime - */ - public Calendar getEndTime() { - return endTime; - } - - /** - * @param endTime - * to set - */ - public void setEndTime(Calendar endTime) { - this.endTime = endTime; - } - - /** - * @return the hazardType - */ - public String getHazardType() { - return hazardType; - } - - /** - * @param hazardType - * to set - */ - public void setHazardType(String hazardType) { - this.hazardType = hazardType; - } - - /** - * @return the hazardIntensity - */ - public String getHazardIntensity() { - return hazardIntensity; - } - - /** - * @param hazardIntensity - * to set - */ - public void setHazardIntensity(String hazardIntensity) { - this.hazardIntensity = hazardIntensity; - } - - /** - * @return the hazardCause - */ - public String getHazardCause() { - return hazardCause; - } - - /** - * @param hazardCause - * to set - */ - public void setHazardCause(String hazardCause) { - this.hazardCause = hazardCause; - } - - /** - * @return the hazardCondition - */ - public String getHazardCondition() { - return hazardCondition; - } - - /** - * @param hazardCondition - * to set - */ - public void setHazardCondition(String hazardCondition) { - this.hazardCondition = hazardCondition; - } - - /** - * @return the flightLevel1 - */ - public int getFlightLevel1() { - return flightLevel1; - } - - /** - * @param flightLevel1 - * to set - */ - public void setFlightLevel1(int flightLevel1) { - this.flightLevel1 = flightLevel1; - } - - /** - * @return the flightLevel2 - */ - public int getFlightLevel2() { - return flightLevel2; - } - - /** - * @param flightLevel2 - * to set - */ - public void setFlightLevel2(int flightLevel2) { - this.flightLevel2 = flightLevel2; - } - - /** - * @return the sigmetId - */ - public String getSigmetId() { - return sigmetId; - } - - /** - * @param sigmetId - * to set - */ - public void setSigmetId(String sigmetId) { - this.sigmetId = sigmetId; - } - - /** - * @return the bullMessage - */ - public String getBullMessage() { - return bullMessage; - } - - /** - * @param bullMessage - * to set - */ - public void setBullMessage(String bullMessage) { - this.bullMessage = bullMessage; - } - - /** - * @return the set of nonconvective sigmet location - */ - public Set getNonConvSigmetLocation() { - return nonConvSigmetLocation; - } - - /** - * @param nonconvsigmet - * the location to set - */ - public void setNonConvSigmetLocation( - Set nonConvLocation) { - this.nonConvSigmetLocation = nonConvLocation; - } - - /** - * @param add - * conv Sigmet location to set - */ - public void addNonConvSigmetLocation(NonConvSigmetLocation pLocation) { - nonConvSigmetLocation.add(pLocation); - pLocation.setParentID(this); - } - - /** - * Override existing set method to modify any classes that use the dataURI - * as a foreign key - */ - @Override - public void setIdentifier(Object dataURI) { - - this.identifier = dataURI; - - if (this.getNonConvSigmetLocation() != null - && this.getNonConvSigmetLocation().size() > 0) { - for (Iterator iter = this - .getNonConvSigmetLocation().iterator(); iter.hasNext();) { - NonConvSigmetLocation cl = iter.next(); - cl.setParentID(this); - } - } - - } - +/** + * NonConvsigmetRecord + * + * This java class performs the mapping to the database table for NONCONVSIGMET + * + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 Uma Josyula Initial creation + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; + +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; + +import javax.persistence.CascadeType; +import javax.persistence.Column; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Index; + +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +@Entity +@Table(name = "nonconvsigmet", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) +@DynamicSerialize + + +public class NonConvSigmetRecord extends PluginDataObject{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + // reportType is "non-convective sigmet". + @Column(length=32) + @DynamicSerializeElement + private String reportType; + + // WMO header + @Column(length=32) + @DynamicSerializeElement + private String wmoHeader; + + // forecastRegion as: SL + @Column(length=8) + @DataURI(position=2) + @DynamicSerializeElement + private String forecastRegion; + + // The issue office where the report from + @Column(length=32) + @DataURI(position=1) + @DynamicSerializeElement + private String issueOffice; + + // Issue time of the report + @Column + @DataURI(position=3) + @DynamicSerializeElement + private Calendar issueTime; + + // The designator + @Column(length=8) + @DynamicSerializeElement + private String designatorBBB; + + // CorrectionFlag is a flag with values (1 or 2 or 3) + @Column(length=8) + @DynamicSerializeElement + private String correctionRemarks; + + // The awipsId from the report + @Column(length=32) + @DataURI(position=4) + @DynamicSerializeElement + private String awipsId; + + // The state list from the report + @Column(length=256) + @DynamicSerializeElement + private String stateList; + + // Start time of the report + @Column + @DynamicSerializeElement + private Calendar startTime; + + // End time of the report + @Column + @DynamicSerializeElement + private Calendar endTime; + + // The type of the hazard from the report + @Column(length=16) + @DynamicSerializeElement + private String hazardType; + + // The intensity of the hazard from the report + @Column(length=64) + @DynamicSerializeElement + private String hazardIntensity; + + // The cause for the hazard from the report + @Column(length=128) + @DynamicSerializeElement + private String hazardCause; + + // The conditions stated about the hazard from the report + @Column(length=128) + @DynamicSerializeElement + private String hazardCondition; + + // The lower flight level from the report + @Column + @DynamicSerializeElement + private int flightLevel1; + + // The upper flight level from the report + @Column + @DynamicSerializeElement + private int flightLevel2; + + // The sigmet Identifier from the report + @Column(length=32) + @DynamicSerializeElement + private String sigmetId; + + // The entire report + @Column(length=3000) + @DynamicSerializeElement + private String bullMessage; + + + /** + * Convsigmet location + */ + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "nonConvSigmetLocation_parentid_idex") + private Set nonConvSigmetLocation = new HashSet(); + + + /** + * Default Constructor + */ + public NonConvSigmetRecord() { + this.issueOffice =""; + this.wmoHeader =""; + this.bullMessage =""; + this.designatorBBB =""; + this.forecastRegion =""; + this.reportType =""; + this.correctionRemarks =""; + this.awipsId =""; + this.flightLevel1 =IDecoderConstantsN.INTEGER_MISSING; + this.flightLevel2 =IDecoderConstantsN.INTEGER_MISSING; + this.hazardCause =""; + this.hazardCondition =""; + this.hazardIntensity =""; + this.hazardType ="UNKNOWN"; + this.stateList =""; + this.sigmetId =""; + } + + /** + * Convstructs a non-consigmet record from a dataURI + * + * @param uri The dataURI + */ + public NonConvSigmetRecord(String uri) { + super(uri); + } + + @Override + public IDecoderGettable getDecoderGettable() { + // TODO Auto-generated method stub + return null; + } + + + /** + * @return the reportType + */ + public String getReportType() { + return reportType; + } + + + /** + * @param reportType to set + */ + public void setReportType(String reportType) { + this.reportType = reportType; + } + + + /** + * @return the wmoHeader + */ + public String getWmoHeader() { + return wmoHeader; + } + + + /** + * @param wmoHeader to set + */ + public void setWmoHeader(String wmoHeader) { + this.wmoHeader = wmoHeader; + } + + + /** + * @return the forecastRegion + */ + public String getForecastRegion() { + return forecastRegion; + } + + + /** + * @param forecastRegion to set + */ + public void setForecastRegion(String forecastRegion) { + this.forecastRegion = forecastRegion; + } + + + /** + * @return the issueOffice + */ + public String getIssueOffice() { + return issueOffice; + } + + + /** + * @param issueOffice to set + */ + public void setIssueOffice(String issueOffice) { + this.issueOffice = issueOffice; + } + + + /** + * @return the issueTime + */ + public Calendar getIssueTime() { + return issueTime; + } + + + /** + * @param issueTime to set + */ + public void setIssueTime(Calendar issueTime) { + this.issueTime = issueTime; + } + + + /** + * @return the designatorBBB + */ + public String getDesignatorBBB() { + return designatorBBB; + } + + + /** + * @param designatorBBB to set + */ + public void setDesignatorBBB(String designatorBBB) { + this.designatorBBB = designatorBBB; + } + + + /** + * @return the correctionFlag + */ + public String getCorrectionRemarks() { + return correctionRemarks; + } + + + /** + * @param correctionFlag to set + */ + public void setCorrectionRemarks(String correctionRemarks) { + this.correctionRemarks = correctionRemarks; + } + + + /** + * @return the awipsId + */ + public String getAwipsId() { + return awipsId; + } + + + /** + * @param awipsId to set + */ + public void setAwipsId(String awipsId) { + this.awipsId = awipsId; + } + + + /** + * @return the stateList + */ + public String getStateList() { + return stateList; + } + + + /** + * @param stateList to set + */ + public void setStateList(String stateList) { + this.stateList = stateList; + } + + + /** + * @return the startTime + */ + public Calendar getStartTime() { + return startTime; + } + + + /** + * @param startTime to set + */ + public void setStartTime(Calendar startTime) { + this.startTime = startTime; + } + + + /** + * @return the endTime + */ + public Calendar getEndTime() { + return endTime; + } + + + /** + * @param endTime to set + */ + public void setEndTime(Calendar endTime) { + this.endTime = endTime; + } + + + /** + * @return the hazardType + */ + public String getHazardType() { + return hazardType; + } + + + /** + * @param hazardType to set + */ + public void setHazardType(String hazardType) { + this.hazardType = hazardType; + } + + + /** + * @return the hazardIntensity + */ + public String getHazardIntensity() { + return hazardIntensity; + } + + + /** + * @param hazardIntensity to set + */ + public void setHazardIntensity(String hazardIntensity) { + this.hazardIntensity = hazardIntensity; + } + + + /** + * @return the hazardCause + */ + public String getHazardCause() { + return hazardCause; + } + + + /** + * @param hazardCause to set + */ + public void setHazardCause(String hazardCause) { + this.hazardCause = hazardCause; + } + + + /** + * @return the hazardCondition + */ + public String getHazardCondition() { + return hazardCondition; + } + + + /** + * @param hazardCondition to set + */ + public void setHazardCondition(String hazardCondition) { + this.hazardCondition = hazardCondition; + } + + + /** + * @return the flightLevel1 + */ + public int getFlightLevel1() { + return flightLevel1; + } + + + /** + * @param flightLevel1 to set + */ + public void setFlightLevel1(int flightLevel1) { + this.flightLevel1 = flightLevel1; + } + + + /** + * @return the flightLevel2 + */ + public int getFlightLevel2() { + return flightLevel2; + } + + + /** + * @param flightLevel2 to set + */ + public void setFlightLevel2(int flightLevel2) { + this.flightLevel2 = flightLevel2; + } + + + /** + * @return the sigmetId + */ + public String getSigmetId() { + return sigmetId; + } + + + /** + * @param sigmetId to set + */ + public void setSigmetId(String sigmetId) { + this.sigmetId = sigmetId; + } + + + /** + * @return the bullMessage + */ + public String getBullMessage() { + return bullMessage; + } + + + /** + * @param bullMessage to set + */ + public void setBullMessage(String bullMessage) { + this.bullMessage = bullMessage; + } + + + /** + * @return the set of nonconvective sigmet location + */ + public Set getNonConvSigmetLocation() { + return nonConvSigmetLocation; + } + + /** + * @param nonconvsigmet the location to set + */ + public void setNonConvSigmetLocation(Set nonConvLocation) { + this.nonConvSigmetLocation = nonConvLocation; + } + + /** + * @param add conv Sigmet location to set + */ + public void addNonConvSigmetLocation(NonConvSigmetLocation pLocation){ + nonConvSigmetLocation.add(pLocation); + + } + + + /** + * Override existing set method to modify any + * classes that use the dataURI as a foreign key + */ + @Override + public void setIdentifier(Object dataURI) + { + + this.identifier = dataURI; + + + + } + + + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/dao/NonConvSigmetDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/dao/NonConvSigmetDao.java index 64176dfd62..3d27e41cb7 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/dao/NonConvSigmetDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/dao/NonConvSigmetDao.java @@ -1,31 +1,14 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.dao; import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; import java.util.List; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; /** * TODO Add Description @@ -36,14 +19,15 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 23, 2009 jkorman Initial creation - * + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author jkorman * @version 1.0 */ -public class NonConvSigmetDao extends NcepDefaultPluginDao { +public class NonConvSigmetDao extends PluginDao { /** * Creates a new ReccoDao @@ -92,4 +76,11 @@ public class NonConvSigmetDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/package-info.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/package-info.java old mode 100755 new mode 100644 index 403310ea11..a3058334a5 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/package-info.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet/src/gov/noaa/nws/ncep/common/dataplugin/nonconvsigmet/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains table record for decoder plug-ins -*/ -package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; +/** +* Contains table record for decoder plug-ins +*/ +package gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/component-deploy.xml index 88c53d6d0c..2245318547 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/component-deploy.xml @@ -1,10 +1,8 @@ - - - - - + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/Activator.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/Activator.java deleted file mode 100644 index 4bf51992fc..0000000000 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/Activator.java +++ /dev/null @@ -1,37 +0,0 @@ -package gov.noaa.nws.ncep.common.dataplugin.tcm; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -public class Activator implements BundleActivator { - - private static BundleContext context; - - static BundleContext getContext() { - return context; - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext - * ) - */ - @Override - public void start(BundleContext bundleContext) throws Exception { - Activator.context = bundleContext; - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext bundleContext) throws Exception { - Activator.context = null; - } - -} diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmPositionWinds.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmPositionWinds.java index 7c4acf0a31..ef52311f27 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmPositionWinds.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmPositionWinds.java @@ -12,6 +12,8 @@ * ------------ ---------- ----------- -------------------------- * 06/2009 128 T. Lee Initial coding * 11/2009 128 T. Lee Migrated to TO11D6 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -26,21 +28,14 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; -import gov.noaa.nws.ncep.common.dataplugin.tcm.TcmRecord; import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @Entity @Table(name="tcm_position_winds") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class TcmPositionWinds implements Serializable, ISerializableObject { private static final long serialVersionUID = 1L; @@ -49,128 +44,105 @@ public class TcmPositionWinds implements Serializable, ISerializableObject { @GeneratedValue private Integer recordId = null; - /** The TCM record this object belongs to **/ - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private TcmRecord parentID; + /** The forecast valid time **/ @Column - @XmlElement @DynamicSerializeElement private Calendar validTime; /** The forecast hour **/ @Column - @XmlElement @DynamicSerializeElement private String fcstHour; /** The latitude of the storm center **/ @Column - @XmlElement @DynamicSerializeElement private Float clat; /** The longitude of the storm center **/ @Column - @XmlElement @DynamicSerializeElement private Float clon; /** The maximum wind of the storm **/ @Column - @XmlElement @DynamicSerializeElement private Integer windMax; /** The wind gust of the storm **/ @Column - @XmlElement @DynamicSerializeElement private Integer gust; /** Storm moving direction in compass direction */ @Column - @XmlElement @DynamicSerializeElement private Integer stormDrct; /** Storm moving speed */ @Column - @XmlElement @DynamicSerializeElement private Integer stormSped; /** The extent of 34kts wind at NE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String ne34k; /** The extent of 34kts wind at SE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String se34k; /** The extent of 34kts wind at SW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String sw34k; /** The extent of 34kts wind at NW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String nw34k; /** The extent of 50kts wind at NE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String ne50k; /** The extent of 50kts wind at SE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String se50k; /** The extent of 50kts wind at SW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String sw50k; /** The extent of 50kts wind at NW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String nw50k; /** The extent of 64kts wind at NE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String ne64k; /** The extent of 64kts wind at SE quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String se64k; /** The extent of 64kts wind at SW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String sw64k; /** The extent of 64kts wind at NW quadrant of the storm **/ @Column(length=8) - @XmlElement @DynamicSerializeElement private String nw64k; @@ -199,19 +171,7 @@ public class TcmPositionWinds implements Serializable, ISerializableObject { return serialVersionUID; } - /** - * @return the parentID - */ - public TcmRecord getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(TcmRecord parentID) { - this.parentID = parentID; - } + /** * @return the recordId diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java index 51bb27287d..997acca29e 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/TcmRecord.java @@ -12,6 +12,8 @@ * 06/2009 128 T. Lee Initial coding * 07/2009 128 T. Lee Migrated to TO11 * 11/2009 128 T. Lee Migrated to TO11D6 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -22,23 +24,18 @@ package gov.noaa.nws.ncep.common.dataplugin.tcm; import java.util.Calendar; import java.util.HashSet; -import java.util.Iterator; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import javax.xml.bind.annotation.XmlRootElement; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.Index; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.IDecoderGettable; @@ -49,8 +46,6 @@ import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @Entity @Table(name = "tcm", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class TcmRecord extends PluginDataObject { @@ -59,122 +54,104 @@ public class TcmRecord extends PluginDataObject { /** Report type */ @Column(length=32) - @XmlElement @DynamicSerializeElement private String reportType; /** Storm name */ @Column(length=32) @DataURI(position=2) - @XmlElement @DynamicSerializeElement private String stormName; /** Tropical storm basin */ @Column(length=8) @DataURI(position=1) - @XmlElement @DynamicSerializeElement private String basin; /** Storm number */ @Column(length=8) @DataURI(position=3) - @XmlElement @DynamicSerializeElement private String stormNumber; /** Advisory number */ @Column(length=8) @DataURI(position=4) - @XmlElement @DynamicSerializeElement private String advisoryNumber; /** Correction flag */ @Column @DataURI(position=5) - @XmlElement @DynamicSerializeElement private Boolean corr; /** Bulletin insurance time */ @Column - @XmlElement @DynamicSerializeElement private Calendar issueTime; /** Storm observation time **/ @Column - @XmlElement @DynamicSerializeElement private Calendar obsTime; /** Storm type */ @Column(length=32) - @XmlElement @DynamicSerializeElement private String stormType; /** Eye size */ @Column - @XmlElement @DynamicSerializeElement private Integer eyeSize; /** Minimum central pressure */ @Column - @XmlElement @DynamicSerializeElement private Integer centralPressure; /** Position accuracy */ @Column - @XmlElement @DynamicSerializeElement private Integer positionAccuracy; /** Twelve-foot wave height radii at the NE quadrant */ @Column - @XmlElement @DynamicSerializeElement private String ne12ft; /** Twelve-foot wave height radii at the SE quadrant */ @Column - @XmlElement @DynamicSerializeElement private String se12ft; /** Twelve-foot wave height radii at the SW quadrant */ @Column - @XmlElement @DynamicSerializeElement private String sw12ft; /** Twelve-foot wave height radii at the NW quadrant */ @Column - @XmlElement @DynamicSerializeElement private String nw12ft; /** Mass news disseminator (MND) */ @Column(length=72) - @XmlElement @DynamicSerializeElement private String mndTime; /** Bulletin messages */ @Column(length=8000) - @XmlElement @DynamicSerializeElement private String bullMessage; /** TCM position and winds */ @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "tcmPosWinds_parentid_idex") private Set tcmPosWinds = new HashSet(); /** @@ -479,7 +456,7 @@ public class TcmRecord extends PluginDataObject { */ public void addPosWinds(TcmPositionWinds poswinds){ tcmPosWinds.add(poswinds); - poswinds.setParentID (this); + } /** @@ -489,12 +466,7 @@ public class TcmRecord extends PluginDataObject { @Override public void setIdentifier(Object dataURI) { this.identifier = dataURI; - if (this.getTcmPosWinds() != null && this.getTcmPosWinds().size() > 0) { - for (Iterator iter = this.getTcmPosWinds().iterator(); iter.hasNext();) { - TcmPositionWinds tpw = iter.next(); - tpw.setParentID(this); - } - } + } @Override diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/dao/TcmDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/dao/TcmDao.java index c48f8cf170..a69df6804e 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/dao/TcmDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.tcm/src/gov/noaa/nws/ncep/common/dataplugin/tcm/dao/TcmDao.java @@ -10,6 +10,8 @@ * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 05/2010 128 T. Lee Migration to TO11DR11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author T.Lee @@ -19,13 +21,15 @@ package gov.noaa.nws.ncep.common.dataplugin.tcm.dao; import gov.noaa.nws.ncep.common.dataplugin.tcm.TcmRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; import java.util.List; import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; +import com.raytheon.uf.edex.database.plugin.PluginDao; -public class TcmDao extends NcepDefaultPluginDao { +public class TcmDao extends PluginDao { /** * FfgDao constructor. @@ -74,4 +78,11 @@ public class TcmDao extends NcepDefaultPluginDao { return results; } + + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/component-deploy.xml index 05d3e61917..4495eeca63 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpLatlons.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpLatlons.java index 59d7316ebe..d9a55b717d 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpLatlons.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpLatlons.java @@ -14,6 +14,8 @@ * 12Dec2008 37 F. J. Yen Initial * 17Apr2009 37 F. J. Yen Redesigned table and refactored for TO10 * 17May2010 37 F. J. Yen Refactored to dataplugin for migration to to11dr11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @@ -27,12 +29,7 @@ import java.io.Serializable; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -40,7 +37,6 @@ import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; @Entity @Table(name="wcp_latlons") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class WcpLatlons implements Serializable, ISerializableObject { @@ -53,26 +49,19 @@ public class WcpLatlons implements Serializable, ISerializableObject { @GeneratedValue private Integer recordId = null; - /** The wcp record this object belongs to **/ - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private WcpSevrln parentID; - + /** The latitude of the index-th position **/ //@DataURI(position=2) - @XmlElement @DynamicSerializeElement private Float lat; /** The longitude of the index-th position **/ //@DataURI(position=3) - @XmlElement @DynamicSerializeElement private Float lon; /** index for the order of lat/lons */ //@DataURI(position=4) - @XmlElement @DynamicSerializeElement private Integer index; @@ -92,19 +81,7 @@ public class WcpLatlons implements Serializable, ISerializableObject { return serialVersionUID; } - /** - * @return the parentID - */ - public WcpSevrln getParentID() { - return parentID; - } - - /** - * @param parentID the parentID to set - */ - public void setParentID(WcpSevrln parentID) { - this.parentID = parentID; - } + /** * @return The recordId. If not set returns to null. diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java index 0834732f99..7915a62c7e 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpRecord.java @@ -1,52 +1,3 @@ -/* - * - * WcpRecord - * - * This class performs the mapping to the database tables for the Watch Corner Point - * (WCP) Decoder Plug-In - * - * SOFTWARE HISTORY - * Date Ticket# Engineer Description - * ------------ ----------- -------------- ----------------------------------- - * 02Dec2008 37 F. J. Yen Initial creation - * 03Apr2009 37 F. J. Yen Refactored for TO10 - * * - * This code has been develped by the SIB for use in the AWIPS2 system. - * - * - * @author F. J. Yen, SIB - * @version 1 - - */ - -package gov.noaa.nws.ncep.common.dataplugin.wcp; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpSevrln; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; - -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.IDecoderGettable; -import com.raytheon.uf.common.dataplugin.annotations.DataURI; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * WcpRecord is the Data Access component for WCP Watch Corner Point data. @@ -63,15 +14,39 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * 17Apr2009 37 F. J. Yen Refactored for TO10 * 24Aug2009 37 F. J. Yen Refactored for TO11 * 17May2010 37 F. J. Yen Refactored to dataplugin for migration to to11dr11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author F. J. Yen, SIB * @version 1.0 */ + +package gov.noaa.nws.ncep.common.dataplugin.wcp; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpSevrln; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Index; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.IDecoderGettable; +import com.raytheon.uf.common.dataplugin.annotations.DataURI; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name = "wcp", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) }) -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class WcpRecord extends PluginDataObject{ @@ -80,33 +55,29 @@ public class WcpRecord extends PluginDataObject{ /** Report type */ @Column(length=32) - @XmlElement @DynamicSerializeElement private String reportType; //@DataURI(position = 1) @Column @DynamicSerializeElement - @XmlElement private Calendar issueTime; //@DataURI(position = 2) @DataURI(position = 1) @Column(length = 8) @DynamicSerializeElement - @XmlElement private String designatorBBB; @Column(length = 2500) @DynamicSerializeElement - @XmlElement private String bullMessage; /** WcpSevrln */ - @XmlElement - @DynamicSerializeElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @DynamicSerializeElement + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "wcpSevrLn_parentid_idex") private Set wcpSevrLn = new HashSet(); /** @@ -178,18 +149,12 @@ public class WcpRecord extends PluginDataObject{ */ public void addWcpSevrLn(WcpSevrln psevrln) { wcpSevrLn.add(psevrln); - psevrln.setParentID(this); + } public void setIdentifier(Object dataURI){ this.identifier = dataURI; - if(this.getWcpSevrLn() != null && this.getWcpSevrLn().size() > 0) - { - for (Iterator iter = this.getWcpSevrLn().iterator(); iter.hasNext();) { - WcpSevrln ws = iter.next(); - ws.setParentID(this); - } - } + } diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpSevrln.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpSevrln.java index 25c2231e6c..7ec2114176 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpSevrln.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/WcpSevrln.java @@ -14,6 +14,8 @@ * 12Dec2008 37 F. J. Yen Initial * 17Apr2009 37 F. J. Yen Refactored for TO10 * 17May2010 37 F. J. Yen Refactored to dataplugin for migration to to11dr11 + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @@ -27,9 +29,6 @@ import java.io.Serializable; import java.util.Calendar; import java.util.HashSet; import java.util.Set; -import java.util.Iterator; - -import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpRecord; import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpLatlons; import javax.persistence.CascadeType; @@ -39,15 +38,10 @@ import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.Index; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; @@ -55,7 +49,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @Entity @Table(name="wcp_sevrln") -@XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize /* * 8888888888888888 public class WcpSevrln extends PersistableDataObject @@ -69,49 +62,39 @@ public class WcpSevrln implements Serializable, ISerializableObject { @GeneratedValue private Integer recordId = null; - /** An identifier used to link this to its parent WcpRecord */ - /** The WcpSevrln record this object belongs to */ - @ManyToOne - @JoinColumn(name="parentID", nullable=false) - private WcpRecord parentID; + //@DataURI(position=1) @Column(length = 8) - @XmlElement @DynamicSerializeElement private String watchNumber; //@DataURI(position=2) @Column(length = 8) - @XmlElement @DynamicSerializeElement private String eventType; @Column - @XmlElement @DynamicSerializeElement private Calendar startTime; @Column - @XmlElement @DynamicSerializeElement private Calendar endTime; @Column - @XmlElement @DynamicSerializeElement private Integer numPnts; @Column(length = 272) - @XmlElement @DynamicSerializeElement private String sevrLines; @DynamicSerializeElement - @XmlElement - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parentID", fetch = FetchType.EAGER) - @OnDelete(action = OnDeleteAction.CASCADE) + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "parentID", nullable = false) + @Index(name = "wcpLatLon_parentid_idex") private Set wcpLatLon = new HashSet(); /** @@ -129,28 +112,7 @@ public class WcpSevrln implements Serializable, ISerializableObject { return serialVersionUID; } - /** - * @return the parentID - */ - public WcpRecord getParentID() { - return parentID; - } - - /** - * @param parentID - * the parentID to set - */ - public void setParentID(WcpRecord parentID) { - this.parentID = parentID; - - if (this.getWcpLatLon() != null && this.getWcpLatLon().size() > 0) { - for (Iterator iter = this.getWcpLatLon().iterator(); - iter.hasNext();) { - WcpLatlons cond = iter.next(); - cond.setParentID(this); - } - } - } + public String getWatchNumber() { return watchNumber; diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/dao/WcpDao.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/dao/WcpDao.java index 078b2e9042..a36a65dea1 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/dao/WcpDao.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.wcp/src/gov/noaa/nws/ncep/common/dataplugin/wcp/dao/WcpDao.java @@ -8,68 +8,79 @@ * Date Ticket# Engineer Description * ------------ ----------- ----------- -------------------------- * 17May2010 37 F. J. Yen Initial Coding (Following one of RTN's DAO to refactor) + * 09/2011 Chin Chen changed to improve purge performance and + * removed xml serialization as well * * * @author fjyen * @version 1.0 - **/ -package gov.noaa.nws.ncep.common.dataplugin.wcp.dao; + **/ +package gov.noaa.nws.ncep.common.dataplugin.wcp.dao; + +import java.util.List; + +import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpRecord; -import java.util.List; - -import gov.noaa.nws.ncep.common.dataplugin.wcp.WcpRecord; -import gov.noaa.nws.ncep.edex.common.dao.NcepDefaultPluginDao; - -import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.persist.IPersistable; +import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.edex.database.DataAccessLayerException; - -public class WcpDao extends NcepDefaultPluginDao { - - - /** - * Creates a new ReccoDao - * @throws PluginException - */ - public WcpDao(String pluginName) throws PluginException { - super(pluginName); +import com.raytheon.uf.edex.database.plugin.PluginDao; + +public class WcpDao extends PluginDao { + + + /** + * Creates a new ReccoDao + * @throws PluginException + */ + public WcpDao(String pluginName) throws PluginException { + super(pluginName); + } + + /** + * Retrieves a WCP report using the datauri . + * + * @param dataURI + * The dataURI to match against. + * @return The report record if it exists. + */ + public WcpRecord queryByDataURI(String dataURI) { + WcpRecord report = null; + List obs = null; + try { + obs = queryBySingleCriteria("dataURI", dataURI); + } catch (DataAccessLayerException e) { + e.printStackTrace(); + } + if((obs != null)&&(obs.size() > 0)) { + report = (WcpRecord) obs.get(0); + } + return report; + } + + /** + * Queries for to determine if a given data uri exists on the WCP table. + * + * @param dataUri + * The DataURI to find. + * @return An array of objects. If not null, there should only be a single + * element. + */ + public Object[] queryDataUriColumn(final String dataUri) { + + String sql = "select datauri from awips.wcp where datauri='" + + dataUri + "';"; + + Object[] results = executeSQLQuery(sql); + + return results; } - /** - * Retrieves a WCP report using the datauri . - * - * @param dataURI - * The dataURI to match against. - * @return The report record if it exists. - */ - public WcpRecord queryByDataURI(String dataURI) { - WcpRecord report = null; - List obs = null; - try { - obs = queryBySingleCriteria("dataURI", dataURI); - } catch (DataAccessLayerException e) { - e.printStackTrace(); - } - if((obs != null)&&(obs.size() > 0)) { - report = (WcpRecord) obs.get(0); - } - return report; - } - - /** - * Queries for to determine if a given data uri exists on the WCP table. - * - * @param dataUri - * The DataURI to find. - * @return An array of objects. If not null, there should only be a single - * element. - */ - public Object[] queryDataUriColumn(final String dataUri) { - - String sql = "select datauri from awips.wcp where datauri='" - + dataUri + "';"; - - Object[] results = executeSQLQuery(sql); - - return results; - } -} + @Override + protected IDataStore populateDataStore(IDataStore dataStore, + IPersistable obj) throws Exception { + // TODO Auto-generated method stub + return null; + } +} diff --git a/ncep/gov.noaa.nws.ncep.common.log/component-deploy.xml b/ncep/gov.noaa.nws.ncep.common.log/component-deploy.xml index 54a2ee4ef6..d7ee64ae7f 100644 --- a/ncep/gov.noaa.nws.ncep.common.log/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.common.log/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.common/src/gov/noaa/nws/ncep/common/tools/IDecoderConstantsN.java b/ncep/gov.noaa.nws.ncep.common/src/gov/noaa/nws/ncep/common/tools/IDecoderConstantsN.java index d0dd8b35df..33ff60334b 100644 --- a/ncep/gov.noaa.nws.ncep.common/src/gov/noaa/nws/ncep/common/tools/IDecoderConstantsN.java +++ b/ncep/gov.noaa.nws.ncep.common/src/gov/noaa/nws/ncep/common/tools/IDecoderConstantsN.java @@ -1,71 +1,63 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ package gov.noaa.nws.ncep.common.tools; +import java.util.Calendar; + import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; +import com.raytheon.uf.edex.decodertools.time.TimeTools; /** - * TODO Add Description + * This software was a utility class developed by NCEP. * *
- * 
+ *
  * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Sep 29, 2009            jkorman     Initial creation
- * May 17, 2010			   LLin		   Modify Integer and float missing
- * 									   identical to Raytheon's.
- * 4/2011                   T. Lee      Added UAIR_INTEGER_MISSING
- * 
+ *
+ * Date         Ticket#    	Engineer   	 Description
+ * ------------ ---------- 	----------- 	--------------------------
+ * Sep 29, 2009            	jkorman    	Initial creation
+ * May 17, 2010			   	LLin		Modify Integer and float missing
+ * 									   	identical to Raytheon's.
+ * 4/2011					T. Lee		Added UAIR_INTEGER_MISSING
+ * 7/2011					T. Lee		Added STORM_BULLSEPARATOR
+ * 9/2011					B. Hebbard	Added CALENDAR_MISSING
+ * 11/2011					S. Gurung	Added NEGATIVE_FLOAT_MISSING and NEGATIVE_INTEGER_MISSING
+ *
  * 
- * + * * @author jkorman - * @version 1.0 + * @version 1.0 */ public interface IDecoderConstantsN extends IDecoderConstants { /** Missing values */ public static final Integer INTEGER_MISSING = IDecoderConstants.VAL_MISSING; - public static final Float FLOAT_MISSING = 999999.f; - public static final Float UAIR_FLOAT_MISSING = -9999.f; - + public static final Float NEGATIVE_FLOAT_MISSING = -9999.f; public static final Integer UAIR_INTEGER_MISSING = -9999; - + public static final Integer NEGATIVE_INTEGER_MISSING = -9999; public static final float GRID_MISSING = -999999.f; - + public static final Double DOUBLE_MISSING = -9999.0; + public static final Calendar CALENDAR_MISSING = TimeTools.newCalendar(INTEGER_MISSING); + /** FFG separator */ - public static final String FFG_BULLSEPARATOR = "\\d{3} \\r\\r\\n" - + IDecoderConstants.WMO_HEADER + "(FFG[A-Z]{2}).\\r\\r\\n"; - + public static final String FFG_BULLSEPARATOR = "\\d{3} \\r\\r\\n"+ + IDecoderConstants.WMO_HEADER + "(FFG[A-Z]{2}).\\r\\r\\n"; + /** Regular expression for FFG report */ - public static final String FFG_REPORT = "([A-Z]{3}\\d{3})\\s{2}(.*)(\\r\\r\\n)"; - + public static final String FFG_REPORT = "([A-Z]{3}\\d{3})\\s{2}(.*)(\\r\\r\\n)"; + /** SCD separator */ - public static final String SCD_BULLSEPARATOR = "\\d{3} \\r\\r\\n" - + IDecoderConstants.WMO_HEADER + "(SCD[A-Z]{2}).\\r\\r\\n"; - + public static final String SCD_BULLSEPARATOR = "\\d{3} \\r\\r\\n"+ + IDecoderConstants.WMO_HEADER + "(SCD[A-Z]{2}).\\r\\r\\n"; + /** Regular expression for SCD report */ - public static final String SCD_REPORT = "([A-Z]{4}) (SCD) ([A-Z]{3} )*(\\d{4})(.*)(\\r\\r\\n)" - + "(([0-9]{1}|/)(.*)(\\r\\r\\n))*"; -} \ No newline at end of file + public static final String SCD_REPORT = "([A-Z]{4}) (SCD) ([A-Z]{3} )*(\\d{4})(.*)(\\r\\r\\n)" + + "(([0-9]{1}|/)(.*)(\\r\\r\\n))*"; + + /** Regular expression for STORM_TRACK report */ + public static final String STORM_BULLSEPARATOR = + "(WP|IO|SH|CP|EP|AL|ML), +(\\d{1,2}|\\w{1,4}), +\\d{10}, +\\d{1,2}, +\\w{1,4}, +" + +"(-|\\d)\\d{0,2}, +\\d{1,3}(N|S| ), +\\d{1,4}(E|W|\\W), +.*\\x0a"; +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.edex.common/META-INF/MANIFEST.MF index bc47e8f184..3d55fe6462 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.edex.common/META-INF/MANIFEST.MF @@ -7,11 +7,15 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Export-Package: gov.noaa.nws.ncep.edex.common.dao, gov.noaa.nws.ncep.edex.common.dataRecords, + gov.noaa.nws.ncep.edex.common.metparameters, + gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion, + gov.noaa.nws.ncep.edex.common.metparameters.quantity, gov.noaa.nws.ncep.edex.common.sounding, gov.noaa.nws.ncep.edex.common.stationTables, gov.noaa.nws.ncep.edex.locations, gov.noaa.nws.ncep.edex.tools.decoder, - gov.noaa.nws.ncep.edex.util + gov.noaa.nws.ncep.edex.util, + gov.noaa.nws.ncep.metparameters.util Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.12", com.raytheon.uf.edex.decodertools;bundle-version="1.11.16", com.raytheon.uf.common.localization;bundle-version="1.11.16", @@ -20,6 +24,12 @@ Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.12", org.geotools;bundle-version="2.5.8", com.facebook.thrift, javax.persistence;bundle-version="1.0.0", - com.raytheon.uf.common.serialization.comm;bundle-version="1.11.31" -Import-Package: gov.noaa.nws.ncep.common.tools, - org.eclipse.core.runtime;version="3.4.0" + com.raytheon.uf.common.serialization.comm;bundle-version="1.11.31", + com.raytheon.uf.edex.pointdata;bundle-version="1.12.1174", + com.raytheon.uf.common.pointdata;bundle-version="1.12.1174", + com.raytheon.uf.common.status;bundle-version="1.12.1174" +Import-Package: gov.noaa.nws.ncep.common.log.logger, + gov.noaa.nws.ncep.common.tools, + javax.measure.converter, + javax.measure.quantity, + javax.measure.unit diff --git a/ncep/gov.noaa.nws.ncep.edex.common/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.edex.common/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject index fc890712a7..93633f5d94 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject +++ b/ncep/gov.noaa.nws.ncep.edex.common/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -6,3 +6,272 @@ gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfo gov.noaa.nws.ncep.edex.common.sounding.NcSoundingTimeLines gov.noaa.nws.ncep.edex.common.sounding.NcSoundingModel +gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer2 +gov.noaa.nws.ncep.edex.common.metparameters.AbstractMetParameter +gov.noaa.nws.ncep.edex.common.metparameters.AircraftReportType +gov.noaa.nws.ncep.edex.common.metparameters.AircraftType +gov.noaa.nws.ncep.edex.common.metparameters.AirParcelTemp +gov.noaa.nws.ncep.edex.common.metparameters.AirTemperature +gov.noaa.nws.ncep.edex.common.metparameters.Amount +gov.noaa.nws.ncep.edex.common.metparameters.Avg3HrShipSpeed +gov.noaa.nws.ncep.edex.common.metparameters.BaseOfIcing +gov.noaa.nws.ncep.edex.common.metparameters.BaseOfTurbulence +gov.noaa.nws.ncep.edex.common.metparameters.BaseOfWeather +gov.noaa.nws.ncep.edex.common.metparameters.BruntVaisalaFreq +gov.noaa.nws.ncep.edex.common.metparameters.BruntVaisalaFreqSquared +gov.noaa.nws.ncep.edex.common.metparameters.BruntVaisalaPeriod +gov.noaa.nws.ncep.edex.common.metparameters.CatFcstCeilingHeightCond +gov.noaa.nws.ncep.edex.common.metparameters.CatFcstObstructionsVision +gov.noaa.nws.ncep.edex.common.metparameters.CatFcstPrecipitation +gov.noaa.nws.ncep.edex.common.metparameters.CatFcstSnowAmountFalling24hr +gov.noaa.nws.ncep.edex.common.metparameters.CatFcstVisibilityCond +gov.noaa.nws.ncep.edex.common.metparameters.CeilingFromSeaLevel +gov.noaa.nws.ncep.edex.common.metparameters.CeilingFromSeaLevelWorstCase +gov.noaa.nws.ncep.edex.common.metparameters.CeilingFromSurface +gov.noaa.nws.ncep.edex.common.metparameters.Clim12HrPOP +gov.noaa.nws.ncep.edex.common.metparameters.Clim24HrPOP +gov.noaa.nws.ncep.edex.common.metparameters.ClimDayTemp +gov.noaa.nws.ncep.edex.common.metparameters.ClimNightTemp +gov.noaa.nws.ncep.edex.common.metparameters.CloudBase1 +gov.noaa.nws.ncep.edex.common.metparameters.CloudBase2 +gov.noaa.nws.ncep.edex.common.metparameters.CloudCover +gov.noaa.nws.ncep.edex.common.metparameters.CloudFractionInLayer +gov.noaa.nws.ncep.edex.common.metparameters.CloudTop1 +gov.noaa.nws.ncep.edex.common.metparameters.CloudTop2 +gov.noaa.nws.ncep.edex.common.metparameters.CloudWater +gov.noaa.nws.ncep.edex.common.metparameters.CondFcstPrecip12HrType +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf12HrFreezingPrecip +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf12HrMixedLiquidOrFrozenSolid +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf12HrRain +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf12HrSevereWeather +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf12HrSnow +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf24HrSevereWeather +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOf6HrSevereWeather +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOfFreezingPrecip +gov.noaa.nws.ncep.edex.common.metparameters.CondProbOfSnow +gov.noaa.nws.ncep.edex.common.metparameters.DayTempAnomaly +gov.noaa.nws.ncep.edex.common.metparameters.DayTempFcst +gov.noaa.nws.ncep.edex.common.metparameters.DewPointDepression +gov.noaa.nws.ncep.edex.common.metparameters.DewPointTemp +gov.noaa.nws.ncep.edex.common.metparameters.DPRN +gov.noaa.nws.ncep.edex.common.metparameters.DryAirDensity +gov.noaa.nws.ncep.edex.common.metparameters.DryHydrostaticHeight +gov.noaa.nws.ncep.edex.common.metparameters.EquivPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.EquivWindSpeed10min +gov.noaa.nws.ncep.edex.common.metparameters.EquivWindSpeed20min +gov.noaa.nws.ncep.edex.common.metparameters.EstStormDirectionUComp +gov.noaa.nws.ncep.edex.common.metparameters.EstStormDirectionVComp +gov.noaa.nws.ncep.edex.common.metparameters.FcstFZRainAccumulationIn12Hours +gov.noaa.nws.ncep.edex.common.metparameters.FcstFZRainAccumulationToWatchThresh +gov.noaa.nws.ncep.edex.common.metparameters.FcstSnowIcePelletAccumToWatchThresh +gov.noaa.nws.ncep.edex.common.metparameters.FcstSnowIcePelletAccumulation12Hrs +gov.noaa.nws.ncep.edex.common.metparameters.FiveSecPeakWindDir +gov.noaa.nws.ncep.edex.common.metparameters.FlashFloodGuid01Hr +gov.noaa.nws.ncep.edex.common.metparameters.FlashFloodGuid03Hr +gov.noaa.nws.ncep.edex.common.metparameters.FlashFloodGuid06Hr +gov.noaa.nws.ncep.edex.common.metparameters.FlashFloodGuid12Hr +gov.noaa.nws.ncep.edex.common.metparameters.FlashFloodGuid24Hr +gov.noaa.nws.ncep.edex.common.metparameters.FlightLevel +gov.noaa.nws.ncep.edex.common.metparameters.FlightRulesID +gov.noaa.nws.ncep.edex.common.metparameters.FlightRulesIdWorstCase +gov.noaa.nws.ncep.edex.common.metparameters.FosbergFireWxIndex +gov.noaa.nws.ncep.edex.common.metparameters.FZRainWatchThresh +gov.noaa.nws.ncep.edex.common.metparameters.HailSize +gov.noaa.nws.ncep.edex.common.metparameters.HeatIndex +gov.noaa.nws.ncep.edex.common.metparameters.HeightAboveSeaLevel +gov.noaa.nws.ncep.edex.common.metparameters.Highest1MinMeanWindSpeedInPastHour +gov.noaa.nws.ncep.edex.common.metparameters.HighResWaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.HumitureIndex +gov.noaa.nws.ncep.edex.common.metparameters.IceCode +gov.noaa.nws.ncep.edex.common.metparameters.IcingIntensitySymbol +gov.noaa.nws.ncep.edex.common.metparameters.IcingTypeSymbol +gov.noaa.nws.ncep.edex.common.metparameters.InstrumentWaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.InstrumentWavePeriod +gov.noaa.nws.ncep.edex.common.metparameters.InterWindDir +gov.noaa.nws.ncep.edex.common.metparameters.InterWindSpeed +gov.noaa.nws.ncep.edex.common.metparameters.InterWindTime +gov.noaa.nws.ncep.edex.common.metparameters.IsentropesVerticalSeparation +gov.noaa.nws.ncep.edex.common.metparameters.LatentHeatOfVapor +gov.noaa.nws.ncep.edex.common.metparameters.LCLParcelPressure +gov.noaa.nws.ncep.edex.common.metparameters.LCLParcelTemperature +gov.noaa.nws.ncep.edex.common.metparameters.LiftedIndex +gov.noaa.nws.ncep.edex.common.metparameters.LiftedSurfaceAirTempAt500mb +gov.noaa.nws.ncep.edex.common.metparameters.Lowest01MinAvgPressInPastHour +gov.noaa.nws.ncep.edex.common.metparameters.Max12HrPrecipFcst +gov.noaa.nws.ncep.edex.common.metparameters.Max24HrTemp +gov.noaa.nws.ncep.edex.common.metparameters.Max6HrTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxCloudCover +gov.noaa.nws.ncep.edex.common.metparameters.MaxDailyWeatherMapTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxDayTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxEditedTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxMidnightTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxOrMinTemp +gov.noaa.nws.ncep.edex.common.metparameters.MaxPrecipPR6X +gov.noaa.nws.ncep.edex.common.metparameters.MaxSustSurfWindSpeedFcst +gov.noaa.nws.ncep.edex.common.metparameters.MaxWindSpeed +gov.noaa.nws.ncep.edex.common.metparameters.MeanSeaLevelPres +gov.noaa.nws.ncep.edex.common.metparameters.MetParameterFactory +gov.noaa.nws.ncep.edex.common.metparameters.Min24HrTemp +gov.noaa.nws.ncep.edex.common.metparameters.Min6HrTemp +gov.noaa.nws.ncep.edex.common.metparameters.MinDailyWeatherMapTemp +gov.noaa.nws.ncep.edex.common.metparameters.MinNightTemp +gov.noaa.nws.ncep.edex.common.metparameters.MixingRatio +gov.noaa.nws.ncep.edex.common.metparameters.MoistHydrostaticHeight +gov.noaa.nws.ncep.edex.common.metparameters.MontgomeryStreamFnct +gov.noaa.nws.ncep.edex.common.metparameters.MountainObscThresh +gov.noaa.nws.ncep.edex.common.metparameters.MountainObscThreshMetIndicator +gov.noaa.nws.ncep.edex.common.metparameters.MountainObscThreshMetIndicatorWorstCase +gov.noaa.nws.ncep.edex.common.metparameters.NewSnowAmount +gov.noaa.nws.ncep.edex.common.metparameters.NightTempAnomaly +gov.noaa.nws.ncep.edex.common.metparameters.NightTempFcst +gov.noaa.nws.ncep.edex.common.metparameters.NumInterWinds +gov.noaa.nws.ncep.edex.common.metparameters.Omega +gov.noaa.nws.ncep.edex.common.metparameters.OneMinPeakWindDir +gov.noaa.nws.ncep.edex.common.metparameters.PeakWindDir +gov.noaa.nws.ncep.edex.common.metparameters.PeakWindSpeed +gov.noaa.nws.ncep.edex.common.metparameters.PeakWindSpeedTime +gov.noaa.nws.ncep.edex.common.metparameters.PerpendicularWindComp +gov.noaa.nws.ncep.edex.common.metparameters.PlatformTrueDirection +gov.noaa.nws.ncep.edex.common.metparameters.PlatformTrueSpeed +gov.noaa.nws.ncep.edex.common.metparameters.POP12Hrs +gov.noaa.nws.ncep.edex.common.metparameters.POP24Hrs +gov.noaa.nws.ncep.edex.common.metparameters.POPAnomalyIn12hrs +gov.noaa.nws.ncep.edex.common.metparameters.POPAnomalyIn24hrs +gov.noaa.nws.ncep.edex.common.metparameters.POPFcst06Hrs +gov.noaa.nws.ncep.edex.common.metparameters.POPFcst12Hrs +gov.noaa.nws.ncep.edex.common.metparameters.POPFcst24Hrs +gov.noaa.nws.ncep.edex.common.metparameters.PotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.PotentialTempLapseRate +gov.noaa.nws.ncep.edex.common.metparameters.Precip01Hr +gov.noaa.nws.ncep.edex.common.metparameters.Precip03Hr +gov.noaa.nws.ncep.edex.common.metparameters.Precip06Hr +gov.noaa.nws.ncep.edex.common.metparameters.Precip12Hr +gov.noaa.nws.ncep.edex.common.metparameters.Precip18Hr +gov.noaa.nws.ncep.edex.common.metparameters.Precip24Hr +gov.noaa.nws.ncep.edex.common.metparameters.PrecipitableWaterForEntireSounding +gov.noaa.nws.ncep.edex.common.metparameters.PrecipitableWaterUptoSpecifiedLevel +gov.noaa.nws.ncep.edex.common.metparameters.Precipitation +gov.noaa.nws.ncep.edex.common.metparameters.PredomSwellWaveDir +gov.noaa.nws.ncep.edex.common.metparameters.PredomSwellWaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.PredomSwellWavePeriod +gov.noaa.nws.ncep.edex.common.metparameters.PresentWeather +gov.noaa.nws.ncep.edex.common.metparameters.PressChange24Hr +gov.noaa.nws.ncep.edex.common.metparameters.PressChange3Hr +gov.noaa.nws.ncep.edex.common.metparameters.PressureTendencySymbol +gov.noaa.nws.ncep.edex.common.metparameters.PressureLevel +gov.noaa.nws.ncep.edex.common.metparameters.RateOfIceAccretionOnVesselInSaltWater +gov.noaa.nws.ncep.edex.common.metparameters.RelativeHumidity +gov.noaa.nws.ncep.edex.common.metparameters.RichardsonNumber +gov.noaa.nws.ncep.edex.common.metparameters.SatEquivPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.SatMixingRatio +gov.noaa.nws.ncep.edex.common.metparameters.SatVaporPressure +gov.noaa.nws.ncep.edex.common.metparameters.SeaIceDriftDist +gov.noaa.nws.ncep.edex.common.metparameters.SeaLevelPressure +gov.noaa.nws.ncep.edex.common.metparameters.SeaSurfaceTemp +gov.noaa.nws.ncep.edex.common.metparameters.SecondarySwellWaveDir +gov.noaa.nws.ncep.edex.common.metparameters.SecondarySwellWaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.SecondarySwellWavePeriod +gov.noaa.nws.ncep.edex.common.metparameters.ShipCourse +gov.noaa.nws.ncep.edex.common.metparameters.ShipIceThickness +gov.noaa.nws.ncep.edex.common.metparameters.ShowalterIndex +gov.noaa.nws.ncep.edex.common.metparameters.SkyCoverage +gov.noaa.nws.ncep.edex.common.metparameters.SnowDepth +gov.noaa.nws.ncep.edex.common.metparameters.SnowIcePelletWatchThresh +gov.noaa.nws.ncep.edex.common.metparameters.SpecificHumidity +gov.noaa.nws.ncep.edex.common.metparameters.SpeedOf05SecPeakWind +gov.noaa.nws.ncep.edex.common.metparameters.StabilityWithRespectToPressure +gov.noaa.nws.ncep.edex.common.metparameters.StationElevation +gov.noaa.nws.ncep.edex.common.metparameters.StationID +gov.noaa.nws.ncep.edex.common.metparameters.StationLatitude +gov.noaa.nws.ncep.edex.common.metparameters.StationLongitude +gov.noaa.nws.ncep.edex.common.metparameters.StationName +gov.noaa.nws.ncep.edex.common.metparameters.StormMotionDirection +gov.noaa.nws.ncep.edex.common.metparameters.StormMotionSpeed +gov.noaa.nws.ncep.edex.common.metparameters.SunshineDuration +gov.noaa.nws.ncep.edex.common.metparameters.SurfaceEquivPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.SurfaceMixingRatio +gov.noaa.nws.ncep.edex.common.metparameters.SurfacePotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.SurfacePressure +gov.noaa.nws.ncep.edex.common.metparameters.SurfaceSatEquivPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.SurfaceSatMixingRatio +gov.noaa.nws.ncep.edex.common.metparameters.TempLapseRate +gov.noaa.nws.ncep.edex.common.metparameters.ProbableCeilingAsMeanSeaLevel +gov.noaa.nws.ncep.edex.common.metparameters.ProbableCeiling +gov.noaa.nws.ncep.edex.common.metparameters.ProbableFlightRuleIdentifier +gov.noaa.nws.ncep.edex.common.metparameters.ProbableMountainObscThreshMetIndicator +gov.noaa.nws.ncep.edex.common.metparameters.ProbableVisibility +gov.noaa.nws.ncep.edex.common.metparameters.ProbableWindDirection +gov.noaa.nws.ncep.edex.common.metparameters.ProbableWindGust +gov.noaa.nws.ncep.edex.common.metparameters.ProbableWindSpeed +gov.noaa.nws.ncep.edex.common.metparameters.TempTndncyFromAllRad +gov.noaa.nws.ncep.edex.common.metparameters.TempTndncyFromConvPhaseChange +gov.noaa.nws.ncep.edex.common.metparameters.TempTndncyFromGrdSclPhaseChange +gov.noaa.nws.ncep.edex.common.metparameters.TempTndncyFromLongWaveRad +gov.noaa.nws.ncep.edex.common.metparameters.TempTndncyFromShortWaveRad +gov.noaa.nws.ncep.edex.common.metparameters.TimeOf5SecPeakWindInHrs +gov.noaa.nws.ncep.edex.common.metparameters.TimeOf5SecPeakWindInMins +gov.noaa.nws.ncep.edex.common.metparameters.TopOfIcing +gov.noaa.nws.ncep.edex.common.metparameters.TopOfTurbulence +gov.noaa.nws.ncep.edex.common.metparameters.TopOfWeather +gov.noaa.nws.ncep.edex.common.metparameters.TurbulenceFrequencySymbol +gov.noaa.nws.ncep.edex.common.metparameters.TurbulenceIntensitySymbol +gov.noaa.nws.ncep.edex.common.metparameters.TurbulentKineticEnergy +gov.noaa.nws.ncep.edex.common.metparameters.UncondProbOfTstorms12hr +gov.noaa.nws.ncep.edex.common.metparameters.UncondProbOfTstorms24hr +gov.noaa.nws.ncep.edex.common.metparameters.UncondProbOfTstorms2hr +gov.noaa.nws.ncep.edex.common.metparameters.UncondProbOfTstorms6hr +gov.noaa.nws.ncep.edex.common.metparameters.VaporPressure +gov.noaa.nws.ncep.edex.common.metparameters.VerticalVelocity +gov.noaa.nws.ncep.edex.common.metparameters.VirtualPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.VirtualTemp +gov.noaa.nws.ncep.edex.common.metparameters.Visibility +gov.noaa.nws.ncep.edex.common.metparameters.WaterEquivOfNewSnow +gov.noaa.nws.ncep.edex.common.metparameters.WaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.WavePeriod +gov.noaa.nws.ncep.edex.common.metparameters.WaveSteepness +gov.noaa.nws.ncep.edex.common.metparameters.WetBulbPotentialTemp +gov.noaa.nws.ncep.edex.common.metparameters.WetBulbTemp +gov.noaa.nws.ncep.edex.common.metparameters.WindChillEquivalentTemp +gov.noaa.nws.ncep.edex.common.metparameters.WindChillTemperature +gov.noaa.nws.ncep.edex.common.metparameters.WindCompDirection +gov.noaa.nws.ncep.edex.common.metparameters.WindDirection +gov.noaa.nws.ncep.edex.common.metparameters.WindDirectionUComp +gov.noaa.nws.ncep.edex.common.metparameters.WindDirectionVComp +gov.noaa.nws.ncep.edex.common.metparameters.WindGust +gov.noaa.nws.ncep.edex.common.metparameters.WindSpeedComp +gov.noaa.nws.ncep.edex.common.metparameters.WindSpeed +gov.noaa.nws.ncep.edex.common.metparameters.WindWaveHeight +gov.noaa.nws.ncep.edex.common.metparameters.WindWavePeriod +gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion.GempakConstants +gov.noaa.nws.ncep.edex.common.metparameters.Avg1HrHeatFlux +gov.noaa.nws.ncep.edex.common.metparameters.Avg1HrSnowPhaseChangeHeatFlux +gov.noaa.nws.ncep.edex.common.metparameters.Avg1HrSubSurfaceHeatFlux +gov.noaa.nws.ncep.edex.common.metparameters.AccumSnowFallIn01Hr +gov.noaa.nws.ncep.edex.common.metparameters.AccumSnowMeltIn01Hr +gov.noaa.nws.ncep.edex.common.metparameters.AmountOfHighClouds +gov.noaa.nws.ncep.edex.common.metparameters.AmountOfLowClouds +gov.noaa.nws.ncep.edex.common.metparameters.AmountOfMidClouds +gov.noaa.nws.ncep.edex.common.metparameters.ConvectivePrecip +gov.noaa.nws.ncep.edex.common.metparameters.DryBulbTemp +gov.noaa.nws.ncep.edex.common.metparameters.FreezingRainType +gov.noaa.nws.ncep.edex.common.metparameters.IceType +gov.noaa.nws.ncep.edex.common.metparameters.LandSea +gov.noaa.nws.ncep.edex.common.metparameters.NumProfileLevels +gov.noaa.nws.ncep.edex.common.metparameters.PercentageOfCloudCover +gov.noaa.nws.ncep.edex.common.metparameters.PotentialTempAt10Meters +gov.noaa.nws.ncep.edex.common.metparameters.PressureAtCloudLevel +gov.noaa.nws.ncep.edex.common.metparameters.RainType +gov.noaa.nws.ncep.edex.common.metparameters.SkinTemperature +gov.noaa.nws.ncep.edex.common.metparameters.SnowFall +gov.noaa.nws.ncep.edex.common.metparameters.SnowPrecipType +gov.noaa.nws.ncep.edex.common.metparameters.SpecificHumidityAt02Meters +gov.noaa.nws.ncep.edex.common.metparameters.SpecificHumidityAt10Meters +gov.noaa.nws.ncep.edex.common.metparameters.StormRelativeHelicity +gov.noaa.nws.ncep.edex.common.metparameters.TotalPrecip +gov.noaa.nws.ncep.edex.common.metparameters.UCompAt10Meters +gov.noaa.nws.ncep.edex.common.metparameters.VCompAt10Meters +gov.noaa.nws.ncep.edex.common.metparameters.Probability +gov.noaa.nws.ncep.edex.common.metparameters.ProbableSkyCoverage +gov.noaa.nws.ncep.edex.common.metparameters.ReportTimeInHourMins +gov.noaa.nws.ncep.edex.common.metparameters.ProbablePresentWeather +gov.noaa.nws.ncep.edex.common.metparameters.LowLevelWindShear \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.common/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.common/component-deploy.xml index c4ce27a1c8..b4efb03c7c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/dao/NcepDefaultPluginDao.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/dao/NcepDefaultPluginDao.java index 04ec498ff3..6d554e2e04 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/dao/NcepDefaultPluginDao.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/dao/NcepDefaultPluginDao.java @@ -60,6 +60,7 @@ public class NcepDefaultPluginDao extends PluginDao { String queryString = "delete " + daoClass.getSimpleName() + " x"; + logger.info("query..."+ queryString); Query query = s.createQuery(queryString); results = query.executeUpdate(); tx.commit(); @@ -77,22 +78,24 @@ public class NcepDefaultPluginDao extends PluginDao { } return results; } - @Override + /*@Override /** * Purges all data associated with the owning plugin based on criteria * specified by the owning plugin * * @throws PluginException * If problems occur while interacting with the data stores - */ + * public void purgeAllData() throws PluginException { purgeAllTables(); + ArrayList files = FileUtil.listFiles(new File(PLUGIN_HDF5_DIR), new HDF5PluginFilenameFilter(pluginName), true); for (File file : files) { file.delete(); } - } + + }*/ @Override protected IDataStore populateDataStore(IDataStore dataStore, diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingCube.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingCube.java index 46c406be4c..d05ff9b9ac 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingCube.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingCube.java @@ -15,13 +15,14 @@ package gov.noaa.nws.ncep.edex.common.sounding; * Date Ticket# Engineer Description * ------- ------- -------- ----------- * 11/18/2010 TBD Chin Chen Initial coding - * + *10/06/2011 465 Archana Generated a fresh serial version id * * * @author Chin Chen * @version 1.0 */ +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -36,12 +37,17 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize public class NcSoundingCube implements ISerializableObject { + /** + * + */ + private static final long serialVersionUID = 8077693951195416377L; + public enum QueryStatus { OK, FAILED, LOCATION_NOT_FOUND } - @DynamicSerializeElement - private static final long serialVersionUID = 1324632468L; +// @DynamicSerializeElement + // private static final long serialVersionUID = 1324632468L; @DynamicSerializeElement private List soundingProfileList; @@ -78,3 +84,4 @@ public class NcSoundingCube implements ISerializableObject { } + diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java index 1dc62ae4c0..76ca77a997 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java @@ -11,17 +11,19 @@ package gov.noaa.nws.ncep.edex.common.sounding; *
  * SOFTWARE HISTORY
  * 
- * Date         Ticket#    	Engineer    Description
- * -------		------- 	-------- 	-----------
- * 09/13/2010	362			Chin Chen	Initial coding
- * 12/16/2010   362         Chin Chen   add support of BUFRUA observed sounding and PFC (NAM and GFS) model sounding data
- *
+ * Date             Ticket#    	Engineer       Description
+ * -------		      ---------   ---------------    ------------------
+ * 09/13/2010	362		   Chin Chen	 Initial coding
+ * 12/16/2010   362         Chin Chen    add support of BUFRUA observed sounding and PFC (NAM and GFS) model sounding data
+ * 09/14/2011   457         S. Gurung     Renamed ObsSndType.H5UAIR to ObsSndType.NCUAIR
+ *10/06/2011    465         Archana        Added a list of NcSoundingLayer2 objects to the sounding profile
  * 
* * @author Chin Chen * @version 1.0 */ +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -35,10 +37,13 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize -public class NcSoundingProfile implements ISerializableObject{ - @DynamicSerializeElement - private static final long serialVersionUID = 1324632468L; +public class NcSoundingProfile implements ISerializableObject{ + /** + * + */ + private static final long serialVersionUID = 6858474095965608817L; + @DynamicSerializeElement public static final float MISSING = -9999.f; public static enum PfcSndType { NAMSND, GFSSND, RUC2SND, RUCPTYPSND, BROWSE, NONE @@ -47,7 +52,7 @@ public class NcSoundingProfile implements ISerializableObject{ ANY, NONE }; public static enum ObsSndType { - H5UAIR, UAIR, DROP, TAMDAR, BUFRUA //same as uair but using bufrua decoder and data is saved in HDF5 + NCUAIR, UAIR, DROP, TAMDAR, BUFRUA //same as uair but using bufrua decoder and data is saved in HDF5 ,BROWSE, NONE }; //Important Note: @@ -60,7 +65,11 @@ public class NcSoundingProfile implements ISerializableObject{ }; @DynamicSerializeElement private List soundingLyLst; + @DynamicSerializeElement + private List soundingLyLst2; + + @DynamicSerializeElement private float stationElevation; //@DynamicSerializeElement //private String stationId; @@ -77,6 +86,7 @@ public class NcSoundingProfile implements ISerializableObject{ @DynamicSerializeElement private int stationNum; + @DynamicSerializeElement private NcSoundingCube.QueryStatus rtnStatus = NcSoundingCube.QueryStatus.OK; @@ -112,6 +122,20 @@ public class NcSoundingProfile implements ISerializableObject{ this.soundingLyLst = soundingLyLst; } + /** + * @return the soundingLyLst2 + */ + public List getSoundingLyLst2() { + return soundingLyLst2; + } + + /** + * @param soundingLyLst2 the soundingLyLst2 to set + */ + public void setSoundingLyLst2(List soundingLyLst2) { + this.soundingLyLst2 = soundingLyLst2; + } + public float getStationElevation() { return stationElevation; } @@ -150,10 +174,12 @@ public class NcSoundingProfile implements ISerializableObject{ } // TO-DO: Add station number (stationNumber) - public NcSoundingProfile(List soundingLyLst, + public NcSoundingProfile(List soundingLyLst2, + List soundingLyLst, float stationElevation, String stationId, float stationLatitude, float stationLongitude, float sfcPress, int stnNum) { super(); + this.soundingLyLst2 = soundingLyLst2; this.soundingLyLst = soundingLyLst; this.stationElevation = stationElevation; this.stationId = stationId; @@ -166,6 +192,7 @@ public class NcSoundingProfile implements ISerializableObject{ public NcSoundingProfile() { super(); this.soundingLyLst = new ArrayList(); + this.soundingLyLst2 = new ArrayList(); this.stationElevation = MISSING; this.stationId = ""; this.stationLatitude = MISSING; @@ -211,3 +238,4 @@ public class NcSoundingProfile implements ISerializableObject{ */ } + diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/IStationField.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/IStationField.java old mode 100755 new mode 100644 index 1277e1931e..f61765c1bd --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/IStationField.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/IStationField.java @@ -1,19 +1,19 @@ -package gov.noaa.nws.ncep.edex.common.stationTables; - -public interface IStationField { - - public static enum StationField { - STID, // station id - STNM, // station number - NAME, // station name - ST, // state - CO, // country - //LAT, // latitude - //LON, // longitude - //ELV, // elevation - //PRI, // priority - WFO, // WFO - LOC // location - } - -} +package gov.noaa.nws.ncep.edex.common.stationTables; + +public interface IStationField { + + public static enum StationField { + STID, // station id + STNM, // station number + NAME, // station name + ST, // state + CO, // country + //LAT, // latitude + //LON, // longitude + //ELV, // elevation + //PRI, // priority + WFO, // WFO + LOC // location + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/ObjectFactory.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/ObjectFactory.java old mode 100755 new mode 100644 index 7fe56dbf70..b7c82ddfab --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/ObjectFactory.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/ObjectFactory.java @@ -1,168 +1,168 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.06.08 at 02:36:43 PM EDT -// - - -package gov.noaa.nws.ncep.edex.common.stationTables; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the gov.noaa.nws.ncep.viz.common.stnTables package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Wfo_QNAME = new QName("", "wfo"); - private final static QName _Stid_QNAME = new QName("", "stid"); - private final static QName _Stnnum_QNAME = new QName("", "stnnum"); - private final static QName _Location_QNAME = new QName("", "location"); - private final static QName _Priority_QNAME = new QName("", "priority"); - private final static QName _Elevation_QNAME = new QName("", "elevation"); - private final static QName _State_QNAME = new QName("", "state"); - private final static QName _Longitude_QNAME = new QName("", "longitude"); - private final static QName _Stnname_QNAME = new QName("", "stnname"); - private final static QName _Latitude_QNAME = new QName("", "latitude"); - private final static QName _Country_QNAME = new QName("", "country"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: gov.noaa.nws.ncep.viz.common.stnTables - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link StationList } - * - */ - public StationList createStationList() { - return new StationList(); - } - - /** - * Create an instance of {@link Station } - * - */ - public Station createStation() { - return new Station(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "wfo") - public JAXBElement createWfo(String value) { - return new JAXBElement(_Wfo_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stid") - public JAXBElement createStid(String value) { - return new JAXBElement(_Stid_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stnnum") - public JAXBElement createStnnum(String value) { - return new JAXBElement(_Stnnum_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "location") - public JAXBElement createLocation(String value) { - return new JAXBElement(_Location_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "priority") - public JAXBElement createPriority(Integer value) { - return new JAXBElement(_Priority_QNAME, Integer.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "elevation") - public JAXBElement createElevation(Integer value) { - return new JAXBElement(_Elevation_QNAME, Integer.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "state") - public JAXBElement createState(String value) { - return new JAXBElement(_State_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "longitude") - public JAXBElement createLongitude(Float value) { - return new JAXBElement(_Longitude_QNAME, Float.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stnname") - public JAXBElement createStnname(String value) { - return new JAXBElement(_Stnname_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "latitude") - public JAXBElement createLatitude(Float value) { - return new JAXBElement(_Latitude_QNAME, Float.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "country") - public JAXBElement createCountry(String value) { - return new JAXBElement(_Country_QNAME, String.class, null, value); - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.06.08 at 02:36:43 PM EDT +// + + +package gov.noaa.nws.ncep.edex.common.stationTables; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the gov.noaa.nws.ncep.viz.common.stnTables package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _Wfo_QNAME = new QName("", "wfo"); + private final static QName _Stid_QNAME = new QName("", "stid"); + private final static QName _Stnnum_QNAME = new QName("", "stnnum"); + private final static QName _Location_QNAME = new QName("", "location"); + private final static QName _Priority_QNAME = new QName("", "priority"); + private final static QName _Elevation_QNAME = new QName("", "elevation"); + private final static QName _State_QNAME = new QName("", "state"); + private final static QName _Longitude_QNAME = new QName("", "longitude"); + private final static QName _Stnname_QNAME = new QName("", "stnname"); + private final static QName _Latitude_QNAME = new QName("", "latitude"); + private final static QName _Country_QNAME = new QName("", "country"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: gov.noaa.nws.ncep.viz.common.stnTables + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link StationList } + * + */ + public StationList createStationList() { + return new StationList(); + } + + /** + * Create an instance of {@link Station } + * + */ + public Station createStation() { + return new Station(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "wfo") + public JAXBElement createWfo(String value) { + return new JAXBElement(_Wfo_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stid") + public JAXBElement createStid(String value) { + return new JAXBElement(_Stid_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stnnum") + public JAXBElement createStnnum(String value) { + return new JAXBElement(_Stnnum_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "location") + public JAXBElement createLocation(String value) { + return new JAXBElement(_Location_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "priority") + public JAXBElement createPriority(Integer value) { + return new JAXBElement(_Priority_QNAME, Integer.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "elevation") + public JAXBElement createElevation(Integer value) { + return new JAXBElement(_Elevation_QNAME, Integer.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "state") + public JAXBElement createState(String value) { + return new JAXBElement(_State_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "longitude") + public JAXBElement createLongitude(Float value) { + return new JAXBElement(_Longitude_QNAME, Float.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stnname") + public JAXBElement createStnname(String value) { + return new JAXBElement(_Stnname_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "latitude") + public JAXBElement createLatitude(Float value) { + return new JAXBElement(_Latitude_QNAME, Float.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "country") + public JAXBElement createCountry(String value) { + return new JAXBElement(_Country_QNAME, String.class, null, value); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/Station.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/Station.java old mode 100755 new mode 100644 index dd7a0f878d..16e73c4d48 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/Station.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/Station.java @@ -1,339 +1,339 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.06.08 at 02:36:43 PM EDT -// - - -package gov.noaa.nws.ncep.edex.common.stationTables; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}stid" minOccurs="0"/>
- *         <element ref="{}stnnum" minOccurs="0"/>
- *         <element ref="{}stnname" minOccurs="0"/>
- *         <element ref="{}state" minOccurs="0"/>
- *         <element ref="{}country" minOccurs="0"/>
- *         <element ref="{}latitude" minOccurs="0"/>
- *         <element ref="{}longitude" minOccurs="0"/>
- *         <element ref="{}elevation" minOccurs="0"/>
- *         <element ref="{}priority" minOccurs="0"/>
- *         <element ref="{}location" minOccurs="0"/>
- *         <element ref="{}wfo" minOccurs="0"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "stid", - "stnnum", - "stnname", - "state", - "country", - "latitude", - "longitude", - "elevation", - "priority", - "location", - "wfo" -}) -@XmlRootElement(name = "station") -public class Station { - - protected String stid; - protected String stnnum; - protected String stnname; - protected String state; - protected String country; - protected Float latitude; - protected Float longitude; - protected Integer elevation; - protected Integer priority; - protected String location; - protected String wfo; - - /** - * Gets the value of the stid property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStid() { - return stid; - } - - /** - * Sets the value of the stid property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStid(String value) { - this.stid = value; - } - - /** - * Gets the value of the stnnum property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStnnum() { - return stnnum; - } - - /** - * Sets the value of the stnnum property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStnnum(String value) { - this.stnnum = value; - } - - /** - * Gets the value of the stnname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStnname() { - return stnname; - } - - /** - * Sets the value of the stnname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStnname(String value) { - this.stnname = value; - } - - /** - * Gets the value of the state property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getState() { - return state; - } - - /** - * Sets the value of the state property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setState(String value) { - this.state = value; - } - - /** - * Gets the value of the country property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getCountry() { - return country; - } - - /** - * Sets the value of the country property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setCountry(String value) { - this.country = value; - } - - /** - * Gets the value of the latitude property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getLatitude() { - return latitude; - } - - /** - * Sets the value of the latitude property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setLatitude(Float value) { - this.latitude = value; - } - - /** - * Gets the value of the longitude property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getLongitude() { - return longitude; - } - - /** - * Sets the value of the longitude property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setLongitude(Float value) { - this.longitude = value; - } - - /** - * Gets the value of the elevation property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public Integer getElevation() { - return elevation; - } - - /** - * Sets the value of the elevation property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setElevation(Integer value) { - this.elevation = value; - } - - /** - * Gets the value of the priority property. - * - * @return - * possible object is - * {@link Integer } - * - */ - public Integer getPriority() { - return priority; - } - - /** - * Sets the value of the priority property. - * - * @param value - * allowed object is - * {@link Integer } - * - */ - public void setPriority(Integer value) { - this.priority = value; - } - - /** - * Gets the value of the location property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getLocation() { - return location; - } - - /** - * Sets the value of the location property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setLocation(String value) { - this.location = value; - } - - /** - * Gets the value of the wfo property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getWfo() { - return wfo; - } - - /** - * Sets the value of the wfo property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setWfo(String value) { - this.wfo = value; - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.06.08 at 02:36:43 PM EDT +// + + +package gov.noaa.nws.ncep.edex.common.stationTables; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}stid" minOccurs="0"/>
+ *         <element ref="{}stnnum" minOccurs="0"/>
+ *         <element ref="{}stnname" minOccurs="0"/>
+ *         <element ref="{}state" minOccurs="0"/>
+ *         <element ref="{}country" minOccurs="0"/>
+ *         <element ref="{}latitude" minOccurs="0"/>
+ *         <element ref="{}longitude" minOccurs="0"/>
+ *         <element ref="{}elevation" minOccurs="0"/>
+ *         <element ref="{}priority" minOccurs="0"/>
+ *         <element ref="{}location" minOccurs="0"/>
+ *         <element ref="{}wfo" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "stid", + "stnnum", + "stnname", + "state", + "country", + "latitude", + "longitude", + "elevation", + "priority", + "location", + "wfo" +}) +@XmlRootElement(name = "station") +public class Station { + + protected String stid; + protected String stnnum; + protected String stnname; + protected String state; + protected String country; + protected Float latitude; + protected Float longitude; + protected Integer elevation; + protected Integer priority; + protected String location; + protected String wfo; + + /** + * Gets the value of the stid property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStid() { + return stid; + } + + /** + * Sets the value of the stid property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStid(String value) { + this.stid = value; + } + + /** + * Gets the value of the stnnum property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStnnum() { + return stnnum; + } + + /** + * Sets the value of the stnnum property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStnnum(String value) { + this.stnnum = value; + } + + /** + * Gets the value of the stnname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStnname() { + return stnname; + } + + /** + * Sets the value of the stnname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStnname(String value) { + this.stnname = value; + } + + /** + * Gets the value of the state property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getState() { + return state; + } + + /** + * Sets the value of the state property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setState(String value) { + this.state = value; + } + + /** + * Gets the value of the country property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCountry() { + return country; + } + + /** + * Sets the value of the country property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCountry(String value) { + this.country = value; + } + + /** + * Gets the value of the latitude property. + * + * @return + * possible object is + * {@link Float } + * + */ + public Float getLatitude() { + return latitude; + } + + /** + * Sets the value of the latitude property. + * + * @param value + * allowed object is + * {@link Float } + * + */ + public void setLatitude(Float value) { + this.latitude = value; + } + + /** + * Gets the value of the longitude property. + * + * @return + * possible object is + * {@link Float } + * + */ + public Float getLongitude() { + return longitude; + } + + /** + * Sets the value of the longitude property. + * + * @param value + * allowed object is + * {@link Float } + * + */ + public void setLongitude(Float value) { + this.longitude = value; + } + + /** + * Gets the value of the elevation property. + * + * @return + * possible object is + * {@link Integer } + * + */ + public Integer getElevation() { + return elevation; + } + + /** + * Sets the value of the elevation property. + * + * @param value + * allowed object is + * {@link Integer } + * + */ + public void setElevation(Integer value) { + this.elevation = value; + } + + /** + * Gets the value of the priority property. + * + * @return + * possible object is + * {@link Integer } + * + */ + public Integer getPriority() { + return priority; + } + + /** + * Sets the value of the priority property. + * + * @param value + * allowed object is + * {@link Integer } + * + */ + public void setPriority(Integer value) { + this.priority = value; + } + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + + /** + * Gets the value of the wfo property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getWfo() { + return wfo; + } + + /** + * Sets the value of the wfo property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setWfo(String value) { + this.wfo = value; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationComparator.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationComparator.java old mode 100755 new mode 100644 index ce509d026f..0a2a02e19c --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationComparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationComparator.java @@ -1,61 +1,61 @@ -package gov.noaa.nws.ncep.edex.common.stationTables; - -import java.util.Comparator; - -/** - * Comparator for Station fields. - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 06/09		134  		M. Li	   Initial Creation
- *                       
- * 
- * - * @author mli - * @version 1 - */ - -public class StationComparator implements Comparator, IStationField { - - private StationField field; - - public StationComparator(StationField f) { - this.field = f; - } - - public int compare(Station o1, Station o2) { - switch (field) { - case STID: - return o1.getStid().compareToIgnoreCase(o2.getStid()); - case STNM: - return o1.getStnnum().compareToIgnoreCase(o2.getStnnum()); - case NAME: - return o1.getStnnum().compareToIgnoreCase(o2.getStnnum()); - case ST: - return o1.getState().compareToIgnoreCase(o2.getState()); - case CO: - return o1.getCountry().compareToIgnoreCase(o2.getCountry()); - /* - case LAT: - return o1.getLatitude().compareTo(o2.getLatitude()); - case LON: - return o1.getLongitude().compareTo(o2.getLongitude()); - case ELV: - return o1.getElevation() - o2.getElevation(); - case PRI: - return o1.getPriority() - o2.getPriority(); - */ - case WFO: - return o1.getWfo().compareToIgnoreCase(o2.getWfo()); - case LOC: - return o1.getLocation().compareToIgnoreCase(o2.getLocation()); - - default: - return 0; - } - - } +package gov.noaa.nws.ncep.edex.common.stationTables; + +import java.util.Comparator; + +/** + * Comparator for Station fields. + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 06/09		134  		M. Li	   Initial Creation
+ *                       
+ * 
+ * + * @author mli + * @version 1 + */ + +public class StationComparator implements Comparator, IStationField { + + private StationField field; + + public StationComparator(StationField f) { + this.field = f; + } + + public int compare(Station o1, Station o2) { + switch (field) { + case STID: + return o1.getStid().compareToIgnoreCase(o2.getStid()); + case STNM: + return o1.getStnnum().compareToIgnoreCase(o2.getStnnum()); + case NAME: + return o1.getStnnum().compareToIgnoreCase(o2.getStnnum()); + case ST: + return o1.getState().compareToIgnoreCase(o2.getState()); + case CO: + return o1.getCountry().compareToIgnoreCase(o2.getCountry()); + /* + case LAT: + return o1.getLatitude().compareTo(o2.getLatitude()); + case LON: + return o1.getLongitude().compareTo(o2.getLongitude()); + case ELV: + return o1.getElevation() - o2.getElevation(); + case PRI: + return o1.getPriority() - o2.getPriority(); + */ + case WFO: + return o1.getWfo().compareToIgnoreCase(o2.getWfo()); + case LOC: + return o1.getLocation().compareToIgnoreCase(o2.getLocation()); + + default: + return 0; + } + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationList.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationList.java old mode 100755 new mode 100644 index e8826da29d..6ea06463d4 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationList.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationList.java @@ -1,76 +1,76 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.06.08 at 02:36:43 PM EDT -// - - -package gov.noaa.nws.ncep.edex.common.stationTables; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}station" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "station" -}) -@XmlRootElement(name = "stationList") -public class StationList { - - protected List station; - - /** - * Gets the value of the station property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the station property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getStation().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Station } - * - * - */ - public List getStation() { - if (station == null) { - station = new ArrayList(); - } - return this.station; - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.06.08 at 02:36:43 PM EDT +// + + +package gov.noaa.nws.ncep.edex.common.stationTables; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}station" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "station" +}) +@XmlRootElement(name = "stationList") +public class StationList { + + protected List station; + + /** + * Gets the value of the station property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the station property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getStation().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Station } + * + * + */ + public List getStation() { + if (station == null) { + station = new ArrayList(); + } + return this.station; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationTable.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationTable.java old mode 100755 new mode 100644 index 432fed382e..99fa8b3ddf --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationTable.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/stationTables/StationTable.java @@ -1,91 +1,91 @@ -package gov.noaa.nws.ncep.edex.common.stationTables; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.ArrayList; -import java.util.Collections; +package gov.noaa.nws.ncep.edex.common.stationTables; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.index.quadtree.Quadtree; import org.geotools.referencing.GeodeticCalculator; -/** - * This class reads a station table from an xml file and contains a list of stations. - * This class also provide general station search functions given station field, and - * field value. - * - *

- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 06/09  		?    	   	B. Yin   Initial Creation
- * 06/09		134			M. Li		Add station search
+/**
+ * This class reads a station table from an xml file and contains a list of stations.
+ * This class also provide general station search functions given station field, and
+ * field value.
+ * 
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 06/09  		?    	   	B. Yin   Initial Creation
+ * 06/09		134			M. Li		Add station search
  * 10/09        39/87/114   L. Lin   Make "last" as private StationField.
  * 12/09		159			B. Yin	 Add getNearestStation(...)
- *                       
- * 
- * - * @author bingfan - * @version 1 - */ - -public class StationTable implements IStationField { - - private final String PACKAGE = "gov.noaa.nws.ncep.edex.common.stationTables"; - - private List stationList; - + * + *
+ * + * @author bingfan + * @version 1 + */ + +public class StationTable implements IStationField { + + private final String PACKAGE = "gov.noaa.nws.ncep.edex.common.stationTables"; + + private List stationList; + private StationField last = null; private Quadtree stTree = null; private final double DIST = 1.0; - - /** - * Constructor. - * @param tableFileName - full path of the xml table file - */ - public StationTable( String tableFileName ) { - - try{ - stationList = readStationTable( tableFileName ); - } - catch ( JAXBException exp ){ - stationList = null; - exp.printStackTrace(); - } - - } - - /** - * Reads the contents of the input station table file - * @param xmlFilename - full path of the xml table name - * @return - a list of stations - * @throws JAXBException - */ - private List readStationTable( String xmlFilename ) throws JAXBException{ - - File xmlFile = new File(xmlFilename); - - JAXBContext context = JAXBContext.newInstance( - PACKAGE); - Unmarshaller unmarshaller = context.createUnmarshaller(); - StationList stns = null; - - try { - stns = (StationList)unmarshaller.unmarshal( - new FileReader(xmlFile)); - List listOfItems = stns.getStation(); + + /** + * Constructor. + * @param tableFileName - full path of the xml table file + */ + public StationTable( String tableFileName ) { + + try{ + stationList = readStationTable( tableFileName ); + } + catch ( JAXBException exp ){ + stationList = null; + exp.printStackTrace(); + } + + } + + /** + * Reads the contents of the input station table file + * @param xmlFilename - full path of the xml table name + * @return - a list of stations + * @throws JAXBException + */ + private List readStationTable( String xmlFilename ) throws JAXBException{ + + File xmlFile = new File(xmlFilename); + + JAXBContext context = JAXBContext.newInstance( + PACKAGE); + Unmarshaller unmarshaller = context.createUnmarshaller(); + StationList stns = null; + + try { + stns = (StationList)unmarshaller.unmarshal( + new FileReader(xmlFile)); + List listOfItems = stns.getStation(); /* * save stations in a Quadtree for efficient spatial query @@ -97,136 +97,136 @@ public class StationTable implements IStationField { stTree.insert(env, st); } - return listOfItems; - - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - - } catch (NullPointerException e2) { - e2.printStackTrace(); - } - - return null; - - } - - /** - * Gets the list of the stations - * @return - the list of stations - */ - public List getStationList(){ - - return stationList; - - } - - /** - * Search a station given a field, and search key value. - * - * @param sf - * @param key - * @return Station - */ - public Station getStation(StationField sf, String key) { - if (stationList == null || stationList.isEmpty()) return null; - - StationComparator comparator = new StationComparator(sf); - if (last == null || (last != null && last != sf )) { - Collections.sort(stationList, comparator); - last = sf; - } - - Station s = getComparedStation(sf, key); - int index = Collections.binarySearch(stationList, s, comparator); - - if (index >= 0){ - return stationList.get(index); - } else - return null; - } - - /** - * Search station list given a field, and search key value. - * - * @param sf - * @param key - * @return Station - */ - public List getStations(StationField sf, String key) { - if (stationList == null || stationList.isEmpty()) return null; - - StationComparator comparator = new StationComparator(sf); - if (last == null || (last != null && last != sf )) { - Collections.sort(stationList, comparator); - last = sf; - } - - List list = new ArrayList(); - - Station s = getComparedStation(sf, key); - int index; - while ((index = Collections.binarySearch(stationList, s, comparator)) >= 0) { - list.add(stationList.get(index)); - stationList.remove(index); - } - - if (list.size() > 0) { - for (Station st : list) { - stationList.add(st); - } - - last = null; - return list; - } - else { - return null; - } - } - - - private Station getComparedStation(StationField sf, String key){ - Station station = new Station(); - switch (sf) { - case STID: - station.setStid((String)key); - break; - case STNM: - station.setStnnum((String)key); - break; - case NAME: - station.setStnname((String)key); - break; - case ST: - station.setState((String)key); - break; - case CO: - station.setCountry((String)key); - break; - /* - case LAT: - station.setLatitude((Float)key); - break; - case LON: - station.setLongitude((Float)key); - break; - case ELV: - station.setElevation((Integer)key); - break; - case PRI: - station.setPriority((Integer)key); - break; - */ - case WFO: - station.setWfo((String)key); - break; - case LOC: - station.setLocation((String)key); - break; - } - - return station; - } - + return listOfItems; + + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + + } catch (NullPointerException e2) { + e2.printStackTrace(); + } + + return null; + + } + + /** + * Gets the list of the stations + * @return - the list of stations + */ + public List getStationList(){ + + return stationList; + + } + + /** + * Search a station given a field, and search key value. + * + * @param sf + * @param key + * @return Station + */ + public Station getStation(StationField sf, String key) { + if (stationList == null || stationList.isEmpty()) return null; + + StationComparator comparator = new StationComparator(sf); + if (last == null || (last != null && last != sf )) { + Collections.sort(stationList, comparator); + last = sf; + } + + Station s = getComparedStation(sf, key); + int index = Collections.binarySearch(stationList, s, comparator); + + if (index >= 0){ + return stationList.get(index); + } else + return null; + } + + /** + * Search station list given a field, and search key value. + * + * @param sf + * @param key + * @return Station + */ + public List getStations(StationField sf, String key) { + if (stationList == null || stationList.isEmpty()) return null; + + StationComparator comparator = new StationComparator(sf); + if (last == null || (last != null && last != sf )) { + Collections.sort(stationList, comparator); + last = sf; + } + + List list = new ArrayList(); + + Station s = getComparedStation(sf, key); + int index; + while ((index = Collections.binarySearch(stationList, s, comparator)) >= 0) { + list.add(stationList.get(index)); + stationList.remove(index); + } + + if (list.size() > 0) { + for (Station st : list) { + stationList.add(st); + } + + last = null; + return list; + } + else { + return null; + } + } + + + private Station getComparedStation(StationField sf, String key){ + Station station = new Station(); + switch (sf) { + case STID: + station.setStid((String)key); + break; + case STNM: + station.setStnnum((String)key); + break; + case NAME: + station.setStnname((String)key); + break; + case ST: + station.setState((String)key); + break; + case CO: + station.setCountry((String)key); + break; + /* + case LAT: + station.setLatitude((Float)key); + break; + case LON: + station.setLongitude((Float)key); + break; + case ELV: + station.setElevation((Integer)key); + break; + case PRI: + station.setPriority((Integer)key); + break; + */ + case WFO: + station.setWfo((String)key); + break; + case LOC: + station.setLocation((String)key); + break; + } + + return station; + } + /** * Get the nearest station from the input location * @param loc diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocs.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocs.java old mode 100755 new mode 100644 index 46c89085f1..3aea9f3dc8 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocs.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocs.java @@ -1,78 +1,78 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.05.05 at 04:38:50 PM EDT -// - - -package gov.noaa.nws.ncep.edex.locations; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}idftPoint" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "idftPoint" -}) -@XmlRootElement(name = "idftLocs") -public class IdftLocs { - - @XmlElement(required = true) - protected List idftPoint; - - /** - * Gets the value of the idftPoint property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the idftPoint property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getIdftPoint().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link IdftPoint } - * - * - */ - public List getIdftPoint() { - if (idftPoint == null) { - idftPoint = new ArrayList(); - } - return this.idftPoint; - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.05.05 at 04:38:50 PM EDT +// + + +package gov.noaa.nws.ncep.edex.locations; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}idftPoint" maxOccurs="unbounded"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "idftPoint" +}) +@XmlRootElement(name = "idftLocs") +public class IdftLocs { + + @XmlElement(required = true) + protected List idftPoint; + + /** + * Gets the value of the idftPoint property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the idftPoint property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIdftPoint().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link IdftPoint } + * + * + */ + public List getIdftPoint() { + if (idftPoint == null) { + idftPoint = new ArrayList(); + } + return this.idftPoint; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocsTableReader.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocsTableReader.java old mode 100755 new mode 100644 index b4b274938d..e3429521c6 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocsTableReader.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftLocsTableReader.java @@ -1,71 +1,71 @@ -/** - * This function reads the Idft Point Location Table from idftLoc.xml - * and unmarshall it. - * - *

- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 14May2009  	98    	   F. J. Yen   Initial Creation
- *                       
- * 
- * - * @author Fee Jing Yen, SIB - * @version 1 - */ -package gov.noaa.nws.ncep.edex.locations; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -public class IdftLocsTableReader { - - - private final String PACKAGE = "gov.noaa.nws.ncep.edex.locations"; - - private String xmlFilename = null; - - public IdftLocsTableReader(String file) { - /* - * file is the full name including the path for the - * idft point location xml file, idftLoc.xml - */ - - xmlFilename = file; - } - - public List getIdftLocsTable() throws JAXBException{ - - File xmlFile = new File(xmlFilename); - - JAXBContext context = JAXBContext.newInstance( - PACKAGE); - Unmarshaller unmarshaller = context.createUnmarshaller(); - IdftLocs loc = null; - - try { - loc = (IdftLocs)unmarshaller.unmarshal( - new FileReader(xmlFile)); - List listOfItems = loc.getIdftPoint(); - return listOfItems; - - } catch (FileNotFoundException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - - } catch (NullPointerException e2) { - e2.printStackTrace(); - } - - return null; - - } +/** + * This function reads the Idft Point Location Table from idftLoc.xml + * and unmarshall it. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 14May2009  	98    	   F. J. Yen   Initial Creation
+ *                       
+ * 
+ * + * @author Fee Jing Yen, SIB + * @version 1 + */ +package gov.noaa.nws.ncep.edex.locations; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +public class IdftLocsTableReader { + + + private final String PACKAGE = "gov.noaa.nws.ncep.edex.locations"; + + private String xmlFilename = null; + + public IdftLocsTableReader(String file) { + /* + * file is the full name including the path for the + * idft point location xml file, idftLoc.xml + */ + + xmlFilename = file; + } + + public List getIdftLocsTable() throws JAXBException{ + + File xmlFile = new File(xmlFilename); + + JAXBContext context = JAXBContext.newInstance( + PACKAGE); + Unmarshaller unmarshaller = context.createUnmarshaller(); + IdftLocs loc = null; + + try { + loc = (IdftLocs)unmarshaller.unmarshal( + new FileReader(xmlFile)); + List listOfItems = loc.getIdftPoint(); + return listOfItems; + + } catch (FileNotFoundException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + + } catch (NullPointerException e2) { + e2.printStackTrace(); + } + + return null; + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftPoint.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftPoint.java old mode 100755 new mode 100644 index a8db5002d7..89e90b5324 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftPoint.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/IdftPoint.java @@ -1,203 +1,203 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.05.05 at 04:38:50 PM EDT -// - - -package gov.noaa.nws.ncep.edex.locations; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}stid"/>
- *         <element ref="{}stnnum"/>
- *         <element ref="{}stnname"/>
- *         <element ref="{}latitude"/>
- *         <element ref="{}longitude"/>
- *         <element ref="{}elevation"/>
- *         <element ref="{}priority"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "stid", - "stnnum", - "stnname", - "latitude", - "longitude", - "elevation", - "priority" -}) -@XmlRootElement(name = "idftPoint") -public class IdftPoint { - - @XmlElement(required = true) - protected String stid; - @XmlElement(required = true) - protected String stnnum; - @XmlElement(required = true) - protected String stnname; - protected float latitude; - protected float longitude; - protected int elevation; - protected int priority; - - /** - * Gets the value of the stid property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStid() { - return stid; - } - - /** - * Sets the value of the stid property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStid(String value) { - this.stid = value; - } - - /** - * Gets the value of the stnnum property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStnnum() { - return stnnum; - } - - /** - * Sets the value of the stnnum property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStnnum(String value) { - this.stnnum = value; - } - - /** - * Gets the value of the stnname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStnname() { - return stnname; - } - - /** - * Sets the value of the stnname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStnname(String value) { - this.stnname = value; - } - - /** - * Gets the value of the latitude property. - * - */ - public float getLatitude() { - return latitude; - } - - /** - * Sets the value of the latitude property. - * - */ - public void setLatitude(float value) { - this.latitude = value; - } - - /** - * Gets the value of the longitude property. - * - */ - public float getLongitude() { - return longitude; - } - - /** - * Sets the value of the longitude property. - * - */ - public void setLongitude(float value) { - this.longitude = value; - } - - /** - * Gets the value of the elevation property. - * - */ - public int getElevation() { - return elevation; - } - - /** - * Sets the value of the elevation property. - * - */ - public void setElevation(int value) { - this.elevation = value; - } - - /** - * Gets the value of the priority property. - * - */ - public int getPriority() { - return priority; - } - - /** - * Sets the value of the priority property. - * - */ - public void setPriority(int value) { - this.priority = value; - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.05.05 at 04:38:50 PM EDT +// + + +package gov.noaa.nws.ncep.edex.locations; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{}stid"/>
+ *         <element ref="{}stnnum"/>
+ *         <element ref="{}stnname"/>
+ *         <element ref="{}latitude"/>
+ *         <element ref="{}longitude"/>
+ *         <element ref="{}elevation"/>
+ *         <element ref="{}priority"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "stid", + "stnnum", + "stnname", + "latitude", + "longitude", + "elevation", + "priority" +}) +@XmlRootElement(name = "idftPoint") +public class IdftPoint { + + @XmlElement(required = true) + protected String stid; + @XmlElement(required = true) + protected String stnnum; + @XmlElement(required = true) + protected String stnname; + protected float latitude; + protected float longitude; + protected int elevation; + protected int priority; + + /** + * Gets the value of the stid property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStid() { + return stid; + } + + /** + * Sets the value of the stid property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStid(String value) { + this.stid = value; + } + + /** + * Gets the value of the stnnum property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStnnum() { + return stnnum; + } + + /** + * Sets the value of the stnnum property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStnnum(String value) { + this.stnnum = value; + } + + /** + * Gets the value of the stnname property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStnname() { + return stnname; + } + + /** + * Sets the value of the stnname property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStnname(String value) { + this.stnname = value; + } + + /** + * Gets the value of the latitude property. + * + */ + public float getLatitude() { + return latitude; + } + + /** + * Sets the value of the latitude property. + * + */ + public void setLatitude(float value) { + this.latitude = value; + } + + /** + * Gets the value of the longitude property. + * + */ + public float getLongitude() { + return longitude; + } + + /** + * Sets the value of the longitude property. + * + */ + public void setLongitude(float value) { + this.longitude = value; + } + + /** + * Gets the value of the elevation property. + * + */ + public int getElevation() { + return elevation; + } + + /** + * Sets the value of the elevation property. + * + */ + public void setElevation(int value) { + this.elevation = value; + } + + /** + * Gets the value of the priority property. + * + */ + public int getPriority() { + return priority; + } + + /** + * Sets the value of the priority property. + * + */ + public void setPriority(int value) { + this.priority = value; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/ObjectFactory.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/ObjectFactory.java old mode 100755 new mode 100644 index 7c3ff7312e..a57f13ba18 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/ObjectFactory.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/ObjectFactory.java @@ -1,128 +1,128 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2009.05.05 at 04:38:50 PM EDT -// - - -package gov.noaa.nws.ncep.edex.locations; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the generated package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Stid_QNAME = new QName("", "stid"); - private final static QName _Stnnum_QNAME = new QName("", "stnnum"); - private final static QName _Priority_QNAME = new QName("", "priority"); - private final static QName _Elevation_QNAME = new QName("", "elevation"); - private final static QName _Longitude_QNAME = new QName("", "longitude"); - private final static QName _Stnname_QNAME = new QName("", "stnname"); - private final static QName _Latitude_QNAME = new QName("", "latitude"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link IdftLocs } - * - */ - public IdftLocs createIdftLocs() { - return new IdftLocs(); - } - - /** - * Create an instance of {@link IdftPoint } - * - */ - public IdftPoint createIdftPoint() { - return new IdftPoint(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stid") - public JAXBElement createStid(String value) { - return new JAXBElement(_Stid_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stnnum") - public JAXBElement createStnnum(String value) { - return new JAXBElement(_Stnnum_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "priority") - public JAXBElement createPriority(Integer value) { - return new JAXBElement(_Priority_QNAME, Integer.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "elevation") - public JAXBElement createElevation(Integer value) { - return new JAXBElement(_Elevation_QNAME, Integer.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "longitude") - public JAXBElement createLongitude(Float value) { - return new JAXBElement(_Longitude_QNAME, Float.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "stnname") - public JAXBElement createStnname(String value) { - return new JAXBElement(_Stnname_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "latitude") - public JAXBElement createLatitude(Float value) { - return new JAXBElement(_Latitude_QNAME, Float.class, null, value); - } - -} +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.05.05 at 04:38:50 PM EDT +// + + +package gov.noaa.nws.ncep.edex.locations; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the generated package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _Stid_QNAME = new QName("", "stid"); + private final static QName _Stnnum_QNAME = new QName("", "stnnum"); + private final static QName _Priority_QNAME = new QName("", "priority"); + private final static QName _Elevation_QNAME = new QName("", "elevation"); + private final static QName _Longitude_QNAME = new QName("", "longitude"); + private final static QName _Stnname_QNAME = new QName("", "stnname"); + private final static QName _Latitude_QNAME = new QName("", "latitude"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link IdftLocs } + * + */ + public IdftLocs createIdftLocs() { + return new IdftLocs(); + } + + /** + * Create an instance of {@link IdftPoint } + * + */ + public IdftPoint createIdftPoint() { + return new IdftPoint(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stid") + public JAXBElement createStid(String value) { + return new JAXBElement(_Stid_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stnnum") + public JAXBElement createStnnum(String value) { + return new JAXBElement(_Stnnum_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "priority") + public JAXBElement createPriority(Integer value) { + return new JAXBElement(_Priority_QNAME, Integer.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Integer }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "elevation") + public JAXBElement createElevation(Integer value) { + return new JAXBElement(_Elevation_QNAME, Integer.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "longitude") + public JAXBElement createLongitude(Float value) { + return new JAXBElement(_Longitude_QNAME, Float.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "stnname") + public JAXBElement createStnname(String value) { + return new JAXBElement(_Stnname_QNAME, String.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "latitude") + public JAXBElement createLatitude(Float value) { + return new JAXBElement(_Latitude_QNAME, Float.class, null, value); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/package-info.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/package-info.java old mode 100755 new mode 100644 index d41b4dd232..d13910d183 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains supporting and test methods for reading and unmarshalling idftLocs.tbl -*/ -package gov.noaa.nws.ncep.edex.locations; +/** +* Contains supporting and test methods for reading and unmarshalling idftLocs.tbl +*/ +package gov.noaa.nws.ncep.edex.locations; diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/test_IdftLocsTableReader.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/test_IdftLocsTableReader.java old mode 100755 new mode 100644 index 028a36dd72..84eef8c9ea --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/test_IdftLocsTableReader.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/locations/test_IdftLocsTableReader.java @@ -1,51 +1,51 @@ -/** - * This function tests the Idft Point Location Table Reader, IdftLocsTableReader - * by printing out all the elements in the XML file. It also gets the first and - * last element from the list and prints them out - *

- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 12May2009  	98    	   F. J. Yen   Initial Creation
- *                       
- * 
- * - * @author Fee Jing Yen, SIB - * @version 1 - */ -package gov.noaa.nws.ncep.edex.locations; - -import java.util.List; - -public class test_IdftLocsTableReader { - - public static void main(String args[]) throws Exception{ - String idftLocsXmlName = "../build.edex/esb/data/utility/edex_static/base/ncep/stns/idftLoc.xml"; - IdftLocsTableReader myloc = new IdftLocsTableReader (idftLocsXmlName); - List list = myloc.getIdftLocsTable(); - for(IdftPoint itm : list){ - System.out.println( - " Stid = " + itm.getStid() + - " Stnnum= " + itm.getStnnum() + - " Stnname = " + itm.getStnname() + - " Latitude = " + itm.getLatitude() + - " Longitude =" + itm.getLongitude() + - " Elevation =" + itm.getElevation() + - " Priortiy =" + itm.getPriority() ); - } - // Get the first and last elements of the list and print them along with the list size - System.out.println(" Stid(0)=" + list.get(0).stid - + " Stnnum(0) = " + list.get(0).stnnum - + " Stnname(0) = " + list.get(0).stnname - + " Latitude(0) = " + list.get(0).latitude - + " Longitude(0) = " + list.get(0).longitude - + "\n Stid(206) = " + list.get(206).stid - + " Stnnum(206) = " + list.get(206).stnnum - + " Stnname(206) = " + list.get(206).stnname - + " Latitude(206) = " + list.get(206).latitude - + " Longitude(206) = " + list.get(206).longitude - + "\n size = " + list.size()); - } -} +/** + * This function tests the Idft Point Location Table Reader, IdftLocsTableReader + * by printing out all the elements in the XML file. It also gets the first and + * last element from the list and prints them out + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 12May2009  	98    	   F. J. Yen   Initial Creation
+ *                       
+ * 
+ * + * @author Fee Jing Yen, SIB + * @version 1 + */ +package gov.noaa.nws.ncep.edex.locations; + +import java.util.List; + +public class test_IdftLocsTableReader { + + public static void main(String args[]) throws Exception{ + String idftLocsXmlName = "../build.edex/esb/data/utility/edex_static/base/ncep/stns/idftLoc.xml"; + IdftLocsTableReader myloc = new IdftLocsTableReader (idftLocsXmlName); + List list = myloc.getIdftLocsTable(); + for(IdftPoint itm : list){ + System.out.println( + " Stid = " + itm.getStid() + + " Stnnum= " + itm.getStnnum() + + " Stnname = " + itm.getStnname() + + " Latitude = " + itm.getLatitude() + + " Longitude =" + itm.getLongitude() + + " Elevation =" + itm.getElevation() + + " Priortiy =" + itm.getPriority() ); + } + // Get the first and last elements of the list and print them along with the list size + System.out.println(" Stid(0)=" + list.get(0).stid + + " Stnnum(0) = " + list.get(0).stnnum + + " Stnname(0) = " + list.get(0).stnname + + " Latitude(0) = " + list.get(0).latitude + + " Longitude(0) = " + list.get(0).longitude + + "\n Stid(206) = " + list.get(206).stid + + " Stnnum(206) = " + list.get(206).stnnum + + " Stnname(206) = " + list.get(206).stnname + + " Latitude(206) = " + list.get(206).latitude + + " Longitude(206) = " + list.get(206).longitude + + "\n size = " + list.size()); + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/LatLonLocTbl.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/LatLonLocTbl.java old mode 100755 new mode 100644 index 84cc63656f..ac74fc8dbc --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/LatLonLocTbl.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/LatLonLocTbl.java @@ -1,182 +1,182 @@ -/** - * LatLonLocTbl - A Java class to define some known VORs and Intlsig talbes - * used to define convective/nonconvective/airmet/intl SIGMET locations. - * - * SOFTWARE HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 12 Jun 2009 95/132 B. Hebbard Initial creation. - * 10 Sep 2009 39/87/114 L. Lin Remove the temporary enum - * and add xml for VORs and - * Intlsig gempak tables. - * 30 Sep 2009 3102 jkorman Changed printlns to logging statements. - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ -package gov.noaa.nws.ncep.edex.tools.decoder; - -import static com.raytheon.uf.common.localization.LocalizationContext.LocalizationType.EDEX_STATIC; -import gov.noaa.nws.ncep.edex.common.stationTables.IStationField.StationField; -import gov.noaa.nws.ncep.edex.common.stationTables.Station; -import gov.noaa.nws.ncep.edex.common.stationTables.StationTable; - -import java.io.File; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.uf.common.localization.IPathManager; -import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; -import com.raytheon.uf.common.localization.PathManagerFactory; -import com.raytheon.uf.edex.decodertools.core.LatLonPoint; - -public class LatLonLocTbl { - private static Log logger = LogFactory.getLog(LatLonLocTbl.class); - - static StationTable vorsloc = null; - - static StationTable intlsigloc = null; - - static StationTable myloc = null; - - private double latitude; - - private double longitude; - - private LatLonLocTbl(double latitude, double longitude) { - this.latitude = latitude; - this.longitude = longitude; - } - - public static void readLocTable(String tableName) throws Exception { - - final String NCEP_DIR = "ncep"; - final String stnsDir = "stns"; - final String vorsLocTableName = "vors.xml"; - - IPathManager manager = PathManagerFactory.getPathManager(); - - LocalizationContext baseContext = null; - File baseDir = null; - String stnsFileName = null; - baseContext = manager.getContext(EDEX_STATIC, LocalizationLevel.BASE); - baseContext.setContextName(NCEP_DIR); - baseDir = manager.getFile(baseContext, ""); - if (tableName == "vors") { - stnsFileName = baseDir + File.separator + stnsDir + File.separator - + vorsLocTableName; - } - logger.debug(" stnsFileName=" + stnsFileName); - myloc = new StationTable(stnsFileName); - - } - - public double getLatitude() { - return latitude; - } - - public double getLongitude() { - return longitude; - } - - public LatLonPoint getLatLonPoint() { - return new LatLonPoint(latitude, longitude, LatLonPoint.INDEGREES); - } - - private enum Direction { - N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW; - public double getDegrees() { - return ordinal() * 22.5; - } - } - - private static final double ONE_NM_RADIANS = Math.toRadians(1.0 / 60.0); - - /** - * Given a relative reference string, returns a LatLonPoint - * (com.raytheon.uf.edex.decodertools.core.LatLonPoint). - * - * @param location - * A String such as... "BOS" "20S EMI" "30 WNW BUM" " 40ENE HUH " - * ...referencing a VOR listed in AC 00-45F (Appendix F), - * optionally preceded by distance in nautical miles and 16-point - * compass direction string. - * @param locTable - * A string such as "vors" referring to "vors" location table or - * "intlsig" referring to intl location table - * @return The decoded location as a LatLonPoint; null on error (such as - * unrecognized VOR identifier or direction string). - * - */ - public static LatLonPoint getLatLonPoint(String location, String locTable) { - LatLonPoint point = null; - Station vor = null; - // Wrap decoding in a try block, in case of exception on - // one of the xml or direction enum, or other problems. - - try { - location = location.trim(); - - // VOR is always last 3 nonblank char of location - String navaid = location.substring(location.length() - 3); - - // Read in the location table XML if not exists - if (myloc == null) { - readLocTable(locTable); - logger.debug(" - read vors.xml to cache"); - } - // Search station ID and return whole station record - if (myloc != null) { - logger.debug(" - navaid = " + navaid); - vor = myloc.getStation(StationField.STID, navaid); - } else { - logger.debug(" - myloc is null"); - } - - // Get LatLonPoint from lat/lon - if (vor != null) { - point = new LatLonPoint(vor.getLatitude(), vor.getLongitude(), - LatLonPoint.INDEGREES); - } else { - logger.debug(" - DID NOT find station ID in vors.xml"); - } - - // If there's an offset direction/bearing, process it - if (location.length() > 3) { - String u = location.substring(0, location.length() - 3); - - Pattern p = Pattern.compile("^([0-9]+)\\s*([A-Z]+)"); - Matcher m = p.matcher(u); - if (m.find()) { - String distanceStr = m.group(1); - - String bearingStr = m.group(2); - - int distanceNM = Integer.parseInt(distanceStr); - - double distanceRad = distanceNM * ONE_NM_RADIANS; - // LatLonPoint.positionOf thinks bearing is CCW, not CW... - double bearingDeg = 360.0 - Direction.valueOf(bearingStr) - .getDegrees(); - double bearingRad = Math.toRadians(bearingDeg); - point = point.positionOf(bearingRad, distanceRad); - logger.debug(" - get a good latlon point"); - } - } - return point; - } catch (Exception e) { - logger.error("[Error decoding location in LatLonLocTbl: " - + location + "]"); - return null; - } - } - -} +/** + * LatLonLocTbl - A Java class to define some known VORs and Intlsig talbes + * used to define convective/nonconvective/airmet/intl SIGMET locations. + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 12 Jun 2009 95/132 B. Hebbard Initial creation. + * 10 Sep 2009 39/87/114 L. Lin Remove the temporary enum + * and add xml for VORs and + * Intlsig gempak tables. + * 30 Sep 2009 3102 jkorman Changed printlns to logging statements. + * + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ +package gov.noaa.nws.ncep.edex.tools.decoder; + +import static com.raytheon.uf.common.localization.LocalizationContext.LocalizationType.EDEX_STATIC; +import gov.noaa.nws.ncep.edex.common.stationTables.IStationField.StationField; +import gov.noaa.nws.ncep.edex.common.stationTables.Station; +import gov.noaa.nws.ncep.edex.common.stationTables.StationTable; + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; + +public class LatLonLocTbl { + private static Log logger = LogFactory.getLog(LatLonLocTbl.class); + + static StationTable vorsloc = null; + + static StationTable intlsigloc = null; + + static StationTable myloc = null; + + private double latitude; + + private double longitude; + + private LatLonLocTbl(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + + public static void readLocTable(String tableName) throws Exception { + + final String NCEP_DIR = "ncep"; + final String stnsDir = "stns"; + final String vorsLocTableName = "vors.xml"; + + IPathManager manager = PathManagerFactory.getPathManager(); + + LocalizationContext baseContext = null; + File baseDir = null; + String stnsFileName = null; + baseContext = manager.getContext(EDEX_STATIC, LocalizationLevel.BASE); + baseContext.setContextName(NCEP_DIR); + baseDir = manager.getFile(baseContext, ""); + if (tableName == "vors") { + stnsFileName = baseDir + File.separator + stnsDir + File.separator + + vorsLocTableName; + } + logger.debug(" stnsFileName=" + stnsFileName); + myloc = new StationTable(stnsFileName); + + } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + + public LatLonPoint getLatLonPoint() { + return new LatLonPoint(latitude, longitude, LatLonPoint.INDEGREES); + } + + private enum Direction { + N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW; + public double getDegrees() { + return ordinal() * 22.5; + } + } + + private static final double ONE_NM_RADIANS = Math.toRadians(1.0 / 60.0); + + /** + * Given a relative reference string, returns a LatLonPoint + * (com.raytheon.uf.edex.decodertools.core.LatLonPoint). + * + * @param location + * A String such as... "BOS" "20S EMI" "30 WNW BUM" " 40ENE HUH " + * ...referencing a VOR listed in AC 00-45F (Appendix F), + * optionally preceded by distance in nautical miles and 16-point + * compass direction string. + * @param locTable + * A string such as "vors" referring to "vors" location table or + * "intlsig" referring to intl location table + * @return The decoded location as a LatLonPoint; null on error (such as + * unrecognized VOR identifier or direction string). + * + */ + public static LatLonPoint getLatLonPoint(String location, String locTable) { + LatLonPoint point = null; + Station vor = null; + // Wrap decoding in a try block, in case of exception on + // one of the xml or direction enum, or other problems. + + try { + location = location.trim(); + + // VOR is always last 3 nonblank char of location + String navaid = location.substring(location.length() - 3); + + // Read in the location table XML if not exists + if (myloc == null) { + readLocTable(locTable); + logger.debug(" - read vors.xml to cache"); + } + // Search station ID and return whole station record + if (myloc != null) { + logger.debug(" - navaid = " + navaid); + vor = myloc.getStation(StationField.STID, navaid); + } else { + logger.debug(" - myloc is null"); + } + + // Get LatLonPoint from lat/lon + if (vor != null) { + point = new LatLonPoint(vor.getLatitude(), vor.getLongitude(), + LatLonPoint.INDEGREES); + } else { + logger.debug(" - DID NOT find station ID in vors.xml"); + } + + // If there's an offset direction/bearing, process it + if (location.length() > 3) { + String u = location.substring(0, location.length() - 3); + + Pattern p = Pattern.compile("^([0-9]+)\\s*([A-Z]+)"); + Matcher m = p.matcher(u); + if (m.find()) { + String distanceStr = m.group(1); + + String bearingStr = m.group(2); + + int distanceNM = Integer.parseInt(distanceStr); + + double distanceRad = distanceNM * ONE_NM_RADIANS; + // LatLonPoint.positionOf thinks bearing is CCW, not CW... + double bearingDeg = 360.0 - Direction.valueOf(bearingStr) + .getDegrees(); + double bearingRad = Math.toRadians(bearingDeg); + point = point.positionOf(bearingRad, distanceRad); + logger.debug(" - get a good latlon point"); + } + } + return point; + } catch (Exception e) { + logger.error("[Error decoding location in LatLonLocTbl: " + + location + "]"); + return null; + } + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/MndTime.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/MndTime.java old mode 100755 new mode 100644 index 186abc02be..f1a2c95cd9 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/MndTime.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/MndTime.java @@ -1,600 +1,600 @@ -/* - * - * MndTime - * - * This java class processes MND (Mass News Disseminator) block. - *
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    	Engineer    Description
- * ------------ ---------- 	----------- --------------------------
- * 10/2008		14			T. Lee		Creation
- * 04/2009		14			T. Lee		Used log4j logger
- * 06/2009		128			T. Lee		Added UTC/Zulu; Returned UTC 
- * 										or null for MND time
- * 07/2009		128			T. Lee		Migration to TO11
- * 01/26/2011   N/A         M. Gao      Refactor the logic of parsing MndTime string
- *                                      Now the regular expression is more flexible. 
- *                                      It can tolerate extra spaces at the beginning, ending 
- *                                      or in between of words. It can either take THU abbreviation
- *                                      or Thursday. The similar flexibility applies to MON and MONDAY too.
- *                                      It can also understand both format listed as below: 
- *                                      1018 PM CDT THU APR 1 2010 or
- *                                      1018 PM CDT THURSDAY 1 APR  2010 
- * 
- * - * @author T.Lee - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.tools.decoder; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public final class MndTime { - private final Log logger = LogFactory.getLog(getClass()); - - /** MND time calendar*/ - private Calendar mndTm = null; - - /** MND time string */ - private String mndTmStr = null; - - /** - * Constructor the MND time - * - * @param messageData - */ - public MndTime (byte[] messageData) { - mndTm = processMndTime (messageData); - } - - /** - * Get MND time - * - * @return mndTm - */ - public Calendar getMndTime() { - return mndTm; - } - - /** - * Get MND time string - * - * @return mndTmStr - */ - public String getMndTimeString() { - return mndTmStr; - } - - /** - * Return MND time as Calendar object. - * - * @param tm the Matcher object - * @return cal - */ - - public Calendar processMndTime (byte[] msg) { - String s = new String(msg); - SimpleDateFormat sdf; - - /* - * MND time (local format) - */ -// final String MNDTIME_EXP_LOCAL = "(\\d{3,4}) ([A-Za-z]{2}) ([A-Za-z]{3}) " + -// "([A-Za-z]{3}) ([A-Za-z]{3}) (\\d{1,2}) (\\d{4})\r\r\n"; -// Pattern pt = Pattern.compile(MNDTIME_EXP_LOCAL); -// Matcher tm = pt.matcher(s); -// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); -// -// /* -// * Decode local time pattern -// */ -// if (tm.find()) { -// String group1; -// String group6; -// mndTmStr = tm.group(0).trim(); -// sdf = new SimpleDateFormat ("HHmm a zzz EEE MMM dd yy"); -// group1 = tm.group(1); -// if ( tm.group(1).length() == 3 ) { -// group1 = "0"+tm.group(1); -// } -// /* -// * changes made are: -// * 1. Handle both cases of "1 APR" and "APR 1" for the string fields -// * group(5) and group(6) -// */ -//// group6 = tm.group(6); -//// if ( tm.group(6).length() == 1 ) { -//// group6 = "0"+tm.group(6); -//// } -//// String mnd = group1+" "+tm.group(2)+" "+tm.group(3)+" "+ tm.group(4)+" "+ -//// tm.group(5)+" "+group6+" "+tm.group(7); -// String [] monthAndDayStringArray = verifyAndRetrieveMonthAndDay(tm.group(5), tm.group(6)); -// String mnd = group1+" "+tm.group(2)+" "+tm.group(3)+" "+ tm.group(4)+" "+ -// monthAndDayStringArray[0]+" "+ monthAndDayStringArray[1] +" "+tm.group(7); -// try { -// java.util.Date parsedDate = sdf.parse(mnd); -// cal.setTime(parsedDate); -// } catch (ParseException pe) { -// if ( logger.isInfoEnabled()) { -// logger.info ( "Errors in processing MND local time"); -// } -// if(isTimeZoneInvalid(tm.group(3))) { -// setDayOfMonthAndMonthAndYearToCalendar(cal, monthAndDayStringArray[1], -// monthAndDayStringArray[0], tm.group(7)); -// } -// } - /* - * expression pattern string match something like "800 AM PDT THU APR 1 2010" - */ - final String MNDTIME_EXP_LOCAL_1 = "( *\\d{3,4})( *[A-Za-z]{2})( *[A-Za-z]{3})" + - "( *[A-Za-z]{3,9})( *[A-Za-z]{3,9})( *\\d{1,2})( *\\d{4} *)\r\r\n"; - Pattern pattern1 = Pattern.compile(MNDTIME_EXP_LOCAL_1); - Matcher matcher1 = pattern1.matcher(s); - /* - * expression pattern string match something like "800 AM PDT THU 1 APR 2010" - */ - final String MNDTIME_EXP_LOCAL_2 = "( *\\d{3,4})( *[A-Za-z]{2})( *[A-Za-z]{3})" + - "( *[A-Za-z]{3,9})( *\\d{1,2})( *[A-Za-z]{3,9})( *\\d{4} *)\r\r\n"; - Pattern pattern2 = Pattern.compile(MNDTIME_EXP_LOCAL_2); - Matcher matcher2 = pattern2.matcher(s); - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - Matcher matcher = getMatcher(matcher1, matcher2); - - Pattern pt = null; - Matcher tm = null; - /* - * Decode local time pattern - */ - if (matcher != null) { - mndTmStr = matcher.group(0).trim(); - sdf = new SimpleDateFormat ("HHmm a zzz EEE MMM dd yy"); - String group1; - group1 = matcher.group(1).trim(); - if ( group1.length() == 3 ) { - group1 = "0"+matcher.group(1); - } - /* - * changes made are: - * 1. Handle both cases of "1 APR" and "APR 1" for the string fields - * group(5) and group(6) - */ - String group2 = matcher.group(2).trim(); - String group3 = matcher.group(3).trim(); - String group4 = matcher.group(4).trim(); - String group5 = matcher.group(5).trim(); - String group6 = matcher.group(6).trim(); - String group7 = matcher.group(7).trim(); - String [] monthAndDayStringArray = verifyAndRetrieveMonthAndDay(group5, group6); - String mnd = group1+" "+ group2 + " "+ group3 +" "+ group4 + " " + - monthAndDayStringArray[0] + " "+ monthAndDayStringArray[1] +" "+ group7; - try { - java.util.Date parsedDate = sdf.parse(mnd); - cal.setTime(parsedDate); - } catch (ParseException pe) { - if ( logger.isInfoEnabled()) { - logger.info ( "Errors in processing MND local time"); - } - if(isTimeZoneInvalid(group3)) { - setDayOfMonthAndMonthAndYearToCalendar(cal, monthAndDayStringArray[1], - monthAndDayStringArray[0], group7); - } - } - - } else { - - /* - * UTC format, e.g., 1500 UTC THU MAY 28 2009 - */ - final String MNDTIME_EXP_UTC = "(\\d{3,4}) UTC ([A-Za-z]{3}) ([A-Za-z]{3}) " + - "(\\d{1,2}) (\\d{4})\r\r\n"; - - pt = Pattern.compile(MNDTIME_EXP_UTC); - tm = pt.matcher(s); - - /* - * decode UTC pattern - */ - if (tm.find()) { - String group1, group4; - sdf = new SimpleDateFormat ("HHmm zzz EEE MMM dd yyyy"); - mndTmStr = tm.group(0).trim(); - try { - group1 = tm.group(1); - if ( tm.group(1).length() == 3 ) { - group1 = "0"+tm.group(1); - } - group4 = tm.group(4); - if ( tm.group(4).length() == 1 ) { - group4 = "0"+tm.group(4); - } - String mnd = group1+" UTC "+tm.group(2)+" "+tm.group(3)+" "+ group4+ - " "+tm.group(5); - cal.setTime(sdf.parse(mnd)); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - } catch (Exception e) { - if ( logger.isInfoEnabled()) { - logger.info ( "Errors in processing MND UTC time"); - } - } - - } else { - - /* - * Check Zulu pattern - */ - String MNDTIME_EXP_ZULU = "(\\d{5,6})(z|Z) ([A-Za-z]{3}) (\\d{2})//(\r\r\n|\r\n)"; - pt = Pattern.compile(MNDTIME_EXP_ZULU); - tm = pt.matcher(s); - - /* - * Check UTC pattern - */ - if (tm.find()) { - String group1; - sdf = new SimpleDateFormat ("ddHHmm zzz MMM yy"); - mndTmStr = tm.group(0).trim(); - try { - group1 = tm.group(1); - if ( tm.group(1).length() == 5 ) { - group1 = "0"+tm.group(1); - } - String time = group1+" UTC "+tm.group(3)+" "+tm.group(4); - cal.setTime(sdf.parse(time)); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - } catch (Exception e) { - if ( logger.isInfoEnabled()) { - logger.info ( "Errors in processing MND zulu time"); - } - } - } else { - - /* - * Check Zulu pattern - */ - MNDTIME_EXP_ZULU = "(\\d{5,6})(z|Z)([A-Za-z]{3})(\\d{4})//(\n|\r\n)"; - pt = Pattern.compile(MNDTIME_EXP_ZULU); - tm = pt.matcher(s); - - /* - * Check UTC pattern - */ - if (tm.find()) { - String group1; - sdf = new SimpleDateFormat ("ddHHmm zzz MMM yyyy"); - mndTmStr = tm.group(0).trim(); - try { - group1 = tm.group(1); - if ( tm.group(1).length() == 5 ) { - group1 = "0"+tm.group(1); - } - String time = group1+" UTC "+tm.group(3)+" "+tm.group(4); - cal.setTime(sdf.parse(time)); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - } catch (Exception e) { - if ( logger.isInfoEnabled()) { - logger.info ( "Errors in processing MND zulu time"); - } - } - } else { - - /* - * return null if no MND time - */ - cal = null; - } - } - } - } - return cal; - } - - private String stripExtraSpace(String str) { - if(isStringEmpty(str)) - return ""; - StringBuilder builder = new StringBuilder(str.length()); - String [] strArray = str.split(" "); - displayStringArray(strArray); - /* - * find the first string that can be parsed as an integer - * and discard any strings in front of it - */ - int firstIntegerStringIndex = findFirstIntegerStringIndex(strArray); - for(int i=firstIntegerStringIndex; i< strArray.length; i++) { - builder.append(strArray[i].trim()) - .append(" "); - } - return builder.toString().trim(); - } - - private void displayStringArray(String[] strArray) { - if(strArray == null) - System.out.println("=====, the input strArray is NULL and thus can not be displayed!!!!"); - else { - System.out.println("=======, the total number of String array is = " + strArray.length); - int arrayIndex = 1; - for(String eachString : strArray) { - System.out.println(" Array Intem No." + arrayIndex + ":= "+eachString + " with LENGTH ="+eachString.length()); - arrayIndex++; - } - } - } - - /** - * - * @param timezoneString - * @return - */ - private String replaceInvalidTimezoneValue(String timezoneString) { - String timezoneValueReturned = timezoneString; - if(timezoneValueReturned != null && timezoneValueReturned.trim().length() > 0) { - if(timezoneValueReturned.equalsIgnoreCase("PLT")) - timezoneValueReturned = "PDT"; - } - return timezoneValueReturned; - } - - /** - * - * @param strArray - * @return - */ - private int findFirstIntegerStringIndex(String[] strArray) { - int firstIntegerStringIndex = 0; - if(strArray != null) { - for(String eachString : strArray) { - if(isIntegerString(eachString)) - break; - firstIntegerStringIndex++; - } - } - return firstIntegerStringIndex; - } - - private boolean isIntegerString(String str) { - boolean isIntegerString = false; - try { - Integer.parseInt(str); - isIntegerString = true; - } catch(NumberFormatException nfe) { - //do nothing - } - return isIntegerString; - } - - /** - * a helper method to check is a string is empty - * @param str - * @return - */ - private boolean isStringEmpty(String str) { - boolean isEmpty = false; - if(str == null || str.trim().length() == 0) - isEmpty = true; - return isEmpty; - } - /** - * - * @param matcher1 - * @param matcher2 - * @return - */ - private Matcher getMatcher(Matcher matcher1, Matcher matcher2) { - Matcher matcher = null; - if(matcher1 != null && matcher1.find()) - matcher = matcher1; - else if(matcher2 != null && matcher2.find()) - matcher = matcher2; - return matcher; - } - - /** - * - * @param timeZoneString - * @return - */ - private boolean isTimeZoneInvalid(String timeZoneString) { - boolean isInvalid = false; - if(isStringEqual("PLT", timeZoneString)) - isInvalid = true; - return isInvalid; - } - - /** - * A helper method to parse and monthString and yearString directly - * and then set to the calendar object - * @param calendar - * @param monthString - * @param yearString - */ - private void setDayOfMonthAndMonthAndYearToCalendar(Calendar calendar, String dayOfMonthString, - String monthString, String yearString) { - if(calendar == null) - return; - /* - * set day of month - */ - int dayOfMonthInt = getDayOfMonthInt(dayOfMonthString); - if(isDayOfMonthIntValid(dayOfMonthInt)) - calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthInt); - - /* - * set month - */ - int monthId = getMonthId(monthString); - if(isMonthIdValid(monthId)) - calendar.set(Calendar.MONTH, monthId); - - /* - * Now set year value - */ - int yearInt = getYearInt(yearString); - if(isYearIntValid(yearInt)) - calendar.set(Calendar.YEAR, yearInt); - } - - private int getMonthId(String monthString) { - int monthId = -1; - if(isStringEqual("JAN", monthString) || isStringEqual("JANUARY", monthString)) - monthId = Calendar.JANUARY; - else if(isStringEqual("FEB", monthString) || isStringEqual("FEBRUARY", monthString)) - monthId = Calendar.FEBRUARY; - else if(isStringEqual("MAR", monthString) || isStringEqual("MARCH", monthString)) - monthId = Calendar.MARCH; - else if(isStringEqual("APR", monthString) || isStringEqual("APRIL", monthString)) - monthId = Calendar.APRIL; - else if(isStringEqual("MAY", monthString)) - monthId = Calendar.MAY; - else if(isStringEqual("JUN", monthString) || isStringEqual("JUNE", monthString)) - monthId = Calendar.JUNE; - else if(isStringEqual("JUL", monthString) || isStringEqual("JULY", monthString)) - monthId = Calendar.JULY; - else if(isStringEqual("AUG", monthString) || isStringEqual("AUGUST", monthString)) - monthId = Calendar.AUGUST; - else if(isStringEqual("SEP", monthString) || isStringEqual("SEPTEMBER", monthString)) - monthId = Calendar.SEPTEMBER; - else if(isStringEqual("OCT", monthString) || isStringEqual("OCTOBER", monthString)) - monthId = Calendar.OCTOBER; - else if(isStringEqual("NOV", monthString) || isStringEqual("NOVEMBER", monthString)) - monthId = Calendar.NOVEMBER; - else if(isStringEqual("DEC", monthString) || isStringEqual("DECEMBER", monthString)) - monthId = Calendar.DECEMBER; - return monthId; - } - - private boolean isStringEqual(String str1, String str2) { - boolean isEqual = false; - if(str1.equalsIgnoreCase(str2)) - isEqual = true; - return isEqual; - } - - /** - * - * @param yearString - * @return - */ - private int getYearInt(String yearString) { - int yearInt = -1; - if(yearString != null) { - try { - yearInt = Integer.parseInt(yearString); - } catch(NumberFormatException nfe) { - //do nothing - } - } - return yearInt; - } - - private int getDayOfMonthInt(String dayOfMonthString) { - int dayOfMonthInt = -1; - if(dayOfMonthString != null) { - try { - dayOfMonthInt = Integer.parseInt(dayOfMonthString); - } catch(NumberFormatException nfe) { - //do nothing - } - } - return dayOfMonthInt; - } - - - /** - * - * @param monthId - * @return - */ - private boolean isMonthIdValid(int monthId) { - boolean isValid = true; - if(isIntegerNegative(monthId)) - isValid = false; - return isValid; - } - - /** - * - * @param yearInt - * @return - */ - private boolean isYearIntValid(int yearInt) { - boolean isValid = true; - if(isIntegerNegative(yearInt)) - isValid = false; - return isValid; - } - - private boolean isDayOfMonthIntValid(int dayOfMonthInt) { - boolean isValid = true; - if(isIntegerNegative(dayOfMonthInt)) - isValid = false; - return isValid; - } - - /** - * a method to return true if the input is a negative number - * @param intValue - * @return - */ - private boolean isIntegerNegative(int intValue) { - return intValue < 0 ? true : false; - } - - /* - * A helper method to retrieve month and day values - * Case No.1: 12 APR - * Case No.2: APR 12 - */ - private String[] verifyAndRetrieveMonthAndDay(String monthAndDayValue1, String monthAndDayValue2) { - String [] monthAndDayStringArray = new String[2]; - if(canStringBeParsedAsInteger(monthAndDayValue2)) { - monthAndDayStringArray[0] = monthAndDayValue1; - monthAndDayStringArray[1] = monthAndDayValue2; - } else if(canStringBeParsedAsInteger(monthAndDayValue1)) { - monthAndDayStringArray[0] = monthAndDayValue2; - monthAndDayStringArray[1] = monthAndDayValue1; - } - if(monthAndDayStringArray[1] != null && monthAndDayStringArray[1].length()==1) - monthAndDayStringArray[1] = "0" + monthAndDayStringArray[1]; - - checkStringArray(monthAndDayStringArray); - return monthAndDayStringArray; - } - - /* - * A helper method to check each element of the array - * to make sure there is no any null value exists in the array - * Assign an empty string value to any null element of the array - */ - private void checkStringArray(String[] stringArray) { - for(int i=0; i + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 10/2008 14 T. Lee Creation + * 04/2009 14 T. Lee Used log4j logger + * 06/2009 128 T. Lee Added UTC/Zulu; Returned UTC + * or null for MND time + * 07/2009 128 T. Lee Migration to TO11 + * 01/26/2011 N/A M. Gao Refactor the logic of parsing MndTime string + * Now the regular expression is more flexible. + * It can tolerate extra spaces at the beginning, ending + * or in between of words. It can either take THU abbreviation + * or Thursday. The similar flexibility applies to MON and MONDAY too. + * It can also understand both format listed as below: + * 1018 PM CDT THU APR 1 2010 or + * 1018 PM CDT THURSDAY 1 APR 2010 + * + * + * @author T.Lee + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.tools.decoder; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public final class MndTime { + private final Log logger = LogFactory.getLog(getClass()); + + /** MND time calendar*/ + private Calendar mndTm = null; + + /** MND time string */ + private String mndTmStr = null; + + /** + * Constructor the MND time + * + * @param messageData + */ + public MndTime (byte[] messageData) { + mndTm = processMndTime (messageData); + } + + /** + * Get MND time + * + * @return mndTm + */ + public Calendar getMndTime() { + return mndTm; + } + + /** + * Get MND time string + * + * @return mndTmStr + */ + public String getMndTimeString() { + return mndTmStr; + } + + /** + * Return MND time as Calendar object. + * + * @param tm the Matcher object + * @return cal + */ + + public Calendar processMndTime (byte[] msg) { + String s = new String(msg); + SimpleDateFormat sdf; + + /* + * MND time (local format) + */ +// final String MNDTIME_EXP_LOCAL = "(\\d{3,4}) ([A-Za-z]{2}) ([A-Za-z]{3}) " + +// "([A-Za-z]{3}) ([A-Za-z]{3}) (\\d{1,2}) (\\d{4})\r\r\n"; +// Pattern pt = Pattern.compile(MNDTIME_EXP_LOCAL); +// Matcher tm = pt.matcher(s); +// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); +// +// /* +// * Decode local time pattern +// */ +// if (tm.find()) { +// String group1; +// String group6; +// mndTmStr = tm.group(0).trim(); +// sdf = new SimpleDateFormat ("HHmm a zzz EEE MMM dd yy"); +// group1 = tm.group(1); +// if ( tm.group(1).length() == 3 ) { +// group1 = "0"+tm.group(1); +// } +// /* +// * changes made are: +// * 1. Handle both cases of "1 APR" and "APR 1" for the string fields +// * group(5) and group(6) +// */ +//// group6 = tm.group(6); +//// if ( tm.group(6).length() == 1 ) { +//// group6 = "0"+tm.group(6); +//// } +//// String mnd = group1+" "+tm.group(2)+" "+tm.group(3)+" "+ tm.group(4)+" "+ +//// tm.group(5)+" "+group6+" "+tm.group(7); +// String [] monthAndDayStringArray = verifyAndRetrieveMonthAndDay(tm.group(5), tm.group(6)); +// String mnd = group1+" "+tm.group(2)+" "+tm.group(3)+" "+ tm.group(4)+" "+ +// monthAndDayStringArray[0]+" "+ monthAndDayStringArray[1] +" "+tm.group(7); +// try { +// java.util.Date parsedDate = sdf.parse(mnd); +// cal.setTime(parsedDate); +// } catch (ParseException pe) { +// if ( logger.isInfoEnabled()) { +// logger.info ( "Errors in processing MND local time"); +// } +// if(isTimeZoneInvalid(tm.group(3))) { +// setDayOfMonthAndMonthAndYearToCalendar(cal, monthAndDayStringArray[1], +// monthAndDayStringArray[0], tm.group(7)); +// } +// } + /* + * expression pattern string match something like "800 AM PDT THU APR 1 2010" + */ + final String MNDTIME_EXP_LOCAL_1 = "( *\\d{3,4})( *[A-Za-z]{2})( *[A-Za-z]{3})" + + "( *[A-Za-z]{3,9})( *[A-Za-z]{3,9})( *\\d{1,2})( *\\d{4} *)\r\r\n"; + Pattern pattern1 = Pattern.compile(MNDTIME_EXP_LOCAL_1); + Matcher matcher1 = pattern1.matcher(s); + /* + * expression pattern string match something like "800 AM PDT THU 1 APR 2010" + */ + final String MNDTIME_EXP_LOCAL_2 = "( *\\d{3,4})( *[A-Za-z]{2})( *[A-Za-z]{3})" + + "( *[A-Za-z]{3,9})( *\\d{1,2})( *[A-Za-z]{3,9})( *\\d{4} *)\r\r\n"; + Pattern pattern2 = Pattern.compile(MNDTIME_EXP_LOCAL_2); + Matcher matcher2 = pattern2.matcher(s); + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + Matcher matcher = getMatcher(matcher1, matcher2); + + Pattern pt = null; + Matcher tm = null; + /* + * Decode local time pattern + */ + if (matcher != null) { + mndTmStr = matcher.group(0).trim(); + sdf = new SimpleDateFormat ("HHmm a zzz EEE MMM dd yy"); + String group1; + group1 = matcher.group(1).trim(); + if ( group1.length() == 3 ) { + group1 = "0"+matcher.group(1); + } + /* + * changes made are: + * 1. Handle both cases of "1 APR" and "APR 1" for the string fields + * group(5) and group(6) + */ + String group2 = matcher.group(2).trim(); + String group3 = matcher.group(3).trim(); + String group4 = matcher.group(4).trim(); + String group5 = matcher.group(5).trim(); + String group6 = matcher.group(6).trim(); + String group7 = matcher.group(7).trim(); + String [] monthAndDayStringArray = verifyAndRetrieveMonthAndDay(group5, group6); + String mnd = group1+" "+ group2 + " "+ group3 +" "+ group4 + " " + + monthAndDayStringArray[0] + " "+ monthAndDayStringArray[1] +" "+ group7; + try { + java.util.Date parsedDate = sdf.parse(mnd); + cal.setTime(parsedDate); + } catch (ParseException pe) { + if ( logger.isInfoEnabled()) { + logger.info ( "Errors in processing MND local time"); + } + if(isTimeZoneInvalid(group3)) { + setDayOfMonthAndMonthAndYearToCalendar(cal, monthAndDayStringArray[1], + monthAndDayStringArray[0], group7); + } + } + + } else { + + /* + * UTC format, e.g., 1500 UTC THU MAY 28 2009 + */ + final String MNDTIME_EXP_UTC = "(\\d{3,4}) UTC ([A-Za-z]{3}) ([A-Za-z]{3}) " + + "(\\d{1,2}) (\\d{4})\r\r\n"; + + pt = Pattern.compile(MNDTIME_EXP_UTC); + tm = pt.matcher(s); + + /* + * decode UTC pattern + */ + if (tm.find()) { + String group1, group4; + sdf = new SimpleDateFormat ("HHmm zzz EEE MMM dd yyyy"); + mndTmStr = tm.group(0).trim(); + try { + group1 = tm.group(1); + if ( tm.group(1).length() == 3 ) { + group1 = "0"+tm.group(1); + } + group4 = tm.group(4); + if ( tm.group(4).length() == 1 ) { + group4 = "0"+tm.group(4); + } + String mnd = group1+" UTC "+tm.group(2)+" "+tm.group(3)+" "+ group4+ + " "+tm.group(5); + cal.setTime(sdf.parse(mnd)); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + } catch (Exception e) { + if ( logger.isInfoEnabled()) { + logger.info ( "Errors in processing MND UTC time"); + } + } + + } else { + + /* + * Check Zulu pattern + */ + String MNDTIME_EXP_ZULU = "(\\d{5,6})(z|Z) ([A-Za-z]{3}) (\\d{2})//(\r\r\n|\r\n)"; + pt = Pattern.compile(MNDTIME_EXP_ZULU); + tm = pt.matcher(s); + + /* + * Check UTC pattern + */ + if (tm.find()) { + String group1; + sdf = new SimpleDateFormat ("ddHHmm zzz MMM yy"); + mndTmStr = tm.group(0).trim(); + try { + group1 = tm.group(1); + if ( tm.group(1).length() == 5 ) { + group1 = "0"+tm.group(1); + } + String time = group1+" UTC "+tm.group(3)+" "+tm.group(4); + cal.setTime(sdf.parse(time)); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + } catch (Exception e) { + if ( logger.isInfoEnabled()) { + logger.info ( "Errors in processing MND zulu time"); + } + } + } else { + + /* + * Check Zulu pattern + */ + MNDTIME_EXP_ZULU = "(\\d{5,6})(z|Z)([A-Za-z]{3})(\\d{4})//(\n|\r\n)"; + pt = Pattern.compile(MNDTIME_EXP_ZULU); + tm = pt.matcher(s); + + /* + * Check UTC pattern + */ + if (tm.find()) { + String group1; + sdf = new SimpleDateFormat ("ddHHmm zzz MMM yyyy"); + mndTmStr = tm.group(0).trim(); + try { + group1 = tm.group(1); + if ( tm.group(1).length() == 5 ) { + group1 = "0"+tm.group(1); + } + String time = group1+" UTC "+tm.group(3)+" "+tm.group(4); + cal.setTime(sdf.parse(time)); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + } catch (Exception e) { + if ( logger.isInfoEnabled()) { + logger.info ( "Errors in processing MND zulu time"); + } + } + } else { + + /* + * return null if no MND time + */ + cal = null; + } + } + } + } + return cal; + } + + private String stripExtraSpace(String str) { + if(isStringEmpty(str)) + return ""; + StringBuilder builder = new StringBuilder(str.length()); + String [] strArray = str.split(" "); + displayStringArray(strArray); + /* + * find the first string that can be parsed as an integer + * and discard any strings in front of it + */ + int firstIntegerStringIndex = findFirstIntegerStringIndex(strArray); + for(int i=firstIntegerStringIndex; i< strArray.length; i++) { + builder.append(strArray[i].trim()) + .append(" "); + } + return builder.toString().trim(); + } + + private void displayStringArray(String[] strArray) { + if(strArray == null) + System.out.println("=====, the input strArray is NULL and thus can not be displayed!!!!"); + else { + System.out.println("=======, the total number of String array is = " + strArray.length); + int arrayIndex = 1; + for(String eachString : strArray) { + System.out.println(" Array Intem No." + arrayIndex + ":= "+eachString + " with LENGTH ="+eachString.length()); + arrayIndex++; + } + } + } + + /** + * + * @param timezoneString + * @return + */ + private String replaceInvalidTimezoneValue(String timezoneString) { + String timezoneValueReturned = timezoneString; + if(timezoneValueReturned != null && timezoneValueReturned.trim().length() > 0) { + if(timezoneValueReturned.equalsIgnoreCase("PLT")) + timezoneValueReturned = "PDT"; + } + return timezoneValueReturned; + } + + /** + * + * @param strArray + * @return + */ + private int findFirstIntegerStringIndex(String[] strArray) { + int firstIntegerStringIndex = 0; + if(strArray != null) { + for(String eachString : strArray) { + if(isIntegerString(eachString)) + break; + firstIntegerStringIndex++; + } + } + return firstIntegerStringIndex; + } + + private boolean isIntegerString(String str) { + boolean isIntegerString = false; + try { + Integer.parseInt(str); + isIntegerString = true; + } catch(NumberFormatException nfe) { + //do nothing + } + return isIntegerString; + } + + /** + * a helper method to check is a string is empty + * @param str + * @return + */ + private boolean isStringEmpty(String str) { + boolean isEmpty = false; + if(str == null || str.trim().length() == 0) + isEmpty = true; + return isEmpty; + } + /** + * + * @param matcher1 + * @param matcher2 + * @return + */ + private Matcher getMatcher(Matcher matcher1, Matcher matcher2) { + Matcher matcher = null; + if(matcher1 != null && matcher1.find()) + matcher = matcher1; + else if(matcher2 != null && matcher2.find()) + matcher = matcher2; + return matcher; + } + + /** + * + * @param timeZoneString + * @return + */ + private boolean isTimeZoneInvalid(String timeZoneString) { + boolean isInvalid = false; + if(isStringEqual("PLT", timeZoneString)) + isInvalid = true; + return isInvalid; + } + + /** + * A helper method to parse and monthString and yearString directly + * and then set to the calendar object + * @param calendar + * @param monthString + * @param yearString + */ + private void setDayOfMonthAndMonthAndYearToCalendar(Calendar calendar, String dayOfMonthString, + String monthString, String yearString) { + if(calendar == null) + return; + /* + * set day of month + */ + int dayOfMonthInt = getDayOfMonthInt(dayOfMonthString); + if(isDayOfMonthIntValid(dayOfMonthInt)) + calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthInt); + + /* + * set month + */ + int monthId = getMonthId(monthString); + if(isMonthIdValid(monthId)) + calendar.set(Calendar.MONTH, monthId); + + /* + * Now set year value + */ + int yearInt = getYearInt(yearString); + if(isYearIntValid(yearInt)) + calendar.set(Calendar.YEAR, yearInt); + } + + private int getMonthId(String monthString) { + int monthId = -1; + if(isStringEqual("JAN", monthString) || isStringEqual("JANUARY", monthString)) + monthId = Calendar.JANUARY; + else if(isStringEqual("FEB", monthString) || isStringEqual("FEBRUARY", monthString)) + monthId = Calendar.FEBRUARY; + else if(isStringEqual("MAR", monthString) || isStringEqual("MARCH", monthString)) + monthId = Calendar.MARCH; + else if(isStringEqual("APR", monthString) || isStringEqual("APRIL", monthString)) + monthId = Calendar.APRIL; + else if(isStringEqual("MAY", monthString)) + monthId = Calendar.MAY; + else if(isStringEqual("JUN", monthString) || isStringEqual("JUNE", monthString)) + monthId = Calendar.JUNE; + else if(isStringEqual("JUL", monthString) || isStringEqual("JULY", monthString)) + monthId = Calendar.JULY; + else if(isStringEqual("AUG", monthString) || isStringEqual("AUGUST", monthString)) + monthId = Calendar.AUGUST; + else if(isStringEqual("SEP", monthString) || isStringEqual("SEPTEMBER", monthString)) + monthId = Calendar.SEPTEMBER; + else if(isStringEqual("OCT", monthString) || isStringEqual("OCTOBER", monthString)) + monthId = Calendar.OCTOBER; + else if(isStringEqual("NOV", monthString) || isStringEqual("NOVEMBER", monthString)) + monthId = Calendar.NOVEMBER; + else if(isStringEqual("DEC", monthString) || isStringEqual("DECEMBER", monthString)) + monthId = Calendar.DECEMBER; + return monthId; + } + + private boolean isStringEqual(String str1, String str2) { + boolean isEqual = false; + if(str1.equalsIgnoreCase(str2)) + isEqual = true; + return isEqual; + } + + /** + * + * @param yearString + * @return + */ + private int getYearInt(String yearString) { + int yearInt = -1; + if(yearString != null) { + try { + yearInt = Integer.parseInt(yearString); + } catch(NumberFormatException nfe) { + //do nothing + } + } + return yearInt; + } + + private int getDayOfMonthInt(String dayOfMonthString) { + int dayOfMonthInt = -1; + if(dayOfMonthString != null) { + try { + dayOfMonthInt = Integer.parseInt(dayOfMonthString); + } catch(NumberFormatException nfe) { + //do nothing + } + } + return dayOfMonthInt; + } + + + /** + * + * @param monthId + * @return + */ + private boolean isMonthIdValid(int monthId) { + boolean isValid = true; + if(isIntegerNegative(monthId)) + isValid = false; + return isValid; + } + + /** + * + * @param yearInt + * @return + */ + private boolean isYearIntValid(int yearInt) { + boolean isValid = true; + if(isIntegerNegative(yearInt)) + isValid = false; + return isValid; + } + + private boolean isDayOfMonthIntValid(int dayOfMonthInt) { + boolean isValid = true; + if(isIntegerNegative(dayOfMonthInt)) + isValid = false; + return isValid; + } + + /** + * a method to return true if the input is a negative number + * @param intValue + * @return + */ + private boolean isIntegerNegative(int intValue) { + return intValue < 0 ? true : false; + } + + /* + * A helper method to retrieve month and day values + * Case No.1: 12 APR + * Case No.2: APR 12 + */ + private String[] verifyAndRetrieveMonthAndDay(String monthAndDayValue1, String monthAndDayValue2) { + String [] monthAndDayStringArray = new String[2]; + if(canStringBeParsedAsInteger(monthAndDayValue2)) { + monthAndDayStringArray[0] = monthAndDayValue1; + monthAndDayStringArray[1] = monthAndDayValue2; + } else if(canStringBeParsedAsInteger(monthAndDayValue1)) { + monthAndDayStringArray[0] = monthAndDayValue2; + monthAndDayStringArray[1] = monthAndDayValue1; + } + if(monthAndDayStringArray[1] != null && monthAndDayStringArray[1].length()==1) + monthAndDayStringArray[1] = "0" + monthAndDayStringArray[1]; + + checkStringArray(monthAndDayStringArray); + return monthAndDayStringArray; + } + + /* + * A helper method to check each element of the array + * to make sure there is no any null value exists in the array + * Assign an empty string value to any null element of the array + */ + private void checkStringArray(String[] stringArray) { + for(int i=0; i - * SOFTWARE HISTORY - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 12 Jun 2009 95 B. Hebbard Initial creation. - * 24 Jun 2009 95/132 B. Hebbard Add getLatLonPoint; move to common plugin - * 22 Jul 2009 for 132 B. Hebbard Port to TO11 until station table avail. EDEX - * - * - * - * @author bhebbard - * @version 1.0 - */ -public enum VOR { - - // (From GEMPAK vors.tbl -- for TEMPORARY use only, just until - // this is handled by more general station/location design. - // - // Note these are a SUBSET of the high-altitude VORs in North America - // used by AWC for SIGMET bounding points. It is NOT sufficient - // for lookup in cases where where all VHF NAVAIDs -- or - // even all VORs -- are required [say, for PIREP decoding]) - // - // Lat Lon - YSJ ( 45.32 , -65.88 ) , - HUL ( 46.04 , -67.83 ) , - PQI ( 46.77 , -68.09 ) , - MLT ( 45.58 , -68.52 ) , - BGR ( 44.84 , -68.87 ) , - ACK ( 41.28 , -70.03 ) , - ENE ( 43.43 , -70.61 ) , - BOS ( 42.36 , -70.99 ) , - YQB ( 46.80 , -71.38 ) , - PVD ( 41.72 , -71.43 ) , - CON ( 43.22 , -71.58 ) , - YSC ( 45.43 , -71.68 ) , - HTO ( 40.92 , -72.32 ) , - MPV ( 44.22 , -72.57 ) , - BDL ( 41.94 , -72.69 ) , - PLB ( 44.69 , -73.52 ) , - JFK ( 40.63 , -73.77 ) , - ALB ( 42.75 , -73.80 ) , - CYN ( 39.82 , -74.43 ) , - SAX ( 41.07 , -74.54 ) , - MSS ( 44.91 , -74.72 ) , - SIE ( 39.10 , -74.80 ) , - HNK ( 42.06 , -75.32 ) , - SBY ( 38.35 , -75.52 ) , - YOW ( 45.32 , -75.67 ) , - ETX ( 40.58 , -75.68 ) , - ECG ( 36.25 , -76.18 ) , - SYR ( 43.16 , -76.20 ) , - ORF ( 36.89 , -76.20 ) , - EMI ( 39.50 , -76.98 ) , - HAR ( 40.23 , -77.02 ) , - DCA ( 38.86 , -77.04 ) , - RIC ( 37.50 , -77.32 ) , - CSN ( 38.64 , -77.87 ) , - ILM ( 34.35 , -77.87 ) , - SLT ( 41.51 , -77.97 ) , - PSB ( 40.92 , -77.99 ) , - BUF ( 42.93 , -78.65 ) , - RDU ( 35.87 , -78.78 ) , - JST ( 40.32 , -78.83 ) , - JHW ( 42.19 , -79.12 ) , - LYH ( 37.25 , -79.23 ) , - YYZ ( 43.67 , -79.63 ) , - FLO ( 34.23 , -79.66 ) , - GSO ( 36.05 , -79.98 ) , - CHS ( 32.89 , -80.04 ) , - PBI ( 26.68 , -80.09 ) , - EKN ( 38.92 , -80.10 ) , - EWC ( 40.83 , -80.21 ) , - ERI ( 42.02 , -80.30 ) , - MIA ( 25.80 , -80.30 ) , - VRB ( 27.68 , -80.49 ) , - PSK ( 37.09 , -80.71 ) , - AIR ( 40.02 , -80.82 ) , - CLT ( 35.22 , -80.93 ) , - CAE ( 33.86 , -81.05 ) , - YVV ( 44.75 , -81.10 ) , - SAV ( 32.16 , -81.11 ) , - OMN ( 29.30 , -81.11 ) , - BKW ( 37.78 , -81.12 ) , - ORL ( 28.54 , -81.34 ) , - CRG ( 30.34 , -81.51 ) , - EYW ( 24.59 , -81.80 ) , - FMY ( 26.58 , -81.87 ) , // OBSOLETE - SPA ( 35.03 , -81.93 ) , - HNN ( 38.75 , -82.03 ) , - HMV ( 36.44 , -82.13 ) , - CLE ( 41.42 , -81.85 ) , - IRQ ( 33.71 , -82.16 ) , - AMG ( 31.54 , -82.51 ) , - SRQ ( 27.40 , -82.55 ) , - APE ( 40.15 , -82.59 ) , - PIE ( 27.91 , -82.68 ) , - ECK ( 43.26 , -82.72 ) , - CTY ( 29.60 , -83.05 ) , - ODF ( 34.70 , -83.30 ) , - DXO ( 42.21 , -83.37 ) , - ASP ( 44.45 , -83.39 ) , - MCN ( 32.69 , -83.65 ) , - FNT ( 42.97 , -83.74 ) , - VXV ( 35.90 , -83.89 ) , - ROD ( 40.29 , -84.04 ) , - MBS ( 43.53 , -84.08 ) , - LOZ ( 37.03 , -84.12 ) , - ABY ( 31.65 , -84.30 ) , // OBSOLETE - SSM ( 46.41 , -84.31 ) , - TLH ( 30.56 , -84.37 ) , - ATL ( 33.63 , -84.44 ) , - CVG ( 39.02 , -84.70 ) , - GQO ( 34.96 , -85.15 ) , - FWA ( 40.98 , -85.19 ) , - LGC ( 33.05 , -85.21 ) , - GRR ( 42.79 , -85.50 ) , - TVC ( 44.67 , -85.55 ) , - LOU ( 38.10 , -85.58 ) , // OBSOLETE - MKG ( 43.17 , -86.04 ) , - PMM ( 42.47 , -86.11 ) , - GIJ ( 41.77 , -86.32 ) , - MGM ( 32.22 , -86.32 ) , - IND ( 39.81 , -86.37 ) , - BWG ( 36.93 , -86.44 ) , - BNA ( 36.14 , -86.68 ) , - CEW ( 30.83 , -86.68 ) , - VUZ ( 33.67 , -86.90 ) , - BVT ( 40.56 , -87.07 ) , - TTH ( 39.49 , -87.25 ) , - MSL ( 34.70 , -87.48 ) , - SAW ( 46.36 , -87.40 ) , - PXV ( 37.93 , -87.76 ) , - ORD ( 41.98 , -87.90 ) , - GRB ( 44.56 , -88.19 ) , - BAE ( 43.12 , -88.28 ) , - JOT ( 41.55 , -88.32 ) , - SJI ( 30.73 , -88.36 ) , - IGB ( 33.48 , -88.52 ) , - MEI ( 32.38 , -88.80 ) , - DEC ( 39.74 , -88.86 ) , - YQT ( 48.37 , -89.32 ) , - DYR ( 36.02 , -89.32 ) , - RHI ( 45.63 , -89.45 ) , - BDF ( 41.16 , -89.59 ) , - DLL ( 43.55 , -89.76 ) , - MEM ( 35.06 , -89.98 ) , - LEV ( 29.18 , -90.10 ) , - JAN ( 32.51 , -90.17 ) , - MSY ( 30.00 , -90.27 ) , // OBSOLETE - FAM ( 37.67 , -90.23 ) , - MCB ( 31.30 , -90.26 ) , - SQS ( 33.46 , -90.28 ) , - STL ( 38.86 , -90.48 ) , - DBQ ( 42.40 , -90.71 ) , - ARG ( 36.11 , -90.95 ) , - UIN ( 39.85 , -91.28 ) , - BTR ( 30.48 , -91.30 ) , - ODI ( 43.91 , -91.47 ) , - EAU ( 44.90 , -91.48 ) , - IOW ( 41.52 , -91.61 ) , - MLU ( 32.52 , -92.03 ) , - LIT ( 34.68 , -92.18 ) , - DLH ( 46.80 , -92.20 ) , - COU ( 38.82 , -92.22 ) , - AEX ( 31.26 , -92.50 ) , - IRK ( 40.14 , -92.59 ) , - ELD ( 33.26 , -92.74 ) , - LCH ( 30.14 , -93.11 ) , - MSP ( 44.88 , -93.23 ) , - MCW ( 43.09 , -93.33 ) , - SGF ( 37.36 , -93.33 ) , - INL ( 48.57 , -93.40 ) , - DSM ( 41.44 , -93.65 ) , - EIC ( 32.77 , -93.81 ) , - BRD ( 46.35 , -94.03 ) , - TXK ( 33.51 , -94.07 ) , - RZC ( 36.25 , -94.12 ) , - FSM ( 35.38 , -94.27 ) , - FOD ( 42.61 , -94.29 ) , - BUM ( 38.27 , -94.49 ) , - MKC ( 39.28 , -94.59 ) , // OBSOLETE - LFK ( 31.16 , -94.72 ) , - GGG ( 32.42 , -94.75 ) , - BJI ( 47.58 , -95.02 ) , - RWF ( 44.47 , -95.13 ) , - OSW ( 37.15 , -95.20 ) , - IAH ( 29.96 , -95.35 ) , - OVR ( 41.17 , -95.74 ) , - MLC ( 34.85 , -95.78 ) , - TUL ( 36.20 , -95.79 ) , - PWE ( 40.20 , -96.21 ) , - PSX ( 28.76 , -96.31 ) , - FSD ( 43.65 , -96.78 ) , - FAR ( 46.75 , -96.85 ) , - DFW ( 32.87 , -97.03 ) , // OBSOLETE - ADM ( 34.21 , -97.17 ) , - GFK ( 47.95 , -97.19 ) , - YWG ( 49.90 , -97.23 ) , - ACT ( 31.66 , -97.27 ) , - BRO ( 25.92 , -97.38 ) , - CRP ( 27.90 , -97.45 ) , - ICT ( 37.75 , -97.58 ) , - OKC ( 35.36 , -97.61 ) , - SLN ( 38.93 , -97.62 ) , - AUS ( 30.30 , -97.70 ) , // OBSOLETE - END ( 36.35 , -97.92 ) , - OBH ( 41.38 , -98.35 ) , - ABR ( 45.42 , -98.37 ) , - SAT ( 29.64 , -98.46 ) , - SPS ( 33.99 , -98.59 ) , - ONL ( 42.47 , -98.69 ) , - LRD ( 27.48 , -99.42 ) , - JCT ( 30.60 , -99.82 ) , - ABI ( 32.48 , -99.86 ) , - GAG ( 36.34 , -99.88 ) , - ANW ( 42.57 , -99.99 ) , - PIR ( 44.40 , -100.17 ) , - HLC ( 39.26 , -100.23 ) , - CDS ( 34.37 , -100.28 ) , - SJT ( 31.38 , -100.46 ) , - MCK ( 40.20 , -100.59 ) , - BIS ( 46.77 , -100.67 ) , - LBF ( 41.13 , -100.72 ) , - GCK ( 37.92 , -100.73 ) , - DLF ( 29.36 , -100.77 ) , - LBL ( 37.04 , -100.97 ) , - MOT ( 48.26 , -101.29 ) , - AMA ( 35.29 , -101.64 ) , - GLD ( 39.39 , -101.69 ) , - DPR ( 45.08 , -101.72 ) , - LBB ( 33.70 , -101.92 ) , - MAF ( 32.02 , -102.18 ) , - LAA ( 38.20 , -102.69 ) , - DIK ( 46.86 , -102.77 ) , - TXO ( 34.50 , -102.84 ) , - SNY ( 41.10 , -102.98 ) , - FST ( 30.95 , -102.98 ) , - RAP ( 43.98 , -103.01 ) , - AKO ( 40.16 , -103.18 ) , - INK ( 31.87 , -103.24 ) , - BFF ( 41.89 , -103.48 ) , - TBE ( 37.27 , -103.60 ) , - TCC ( 35.18 , -103.60 ) , - ISN ( 48.18 , -103.63 ) , - MRF ( 30.30 , -103.95 ) , - PUB ( 38.29 , -104.43 ) , - ROW ( 33.34 , -104.62 ) , // OBSOLETE - DEN ( 39.81 , -104.66 ) , - CYS ( 41.21 , -104.77 ) , - CIM ( 36.49 , -104.87 ) , - LVS ( 35.66 , -105.14 ) , // OBSOLETE - LAR ( 41.33 , -105.72 ) , - ALS ( 37.35 , -105.82 ) , - MLS ( 46.38 , -105.95 ) , - DDY ( 43.09 , -106.28 ) , - ELP ( 31.82 , -106.28 ) , - CZI ( 44.00 , -106.44 ) , - GGW ( 48.22 , -106.63 ) , - ABQ ( 35.04 , -106.82 ) , - DBL ( 39.44 , -106.90 ) , - HBU ( 38.45 , -107.04 ) , - SHR ( 44.84 , -107.06 ) , - TCS ( 33.28 , -107.28 ) , - CHE ( 40.52 , -107.31 ) , - DMN ( 32.28 , -107.60 ) , - YYN ( 50.28 , -107.68 ) , - FMN ( 36.75 , -108.10 ) , // OBSOLETE - BOY ( 43.46 , -108.30 ) , - BIL ( 45.81 , -108.63 ) , - JNC ( 39.06 , -108.79 ) , - DVC ( 37.81 , -108.93 ) , - OCS ( 41.59 , -109.02 ) , - SJN ( 34.42 , -109.14 ) , - SSO ( 32.27 , -109.26 ) , - LWT ( 47.05 , -109.61 ) , - HVR ( 48.54 , -109.77 ) , - BPI ( 42.58 , -110.11 ) , - MTU ( 40.15 , -110.13 ) , - HVE ( 38.42 , -110.70 ) , - YXH ( 50.02 , -110.72 ) , - JAC ( 43.62 , -110.73 ) , - INW ( 35.06 , -110.80 ) , - TUS ( 32.10 , -110.92 ) , - TBC ( 36.12 , -111.27 ) , - GTF ( 47.45 , -111.41 ) , - HLN ( 46.61 , -111.95 ) , - PHX ( 33.43 , -112.02 ) , - SLC ( 40.85 , -111.98 ) , - DBS ( 44.09 , -112.21 ) , - BCE ( 37.69 , -112.30 ) , - MLD ( 42.20 , -112.45 ) , - DRK ( 34.70 , -112.48 ) , - DTA ( 39.30 , -112.51 ) , - DLN ( 45.25 , -112.55 ) , - PIH ( 42.87 , -112.65 ) , - YQL ( 49.63 , -112.80 ) , - PGS ( 35.62 , -113.54 ) , - BVL ( 40.73 , -113.76 ) , - LKT ( 45.02 , -114.08 ) , - FCA ( 48.21 , -114.18 ) , - ILC ( 38.25 , -114.39 ) , - EED ( 34.77 , -114.47 ) , - TWF ( 42.48 , -114.49 ) , - BZA ( 32.77 , -114.60 ) , - ELY ( 39.30 , -114.85 ) , - LAS ( 36.08 , -115.16 ) , - MLP ( 47.46 , -115.65 ) , - YXC ( 49.60 , -115.78 ) , - TRM ( 33.63 , -116.16 ) , - BOI ( 43.55 , -116.19 ) , - DNJ ( 44.77 , -116.21 ) , - HEC ( 34.80 , -116.46 ) , - BTY ( 36.80 , -116.75 ) , - BAM ( 40.57 , -116.92 ) , - MZB ( 32.78 , -117.23 ) , - GEG ( 47.56 , -117.63 ) , - OAL ( 38.00 , -117.77 ) , - BKE ( 44.84 , -117.81 ) , - REO ( 42.59 , -117.87 ) , - LAX ( 33.93 , -118.43 ) , - PDT ( 45.70 , -118.94 ) , - EHF ( 35.48 , -119.10 ) , - EPH ( 47.38 , -119.42 ) , - FMG ( 39.53 , -119.66 ) , - RZS ( 34.51 , -119.77 ) , - CZQ ( 36.88 , -119.82 ) , - YKM ( 46.57 , -120.45 ) , - LKV ( 42.49 , -120.51 ) , - YDC ( 49.47 , -120.52 ) , - MOD ( 37.63 , -120.96 ) , - DSD ( 44.25 , -121.30 ) , - SAC ( 38.44 , -121.55 ) , - SNS ( 36.66 , -121.60 ) , - OAK ( 37.73 , -122.22 ) , - RBL ( 40.10 , -122.24 ) , - SEA ( 47.44 , -122.31 ) , - BLI ( 48.95 , -122.58 ) , // OBSOLETE - PDX ( 45.58 , -122.60 ) , - PYE ( 38.08 , -122.87 ) , - OED ( 42.48 , -122.91 ) , - EUG ( 44.12 , -123.22 ) , - ENI ( 39.05 , -123.27 ) , - ONP ( 44.58 , -124.06 ) , - HQM ( 46.95 , -124.15 ) , - FOT ( 40.67 , -124.23 ) , - TOU ( 48.30 , -124.63 ) , - YQV ( 51.27 , -102.47 ) , - ANN ( 55.05 , -131.57 ) , - LVD ( 56.47 , -133.08 ) , - BKA ( 56.86 , -135.55 ) , - SSR ( 58.17 , -135.25 ) , - JNU ( 58.35 , -134.58 ) , - YAK ( 59.50 , -139.67 ) , - MDO ( 59.45 , -146.30 ) , - JOH ( 60.48 , -146.60 ) , - ODK ( 57.75 , -152.50 ) , - HOM ( 59.65 , -151.48 ) , - ENA ( 60.57 , -151.25 ) , - ANC ( 61.17 , -150.00 ) , - BGQ ( 61.53 , -149.82 ) , - ORT ( 62.97 , -141.93 ) , - GKN ( 62.15 , -145.45 ) , - TKA ( 62.32 , -150.10 ) , - SQA ( 61.10 , -155.63 ) , - DLG ( 59.05 , -158.50 ) , - AKN ( 58.68 , -156.65 ) , - PDN ( 56.95 , -158.65 ) , - CDB ( 55.20 , -162.73 ) , - DUT ( 53.90 , -166.55 ) , - NUD ( 51.88 , -176.65 ) , - SYA ( 52.72 , -174.12 ) , - SPY ( 57.17 , -170.22 ) , - EHM ( 58.66 , -162.07 ) , - HPB ( 61.52 , -166.14 ) , - BET ( 60.78 , -161.83 ) , - ANI ( 61.59 , -159.61 ) , - SMA ( 62.06 , -163.30 ) , - UNK ( 63.88 , -160.80 ) , - ULL ( 63.70 , -170.48 ) , - MCG ( 62.95 , -155.60 ) , - ENN ( 64.55 , -149.07 ) , - FAI ( 64.82 , -147.85 ) , - BIG ( 64.00 , -145.72 ) , - FYU ( 66.57 , -145.25 ) , - BTT ( 66.92 , -151.53 ) , - TAL ( 65.18 , -152.18 ) , - CQR ( 67.50 , -148.47 ) , - SCC ( 70.20 , -148.47 ) , - BTI ( 70.13 , -143.57 ) , - BRW ( 71.28 , -156.77 ) , - GAL ( 64.73 , -156.93 ) , - OME ( 64.52 , -165.45 ) , - OTZ ( 66.88 , -162.60 ) , - WLK ( 66.60 , -160.00 ) , - HSL ( 65.71 , -156.37 ) , - BSF ( 19.76 , -155.39 ) , - UPP ( 20.20 , -155.84 ) , - ITO ( 19.72 , -155.01 ) , - HNL ( 21.33 , -157.93 ) , - OGG ( 20.91 , -156.42 ) , - NDB ( 20.88 , -156.44 ) , - MUE ( 20.00 , -155.67 ) , - NGF ( 21.45 , -157.76 ) , - MKK ( 21.14 , -157.17 ) , - NBS ( 22.04 , -159.79 ) , - CKH ( 21.27 , -157.70 ) , - IAI ( 19.65 , -156.02 ) , - LLD ( 20.77 , -156.97 ) , - LNY ( 20.76 , -156.97 ) , - LIH ( 21.97 , -159.34 ) , - SOK ( 21.90 , -159.53 ) , - // - // Newcomers! These are in the set of VORs now used by AWC for Convective SIGMET bounds, - // but not in (out-of-the-box V5.11.4) $GEMTBL/stns/vors.tbl : - // - RSW ( 26.53 , -81.78 ) , // Lee County VORTAC Fort Myers FL L-VORTAC !? replaces FMY - PZD ( 31.66 , -84.29 ) , // Pecan VORTAC Albany GA H-VORTACW replaces ABY - IIU ( 38.10 , -85.58 ) , // Louisville VORTAC Louisville KY H-VORTAC replaces LOU - HRV ( 29.85 , -90.00 ) , // Harvey VORTAC New Orleans LA H-VORTACW replaces MSY - MCI ( 39.29 , -94.74 ) , // Kansas City VORTAC Kansas City MO H-VORTAC replaces MKC - TTT ( 32.87 , -97.04 ) , // Maverick VOR/DME Dallas-Fort Worth TX H-VORW/DME replaces DFW - CWK ( 30.38 , -97.53 ) , // Centex VORTAC Austin TX H-VORTACW replaces AUS - CME ( 33.34 , -104.62 ) , // Chisum VORTAC Roswell NM H-VORTACW replaces ROW - FTI ( 35.66 , -105.14 ) , // Fort Union VORTAC Las Vegas NM H-VORTACW replaces LVS - RSK ( 36.75 , -108.10 ) , // Rattlesnake VORTAC Farmington NM H-VORTACW replaces FMN - HUH ( 48.95 , -122.58 ) ; // Whatcom VORTAC Bellingham WA H-VORTACW replaces BLI - - private static Log logger = LogFactory.getLog(VOR.class); - - private double latitude; - private double longitude; - - private VOR (double latitude, double longitude) - { - this.latitude = latitude; - this.longitude = longitude; - } - - public double getLatitude() - { - return latitude; - } - - public double getLongitude() - { - return longitude; - } - - public LatLonPoint getLatLonPoint() - { - return new LatLonPoint (latitude, longitude, LatLonPoint.INDEGREES); - } - - private enum Direction { - N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW; - public double getDegrees() { return ordinal() * 22.5; } - } - - private static final double ONE_NM_RADIANS = Math.toRadians (1.0 / 60.0); - - /** - * Given a VOR-relative reference string, returns a LatLonPoint - * (com.raytheon.uf.edex.decodertools.core.LatLonPoint). - * - * @param location A String such as... - * "BOS" - * "20S EMI" - * "30 WNW BUM" - * " 40ENE HUH " - * ...referencing a VOR listed in AC 00-45F - * (Appendix F), optionally preceded by - * distance in nautical miles and 16-point - * compass direction string. - * @return The decoded location as a LatLonPoint; - * null on error (such as unrecognized VOR - * identifier or direction string). - * - */ - public static LatLonPoint getLatLonPoint(String location) { - // Wrap decoding in a try block, in case of exception on - // one ofthe two enum valueOf lookups, or other problems. - try { - location = location.trim(); - // VOR is always last 3 nonblank char of location - String navaid = location.substring(location.length()-3); - LatLonPoint point = VOR.valueOf(navaid).getLatLonPoint(); - // If there's an offset direction/bearing, process it - if (location.length() > 3) { - String u = location.substring(0, location.length()-3); - Pattern p = Pattern.compile("^([0-9]+)\\s*([A-Z]+)"); - Matcher m = p.matcher(u); - if (m.find()) { - String distanceStr = m.group(1); - String bearingStr = m.group(2); - int distanceNM = Integer.parseInt(distanceStr); - double distanceRad = distanceNM * ONE_NM_RADIANS; - // LatLonPoint.positionOf thinks bearing is CCW, not CW... - double bearingDeg = 360.0 - Direction.valueOf(bearingStr).getDegrees(); - double bearingRad = Math.toRadians(bearingDeg); - point = point.positionOf(bearingRad, distanceRad); - } - } - return point; - } - catch (Exception e) { - logger.error("[Error decoding location: " + location + "]"); - return null; - } - } - -} +/** + * + */ +package gov.noaa.nws.ncep.edex.tools.decoder; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +//import com.raytheon.edex.tools.decoder.LatLonPoint; //TO10 +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; //TO11 + +/** + * VOR - A *TEMPORARY* enum class to define some known VORs + * used to define convective SIGMET locations. (See below.) + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 12 Jun 2009  95         B. Hebbard  Initial creation.
+ * 24 Jun 2009  95/132     B. Hebbard  Add getLatLonPoint; move to common plugin
+ * 22 Jul 2009  for 132    B. Hebbard  Port to TO11 until station table avail. EDEX
+ * 
+ * 
+ * + * @author bhebbard + * @version 1.0 + */ +public enum VOR { + + // (From GEMPAK vors.tbl -- for TEMPORARY use only, just until + // this is handled by more general station/location design. + // + // Note these are a SUBSET of the high-altitude VORs in North America + // used by AWC for SIGMET bounding points. It is NOT sufficient + // for lookup in cases where where all VHF NAVAIDs -- or + // even all VORs -- are required [say, for PIREP decoding]) + // + // Lat Lon + YSJ ( 45.32 , -65.88 ) , + HUL ( 46.04 , -67.83 ) , + PQI ( 46.77 , -68.09 ) , + MLT ( 45.58 , -68.52 ) , + BGR ( 44.84 , -68.87 ) , + ACK ( 41.28 , -70.03 ) , + ENE ( 43.43 , -70.61 ) , + BOS ( 42.36 , -70.99 ) , + YQB ( 46.80 , -71.38 ) , + PVD ( 41.72 , -71.43 ) , + CON ( 43.22 , -71.58 ) , + YSC ( 45.43 , -71.68 ) , + HTO ( 40.92 , -72.32 ) , + MPV ( 44.22 , -72.57 ) , + BDL ( 41.94 , -72.69 ) , + PLB ( 44.69 , -73.52 ) , + JFK ( 40.63 , -73.77 ) , + ALB ( 42.75 , -73.80 ) , + CYN ( 39.82 , -74.43 ) , + SAX ( 41.07 , -74.54 ) , + MSS ( 44.91 , -74.72 ) , + SIE ( 39.10 , -74.80 ) , + HNK ( 42.06 , -75.32 ) , + SBY ( 38.35 , -75.52 ) , + YOW ( 45.32 , -75.67 ) , + ETX ( 40.58 , -75.68 ) , + ECG ( 36.25 , -76.18 ) , + SYR ( 43.16 , -76.20 ) , + ORF ( 36.89 , -76.20 ) , + EMI ( 39.50 , -76.98 ) , + HAR ( 40.23 , -77.02 ) , + DCA ( 38.86 , -77.04 ) , + RIC ( 37.50 , -77.32 ) , + CSN ( 38.64 , -77.87 ) , + ILM ( 34.35 , -77.87 ) , + SLT ( 41.51 , -77.97 ) , + PSB ( 40.92 , -77.99 ) , + BUF ( 42.93 , -78.65 ) , + RDU ( 35.87 , -78.78 ) , + JST ( 40.32 , -78.83 ) , + JHW ( 42.19 , -79.12 ) , + LYH ( 37.25 , -79.23 ) , + YYZ ( 43.67 , -79.63 ) , + FLO ( 34.23 , -79.66 ) , + GSO ( 36.05 , -79.98 ) , + CHS ( 32.89 , -80.04 ) , + PBI ( 26.68 , -80.09 ) , + EKN ( 38.92 , -80.10 ) , + EWC ( 40.83 , -80.21 ) , + ERI ( 42.02 , -80.30 ) , + MIA ( 25.80 , -80.30 ) , + VRB ( 27.68 , -80.49 ) , + PSK ( 37.09 , -80.71 ) , + AIR ( 40.02 , -80.82 ) , + CLT ( 35.22 , -80.93 ) , + CAE ( 33.86 , -81.05 ) , + YVV ( 44.75 , -81.10 ) , + SAV ( 32.16 , -81.11 ) , + OMN ( 29.30 , -81.11 ) , + BKW ( 37.78 , -81.12 ) , + ORL ( 28.54 , -81.34 ) , + CRG ( 30.34 , -81.51 ) , + EYW ( 24.59 , -81.80 ) , + FMY ( 26.58 , -81.87 ) , // OBSOLETE + SPA ( 35.03 , -81.93 ) , + HNN ( 38.75 , -82.03 ) , + HMV ( 36.44 , -82.13 ) , + CLE ( 41.42 , -81.85 ) , + IRQ ( 33.71 , -82.16 ) , + AMG ( 31.54 , -82.51 ) , + SRQ ( 27.40 , -82.55 ) , + APE ( 40.15 , -82.59 ) , + PIE ( 27.91 , -82.68 ) , + ECK ( 43.26 , -82.72 ) , + CTY ( 29.60 , -83.05 ) , + ODF ( 34.70 , -83.30 ) , + DXO ( 42.21 , -83.37 ) , + ASP ( 44.45 , -83.39 ) , + MCN ( 32.69 , -83.65 ) , + FNT ( 42.97 , -83.74 ) , + VXV ( 35.90 , -83.89 ) , + ROD ( 40.29 , -84.04 ) , + MBS ( 43.53 , -84.08 ) , + LOZ ( 37.03 , -84.12 ) , + ABY ( 31.65 , -84.30 ) , // OBSOLETE + SSM ( 46.41 , -84.31 ) , + TLH ( 30.56 , -84.37 ) , + ATL ( 33.63 , -84.44 ) , + CVG ( 39.02 , -84.70 ) , + GQO ( 34.96 , -85.15 ) , + FWA ( 40.98 , -85.19 ) , + LGC ( 33.05 , -85.21 ) , + GRR ( 42.79 , -85.50 ) , + TVC ( 44.67 , -85.55 ) , + LOU ( 38.10 , -85.58 ) , // OBSOLETE + MKG ( 43.17 , -86.04 ) , + PMM ( 42.47 , -86.11 ) , + GIJ ( 41.77 , -86.32 ) , + MGM ( 32.22 , -86.32 ) , + IND ( 39.81 , -86.37 ) , + BWG ( 36.93 , -86.44 ) , + BNA ( 36.14 , -86.68 ) , + CEW ( 30.83 , -86.68 ) , + VUZ ( 33.67 , -86.90 ) , + BVT ( 40.56 , -87.07 ) , + TTH ( 39.49 , -87.25 ) , + MSL ( 34.70 , -87.48 ) , + SAW ( 46.36 , -87.40 ) , + PXV ( 37.93 , -87.76 ) , + ORD ( 41.98 , -87.90 ) , + GRB ( 44.56 , -88.19 ) , + BAE ( 43.12 , -88.28 ) , + JOT ( 41.55 , -88.32 ) , + SJI ( 30.73 , -88.36 ) , + IGB ( 33.48 , -88.52 ) , + MEI ( 32.38 , -88.80 ) , + DEC ( 39.74 , -88.86 ) , + YQT ( 48.37 , -89.32 ) , + DYR ( 36.02 , -89.32 ) , + RHI ( 45.63 , -89.45 ) , + BDF ( 41.16 , -89.59 ) , + DLL ( 43.55 , -89.76 ) , + MEM ( 35.06 , -89.98 ) , + LEV ( 29.18 , -90.10 ) , + JAN ( 32.51 , -90.17 ) , + MSY ( 30.00 , -90.27 ) , // OBSOLETE + FAM ( 37.67 , -90.23 ) , + MCB ( 31.30 , -90.26 ) , + SQS ( 33.46 , -90.28 ) , + STL ( 38.86 , -90.48 ) , + DBQ ( 42.40 , -90.71 ) , + ARG ( 36.11 , -90.95 ) , + UIN ( 39.85 , -91.28 ) , + BTR ( 30.48 , -91.30 ) , + ODI ( 43.91 , -91.47 ) , + EAU ( 44.90 , -91.48 ) , + IOW ( 41.52 , -91.61 ) , + MLU ( 32.52 , -92.03 ) , + LIT ( 34.68 , -92.18 ) , + DLH ( 46.80 , -92.20 ) , + COU ( 38.82 , -92.22 ) , + AEX ( 31.26 , -92.50 ) , + IRK ( 40.14 , -92.59 ) , + ELD ( 33.26 , -92.74 ) , + LCH ( 30.14 , -93.11 ) , + MSP ( 44.88 , -93.23 ) , + MCW ( 43.09 , -93.33 ) , + SGF ( 37.36 , -93.33 ) , + INL ( 48.57 , -93.40 ) , + DSM ( 41.44 , -93.65 ) , + EIC ( 32.77 , -93.81 ) , + BRD ( 46.35 , -94.03 ) , + TXK ( 33.51 , -94.07 ) , + RZC ( 36.25 , -94.12 ) , + FSM ( 35.38 , -94.27 ) , + FOD ( 42.61 , -94.29 ) , + BUM ( 38.27 , -94.49 ) , + MKC ( 39.28 , -94.59 ) , // OBSOLETE + LFK ( 31.16 , -94.72 ) , + GGG ( 32.42 , -94.75 ) , + BJI ( 47.58 , -95.02 ) , + RWF ( 44.47 , -95.13 ) , + OSW ( 37.15 , -95.20 ) , + IAH ( 29.96 , -95.35 ) , + OVR ( 41.17 , -95.74 ) , + MLC ( 34.85 , -95.78 ) , + TUL ( 36.20 , -95.79 ) , + PWE ( 40.20 , -96.21 ) , + PSX ( 28.76 , -96.31 ) , + FSD ( 43.65 , -96.78 ) , + FAR ( 46.75 , -96.85 ) , + DFW ( 32.87 , -97.03 ) , // OBSOLETE + ADM ( 34.21 , -97.17 ) , + GFK ( 47.95 , -97.19 ) , + YWG ( 49.90 , -97.23 ) , + ACT ( 31.66 , -97.27 ) , + BRO ( 25.92 , -97.38 ) , + CRP ( 27.90 , -97.45 ) , + ICT ( 37.75 , -97.58 ) , + OKC ( 35.36 , -97.61 ) , + SLN ( 38.93 , -97.62 ) , + AUS ( 30.30 , -97.70 ) , // OBSOLETE + END ( 36.35 , -97.92 ) , + OBH ( 41.38 , -98.35 ) , + ABR ( 45.42 , -98.37 ) , + SAT ( 29.64 , -98.46 ) , + SPS ( 33.99 , -98.59 ) , + ONL ( 42.47 , -98.69 ) , + LRD ( 27.48 , -99.42 ) , + JCT ( 30.60 , -99.82 ) , + ABI ( 32.48 , -99.86 ) , + GAG ( 36.34 , -99.88 ) , + ANW ( 42.57 , -99.99 ) , + PIR ( 44.40 , -100.17 ) , + HLC ( 39.26 , -100.23 ) , + CDS ( 34.37 , -100.28 ) , + SJT ( 31.38 , -100.46 ) , + MCK ( 40.20 , -100.59 ) , + BIS ( 46.77 , -100.67 ) , + LBF ( 41.13 , -100.72 ) , + GCK ( 37.92 , -100.73 ) , + DLF ( 29.36 , -100.77 ) , + LBL ( 37.04 , -100.97 ) , + MOT ( 48.26 , -101.29 ) , + AMA ( 35.29 , -101.64 ) , + GLD ( 39.39 , -101.69 ) , + DPR ( 45.08 , -101.72 ) , + LBB ( 33.70 , -101.92 ) , + MAF ( 32.02 , -102.18 ) , + LAA ( 38.20 , -102.69 ) , + DIK ( 46.86 , -102.77 ) , + TXO ( 34.50 , -102.84 ) , + SNY ( 41.10 , -102.98 ) , + FST ( 30.95 , -102.98 ) , + RAP ( 43.98 , -103.01 ) , + AKO ( 40.16 , -103.18 ) , + INK ( 31.87 , -103.24 ) , + BFF ( 41.89 , -103.48 ) , + TBE ( 37.27 , -103.60 ) , + TCC ( 35.18 , -103.60 ) , + ISN ( 48.18 , -103.63 ) , + MRF ( 30.30 , -103.95 ) , + PUB ( 38.29 , -104.43 ) , + ROW ( 33.34 , -104.62 ) , // OBSOLETE + DEN ( 39.81 , -104.66 ) , + CYS ( 41.21 , -104.77 ) , + CIM ( 36.49 , -104.87 ) , + LVS ( 35.66 , -105.14 ) , // OBSOLETE + LAR ( 41.33 , -105.72 ) , + ALS ( 37.35 , -105.82 ) , + MLS ( 46.38 , -105.95 ) , + DDY ( 43.09 , -106.28 ) , + ELP ( 31.82 , -106.28 ) , + CZI ( 44.00 , -106.44 ) , + GGW ( 48.22 , -106.63 ) , + ABQ ( 35.04 , -106.82 ) , + DBL ( 39.44 , -106.90 ) , + HBU ( 38.45 , -107.04 ) , + SHR ( 44.84 , -107.06 ) , + TCS ( 33.28 , -107.28 ) , + CHE ( 40.52 , -107.31 ) , + DMN ( 32.28 , -107.60 ) , + YYN ( 50.28 , -107.68 ) , + FMN ( 36.75 , -108.10 ) , // OBSOLETE + BOY ( 43.46 , -108.30 ) , + BIL ( 45.81 , -108.63 ) , + JNC ( 39.06 , -108.79 ) , + DVC ( 37.81 , -108.93 ) , + OCS ( 41.59 , -109.02 ) , + SJN ( 34.42 , -109.14 ) , + SSO ( 32.27 , -109.26 ) , + LWT ( 47.05 , -109.61 ) , + HVR ( 48.54 , -109.77 ) , + BPI ( 42.58 , -110.11 ) , + MTU ( 40.15 , -110.13 ) , + HVE ( 38.42 , -110.70 ) , + YXH ( 50.02 , -110.72 ) , + JAC ( 43.62 , -110.73 ) , + INW ( 35.06 , -110.80 ) , + TUS ( 32.10 , -110.92 ) , + TBC ( 36.12 , -111.27 ) , + GTF ( 47.45 , -111.41 ) , + HLN ( 46.61 , -111.95 ) , + PHX ( 33.43 , -112.02 ) , + SLC ( 40.85 , -111.98 ) , + DBS ( 44.09 , -112.21 ) , + BCE ( 37.69 , -112.30 ) , + MLD ( 42.20 , -112.45 ) , + DRK ( 34.70 , -112.48 ) , + DTA ( 39.30 , -112.51 ) , + DLN ( 45.25 , -112.55 ) , + PIH ( 42.87 , -112.65 ) , + YQL ( 49.63 , -112.80 ) , + PGS ( 35.62 , -113.54 ) , + BVL ( 40.73 , -113.76 ) , + LKT ( 45.02 , -114.08 ) , + FCA ( 48.21 , -114.18 ) , + ILC ( 38.25 , -114.39 ) , + EED ( 34.77 , -114.47 ) , + TWF ( 42.48 , -114.49 ) , + BZA ( 32.77 , -114.60 ) , + ELY ( 39.30 , -114.85 ) , + LAS ( 36.08 , -115.16 ) , + MLP ( 47.46 , -115.65 ) , + YXC ( 49.60 , -115.78 ) , + TRM ( 33.63 , -116.16 ) , + BOI ( 43.55 , -116.19 ) , + DNJ ( 44.77 , -116.21 ) , + HEC ( 34.80 , -116.46 ) , + BTY ( 36.80 , -116.75 ) , + BAM ( 40.57 , -116.92 ) , + MZB ( 32.78 , -117.23 ) , + GEG ( 47.56 , -117.63 ) , + OAL ( 38.00 , -117.77 ) , + BKE ( 44.84 , -117.81 ) , + REO ( 42.59 , -117.87 ) , + LAX ( 33.93 , -118.43 ) , + PDT ( 45.70 , -118.94 ) , + EHF ( 35.48 , -119.10 ) , + EPH ( 47.38 , -119.42 ) , + FMG ( 39.53 , -119.66 ) , + RZS ( 34.51 , -119.77 ) , + CZQ ( 36.88 , -119.82 ) , + YKM ( 46.57 , -120.45 ) , + LKV ( 42.49 , -120.51 ) , + YDC ( 49.47 , -120.52 ) , + MOD ( 37.63 , -120.96 ) , + DSD ( 44.25 , -121.30 ) , + SAC ( 38.44 , -121.55 ) , + SNS ( 36.66 , -121.60 ) , + OAK ( 37.73 , -122.22 ) , + RBL ( 40.10 , -122.24 ) , + SEA ( 47.44 , -122.31 ) , + BLI ( 48.95 , -122.58 ) , // OBSOLETE + PDX ( 45.58 , -122.60 ) , + PYE ( 38.08 , -122.87 ) , + OED ( 42.48 , -122.91 ) , + EUG ( 44.12 , -123.22 ) , + ENI ( 39.05 , -123.27 ) , + ONP ( 44.58 , -124.06 ) , + HQM ( 46.95 , -124.15 ) , + FOT ( 40.67 , -124.23 ) , + TOU ( 48.30 , -124.63 ) , + YQV ( 51.27 , -102.47 ) , + ANN ( 55.05 , -131.57 ) , + LVD ( 56.47 , -133.08 ) , + BKA ( 56.86 , -135.55 ) , + SSR ( 58.17 , -135.25 ) , + JNU ( 58.35 , -134.58 ) , + YAK ( 59.50 , -139.67 ) , + MDO ( 59.45 , -146.30 ) , + JOH ( 60.48 , -146.60 ) , + ODK ( 57.75 , -152.50 ) , + HOM ( 59.65 , -151.48 ) , + ENA ( 60.57 , -151.25 ) , + ANC ( 61.17 , -150.00 ) , + BGQ ( 61.53 , -149.82 ) , + ORT ( 62.97 , -141.93 ) , + GKN ( 62.15 , -145.45 ) , + TKA ( 62.32 , -150.10 ) , + SQA ( 61.10 , -155.63 ) , + DLG ( 59.05 , -158.50 ) , + AKN ( 58.68 , -156.65 ) , + PDN ( 56.95 , -158.65 ) , + CDB ( 55.20 , -162.73 ) , + DUT ( 53.90 , -166.55 ) , + NUD ( 51.88 , -176.65 ) , + SYA ( 52.72 , -174.12 ) , + SPY ( 57.17 , -170.22 ) , + EHM ( 58.66 , -162.07 ) , + HPB ( 61.52 , -166.14 ) , + BET ( 60.78 , -161.83 ) , + ANI ( 61.59 , -159.61 ) , + SMA ( 62.06 , -163.30 ) , + UNK ( 63.88 , -160.80 ) , + ULL ( 63.70 , -170.48 ) , + MCG ( 62.95 , -155.60 ) , + ENN ( 64.55 , -149.07 ) , + FAI ( 64.82 , -147.85 ) , + BIG ( 64.00 , -145.72 ) , + FYU ( 66.57 , -145.25 ) , + BTT ( 66.92 , -151.53 ) , + TAL ( 65.18 , -152.18 ) , + CQR ( 67.50 , -148.47 ) , + SCC ( 70.20 , -148.47 ) , + BTI ( 70.13 , -143.57 ) , + BRW ( 71.28 , -156.77 ) , + GAL ( 64.73 , -156.93 ) , + OME ( 64.52 , -165.45 ) , + OTZ ( 66.88 , -162.60 ) , + WLK ( 66.60 , -160.00 ) , + HSL ( 65.71 , -156.37 ) , + BSF ( 19.76 , -155.39 ) , + UPP ( 20.20 , -155.84 ) , + ITO ( 19.72 , -155.01 ) , + HNL ( 21.33 , -157.93 ) , + OGG ( 20.91 , -156.42 ) , + NDB ( 20.88 , -156.44 ) , + MUE ( 20.00 , -155.67 ) , + NGF ( 21.45 , -157.76 ) , + MKK ( 21.14 , -157.17 ) , + NBS ( 22.04 , -159.79 ) , + CKH ( 21.27 , -157.70 ) , + IAI ( 19.65 , -156.02 ) , + LLD ( 20.77 , -156.97 ) , + LNY ( 20.76 , -156.97 ) , + LIH ( 21.97 , -159.34 ) , + SOK ( 21.90 , -159.53 ) , + // + // Newcomers! These are in the set of VORs now used by AWC for Convective SIGMET bounds, + // but not in (out-of-the-box V5.11.4) $GEMTBL/stns/vors.tbl : + // + RSW ( 26.53 , -81.78 ) , // Lee County VORTAC Fort Myers FL L-VORTAC !? replaces FMY + PZD ( 31.66 , -84.29 ) , // Pecan VORTAC Albany GA H-VORTACW replaces ABY + IIU ( 38.10 , -85.58 ) , // Louisville VORTAC Louisville KY H-VORTAC replaces LOU + HRV ( 29.85 , -90.00 ) , // Harvey VORTAC New Orleans LA H-VORTACW replaces MSY + MCI ( 39.29 , -94.74 ) , // Kansas City VORTAC Kansas City MO H-VORTAC replaces MKC + TTT ( 32.87 , -97.04 ) , // Maverick VOR/DME Dallas-Fort Worth TX H-VORW/DME replaces DFW + CWK ( 30.38 , -97.53 ) , // Centex VORTAC Austin TX H-VORTACW replaces AUS + CME ( 33.34 , -104.62 ) , // Chisum VORTAC Roswell NM H-VORTACW replaces ROW + FTI ( 35.66 , -105.14 ) , // Fort Union VORTAC Las Vegas NM H-VORTACW replaces LVS + RSK ( 36.75 , -108.10 ) , // Rattlesnake VORTAC Farmington NM H-VORTACW replaces FMN + HUH ( 48.95 , -122.58 ) ; // Whatcom VORTAC Bellingham WA H-VORTACW replaces BLI + + private static Log logger = LogFactory.getLog(VOR.class); + + private double latitude; + private double longitude; + + private VOR (double latitude, double longitude) + { + this.latitude = latitude; + this.longitude = longitude; + } + + public double getLatitude() + { + return latitude; + } + + public double getLongitude() + { + return longitude; + } + + public LatLonPoint getLatLonPoint() + { + return new LatLonPoint (latitude, longitude, LatLonPoint.INDEGREES); + } + + private enum Direction { + N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW; + public double getDegrees() { return ordinal() * 22.5; } + } + + private static final double ONE_NM_RADIANS = Math.toRadians (1.0 / 60.0); + + /** + * Given a VOR-relative reference string, returns a LatLonPoint + * (com.raytheon.uf.edex.decodertools.core.LatLonPoint). + * + * @param location A String such as... + * "BOS" + * "20S EMI" + * "30 WNW BUM" + * " 40ENE HUH " + * ...referencing a VOR listed in AC 00-45F + * (Appendix F), optionally preceded by + * distance in nautical miles and 16-point + * compass direction string. + * @return The decoded location as a LatLonPoint; + * null on error (such as unrecognized VOR + * identifier or direction string). + * + */ + public static LatLonPoint getLatLonPoint(String location) { + // Wrap decoding in a try block, in case of exception on + // one ofthe two enum valueOf lookups, or other problems. + try { + location = location.trim(); + // VOR is always last 3 nonblank char of location + String navaid = location.substring(location.length()-3); + LatLonPoint point = VOR.valueOf(navaid).getLatLonPoint(); + // If there's an offset direction/bearing, process it + if (location.length() > 3) { + String u = location.substring(0, location.length()-3); + Pattern p = Pattern.compile("^([0-9]+)\\s*([A-Z]+)"); + Matcher m = p.matcher(u); + if (m.find()) { + String distanceStr = m.group(1); + String bearingStr = m.group(2); + int distanceNM = Integer.parseInt(distanceStr); + double distanceRad = distanceNM * ONE_NM_RADIANS; + // LatLonPoint.positionOf thinks bearing is CCW, not CW... + double bearingDeg = 360.0 - Direction.valueOf(bearingStr).getDegrees(); + double bearingRad = Math.toRadians(bearingDeg); + point = point.positionOf(bearingRad, distanceRad); + } + } + return point; + } + catch (Exception e) { + logger.error("[Error decoding location: " + location + "]"); + return null; + } + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/package-info.java old mode 100755 new mode 100644 index bd90a7c646..44b8eecc06 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/tools/decoder/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.tools.decoder; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.tools.decoder; diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/UtilN.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/UtilN.java old mode 100755 new mode 100644 index 0d967ca0a4..ac9ad3c11c --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/UtilN.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/UtilN.java @@ -1,122 +1,122 @@ -/* - * - * Util - * - * This java class contains edex generic utility methods for use. - * - * T. Lee 11/2008 Creation - * T. Lee 3/2009 Fixed roll-over cases; added String functions - * T. Lee 4/2009 Added date to the base time - * T. Lee - *
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    	Engineer    Description
- * ------------ ---------- 	----------- --------------------------
- * 11/2008		14			T. Lee		Creation
- *  3/2009		14			T. Lee		Fixed roll-over cases; added String functions
- *  4/2009		14			T. Lee		Added date to the base time
- *  5/2009		128			T. Lee		Used UTC in findDataTime
- * 
- * - * @author T.Lee - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.util; - -import java.util.Calendar; -import java.util.TimeZone; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.raytheon.edex.util.Util; - -public class UtilN { - private static final Log logger = LogFactory.getLog(UtilN.class); - - /** - * Constructor - */ - public UtilN() { - - } - /** - * Convert a string in ddhhmm format to a standard {@link Calendar} format where - * ddhhmm is the GMT format while the standard time is in Calendar format with - * Year and Month information. Usage: ddhhmm is the issue time whereas utcTime - * can be the MDN time. The former comes "after" the latter. - * - * @parm ddhhmm day-hour-minute in GMT - * @parm local Time UTC time in Calendar - */ - public static Calendar findDataTime (String ddhhmm, Calendar utcTime) { - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); ; - if ( utcTime == null ) { - try { - return Util.findCurrentTime(ddhhmm); - } catch (Exception e) { - if ( logger.isInfoEnabled()) { - logger.info( " Error in processing MND time; return current time "); - } - return cal; - } - - } else { - int iDay = Integer.parseInt(ddhhmm.substring(0, 2).trim()); - int iHour = Integer.parseInt(ddhhmm.substring(2, 4).trim()); - int iMinute = Integer.parseInt(ddhhmm.substring(4, 6).trim()); - int iMonth = utcTime.get(Calendar.MONTH); - int iYear = utcTime.get(Calendar.YEAR); - - /* - * adjust the month and year for roll-over situations - */ - if (iDay < utcTime.get(Calendar.DAY_OF_MONTH) ) { - iMonth++; - if ( iMonth == 12 ) { - iMonth = Calendar.JANUARY; - iYear++; - } - } - cal.set(iYear,iMonth,iDay,iHour,iMinute); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - return cal; - } - } - - /** - * Remove the leading spaces and tabs in a string. - */ - public static String removeLeadingWhiteSpaces (String str) { - int i; - for ( i = 0; i < str.length(); i++ ) { - if ( !Character.isWhitespace(str.charAt(i))) { - break; - } - } - return str.substring(i); - } - - /** - * Remove multiple white spaces in a string. - */ - public static String removeExtraWhiteSpaces (String str) { - StringBuffer sb = new StringBuffer(); - int i; - char first = str.charAt(0); - char second; - for ( i = 1; i < str.length(); i++ ) { - second = str.charAt(i); - if ( !Character.isWhitespace(first) || !Character.isWhitespace(second)) { - sb.append(first); - first = second; - } - if ( i == ( str.length()-1) ) { - sb.append(second); - } - } - return sb.toString(); - } -} +/* + * + * Util + * + * This java class contains edex generic utility methods for use. + * + * T. Lee 11/2008 Creation + * T. Lee 3/2009 Fixed roll-over cases; added String functions + * T. Lee 4/2009 Added date to the base time + * T. Lee + *
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    	Engineer    Description
+ * ------------ ---------- 	----------- --------------------------
+ * 11/2008		14			T. Lee		Creation
+ *  3/2009		14			T. Lee		Fixed roll-over cases; added String functions
+ *  4/2009		14			T. Lee		Added date to the base time
+ *  5/2009		128			T. Lee		Used UTC in findDataTime
+ * 
+ * + * @author T.Lee + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.util; + +import java.util.Calendar; +import java.util.TimeZone; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import com.raytheon.edex.util.Util; + +public class UtilN { + private static final Log logger = LogFactory.getLog(UtilN.class); + + /** + * Constructor + */ + public UtilN() { + + } + /** + * Convert a string in ddhhmm format to a standard {@link Calendar} format where + * ddhhmm is the GMT format while the standard time is in Calendar format with + * Year and Month information. Usage: ddhhmm is the issue time whereas utcTime + * can be the MDN time. The former comes "after" the latter. + * + * @parm ddhhmm day-hour-minute in GMT + * @parm local Time UTC time in Calendar + */ + public static Calendar findDataTime (String ddhhmm, Calendar utcTime) { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); ; + if ( utcTime == null ) { + try { + return Util.findCurrentTime(ddhhmm); + } catch (Exception e) { + if ( logger.isInfoEnabled()) { + logger.info( " Error in processing MND time; return current time "); + } + return cal; + } + + } else { + int iDay = Integer.parseInt(ddhhmm.substring(0, 2).trim()); + int iHour = Integer.parseInt(ddhhmm.substring(2, 4).trim()); + int iMinute = Integer.parseInt(ddhhmm.substring(4, 6).trim()); + int iMonth = utcTime.get(Calendar.MONTH); + int iYear = utcTime.get(Calendar.YEAR); + + /* + * adjust the month and year for roll-over situations + */ + if (iDay < utcTime.get(Calendar.DAY_OF_MONTH) ) { + iMonth++; + if ( iMonth == 12 ) { + iMonth = Calendar.JANUARY; + iYear++; + } + } + cal.set(iYear,iMonth,iDay,iHour,iMinute); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal; + } + } + + /** + * Remove the leading spaces and tabs in a string. + */ + public static String removeLeadingWhiteSpaces (String str) { + int i; + for ( i = 0; i < str.length(); i++ ) { + if ( !Character.isWhitespace(str.charAt(i))) { + break; + } + } + return str.substring(i); + } + + /** + * Remove multiple white spaces in a string. + */ + public static String removeExtraWhiteSpaces (String str) { + StringBuffer sb = new StringBuffer(); + int i; + char first = str.charAt(0); + char second; + for ( i = 1; i < str.length(); i++ ) { + second = str.charAt(i); + if ( !Character.isWhitespace(first) || !Character.isWhitespace(second)) { + sb.append(first); + first = second; + } + if ( i == ( str.length()-1) ) { + sb.append(second); + } + } + return sb.toString(); + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/package-info.java old mode 100755 new mode 100644 index 6bd08cd08a..56ea3b8542 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/idftLoc.xml b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/idftLoc.xml old mode 100755 new mode 100644 index e8c90fc54d..bf4bde2cec --- a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/idftLoc.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/idftLoc.xml @@ -1,1868 +1,1868 @@ - - - - - 0001 - 000001 - POINT 1 - 48.88 - -60.02 - 0 - 0 - - - 0002 - 000002 - POINT 2 - 46.24 - -51.39 - 0 - 0 - - - 0003 - 000003 - POINT 3 - 54.46 - -80.00 - 0 - 0 - - - 0004 - 000004 - POINT 4 - 50.58 - -53.43 - 0 - 0 - - - 0005 - 000005 - POINT 5 - 49.02 - -49.04 - 0 - 0 - - - 0006 - 000006 - POINT 6 - 47.27 - -45.01 - 0 - 0 - - - 0007 - 000007 - POINT 7 - 57.63 - -86.34 - 0 - 0 - - - 0008 - 000008 - POINT 8 - 57.82 - -80.00 - 0 - 0 - - - 0009 - 000009 - POINT 9 - 56.18 - -61.57 - 0 - 0 - - - 0010 - 000010 - POINT 10 - 54.97 - -56.04 - 0 - 0 - - - 0011 - 000011 - POINT 11 - 53.48 - -50.95 - 0 - 0 - - - 0012 - 000012 - POINT 12 - 51.76 - -46.31 - 0 - 0 - - - 0013 - 000013 - POINT 13 - 49.86 - -42.13 - 0 - 0 - - - 0014 - 000014 - POINT 14 - 60.39 - -94.04 - 0 - 0 - - - 0015 - 000015 - POINT 15 - 61.03 - -87.13 - 0 - 0 - - - 0016 - 000016 - POINT 16 - 61.24 - -80.00 - 0 - 0 - - - 0017 - 000017 - POINT 17 - 61.03 - -72.88 - 0 - 0 - - - 0018 - 000018 - POINT 18 - 60.39 - -65.96 - 0 - 0 - - - 0019 - 000019 - POINT 19 - 59.37 - -59.44 - 0 - 0 - - - 0020 - 000020 - POINT 20 - 58.01 - -53.43 - 0 - 0 - - - 0021 - 000021 - POINT 21 - 56.36 - -47.99 - 0 - 0 - - - 0022 - 000022 - POINT 22 - 54.46 - -43.13 - 0 - 0 - - - 0023 - 000023 - POINT 23 - 64.46 - -88.13 - 0 - 0 - - - 0024 - 000024 - POINT 24 - 64.71 - -80.00 - 0 - 0 - - - 0025 - 000025 - POINT 25 - 64.46 - -71.87 - 0 - 0 - - - 0026 - 000026 - POINT 26 - 63.74 - -64.05 - 0 - 0 - - - 0027 - 000027 - POINT 27 - 62.57 - -56.80 - 0 - 0 - - - 0028 - 000028 - POINT 28 - 61.03 - -50.26 - 0 - 0 - - - 0029 - 000029 - POINT 29 - 59.18 - -44.46 - 0 - 0 - - - 0030 - 000030 - POINT 30 - 57.08 - -39.40 - 0 - 0 - - - 0031 - 000031 - POINT 31 - 67.08 - -98.43 - 0 - 0 - - - 0032 - 000032 - POINT 32 - 67.94 - -89.46 - 0 - 0 - - - 0033 - 000033 - POINT 33 - 68.23 - -80.00 - 0 - 0 - - - 0034 - 000034 - POINT 34 - 67.08 - -61.57 - 0 - 0 - - - 0035 - 000035 - POINT 35 - 65.73 - -53.43 - 0 - 0 - - - 0036 - 000036 - POINT 36 - 63.98 - -46.31 - 0 - 0 - - - 0037 - 000037 - POINT 37 - 61.90 - -40.19 - 0 - 0 - - - 0038 - 000038 - POINT 38 - 59.58 - -35.00 - 0 - 0 - - - 0039 - 000039 - POINT 39 - 68.83 - -110.96 - 0 - 0 - - - 0040 - 000040 - POINT 40 - 70.42 - -101.80 - 0 - 0 - - - 0041 - 000041 - POINT 41 - 71.44 - -91.31 - 0 - 0 - - - 0042 - 000042 - POINT 42 - 71.79 - -80.00 - 0 - 0 - - - 0043 - 000043 - POINT 43 - 71.44 - -68.69 - 0 - 0 - - - 0044 - 000044 - POINT 44 - 70.42 - -58.20 - 0 - 0 - - - 0045 - 000045 - POINT 45 - 64.46 - -35.00 - 0 - 0 - - - 0046 - 000046 - POINT 46 - 61.90 - -29.81 - 0 - 0 - - - 0047 - 000047 - POINT 47 - 69.45 - -125.00 - 0 - 0 - - - 0048 - 000048 - POINT 48 - 71.79 - -116.87 - 0 - 0 - - - 0049 - 000049 - POINT 49 - 73.69 - -106.57 - 0 - 0 - - - 0050 - 000050 - POINT 50 - 74.95 - -94.04 - 0 - 0 - - - 0051 - 000051 - POINT 51 - 75.39 - -80.00 - 0 - 0 - - - 0052 - 000052 - POINT 52 - 74.95 - -65.96 - 0 - 0 - - - 0053 - 000053 - POINT 53 - 73.69 - -53.43 - 0 - 0 - - - 0054 - 000054 - POINT 54 - 66.81 - -28.66 - 0 - 0 - - - 0055 - 000055 - POINT 55 - 63.98 - -23.69 - 0 - 0 - - - 0056 - 000056 - POINT 56 - 68.83 - -139.04 - 0 - 0 - - - 0057 - 000057 - POINT 57 - 71.79 - -133.13 - 0 - 0 - - - 0058 - 000058 - POINT 58 - 74.51 - -125.00 - 0 - 0 - - - 0059 - 000059 - POINT 59 - 76.82 - -113.69 - 0 - 0 - - - 0060 - 000060 - POINT 60 - 78.43 - -98.43 - 0 - 0 - - - 0061 - 000061 - POINT 61 - 79.02 - -80.00 - 0 - 0 - - - 0062 - 000062 - POINT 62 - 71.79 - -26.87 - 0 - 0 - - - 0063 - 000063 - POINT 63 - 68.83 - -20.96 - 0 - 0 - - - 0064 - 000064 - POINT 64 - 65.73 - -16.57 - 0 - 0 - - - 0065 - 000065 - POINT 65 - 62.57 - -13.20 - 0 - 0 - - - 0066 - 000066 - POINT 66 - 70.42 - -148.20 - 0 - 0 - - - 0067 - 000067 - POINT 67 - 73.69 - -143.44 - 0 - 0 - - - 0068 - 000068 - POINT 68 - 76.82 - -136.31 - 0 - 0 - - - 0069 - 000069 - POINT 69 - 79.64 - -125.00 - 0 - 0 - - - 0070 - 000070 - POINT 70 - 81.80 - -106.57 - 0 - 0 - - - 0071 - 000071 - POINT 71 - 82.67 - -80.00 - 0 - 0 - - - 0072 - 000072 - POINT 72 - 81.80 - -53.43 - 0 - 0 - - - 0073 - 000073 - POINT 73 - 76.82 - -23.69 - 0 - 0 - - - 0074 - 000074 - POINT 74 - 73.69 - -16.57 - 0 - 0 - - - 0075 - 000075 - POINT 75 - 70.42 - -11.80 - 0 - 0 - - - 0076 - 000076 - POINT 76 - 67.08 - -8.43 - 0 - 0 - - - 0077 - 000077 - POINT 77 - 54.30 - -164.29 - 0 - 0 - - - 0078 - 000078 - POINT 78 - 57.63 - -163.66 - 0 - 0 - - - 0079 - 000079 - POINT 79 - 61.03 - -162.88 - 0 - 0 - - - 0080 - 000080 - POINT 80 - 64.46 - -161.87 - 0 - 0 - - - 0081 - 000081 - POINT 81 - 67.94 - -160.54 - 0 - 0 - - - 0082 - 000082 - POINT 82 - 71.44 - -158.69 - 0 - 0 - - - 0083 - 000083 - POINT 83 - 74.95 - -155.96 - 0 - 0 - - - 0084 - 000084 - POINT 84 - 78.43 - -151.57 - 0 - 0 - - - 0085 - 000085 - POINT 85 - 81.80 - -143.44 - 0 - 0 - - - 0086 - 000086 - POINT 86 - 84.81 - -125.00 - 0 - 0 - - - 0087 - 000087 - POINT 87 - 86.33 - -80.00 - 0 - 0 - - - 0088 - 000088 - POINT 88 - 84.81 - -35.00 - 0 - 0 - - - 0089 - 000089 - POINT 89 - 81.80 - -16.57 - 0 - 0 - - - 0090 - 000090 - POINT 90 - 78.43 - -8.43 - 0 - 0 - - - 0091 - 000091 - POINT 91 - 74.95 - -4.04 - 0 - 0 - - - 0092 - 000092 - POINT 92 - 71.44 - -1.31 - 0 - 0 - - - 0093 - 000093 - POINT 93 - 54.46 - -170.00 - 0 - 0 - - - 0094 - 000094 - POINT 94 - 57.82 - -170.00 - 0 - 0 - - - 0095 - 000095 - POINT 95 - 61.24 - -170.00 - 0 - 0 - - - 0096 - 000096 - POINT 96 - 64.71 - -170.00 - 0 - 0 - - - 0097 - 000097 - POINT 97 - 68.23 - -170.00 - 0 - 0 - - - 0098 - 000098 - POINT 98 - 71.79 - -170.00 - 0 - 0 - - - 0099 - 000099 - POINT 99 - 75.39 - -170.00 - 0 - 0 - - - 0100 - 000100 - POINT 100 - 79.02 - -170.00 - 0 - 0 - - - 0101 - 000101 - POINT 101 - 82.67 - -170.00 - 0 - 0 - - - 0102 - 000102 - POINT 102 - 86.33 - -170.00 - 0 - 0 - - - 0103 - 000103 - POINT 103 - 90.00 - -80.00 - 0 - 0 - - - 0104 - 000104 - POINT 104 - 86.33 - 10.00 - 0 - 0 - - - 0105 - 000105 - POINT 105 - 82.67 - 10.00 - 0 - 0 - - - 0106 - 000106 - POINT 106 - 79.02 - 10.00 - 0 - 0 - - - 0107 - 000107 - POINT 107 - 75.39 - 10.00 - 0 - 0 - - - 0108 - 000108 - POINT 108 - 71.79 - 10.00 - 0 - 0 - - - 0109 - 000109 - POINT 109 - 57.82 - 10.00 - 0 - 0 - - - 0110 - 000110 - POINT 110 - 54.46 - 10.00 - 0 - 0 - - - 0111 - 000111 - POINT 111 - 54.30 - -175.71 - 0 - 0 - - - 0112 - 000112 - POINT 112 - 57.63 - -176.34 - 0 - 0 - - - 0113 - 000113 - POINT 113 - 61.03 - -177.13 - 0 - 0 - - - 0114 - 000114 - POINT 114 - 64.46 - -178.13 - 0 - 0 - - - 0115 - 000115 - POINT 115 - 67.94 - -179.46 - 0 - 0 - - - 0116 - 000116 - POINT 116 - 71.44 - 178.69 - 0 - 0 - - - 0117 - 000117 - POINT 117 - 74.95 - 175.96 - 0 - 0 - - - 0118 - 000118 - POINT 118 - 78.43 - 171.57 - 0 - 0 - - - 0119 - 000119 - POINT 119 - 81.80 - 163.44 - 0 - 0 - - - 0120 - 000120 - POINT 120 - 84.81 - 145.00 - 0 - 0 - - - 0121 - 000121 - POINT 121 - 86.33 - 100.00 - 0 - 0 - - - 0122 - 000122 - POINT 122 - 84.81 - 55.00 - 0 - 0 - - - 0123 - 000123 - POINT 123 - 81.80 - 36.57 - 0 - 0 - - - 0124 - 000124 - POINT 124 - 78.43 - 28.44 - 0 - 0 - - - 0125 - 000125 - POINT 125 - 74.95 - 24.04 - 0 - 0 - - - 0126 - 000126 - POINT 126 - 71.44 - 21.31 - 0 - 0 - - - 0127 - 000127 - POINT 127 - 61.03 - 17.13 - 0 - 0 - - - 0128 - 000128 - POINT 128 - 57.63 - 16.34 - 0 - 0 - - - 0129 - 000129 - POINT 129 - 54.30 - 15.71 - 0 - 0 - - - 0130 - 000130 - POINT 130 - 53.80 - 178.69 - 0 - 0 - - - 0131 - 000131 - POINT 131 - 57.08 - 177.47 - 0 - 0 - - - 0132 - 000132 - POINT 132 - 60.39 - 175.96 - 0 - 0 - - - 0133 - 000133 - POINT 133 - 70.42 - 168.20 - 0 - 0 - - - 0134 - 000134 - POINT 134 - 73.69 - 163.44 - 0 - 0 - - - 0135 - 000135 - POINT 135 - 76.82 - 156.31 - 0 - 0 - - - 0136 - 000136 - POINT 136 - 79.64 - 145.00 - 0 - 0 - - - 0137 - 000137 - POINT 137 - 81.80 - 126.57 - 0 - 0 - - - 0138 - 000138 - POINT 138 - 82.67 - 100.00 - 0 - 0 - - - 0139 - 000139 - POINT 139 - 81.80 - 73.44 - 0 - 0 - - - 0140 - 000140 - POINT 140 - 79.64 - 55.00 - 0 - 0 - - - 0141 - 000141 - POINT 141 - 76.82 - 43.69 - 0 - 0 - - - 0142 - 000142 - POINT 142 - 73.69 - 36.57 - 0 - 0 - - - 0143 - 000143 - POINT 143 - 70.42 - 31.80 - 0 - 0 - - - 0144 - 000144 - POINT 144 - 63.74 - 25.95 - 0 - 0 - - - 0145 - 000145 - POINT 145 - 60.39 - 24.04 - 0 - 0 - - - 0146 - 000146 - POINT 146 - 57.08 - 22.53 - 0 - 0 - - - 0147 - 000147 - POINT 147 - 56.18 - 171.57 - 0 - 0 - - - 0148 - 000148 - POINT 148 - 59.37 - 169.44 - 0 - 0 - - - 0149 - 000149 - POINT 149 - 71.79 - 153.13 - 0 - 0 - - - 0150 - 000150 - POINT 150 - 74.51 - 145.00 - 0 - 0 - - - 0151 - 000151 - POINT 151 - 76.82 - 133.69 - 0 - 0 - - - 0152 - 000152 - POINT 152 - 78.43 - 118.44 - 0 - 0 - - - 0153 - 000153 - POINT 153 - 79.02 - 100.00 - 0 - 0 - - - 0154 - 000154 - POINT 154 - 78.43 - 81.57 - 0 - 0 - - - 0155 - 000155 - POINT 155 - 76.82 - 66.31 - 0 - 0 - - - 0156 - 000156 - POINT 156 - 74.51 - 55.00 - 0 - 0 - - - 0157 - 000157 - POINT 157 - 71.79 - 46.87 - 0 - 0 - - - 0158 - 000158 - POINT 158 - 68.83 - 40.96 - 0 - 0 - - - 0159 - 000159 - POINT 159 - 65.73 - 36.57 - 0 - 0 - - - 0160 - 000160 - POINT 160 - 59.37 - 30.56 - 0 - 0 - - - 0161 - 000161 - POINT 161 - 54.97 - 166.04 - 0 - 0 - - - 0162 - 000162 - POINT 162 - 58.01 - 163.44 - 0 - 0 - - - 0163 - 000163 - POINT 163 - 61.03 - 160.26 - 0 - 0 - - - 0164 - 000164 - POINT 164 - 71.79 - 136.87 - 0 - 0 - - - 0165 - 000165 - POINT 165 - 73.69 - 126.57 - 0 - 0 - - - 0166 - 000166 - POINT 166 - 74.95 - 114.04 - 0 - 0 - - - 0167 - 000167 - POINT 167 - 74.95 - 85.96 - 0 - 0 - - - 0168 - 000168 - POINT 168 - 73.69 - 73.44 - 0 - 0 - - - 0169 - 000169 - POINT 169 - 71.79 - 63.13 - 0 - 0 - - - 0170 - 000170 - POINT 170 - 69.45 - 55.00 - 0 - 0 - - - 0171 - 000171 - POINT 171 - 66.81 - 48.66 - 0 - 0 - - - 0172 - 000172 - POINT 172 - 45.87 - 28.44 - 0 - 0 - - - 0173 - 000173 - POINT 173 - 42.90 - 27.10 - 0 - 0 - - - 0174 - 000174 - POINT 174 - 53.48 - 160.95 - 0 - 0 - - - 0175 - 000175 - POINT 175 - 59.18 - 154.46 - 0 - 0 - - - 0176 - 000176 - POINT 176 - 70.42 - 78.20 - 0 - 0 - - - 0177 - 000177 - POINT 177 - 68.83 - 69.04 - 0 - 0 - - - 0178 - 000178 - POINT 178 - 66.81 - 61.34 - 0 - 0 - - - 0179 - 000179 - POINT 179 - 44.77 - 32.62 - 0 - 0 - - - 0180 - 000180 - POINT 180 - 41.89 - 31.04 - 0 - 0 - - - 0181 - 000181 - POINT 181 - 49.02 - 159.04 - 0 - 0 - - - 0182 - 000182 - POINT 182 - 51.76 - 156.31 - 0 - 0 - - - 0183 - 000183 - POINT 183 - 54.46 - 153.13 - 0 - 0 - - - 0184 - 000184 - POINT 184 - 57.08 - 149.40 - 0 - 0 - - - 0185 - 000185 - POINT 185 - 59.58 - 145.00 - 0 - 0 - - - 0186 - 000186 - POINT 186 - 46.24 - 38.61 - 0 - 0 - - - 0187 - 000187 - POINT 187 - 43.47 - 36.57 - 0 - 0 - - - 0188 - 000188 - POINT 188 - 47.27 - 155.01 - 0 - 0 - - - 0189 - 000189 - POINT 189 - 49.86 - 152.13 - 0 - 0 - - - 0190 - 000190 - POINT 190 - 52.38 - 148.81 - 0 - 0 - - - 0191 - 000191 - POINT 191 - 54.80 - 145.00 - 0 - 0 - - - 0192 - 000192 - POINT 192 - 57.08 - 140.60 - 0 - 0 - - - 0193 - 000193 - POINT 193 - 45.37 - 151.34 - 0 - 0 - - - 0194 - 000194 - POINT 194 - 47.80 - 148.37 - 0 - 0 - - - 0195 - 000195 - POINT 195 - 50.14 - 145.00 - 0 - 0 - - - 0196 - 000196 - POINT 196 - 52.38 - 141.19 - 0 - 0 - - - 0197 - 000197 - POINT 197 - 54.46 - 136.87 - 0 - 0 - - - 0198 - 000198 - POINT 198 - 43.35 - 148.01 - 0 - 0 - - - 0199 - 000199 - POINT 199 - 45.62 - 145.00 - 0 - 0 - - - 0200 - 000200 - POINT 200 - 47.80 - 141.63 - 0 - 0 - - - 0201 - 000201 - POINT 201 - 45.37 - 138.66 - 0 - 0 - - - 0202 - 000202 - POINT 202 - 42.90 - 136.03 - 0 - 0 - - - 0203 - 000203 - POINT 203 - 40.39 - 133.69 - 0 - 0 - - - 0204 - 000204 - POINT 204 - 42.00 - 130.26 - 0 - 0 - - - 0205 - 000205 - POINT 205 - 39.36 - 128.30 - 0 - 0 - - - 0206 - 000206 - POINT 206 - 37.96 - 123.20 - 0 - 0 - - - 0207 - 000207 - POINT 207 - 39.05 - 119.65 - 0 - 0 - - + + + + + 0001 + 000001 + POINT 1 + 48.88 + -60.02 + 0 + 0 + + + 0002 + 000002 + POINT 2 + 46.24 + -51.39 + 0 + 0 + + + 0003 + 000003 + POINT 3 + 54.46 + -80.00 + 0 + 0 + + + 0004 + 000004 + POINT 4 + 50.58 + -53.43 + 0 + 0 + + + 0005 + 000005 + POINT 5 + 49.02 + -49.04 + 0 + 0 + + + 0006 + 000006 + POINT 6 + 47.27 + -45.01 + 0 + 0 + + + 0007 + 000007 + POINT 7 + 57.63 + -86.34 + 0 + 0 + + + 0008 + 000008 + POINT 8 + 57.82 + -80.00 + 0 + 0 + + + 0009 + 000009 + POINT 9 + 56.18 + -61.57 + 0 + 0 + + + 0010 + 000010 + POINT 10 + 54.97 + -56.04 + 0 + 0 + + + 0011 + 000011 + POINT 11 + 53.48 + -50.95 + 0 + 0 + + + 0012 + 000012 + POINT 12 + 51.76 + -46.31 + 0 + 0 + + + 0013 + 000013 + POINT 13 + 49.86 + -42.13 + 0 + 0 + + + 0014 + 000014 + POINT 14 + 60.39 + -94.04 + 0 + 0 + + + 0015 + 000015 + POINT 15 + 61.03 + -87.13 + 0 + 0 + + + 0016 + 000016 + POINT 16 + 61.24 + -80.00 + 0 + 0 + + + 0017 + 000017 + POINT 17 + 61.03 + -72.88 + 0 + 0 + + + 0018 + 000018 + POINT 18 + 60.39 + -65.96 + 0 + 0 + + + 0019 + 000019 + POINT 19 + 59.37 + -59.44 + 0 + 0 + + + 0020 + 000020 + POINT 20 + 58.01 + -53.43 + 0 + 0 + + + 0021 + 000021 + POINT 21 + 56.36 + -47.99 + 0 + 0 + + + 0022 + 000022 + POINT 22 + 54.46 + -43.13 + 0 + 0 + + + 0023 + 000023 + POINT 23 + 64.46 + -88.13 + 0 + 0 + + + 0024 + 000024 + POINT 24 + 64.71 + -80.00 + 0 + 0 + + + 0025 + 000025 + POINT 25 + 64.46 + -71.87 + 0 + 0 + + + 0026 + 000026 + POINT 26 + 63.74 + -64.05 + 0 + 0 + + + 0027 + 000027 + POINT 27 + 62.57 + -56.80 + 0 + 0 + + + 0028 + 000028 + POINT 28 + 61.03 + -50.26 + 0 + 0 + + + 0029 + 000029 + POINT 29 + 59.18 + -44.46 + 0 + 0 + + + 0030 + 000030 + POINT 30 + 57.08 + -39.40 + 0 + 0 + + + 0031 + 000031 + POINT 31 + 67.08 + -98.43 + 0 + 0 + + + 0032 + 000032 + POINT 32 + 67.94 + -89.46 + 0 + 0 + + + 0033 + 000033 + POINT 33 + 68.23 + -80.00 + 0 + 0 + + + 0034 + 000034 + POINT 34 + 67.08 + -61.57 + 0 + 0 + + + 0035 + 000035 + POINT 35 + 65.73 + -53.43 + 0 + 0 + + + 0036 + 000036 + POINT 36 + 63.98 + -46.31 + 0 + 0 + + + 0037 + 000037 + POINT 37 + 61.90 + -40.19 + 0 + 0 + + + 0038 + 000038 + POINT 38 + 59.58 + -35.00 + 0 + 0 + + + 0039 + 000039 + POINT 39 + 68.83 + -110.96 + 0 + 0 + + + 0040 + 000040 + POINT 40 + 70.42 + -101.80 + 0 + 0 + + + 0041 + 000041 + POINT 41 + 71.44 + -91.31 + 0 + 0 + + + 0042 + 000042 + POINT 42 + 71.79 + -80.00 + 0 + 0 + + + 0043 + 000043 + POINT 43 + 71.44 + -68.69 + 0 + 0 + + + 0044 + 000044 + POINT 44 + 70.42 + -58.20 + 0 + 0 + + + 0045 + 000045 + POINT 45 + 64.46 + -35.00 + 0 + 0 + + + 0046 + 000046 + POINT 46 + 61.90 + -29.81 + 0 + 0 + + + 0047 + 000047 + POINT 47 + 69.45 + -125.00 + 0 + 0 + + + 0048 + 000048 + POINT 48 + 71.79 + -116.87 + 0 + 0 + + + 0049 + 000049 + POINT 49 + 73.69 + -106.57 + 0 + 0 + + + 0050 + 000050 + POINT 50 + 74.95 + -94.04 + 0 + 0 + + + 0051 + 000051 + POINT 51 + 75.39 + -80.00 + 0 + 0 + + + 0052 + 000052 + POINT 52 + 74.95 + -65.96 + 0 + 0 + + + 0053 + 000053 + POINT 53 + 73.69 + -53.43 + 0 + 0 + + + 0054 + 000054 + POINT 54 + 66.81 + -28.66 + 0 + 0 + + + 0055 + 000055 + POINT 55 + 63.98 + -23.69 + 0 + 0 + + + 0056 + 000056 + POINT 56 + 68.83 + -139.04 + 0 + 0 + + + 0057 + 000057 + POINT 57 + 71.79 + -133.13 + 0 + 0 + + + 0058 + 000058 + POINT 58 + 74.51 + -125.00 + 0 + 0 + + + 0059 + 000059 + POINT 59 + 76.82 + -113.69 + 0 + 0 + + + 0060 + 000060 + POINT 60 + 78.43 + -98.43 + 0 + 0 + + + 0061 + 000061 + POINT 61 + 79.02 + -80.00 + 0 + 0 + + + 0062 + 000062 + POINT 62 + 71.79 + -26.87 + 0 + 0 + + + 0063 + 000063 + POINT 63 + 68.83 + -20.96 + 0 + 0 + + + 0064 + 000064 + POINT 64 + 65.73 + -16.57 + 0 + 0 + + + 0065 + 000065 + POINT 65 + 62.57 + -13.20 + 0 + 0 + + + 0066 + 000066 + POINT 66 + 70.42 + -148.20 + 0 + 0 + + + 0067 + 000067 + POINT 67 + 73.69 + -143.44 + 0 + 0 + + + 0068 + 000068 + POINT 68 + 76.82 + -136.31 + 0 + 0 + + + 0069 + 000069 + POINT 69 + 79.64 + -125.00 + 0 + 0 + + + 0070 + 000070 + POINT 70 + 81.80 + -106.57 + 0 + 0 + + + 0071 + 000071 + POINT 71 + 82.67 + -80.00 + 0 + 0 + + + 0072 + 000072 + POINT 72 + 81.80 + -53.43 + 0 + 0 + + + 0073 + 000073 + POINT 73 + 76.82 + -23.69 + 0 + 0 + + + 0074 + 000074 + POINT 74 + 73.69 + -16.57 + 0 + 0 + + + 0075 + 000075 + POINT 75 + 70.42 + -11.80 + 0 + 0 + + + 0076 + 000076 + POINT 76 + 67.08 + -8.43 + 0 + 0 + + + 0077 + 000077 + POINT 77 + 54.30 + -164.29 + 0 + 0 + + + 0078 + 000078 + POINT 78 + 57.63 + -163.66 + 0 + 0 + + + 0079 + 000079 + POINT 79 + 61.03 + -162.88 + 0 + 0 + + + 0080 + 000080 + POINT 80 + 64.46 + -161.87 + 0 + 0 + + + 0081 + 000081 + POINT 81 + 67.94 + -160.54 + 0 + 0 + + + 0082 + 000082 + POINT 82 + 71.44 + -158.69 + 0 + 0 + + + 0083 + 000083 + POINT 83 + 74.95 + -155.96 + 0 + 0 + + + 0084 + 000084 + POINT 84 + 78.43 + -151.57 + 0 + 0 + + + 0085 + 000085 + POINT 85 + 81.80 + -143.44 + 0 + 0 + + + 0086 + 000086 + POINT 86 + 84.81 + -125.00 + 0 + 0 + + + 0087 + 000087 + POINT 87 + 86.33 + -80.00 + 0 + 0 + + + 0088 + 000088 + POINT 88 + 84.81 + -35.00 + 0 + 0 + + + 0089 + 000089 + POINT 89 + 81.80 + -16.57 + 0 + 0 + + + 0090 + 000090 + POINT 90 + 78.43 + -8.43 + 0 + 0 + + + 0091 + 000091 + POINT 91 + 74.95 + -4.04 + 0 + 0 + + + 0092 + 000092 + POINT 92 + 71.44 + -1.31 + 0 + 0 + + + 0093 + 000093 + POINT 93 + 54.46 + -170.00 + 0 + 0 + + + 0094 + 000094 + POINT 94 + 57.82 + -170.00 + 0 + 0 + + + 0095 + 000095 + POINT 95 + 61.24 + -170.00 + 0 + 0 + + + 0096 + 000096 + POINT 96 + 64.71 + -170.00 + 0 + 0 + + + 0097 + 000097 + POINT 97 + 68.23 + -170.00 + 0 + 0 + + + 0098 + 000098 + POINT 98 + 71.79 + -170.00 + 0 + 0 + + + 0099 + 000099 + POINT 99 + 75.39 + -170.00 + 0 + 0 + + + 0100 + 000100 + POINT 100 + 79.02 + -170.00 + 0 + 0 + + + 0101 + 000101 + POINT 101 + 82.67 + -170.00 + 0 + 0 + + + 0102 + 000102 + POINT 102 + 86.33 + -170.00 + 0 + 0 + + + 0103 + 000103 + POINT 103 + 90.00 + -80.00 + 0 + 0 + + + 0104 + 000104 + POINT 104 + 86.33 + 10.00 + 0 + 0 + + + 0105 + 000105 + POINT 105 + 82.67 + 10.00 + 0 + 0 + + + 0106 + 000106 + POINT 106 + 79.02 + 10.00 + 0 + 0 + + + 0107 + 000107 + POINT 107 + 75.39 + 10.00 + 0 + 0 + + + 0108 + 000108 + POINT 108 + 71.79 + 10.00 + 0 + 0 + + + 0109 + 000109 + POINT 109 + 57.82 + 10.00 + 0 + 0 + + + 0110 + 000110 + POINT 110 + 54.46 + 10.00 + 0 + 0 + + + 0111 + 000111 + POINT 111 + 54.30 + -175.71 + 0 + 0 + + + 0112 + 000112 + POINT 112 + 57.63 + -176.34 + 0 + 0 + + + 0113 + 000113 + POINT 113 + 61.03 + -177.13 + 0 + 0 + + + 0114 + 000114 + POINT 114 + 64.46 + -178.13 + 0 + 0 + + + 0115 + 000115 + POINT 115 + 67.94 + -179.46 + 0 + 0 + + + 0116 + 000116 + POINT 116 + 71.44 + 178.69 + 0 + 0 + + + 0117 + 000117 + POINT 117 + 74.95 + 175.96 + 0 + 0 + + + 0118 + 000118 + POINT 118 + 78.43 + 171.57 + 0 + 0 + + + 0119 + 000119 + POINT 119 + 81.80 + 163.44 + 0 + 0 + + + 0120 + 000120 + POINT 120 + 84.81 + 145.00 + 0 + 0 + + + 0121 + 000121 + POINT 121 + 86.33 + 100.00 + 0 + 0 + + + 0122 + 000122 + POINT 122 + 84.81 + 55.00 + 0 + 0 + + + 0123 + 000123 + POINT 123 + 81.80 + 36.57 + 0 + 0 + + + 0124 + 000124 + POINT 124 + 78.43 + 28.44 + 0 + 0 + + + 0125 + 000125 + POINT 125 + 74.95 + 24.04 + 0 + 0 + + + 0126 + 000126 + POINT 126 + 71.44 + 21.31 + 0 + 0 + + + 0127 + 000127 + POINT 127 + 61.03 + 17.13 + 0 + 0 + + + 0128 + 000128 + POINT 128 + 57.63 + 16.34 + 0 + 0 + + + 0129 + 000129 + POINT 129 + 54.30 + 15.71 + 0 + 0 + + + 0130 + 000130 + POINT 130 + 53.80 + 178.69 + 0 + 0 + + + 0131 + 000131 + POINT 131 + 57.08 + 177.47 + 0 + 0 + + + 0132 + 000132 + POINT 132 + 60.39 + 175.96 + 0 + 0 + + + 0133 + 000133 + POINT 133 + 70.42 + 168.20 + 0 + 0 + + + 0134 + 000134 + POINT 134 + 73.69 + 163.44 + 0 + 0 + + + 0135 + 000135 + POINT 135 + 76.82 + 156.31 + 0 + 0 + + + 0136 + 000136 + POINT 136 + 79.64 + 145.00 + 0 + 0 + + + 0137 + 000137 + POINT 137 + 81.80 + 126.57 + 0 + 0 + + + 0138 + 000138 + POINT 138 + 82.67 + 100.00 + 0 + 0 + + + 0139 + 000139 + POINT 139 + 81.80 + 73.44 + 0 + 0 + + + 0140 + 000140 + POINT 140 + 79.64 + 55.00 + 0 + 0 + + + 0141 + 000141 + POINT 141 + 76.82 + 43.69 + 0 + 0 + + + 0142 + 000142 + POINT 142 + 73.69 + 36.57 + 0 + 0 + + + 0143 + 000143 + POINT 143 + 70.42 + 31.80 + 0 + 0 + + + 0144 + 000144 + POINT 144 + 63.74 + 25.95 + 0 + 0 + + + 0145 + 000145 + POINT 145 + 60.39 + 24.04 + 0 + 0 + + + 0146 + 000146 + POINT 146 + 57.08 + 22.53 + 0 + 0 + + + 0147 + 000147 + POINT 147 + 56.18 + 171.57 + 0 + 0 + + + 0148 + 000148 + POINT 148 + 59.37 + 169.44 + 0 + 0 + + + 0149 + 000149 + POINT 149 + 71.79 + 153.13 + 0 + 0 + + + 0150 + 000150 + POINT 150 + 74.51 + 145.00 + 0 + 0 + + + 0151 + 000151 + POINT 151 + 76.82 + 133.69 + 0 + 0 + + + 0152 + 000152 + POINT 152 + 78.43 + 118.44 + 0 + 0 + + + 0153 + 000153 + POINT 153 + 79.02 + 100.00 + 0 + 0 + + + 0154 + 000154 + POINT 154 + 78.43 + 81.57 + 0 + 0 + + + 0155 + 000155 + POINT 155 + 76.82 + 66.31 + 0 + 0 + + + 0156 + 000156 + POINT 156 + 74.51 + 55.00 + 0 + 0 + + + 0157 + 000157 + POINT 157 + 71.79 + 46.87 + 0 + 0 + + + 0158 + 000158 + POINT 158 + 68.83 + 40.96 + 0 + 0 + + + 0159 + 000159 + POINT 159 + 65.73 + 36.57 + 0 + 0 + + + 0160 + 000160 + POINT 160 + 59.37 + 30.56 + 0 + 0 + + + 0161 + 000161 + POINT 161 + 54.97 + 166.04 + 0 + 0 + + + 0162 + 000162 + POINT 162 + 58.01 + 163.44 + 0 + 0 + + + 0163 + 000163 + POINT 163 + 61.03 + 160.26 + 0 + 0 + + + 0164 + 000164 + POINT 164 + 71.79 + 136.87 + 0 + 0 + + + 0165 + 000165 + POINT 165 + 73.69 + 126.57 + 0 + 0 + + + 0166 + 000166 + POINT 166 + 74.95 + 114.04 + 0 + 0 + + + 0167 + 000167 + POINT 167 + 74.95 + 85.96 + 0 + 0 + + + 0168 + 000168 + POINT 168 + 73.69 + 73.44 + 0 + 0 + + + 0169 + 000169 + POINT 169 + 71.79 + 63.13 + 0 + 0 + + + 0170 + 000170 + POINT 170 + 69.45 + 55.00 + 0 + 0 + + + 0171 + 000171 + POINT 171 + 66.81 + 48.66 + 0 + 0 + + + 0172 + 000172 + POINT 172 + 45.87 + 28.44 + 0 + 0 + + + 0173 + 000173 + POINT 173 + 42.90 + 27.10 + 0 + 0 + + + 0174 + 000174 + POINT 174 + 53.48 + 160.95 + 0 + 0 + + + 0175 + 000175 + POINT 175 + 59.18 + 154.46 + 0 + 0 + + + 0176 + 000176 + POINT 176 + 70.42 + 78.20 + 0 + 0 + + + 0177 + 000177 + POINT 177 + 68.83 + 69.04 + 0 + 0 + + + 0178 + 000178 + POINT 178 + 66.81 + 61.34 + 0 + 0 + + + 0179 + 000179 + POINT 179 + 44.77 + 32.62 + 0 + 0 + + + 0180 + 000180 + POINT 180 + 41.89 + 31.04 + 0 + 0 + + + 0181 + 000181 + POINT 181 + 49.02 + 159.04 + 0 + 0 + + + 0182 + 000182 + POINT 182 + 51.76 + 156.31 + 0 + 0 + + + 0183 + 000183 + POINT 183 + 54.46 + 153.13 + 0 + 0 + + + 0184 + 000184 + POINT 184 + 57.08 + 149.40 + 0 + 0 + + + 0185 + 000185 + POINT 185 + 59.58 + 145.00 + 0 + 0 + + + 0186 + 000186 + POINT 186 + 46.24 + 38.61 + 0 + 0 + + + 0187 + 000187 + POINT 187 + 43.47 + 36.57 + 0 + 0 + + + 0188 + 000188 + POINT 188 + 47.27 + 155.01 + 0 + 0 + + + 0189 + 000189 + POINT 189 + 49.86 + 152.13 + 0 + 0 + + + 0190 + 000190 + POINT 190 + 52.38 + 148.81 + 0 + 0 + + + 0191 + 000191 + POINT 191 + 54.80 + 145.00 + 0 + 0 + + + 0192 + 000192 + POINT 192 + 57.08 + 140.60 + 0 + 0 + + + 0193 + 000193 + POINT 193 + 45.37 + 151.34 + 0 + 0 + + + 0194 + 000194 + POINT 194 + 47.80 + 148.37 + 0 + 0 + + + 0195 + 000195 + POINT 195 + 50.14 + 145.00 + 0 + 0 + + + 0196 + 000196 + POINT 196 + 52.38 + 141.19 + 0 + 0 + + + 0197 + 000197 + POINT 197 + 54.46 + 136.87 + 0 + 0 + + + 0198 + 000198 + POINT 198 + 43.35 + 148.01 + 0 + 0 + + + 0199 + 000199 + POINT 199 + 45.62 + 145.00 + 0 + 0 + + + 0200 + 000200 + POINT 200 + 47.80 + 141.63 + 0 + 0 + + + 0201 + 000201 + POINT 201 + 45.37 + 138.66 + 0 + 0 + + + 0202 + 000202 + POINT 202 + 42.90 + 136.03 + 0 + 0 + + + 0203 + 000203 + POINT 203 + 40.39 + 133.69 + 0 + 0 + + + 0204 + 000204 + POINT 204 + 42.00 + 130.26 + 0 + 0 + + + 0205 + 000205 + POINT 205 + 39.36 + 128.30 + 0 + 0 + + + 0206 + 000206 + POINT 206 + 37.96 + 123.20 + 0 + 0 + + + 0207 + 000207 + POINT 207 + 39.05 + 119.65 + 0 + 0 + + diff --git a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/stns.xsd b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/stns.xsd old mode 100755 new mode 100644 index e4416acbc5..145fba212c --- a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/stns.xsd +++ b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/stns.xsd @@ -1,163 +1,163 @@ - - - - - - The station ID - - - - - - - - - - - - The station number - - - - - - - - - - - - The station name - - - - - - - - - - - state - - - - - - - - - - - country - - - - - - - - - - - The latitude - - - - - - - - - - - - The longitude - - - - - - - - - - - - The elevation - - - - - - - - - - - - The priority - - - - - - - - - - - - Volcano location - - - - - - - - - - - WFO - - - - - - - - - - - - - - - - - - - A station - - - - - - - - - - - - - - - - - - - - + + + + + + The station ID + + + + + + + + + + + + The station number + + + + + + + + + + + + The station name + + + + + + + + + + + state + + + + + + + + + + + country + + + + + + + + + + + The latitude + + + + + + + + + + + + The longitude + + + + + + + + + + + + The elevation + + + + + + + + + + + + The priority + + + + + + + + + + + + Volcano location + + + + + + + + + + + WFO + + + + + + + + + + + + + + + + + + + A station + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/vors.xml b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/vors.xml old mode 100755 new mode 100644 index 80239cf1d0..2e15934cd5 --- a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/vors.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/vors.xml @@ -1,7049 +1,7049 @@ - - - - - YSJ - 000395 - ST_JOHN - NB - CN - 45.32 - -65.88 - 0 - 0 - - - - HUL - 000341 - HOULTON - ME - US - 46.04 - -67.83 - 0 - 0 - - - - PQI - 000367 - PRESQUE_ISLE - ME - US - 46.77 - -68.09 - 0 - 0 - - - - MLT - 000183 - MILLINOCKET - ME - US - 45.58 - -68.52 - 0 - 0 - - - - BGR - 000029 - BANGOR - ME - US - 44.84 - -68.87 - 0 - 0 - - - - ACK - 000005 - NANTUCKET - MA - US - 41.28 - -70.03 - 0 - 0 - - - - ENE - 000322 - KENNEBUNK - ME - US - 43.43 - -70.61 - 0 - 0 - - - - BOS - 000289 - BOSTON - MA - US - 42.36 - -70.99 - 0 - 0 - - - - YQB - 000391 - QUEBEC - QB - CN - 46.80 - -71.38 - 0 - 0 - - - - PVD - 000221 - PROVIDENCE - RI - US - 41.72 - -71.43 - 0 - 0 - - - - CON - 000062 - CONCORD - NH - US - 43.22 - -71.58 - 0 - 0 - - - - YSC - 000394 - SHERBROOKE - QB - CN - 45.43 - -71.68 - 0 - 0 - - - - HTO - 000340 - EAST_HAMPTON - NY - US - 40.92 - -72.32 - 0 - 0 - - - - MPV - 000188 - MONTPELIER - VT - US - 44.22 - -72.57 - 0 - 0 - - - - BDL - 000287 - WINSOR_LOCKS - CT - US - 41.94 - -72.69 - 0 - 0 - - - - PLB - 000365 - PLATTSBURGH - NY - US - 44.69 - -73.52 - 0 - 0 - - - - JFK - 000345 - NEW_YORK/JF_KENNEDY - NY - US - 40.63 - -73.77 - 0 - 0 - - - - ALB - 000012 - ALBANY - NY - US - 42.75 - -73.80 - 0 - 0 - - - - CYN - 000300 - COYLE - NJ - US - 39.82 - -74.43 - 0 - 0 - - - - SAX - 000376 - SPARTA - NJ - US - 41.07 - -74.54 - 0 - 0 - - - - MSS - 000353 - MASSENA - NY - US - 44.91 - -74.72 - 0 - 0 - - - - SIE - 000377 - SEA_ISLE - NJ - US - 39.10 - -74.80 - 0 - 0 - - - - HNK - 000338 - HANCOCK - NY - US - 42.06 - -75.32 - 0 - 0 - - - - SBY - 000242 - SALISBURY - MD - US - 38.35 - -75.52 - 0 - 0 - - - - YOW - 000390 - OTTAWA - ON - CN - 45.32 - -75.67 - 0 - 0 - - - - ETX - 000325 - EAST_TEXAS - PA - US - 40.58 - -75.68 - 0 - 0 - - - - ECG - 000086 - ELIZABETH_CITY - NC - US - 36.25 - -76.18 - 0 - 0 - - - - SYR - 000259 - SYRACUSE - NY - US - 43.16 - -76.20 - 0 - 0 - - - - ORF - 000203 - NORFOLK - VA - US - 36.89 - -76.20 - 0 - 0 - - - - EMI - 000320 - WESTMINSTER - MD - US - 39.50 - -76.98 - 0 - 0 - - - - HAR - 000126 - HARRISBURG - PA - US - 40.23 - -77.02 - 0 - 0 - - - - DCA - 000306 - WASHINGTON - DC - US - 38.86 - -77.04 - 0 - 0 - - - - RIC - 000229 - RICHMOND - VA - US - 37.50 - -77.32 - 0 - 0 - - - - CSN - 000299 - CASSANOVA - VA - US - 38.64 - -77.87 - 0 - 0 - - - - ILM - 000135 - WILMINGTON - NC - US - 34.35 - -77.87 - 0 - 0 - - - - SLT - 000252 - SLATE_RUN - PA - US - 41.51 - -77.97 - 0 - 0 - - - - PSB - 000368 - PHILLIPSBURG - PA - US - 40.92 - -77.99 - 0 - 0 - - - - BUF - 000044 - BUFFALO - NY - US - 42.93 - -78.65 - 0 - 0 - - - - RDU - 000372 - RALEIGH-DURHAM - NC - US - 35.87 - -78.78 - 0 - 0 - - - - JST - 000145 - JOHNSTOWN - PA - US - 40.32 - -78.83 - 0 - 0 - - - - JHW - 000346 - JAMESTOWN - NY - US - 42.19 - -79.12 - 0 - 0 - - - - LYH - 000166 - LYNCHBURG - VA - US - 37.25 - -79.23 - 0 - 0 - - - - YYZ - 000401 - TORONTO - ON - CN - 43.67 - -79.63 - 0 - 0 - - - - FLO - 000102 - FLORENCE - SC - US - 34.23 - -79.66 - 0 - 0 - - - - GSO - 000122 - GREENSBORO - NC - US - 36.05 - -79.98 - 0 - 0 - - - - CHS - 000056 - CHARLESTON - SC - US - 32.89 - -80.04 - 0 - 0 - - - - PBI - 000206 - WEST_PALM_BEACH - FL - US - 26.68 - -80.09 - 0 - 0 - - - - EKN - 000088 - ELKINS - WV - US - 38.92 - -80.10 - 0 - 0 - - - - EWC - 000326 - ELLWOOD_CITY - PA - US - 40.83 - -80.21 - 0 - 0 - - - - ERI - 000092 - ERIE - PA - US - 42.02 - -80.30 - 0 - 0 - - - - MIA - 000176 - MIAMI - FL - US - 25.80 - -80.30 - 0 - 0 - - - - VRB - 000276 - VERO_BEACH - FL - US - 27.68 - -80.49 - 0 - 0 - - - - PSK - 000369 - DUBLIN - VA - US - 37.09 - -80.71 - 0 - 0 - - - - AIR - 000280 - BELLAIRE - OH - US - 40.02 - -80.82 - 0 - 0 - - - - CLT - 000059 - CHARLOTTE - NC - US - 35.22 - -80.93 - 0 - 0 - - - - CAE - 000295 - COLUMBIA - SC - US - 33.86 - -81.05 - 0 - 0 - - - - YVV - 000396 - WIARTON - ON - CN - 44.75 - -81.10 - 0 - 0 - - - - SAV - 000239 - SAVANNAH - GA - US - 32.16 - -81.11 - 0 - 0 - - - - OMN - 000363 - ORMOND_BEACH - FL - US - 29.30 - -81.11 - 0 - 0 - - - - BKW - 000034 - BECKLEY - WV - US - 37.78 - -81.12 - 0 - 0 - - - - ORL - 000204 - ORLANDO - FL - US - 28.54 - -81.34 - 0 - 0 - - - - CRG - 000298 - JACKSONVILLE - FL - US - 30.34 - -81.51 - 0 - 0 - - - - EYW - 000096 - KEY_WEST - FL - US - 24.59 - -81.80 - 0 - 0 - - - - FMY - 000104 - FT_MEYERS - FL - US - 26.58 - -81.87 - 0 - 0 - - - - SPA - 000380 - SPARTANBURG - SC - US - 35.03 - -81.93 - 0 - 0 - - - - HNN - 000339 - HENDERSON - WV - US - 38.75 - -82.03 - 0 - 0 - - - - HMV - 000337 - HOLSTON_MOUNTAIN - TN - US - 36.44 - -82.13 - 0 - 0 - - - - CLE - 000058 - CLEVELAND - OH - US - 41.42 - -81.85 - 0 - 0 - - - - IRQ - 000344 - COLLIERS - SC - US - 33.71 - -82.16 - 0 - 0 - - - - AMG - 000015 - ALMA - GA - US - 31.54 - -82.51 - 0 - 0 - - - - SRQ - 000382 - SARASOTA - FL - US - 27.40 - -82.55 - 0 - 0 - - - - APE - 000283 - APPLETON - OH - US - 40.15 - -82.59 - 0 - 0 - - - - PIE - 000212 - SAINT_PETERSBURG - FL - US - 27.91 - -82.68 - 0 - 0 - - - - ECK - 000316 - PECK - MI - US - 43.26 - -82.72 - 0 - 0 - - - - CTY - 000066 - CROSS_CITY - FL - US - 29.60 - -83.05 - 0 - 0 - - - - ODF - 000360 - TOCCOA - GA - US - 34.70 - -83.30 - 0 - 0 - - - - DXO - 000315 - DETROIT - MI - US - 42.21 - -83.37 - 0 - 0 - - - - ASP - 000284 - OSCODA - MI - US - 44.45 - -83.39 - 0 - 0 - - - - MCN - 000170 - MACON - GA - US - 32.69 - -83.65 - 0 - 0 - - - - FNT - 000328 - FLINT - MI - US - 42.97 - -83.74 - 0 - 0 - - - - VXV - 000388 - KNOXVILLE - TN - US - 35.90 - -83.89 - 0 - 0 - - - - ROD - 000373 - ROSEWOOD - OH - US - 40.29 - -84.04 - 0 - 0 - - - - MBS - 000168 - SAGINAW - MI - US - 43.53 - -84.08 - 0 - 0 - - - - LOZ - 000160 - LONDON - KY - US - 37.03 - -84.12 - 0 - 0 - - - - ABY - 000004 - ALBANY - GA - US - 31.65 - -84.30 - 0 - 0 - - - - SSM - 000255 - SAULT_STE_MARIE - MI - US - 46.41 - -84.31 - 0 - 0 - - - - TLH - 000264 - TALLAHASSEE - FL - US - 30.56 - -84.37 - 0 - 0 - - - - ATL - 000019 - ATLANTA - GA - US - 33.63 - -84.44 - 0 - 0 - - - - CVG - 000067 - COVINGTON - KY - US - 39.02 - -84.70 - 0 - 0 - - - - GQO - 000331 - CHATTANOOGA - TN - US - 34.96 - -85.15 - 0 - 0 - - - - FWA - 000109 - FT_WAYNE - IN - US - 40.98 - -85.19 - 0 - 0 - - - - LGC - 000350 - LA_GRANGE - GA - US - 33.05 - -85.21 - 0 - 0 - - - - GRR - 000332 - GRAND_RAPIDS - MI - US - 42.79 - -85.50 - 0 - 0 - - - - TVC - 000270 - TRAVERSE_CITY - MI - US - 44.67 - -85.55 - 0 - 0 - - - - LOU - 000159 - LOUISVILLE - KY - US - 38.10 - -85.58 - 0 - 0 - - - - MKG - 000179 - MUSKEGON - MI - US - 43.17 - -86.04 - 0 - 0 - - - - PMM - 000366 - PULLMAN - MI - US - 42.47 - -86.11 - 0 - 0 - - - - GIJ - 000330 - NILES - MI - US - 41.77 - -86.32 - 0 - 0 - - - - MGM - 000175 - MONTGOMERY - AL - US - 32.22 - -86.32 - 0 - 0 - - - - IND - 000136 - INDIANAPOLIS - IN - US - 39.81 - -86.37 - 0 - 0 - - - - BWG - 000047 - BOWLING_GREEN - KY - US - 36.93 - -86.44 - 0 - 0 - - - - BNA - 000037 - NASHVILLE - TN - US - 36.14 - -86.68 - 0 - 0 - - - - CEW - 000052 - CRESTVIEW - FL - US - 30.83 - -86.68 - 0 - 0 - - - - VUZ - 000387 - VULCAN - AL - US - 33.67 - -86.90 - 0 - 0 - - - - BVT - 000293 - LAFAYETTE - IN - US - 40.56 - -87.07 - 0 - 0 - - - - TTH - 000384 - TERRE_HAUTE - IN - US - 39.49 - -87.25 - 0 - 0 - - - - MSL - 000191 - MUSCLE_SHOALS - AL - US - 34.70 - -87.48 - 0 - 0 - - - - SAW - 000189 - SAWYER - MI - US - 46.35 - -87.38 - 0 - 0 - - - - PXV - 000370 - POCKET_CITY - IN - US - 37.93 - -87.76 - 0 - 0 - - - - ORD - 000202 - O'HARE_INTERNATIONAL - IL - US - 41.98 - -87.90 - 0 - 0 - - - - GRB - 000119 - GREEN_BAY - WI - US - 44.56 - -88.19 - 0 - 0 - - - - BAE - 000285 - MILWAUKEE - WI - US - 43.12 - -88.28 - 0 - 0 - - - - JOT - 000348 - JOLIET - IL - US - 41.55 - -88.32 - 0 - 0 - - - - SJI - 000378 - SEMMNES - AL - US - 30.73 - -88.36 - 0 - 0 - - - - IGB - 000133 - BIGBEE - MS - US - 33.48 - -88.52 - 0 - 0 - - - - MEI - 000172 - MERIDIAN - MS - US - 32.38 - -88.80 - 0 - 0 - - - - DEC - 000070 - DECATUR - IL - US - 39.74 - -88.86 - 0 - 0 - - - - YQT - 000393 - THUNDER_BAY - ON - CN - 48.37 - -89.32 - 0 - 0 - - - - DYR - 000083 - DYERSBURG - TN - US - 36.02 - -89.32 - 0 - 0 - - - - RHI - 000228 - RHINELANDER - WI - US - 45.63 - -89.45 - 0 - 0 - - - - BDF - 000024 - BRADFORD - IL - US - 41.16 - -89.59 - 0 - 0 - - - - DLL - 000310 - DELLS - WI - US - 43.55 - -89.76 - 0 - 0 - - - - MEM - 000173 - MEMPHIS - TN - US - 35.06 - -89.98 - 0 - 0 - - - - LEV - 000349 - GRAND_ISLE - LA - US - 29.18 - -90.10 - 0 - 0 - - - - JAN - 000142 - JACKSON - MS - US - 32.51 - -90.17 - 0 - 0 - - - - MSY - 000195 - NEW_ORLEANS - LA - US - 30.00 - -90.27 - 0 - 0 - - - - FAM - 000097 - FARMINGTON - MO - US - 37.67 - -90.23 - 0 - 0 - - - - MCB - 000169 - MC_COMB - MS - US - 31.30 - -90.26 - 0 - 0 - - - - SQS - 000381 - SIDON - MS - US - 33.46 - -90.28 - 0 - 0 - - - - STL - 000257 - ST_LOUIS - MO - US - 38.86 - -90.48 - 0 - 0 - - - - DBQ - 000069 - DUBUQUE - IA - US - 42.40 - -90.71 - 0 - 0 - - - - ARG - 000018 - WALNUT_RIDGE - AR - US - 36.11 - -90.95 - 0 - 0 - - - - UIN - 000386 - QUINCY - IL - US - 39.85 - -91.28 - 0 - 0 - - - - BTR - 000042 - BATON_ROUGE - LA - US - 30.48 - -91.30 - 0 - 0 - - - - ODI - 000361 - NODINE - MN - US - 43.91 - -91.47 - 0 - 0 - - - - EAU - 000085 - EAU_CLAIRE - WI - US - 44.90 - -91.48 - 0 - 0 - - - - IOW - 000343 - IOWA_CITY - IA - US - 41.52 - -91.61 - 0 - 0 - - - - MLU - 000184 - MONROE - LA - US - 32.52 - -92.03 - 0 - 0 - - - - LIT - 000156 - LITTLE_ROCK - AR - US - 34.68 - -92.18 - 0 - 0 - - - - DLH - 000075 - DULUTH - MN - US - 46.80 - -92.20 - 0 - 0 - - - - COU - 000063 - COLUMBIA - MO - US - 38.82 - -92.22 - 0 - 0 - - - - AEX - 000009 - ALEXANDRIA - LA - US - 31.26 - -92.50 - 0 - 0 - - - - IRK - 000139 - KIRKSVILLE - MO - US - 40.14 - -92.59 - 0 - 0 - - - - ELD - 000319 - EL_DORADO - AR - US - 33.26 - -92.74 - 0 - 0 - - - - LCH - 000154 - LAKE_CHARLES - LA - US - 30.14 - -93.11 - 0 - 0 - - - - MSP - 000194 - MINNEAPOLIS - MN - US - 44.88 - -93.23 - 0 - 0 - - - - MCW - 000171 - MASON_CITY - IA - US - 43.09 - -93.33 - 0 - 0 - - - - SGF - 000245 - SPRINGFIELD - MO - US - 37.36 - -93.33 - 0 - 0 - - - - INL - 000137 - INTERNATIONAL_FALLS - MN - US - 48.57 - -93.40 - 0 - 0 - - - - DSM - 000079 - DES_MOINES - IA - US - 41.44 - -93.65 - 0 - 0 - - - - EIC - 000318 - SHREVEPORT - LA - US - 32.77 - -93.81 - 0 - 0 - - - - BRD - 000292 - BRAINERD - MN - US - 46.35 - -94.03 - 0 - 0 - - - - TXK - 000272 - TEXARKANA - AR - US - 33.51 - -94.07 - 0 - 0 - - - - RZC - 000374 - RAZORBACK - AR - US - 36.25 - -94.12 - 0 - 0 - - - - FSM - 000108 - FT_SMITH - AR - US - 35.38 - -94.27 - 0 - 0 - - - - FOD - 000105 - FT_DODGE - IA - US - 42.61 - -94.29 - 0 - 0 - - - - BUM - 000045 - BUTLER - MO - US - 38.27 - -94.49 - 0 - 0 - - - - MKC - 000177 - KANSAS_CITY - MO - US - 39.28 - -94.59 - 0 - 0 - - - - LFK - 000155 - LUFKIN - TX - US - 31.16 - -94.72 - 0 - 0 - - - - GGG - 000115 - LONGVIEW - TX - US - 32.42 - -94.75 - 0 - 0 - - - - BJI - 000033 - BEMIDJI - MN - US - 47.58 - -95.02 - 0 - 0 - - - - RWF - 000234 - REDWWOD_FALLS - MN - US - 44.47 - -95.13 - 0 - 0 - - - - OSW - 000205 - OSWEGO - KS - US - 37.15 - -95.20 - 0 - 0 - - - - IAH - 000131 - HOUSTON_INTERNATIONAL - TX - US - 29.96 - -95.35 - 0 - 0 - - - - OVR - 000364 - OMAHA - NE - US - 41.17 - -95.74 - 0 - 0 - - - - MLC - 000180 - MC_CALESTER - OK - US - 34.85 - -95.78 - 0 - 0 - - - - TUL - 000268 - TULSA - OK - US - 36.20 - -95.79 - 0 - 0 - - - - PWE - 000222 - PAWNEE_CITY - NE - US - 40.20 - -96.21 - 0 - 0 - - - - PSX - 000219 - PALACIOS - TX - US - 28.76 - -96.31 - 0 - 0 - - - - FSD - 000107 - SIOUX_FALLS - SD - US - 43.65 - -96.78 - 0 - 0 - - - - FAR - 000098 - FARGO - ND - US - 46.75 - -96.85 - 0 - 0 - - - - DFW - 000072 - DALLAS-FT_WORTH - TX - US - 32.87 - -97.03 - 0 - 0 - - - - ADM - 000008 - ARDMORE - OK - US - 34.21 - -97.17 - 0 - 0 - - - - GFK - 000114 - GRAND_FORKS - ND - US - 47.95 - -97.19 - 0 - 0 - - - - YWG - 000397 - WINNIPEG - MB - CN - 49.90 - -97.23 - 0 - 0 - - - - ACT - 000006 - WACO - TX - US - 31.66 - -97.27 - 0 - 0 - - - - BRO - 000041 - BROWNSVILLE - TX - US - 25.92 - -97.38 - 0 - 0 - - - - CRP - 000065 - CORPUS_CHRISTI - TX - US - 27.90 - -97.45 - 0 - 0 - - - - ICT - 000132 - WICHITA - KS - US - 37.75 - -97.58 - 0 - 0 - - - - OKC - 000198 - OKLAHOMA_CITY - OK - US - 35.36 - -97.61 - 0 - 0 - - - - SLN - 000251 - SALINA - KS - US - 38.93 - -97.62 - 0 - 0 - - - - AUS - 000020 - AUSTIN - TX - US - 30.30 - -97.70 - 0 - 0 - - - - END - 000321 - VANCE_AFB - OK - US - 36.35 - -97.92 - 0 - 0 - - - - OBH - 000358 - WOLBACH - NE - US - 41.38 - -98.35 - 0 - 0 - - - - ABR - 000003 - ABERDEEN - SD - US - 45.42 - -98.37 - 0 - 0 - - - - SAT - 000238 - SAN_ANTONIO - TX - US - 29.64 - -98.46 - 0 - 0 - - - - SPS - 000254 - WICHITA_FALLS - TX - US - 33.99 - -98.59 - 0 - 0 - - - - ONL - 000200 - ONEILL - NE - US - 42.47 - -98.69 - 0 - 0 - - - - LRD - 000161 - LAREDO - TX - US - 27.48 - -99.42 - 0 - 0 - - - - JCT - 000144 - JUNCTION - TX - US - 30.60 - -99.82 - 0 - 0 - - - - ABI - 000001 - ABILENE - TX - US - 32.48 - -99.86 - 0 - 0 - - - - GAG - 000110 - GAGE - OK - US - 36.34 - -99.88 - 0 - 0 - - - - ANW - 000282 - AINSWORTH - NE - US - 42.57 - -99.99 - 0 - 0 - - - - PIR - 000214 - PIERRE - SD - US - 44.40 - -100.17 - 0 - 0 - - - - HLC - 000335 - HILL_CITY - KS - US - 39.26 - -100.23 - 0 - 0 - - - - CDS - 000051 - CHILDRESS - TX - US - 34.37 - -100.28 - 0 - 0 - - - - SJT - 000248 - SAN_ANGELO - TX - US - 31.38 - -100.46 - 0 - 0 - - - - MCK - 000351 - MC_COOK - NE - US - 40.20 - -100.59 - 0 - 0 - - - - BIS - 000032 - BISMARK - ND - US - 46.77 - -100.67 - 0 - 0 - - - - LBF - 000152 - NORTH_PLATTE - NE - US - 41.13 - -100.72 - 0 - 0 - - - - GCK - 000112 - GARDEN_CITY - KS - US - 37.92 - -100.73 - 0 - 0 - - - - DLF - 000309 - LAUGHLIN_AFB - TX - US - 29.36 - -100.77 - 0 - 0 - - - - LBL - 000153 - LIBERAL - KS - US - 37.04 - -100.97 - 0 - 0 - - - - MOT - 000187 - MINOT - ND - US - 48.26 - -101.29 - 0 - 0 - - - - AMA - 000014 - AMARILLO - TX - US - 35.29 - -101.64 - 0 - 0 - - - - GLD - 000118 - GOODLAND - KS - US - 39.39 - -101.69 - 0 - 0 - - - - DPR - 000077 - DUPREE - SD - US - 45.08 - -101.72 - 0 - 0 - - - - LBB - 000151 - LUBBOCK_INTERNATIONAL - TX - US - 33.70 - -101.92 - 0 - 0 - - - - MAF - 000167 - MIDLAND - TX - US - 32.02 - -102.18 - 0 - 0 - - - - LAA - 000146 - LAMAR - CO - US - 38.20 - -102.69 - 0 - 0 - - - - DIK - 000074 - DICKINSIN - ND - US - 46.86 - -102.77 - 0 - 0 - - - - TXO - 000385 - TEXICO_NM/BOVINA - TX - US - 34.50 - -102.84 - 0 - 0 - - - - SNY - 000379 - SIDNEY - NE - US - 41.10 - -102.98 - 0 - 0 - - - - FST - 000329 - FT_STOCKTON - TX - US - 30.95 - -102.98 - 0 - 0 - - - - RAP - 000224 - RAPID_CITY - SD - US - 43.98 - -103.01 - 0 - 0 - - - - AKO - 000011 - AKRON - CO - US - 40.16 - -103.18 - 0 - 0 - - - - INK - 000342 - WINK - TX - US - 31.87 - -103.24 - 0 - 0 - - - - BFF - 000026 - SCOTTSBLUFF - NE - US - 41.89 - -103.48 - 0 - 0 - - - - TBE - 000261 - TOBE - CO - US - 37.27 - -103.60 - 0 - 0 - - - - TCC - 000262 - TUCUMCARI - NM - US - 35.18 - -103.60 - 0 - 0 - - - - ISN - 000140 - WILLISTON - ND - US - 48.18 - -103.63 - 0 - 0 - - - - MRF - 000190 - MARFA - TX - US - 30.30 - -103.95 - 0 - 0 - - - - PUB - 000220 - PUEBLO - CO - US - 38.29 - -104.43 - 0 - 0 - - - - ROW - 000233 - ROSWELL - NM - US - 33.34 - -104.62 - 0 - 0 - - - - DEN - 000071 - DENVER - CO - US - 39.81 - -104.66 - 0 - 0 - - - - CYS - 000301 - CHEYENNE - WY - US - 41.21 - -104.77 - 0 - 0 - - - - CIM - 000297 - CIMARRON - NM - US - 36.49 - -104.87 - 0 - 0 - - - - LVS - 000163 - LAS_VEGAS - NM - US - 35.66 - -105.14 - 0 - 0 - - - - LAR - 000148 - LARAMIE - WY - US - 41.33 - -105.72 - 0 - 0 - - - - ALS - 000013 - ALAMOSA - CO - US - 37.35 - -105.82 - 0 - 0 - - - - MLS - 000182 - MILES_CITY - MT - US - 46.38 - -105.95 - 0 - 0 - - - - DDY - 000307 - CASPER - WY - US - 43.09 - -106.28 - 0 - 0 - - - - ELP - 000090 - EL_PASO - TX - US - 31.82 - -106.28 - 0 - 0 - - - - CZI - 000302 - CRAZY_WOMAN - WY - US - 44.00 - -106.44 - 0 - 0 - - - - GGW - 000116 - GLASGOW - MT - US - 48.22 - -106.63 - 0 - 0 - - - - ABQ - 000002 - ALBUQUERQUE - NM - US - 35.04 - -106.82 - 0 - 0 - - - - DBL - 000304 - EAGLE - CO - US - 39.44 - -106.90 - 0 - 0 - - - - HBU - 000333 - GUNNISON - CO - US - 38.45 - -107.04 - 0 - 0 - - - - SHR - 000246 - SHERIDAN - WY - US - 44.84 - -107.06 - 0 - 0 - - - - TCS - 000263 - TRUTH_OR_CONSEQUENCES - NM - US - 33.28 - -107.28 - 0 - 0 - - - - CHE - 000054 - HAYDEN - CO - US - 40.52 - -107.31 - 0 - 0 - - - - DMN - 000076 - DEMING - NM - US - 32.28 - -107.60 - 0 - 0 - - - - YYN - 000400 - SWIFT_CURRENT - SA - CN - 50.28 - -107.68 - 0 - 0 - - - - FMN - 000103 - FARMINGTON - NM - US - 36.75 - -108.10 - 0 - 0 - - - - BOY - 000290 - BOYSEN_RESV. - WY - US - 43.46 - -108.30 - 0 - 0 - - - - BIL - 000031 - BILLINGS - MT - US - 45.81 - -108.63 - 0 - 0 - - - - JNC - 000347 - GRAND_JUNCTION - CO - US - 39.06 - -108.79 - 0 - 0 - - - - DVC - 000082 - DOVE_CREEK - CO - US - 37.81 - -108.93 - 0 - 0 - - - - OCS - 000359 - ROCKSPRINGS - WY - US - 41.59 - -109.02 - 0 - 0 - - - - SJN - 000247 - ST_JOHNS - AZ - US - 34.42 - -109.14 - 0 - 0 - - - - SSO - 000256 - SAN_SIMON - AZ - US - 32.27 - -109.26 - 0 - 0 - - - - LWT - 000165 - LEWISTOWN - MT - US - 47.05 - -109.61 - 0 - 0 - - - - HVR - 000129 - HAVRE - MT - US - 48.54 - -109.77 - 0 - 0 - - - - BPI - 000291 - BIG_PINEY - WY - US - 42.58 - -110.11 - 0 - 0 - - - - MTU - 000196 - MYTON - UT - US - 40.15 - -110.13 - 0 - 0 - - - - HVE - 000128 - HANKSVILLE - UT - US - 38.42 - -110.70 - 0 - 0 - - - - YXH - 000399 - MEDICINE_HAT - AB - CN - 50.02 - -110.72 - 0 - 0 - - - - JAC - 000141 - JACKSON - WY - US - 43.62 - -110.73 - 0 - 0 - - - - INW - 000138 - WINSLOW - AZ - US - 35.06 - -110.80 - 0 - 0 - - - - TUS - 000269 - TUCSON - AZ - US - 32.10 - -110.92 - 0 - 0 - - - - TBC - 000260 - TUBA_CITY - AZ - US - 36.12 - -111.27 - 0 - 0 - - - - GTF - 000123 - GREAT_FALLS - MT - US - 47.45 - -111.41 - 0 - 0 - - - - HLN - 000336 - HELENA - MT - US - 46.61 - -111.95 - 0 - 0 - - - - PHX - 000211 - PHOENIX - AZ - US - 33.43 - -112.02 - 0 - 0 - - - - SLC - 000249 - SALT_LAKE_CITY - UT - US - 40.85 - -111.98 - 0 - 0 - - - - DBS - 000305 - DUBOIS - ID - US - 44.09 - -112.21 - 0 - 0 - - - - BCE - 000023 - BRYCE_CANYON - UT - US - 37.69 - -112.30 - 0 - 0 - - - - MLD - 000352 - MALAD_CITY - ID - US - 42.20 - -112.45 - 0 - 0 - - - - DRK - 000313 - PRESCOTT - AZ - US - 34.70 - -112.48 - 0 - 0 - - - - DTA - 000080 - DELTA - UT - US - 39.30 - -112.51 - 0 - 0 - - - - DLN - 000311 - DILLON - MT - US - 45.25 - -112.55 - 0 - 0 - - - - PIH - 000213 - POCATELLO - ID - US - 42.87 - -112.65 - 0 - 0 - - - - YQL - 000392 - LETHBRIDGE - AB - CN - 49.63 - -112.80 - 0 - 0 - - - - PGS - 000210 - PEACH_SPRINGS - AZ - US - 35.62 - -113.54 - 0 - 0 - - - - BVL - 000046 - BOONEVILLE - UT - US - 40.73 - -113.76 - 0 - 0 - - - - LKT - 000157 - SALMON - ID - US - 45.02 - -114.08 - 0 - 0 - - - - FCA - 000100 - KALISPELL - MT - US - 48.21 - -114.18 - 0 - 0 - - - - ILC - 000134 - WILSON_CREEK - NV - US - 38.25 - -114.39 - 0 - 0 - - - - EED - 000087 - NEEDLES - CA - US - 34.77 - -114.47 - 0 - 0 - - - - TWF - 000271 - TWIN_FALLS - ID - US - 42.48 - -114.49 - 0 - 0 - - - - BZA - 000294 - YUMA - AZ - US - 32.77 - -114.60 - 0 - 0 - - - - ELY - 000091 - ELY - NV - US - 39.30 - -114.85 - 0 - 0 - - - - LAS - 000149 - LAS_VEGAS - NV - US - 36.08 - -115.16 - 0 - 0 - - - - MLP - 000181 - MULLAN_PASS - ID - US - 47.46 - -115.65 - 0 - 0 - - - - YXC - 000398 - CRANBROOK - BC - CN - 49.60 - -115.78 - 0 - 0 - - - - TRM - 000383 - THERMAL - CA - US - 33.63 - -116.16 - 0 - 0 - - - - BOI - 000039 - BOISE - ID - US - 43.55 - -116.19 - 0 - 0 - - - - DNJ - 000312 - MC_CALL - ID - US - 44.77 - -116.21 - 0 - 0 - - - - HEC - 000334 - HECTOR - CA - US - 34.80 - -116.46 - 0 - 0 - - - - BTY - 000043 - BEATTY - NV - US - 36.80 - -116.75 - 0 - 0 - - - - BAM - 000286 - BATTLE_MOUNTAIN - NV - US - 40.57 - -116.92 - 0 - 0 - - - - MZB - 000354 - MISSION_BAY - CA - US - 32.78 - -117.23 - 0 - 0 - - - - GEG - 000113 - SPOKANE - WA - US - 47.56 - -117.63 - 0 - 0 - - - - OAL - 000357 - COALDALE - NV - US - 38.00 - -117.77 - 0 - 0 - - - - BKE - 000288 - BAKER - OR - US - 44.84 - -117.81 - 0 - 0 - - - - REO - 000227 - ROME - OR - US - 42.59 - -117.87 - 0 - 0 - - - - LAX - 000150 - LOS_ANGELES_INTL - CA - US - 33.93 - -118.43 - 0 - 0 - - - - PDT - 000207 - PENDLETON - OR - US - 45.70 - -118.94 - 0 - 0 - - - - EHF - 000317 - BAKERSFIELD - CA - US - 35.48 - -119.10 - 0 - 0 - - - - EPH - 000324 - EPHRATA - WA - US - 47.38 - -119.42 - 0 - 0 - - - - FMG - 000327 - RENO - NV - US - 39.53 - -119.66 - 0 - 0 - - - - RZS - 000375 - SANTA_BARBARA - CA - US - 34.51 - -119.77 - 0 - 0 - - - - CZQ - 000303 - FRESNO - CA - US - 36.88 - -119.82 - 0 - 0 - - - - YKM - 000279 - YAKIMA - WA - US - 46.57 - -120.45 - 0 - 0 - - - - LKV - 000158 - LAKEVIEW - OR - US - 42.49 - -120.51 - 0 - 0 - - - - YDC - 000389 - PRINCETON - BC - CN - 49.47 - -120.52 - 0 - 0 - - - - MOD - 000186 - MODESTO - CA - US - 37.63 - -120.96 - 0 - 0 - - - - DSD - 000314 - REDMOND - WA - US - 44.25 - -121.30 - 0 - 0 - - - - SAC - 000236 - SACRAMENTO - CA - US - 38.44 - -121.55 - 0 - 0 - - - - SNS - 000253 - SALINAS - CA - US - 36.66 - -121.60 - 0 - 0 - - - - OAK - 000356 - OAKLAND - CA - US - 37.73 - -122.22 - 0 - 0 - - - - RBL - 000225 - RED_BLUFF - CA - US - 40.10 - -122.24 - 0 - 0 - - - - SEA - 000243 - SEATTLE - WA - US - 47.44 - -122.31 - 0 - 0 - - - - BLI - 000035 - BELLINGHAM - WA - US - 48.95 - -122.58 - 0 - 0 - - - - PDX - 000208 - PORTLAND - OR - US - 45.58 - -122.60 - 0 - 0 - - - - PYE - 000371 - POINT_REYES - CA - US - 38.08 - -122.87 - 0 - 0 - - - - OED - 000362 - MEDFORD - OR - US - 42.48 - -122.91 - 0 - 0 - - - - EUG - 000093 - EUGENE - OR - US - 44.12 - -123.22 - 0 - 0 - - - - ENI - 000323 - UKIAH - CA - US - 39.05 - -123.27 - 0 - 0 - - - - ONP - 000201 - NEWPORT - OR - US - 44.58 - -124.06 - 0 - 0 - - - - HQM - 000127 - HOQUIAM - WA - US - 46.95 - -124.15 - 0 - 0 - - - - FOT - 000106 - FORTUNA - CA - US - 40.67 - -124.23 - 0 - 0 - - - - TOU - 000265 - NEAH_BAY - WA - US - 48.30 - -124.63 - 0 - 0 - - - - YQV - 000402 - YORKTON - SA - CN - 51.27 - -102.47 - 0 - 0 - - - - ANN - 0 - ANNETTE_ISLAND - AK - US - 55.05 - -131.57 - 0 - 0 - - - - LVD - 0 - LEVEL_ISLAND - AK - US - 56.47 - -133.08 - 0 - 0 - - - - BKA - 0 - BIORKA_ISLAND - AK - US - 56.86 - -135.55 - 0 - 0 - - - - SSR - 0 - SISTERS_ISLAND - AK - US - 58.17 - -135.25 - 0 - 0 - - - - JNU - 0 - JUNEAU - AK - US - 58.35 - -134.58 - 0 - 0 - - - - YAK - 0 - YAKUTAT - AK - US - 59.50 - -139.67 - 0 - 0 - - - - MDO - 0 - MIDDLETON_ISLAND - AK - US - 59.45 - -146.30 - 0 - 0 - - - - JOH - 0 - JOHNSTONE_POINT - AK - US - 60.48 - -146.60 - 0 - 0 - - - - ODK - 0 - KODIAK - AK - US - 57.75 - -152.50 - 0 - 0 - - - - HOM - 0 - HOMER - AK - US - 59.65 - -151.48 - 0 - 0 - - - - ENA - 0 - KENAI - AK - US - 60.57 - -151.25 - 0 - 0 - - - - ANC - 0 - ANCHORAGE - AK - US - 61.17 - -150.00 - 0 - 0 - - - - BGQ - 0 - BIG_LAKE - AK - US - 61.53 - -149.82 - 0 - 0 - - - - ORT - 0 - NORTHWAY - AK - US - 62.97 - -141.93 - 0 - 0 - - - - GKN - 0 - GULKANA - AK - US - 62.15 - -145.45 - 0 - 0 - - - - TKA - 0 - TALKEETNA - AK - US - 62.32 - -150.10 - 0 - 0 - - - - SQA - 0 - SPARREVOHN - AK - US - 61.10 - -155.63 - 0 - 0 - - - - DLG - 0 - DILLINGHAM - AK - US - 59.05 - -158.50 - 0 - 0 - - - - AKN - 0 - KING_SALMON - AK - US - 58.68 - -156.65 - 0 - 0 - - - - PDN - 0 - PORT_HEIDEN - AK - US - 56.95 - -158.65 - 0 - 0 - - - - CDB - 0 - COLD_BAY - AK - US - 55.20 - -162.73 - 0 - 0 - - - - DUT - 0 - DUTCH_HARBOR - AK - US - 53.90 - -166.55 - 0 - 0 - - - - NUD - 0 - ADAK - AK - US - 51.88 - -176.65 - 0 - 0 - - - - SYA - 0 - SHEMYA - AK - US - 52.72 - 174.12 - 0 - 0 - - - - SPY - 0 - ST_PAUL_ISLAND - AK - US - 57.17 - -170.22 - 0 - 0 - - - - EHM - 0 - CAPE_NEWENHAM - AK - US - 58.66 - -162.07 - 0 - 0 - - - - HPB - 0 - HOOPER_BAY - AK - US - 61.52 - -166.14 - 0 - 0 - - - - BET - 0 - BETHEL - AK - US - 60.78 - -161.83 - 0 - 0 - - - - ANI - 0 - ANIAK - AK - US - 61.59 - -159.61 - 0 - 0 - - - - SMA - 0 - ST_MARYS - AK - US - 62.06 - -163.30 - 0 - 0 - - - - UNK - 0 - UNALAKLEET - AK - US - 63.88 - -160.80 - 0 - 0 - - - - ULL - 0 - KUKULIAK - AK - US - 63.70 - -170.48 - 0 - 0 - - - - MCG - 0 - MC_GRATH - AK - US - 62.95 - -155.60 - 0 - 0 - - - - ENN - 0 - NENANA - AK - US - 64.55 - -149.07 - 0 - 0 - - - - FAI - 0 - FAIRBANKS - AK - US - 64.82 - -147.85 - 0 - 0 - - - - BIG - 0 - BIG_DELTA - AK - US - 64.00 - -145.72 - 0 - 0 - - - - FYU - 0 - FORT_YUKON - AK - US - 66.57 - -145.25 - 0 - 0 - - - - BTT - 0 - BETTLES - AK - US - 66.92 - -151.53 - 0 - 0 - - - - TAL - 0 - TANANA - AK - US - 65.18 - -152.18 - 0 - 0 - - - - CQR - 0 - CHANDALAR_LAKE - AK - US - 67.50 - -148.47 - 0 - 0 - - - - SCC - 0 - DEADHORSE - AK - US - 70.20 - -148.47 - 0 - 0 - - - - BTI - 0 - BARTER_ISLAND - AK - US - 70.13 - -143.57 - 0 - 0 - - - - BRW - 0 - BARROW - AK - US - 71.28 - -156.77 - 0 - 0 - - - - GAL - 0 - GALENA - AK - US - 64.73 - -156.93 - 0 - 0 - - - - OME - 0 - NOME - AK - US - 64.52 - -165.45 - 0 - 0 - - - - OTZ - 0 - KOTZEBUE - AK - US - 66.88 - -162.60 - 0 - 0 - - - - WLK - 0 - SELAWIK - AK - US - 66.60 - -160.00 - 0 - 0 - - - - HSL - 0 - HUSLIA - AK - US - 65.71 - -156.37 - 0 - 0 - - - - BSF - 0 - BRADSHAW - HI - US - 19.76 - -155.39 - 0 - 0 - - - - UPP - 0 - UPOLU_POINT - HI - US - 20.20 - -155.84 - 0 - 0 - - - - ITO - 0 - HILO - HI - US - 19.72 - -155.01 - 0 - 0 - - - - HNL - 0 - HONOLULU - HI - US - 21.33 - -157.93 - 0 - 0 - - - - OGG - 0 - MAUI - HI - US - 20.91 - -156.42 - 0 - 0 - - - - NDB - 0 - VALLEY_ISLAND - HI - US - 20.88 - -156.44 - 0 - 0 - - - - MUE - 0 - KAMUELA - HI - US - 20.00 - -155.67 - 0 - 0 - - - - NGF - 0 - KANEOHE_BAY - HI - US - 21.45 - -157.76 - 0 - 0 - - - - MKK - 0 - MOLOKAI - HI - US - 21.14 - -157.17 - 0 - 0 - - - - NBS - 0 - BARKING_SANDS - HI - US - 22.04 - -159.79 - 0 - 0 - - - - CKH - 0 - KOKO_HEAD - HI - US - 21.27 - -157.70 - 0 - 0 - - - - IAI - 0 - KONA - HI - US - 19.65 - -156.02 - 0 - 0 - - - - LLD - 0 - LANAI - HI - US - 20.77 - -156.97 - 0 - 0 - - - - LNY - 0 - LANAI_CITY - HI - US - 20.76 - -156.97 - 0 - 0 - - - - LIH - 0 - LIHUE - HI - US - 21.97 - -159.34 - 0 - 0 - - - - SOK - 0 - SOUTH_KAUAI - HI - US - 21.90 - -159.53 - 0 - 0 - - - - RSW - 0 - LEE_COUNTY - FL - US - 26.53 - -81.78 - 0 - 0 - - - - PZD - 0 - PECAN - GA - US - 31.66 - -84.29 - 0 - 0 - - - - IIU - 0 - LOUISVILLE - KY - US - 38.10 - -85.58 - 0 - 0 - - - - HRV - 0 - HARVEY - LA - US - 29.85 - -90.00 - 0 - 0 - - - - MCI - 0 - KANSAS_CITY - MO - US - 39.29 - -94.74 - 0 - 0 - - - - TTT - 0 - MAVERICK - TX - US - 32.87 - -97.04 - 0 - 0 - - - - CWK - 0 - CENTEX - TX - US - 30.38 - -97.53 - 0 - 0 - - - - CME - 0 - CHISUM - NM - US - 33.34 - -104.62 - 0 - 0 - - - - FTI - 0 - FT_UNION - NM - US - 35.66 - -105.14 - 0 - 0 - - - - RSK - 0 - RATTLESNAKE - NM - US - 36.75 - -108.10 - 0 - 0 - - - - HUH - 0 - WHATCOM - WA - US - 48.95 - -122.58 - 0 - 0 - - - - ASRF - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - AYPY - 940350 - PORT_MORESBY_INTL - - NG - -9.43 - 147.22 - 47 - 0 - - - - BGSF - 042310 - SONDRE_STROMFJORD - - GL - 67.00 - -50.80 - 53 - 0 - - - - BIRK - 040300 - REYKJAVIK - - IL - 64.13 - -21.90 - 61 - 0 - - - - CWEG - 999999 - ALBERTA_WEATHER_CENTRE - - CN - 53.50 - -113.50 - -9999 - 0 - - - - CWLW - 712030 - KELOWNA - BC - CN - 49.95 - -119.40 - 456 - 0 - - - - CWNT - 712500 - TURTLE_MOUNTAIN - AB - CN - 49.58 - -114.42 - 2164 - 0 - - - - CWTO - 716380 - TORONTO_A_E_S__HQ - ON - CN - 43.78 - -79.47 - 187 - 0 - - - - CWUL - 999999 - QUEBEC_FCST_OFFICE - - CN - 45.50 - -73.68 - -9999 - 0 - - - - CYQX - 718030 - GANDER_INTL_AIRPORT - NF - CN - 48.95 - -54.57 - 151 - 0 - - - - DTTA - 607150 - TUNIS/CARTHAGE - - TS - 36.83 - 10.23 - 4 - 0 - - - - EBBR - 064510 - BRUSSELS_NATIONAL - - BX - 50.90 - 4.53 - 58 - 0 - - - - EDMM - 108680 - MUENCHEN - - DL - 48.25 - 11.58 - 484 - 0 - - - - EDZB - 102380 - BERGEN/HOHNE - - DL - 52.82 - 9.93 - 70 - 0 - - - - EDZE - 104100 - ESSEN/MULHEIM - - DL - 51.40 - 6.97 - 161 - 0 - - - - EDZF - 106370 - FRANKFURT/MAIN - - DL - 50.05 - 8.58 - 112 - 0 - - - - EDZH - 107710 - GAERMERSDORF - - DL - 49.43 - 11.90 - 419 - 0 - - - - EDZM - 108680 - MUENCHEN - - DL - 48.25 - 11.58 - 484 - 0 - - - - EETN - 260380 - TALLIN - - BY - 59.35 - 24.80 - 44 - 0 - - - - EFHK - 029740 - HELSINKI/VANTAA - - FI - 60.32 - 24.97 - 56 - 0 - - - - EFRO - 028450 - ROVANIEMI(CIV/MIL) - - FI - 66.57 - 25.83 - 201 - 0 - - - - EGJJ - 038950 - JERSEY_AIRPORT - - UK - 49.22 - -2.20 - 84 - 0 - - - - EHAM - 062400 - AMSTERDAM/SCHIPHOL - - NL - 52.30 - 4.77 - -2 - 0 - - - - EHDB - 062600 - DE_BILT - - NL - 52.10 - 5.18 - 4 - 0 - - - - EINN - 039620 - SHANNON_AIRPORT - - IE - 52.70 - -8.92 - 20 - 0 - - - - EKCH - 061800 - COPENHAGEN/KASTRUP - - DN - 55.63 - 12.67 - 5 - 0 - - - - ENMI - 999999 - OSLO - - NO - 59.50 - 10.70 - -9999 - 0 - - - - ENVN - 011520 - BODO - - NO - 67.25 - 14.40 - 8 - 0 - - - - ENVV - 014150 - STAVANGER - - NO - 58.87 - 5.67 - 34 - 0 - - - - EPWA - 123750 - WARSAW/OKECIE - - PL - 52.17 - 20.97 - 107 - 0 - - - - ESNN - 023660 - SUNDSVALL/HARNOSAND - - SN - 62.53 - 17.45 - 10 - 0 - - - - ESSA - 024600 - STOCKHOLM/ARLANDA - - SN - 59.65 - 17.95 - 61 - 0 - - - - EVRA - 999999 - RIGA_AIRPORT - LE - BY - 56.92 - 23.97 - 10 - 0 - - - - EYVI - 267300 - VILNIUS_INTL - MI - BY - 54.63 - 25.28 - 156 - 0 - - - - FAJS - 683680 - JAN_SMUTS - - ZA - -26.13 - 28.23 - 1700 - 0 - - - - FCBB - 644500 - BRAZZAVILLE/MAYA-MA - - CG - -4.25 - 15.25 - 316 - 0 - - - - FTTJ - 647000 - NDJAMENA(CIV/MIL) - - CD - 12.13 - 15.03 - 295 - 0 - - - - GCGC - 999999 - CANARY_ISLANDS - - CR - 28.50 - -16.00 - -9999 - 0 - - - - GMMC - 601550 - CASABLANCA - - MC - 33.57 - -7.67 - 62 - 0 - - - - HECA - 623660 - CAIRO_INTL_AIRPORT - - EG - 30.13 - 31.40 - 74 - 0 - - - - LBSF - 156140 - SOFIA - - BU - 42.65 - 23.38 - 595 - 0 - - - - LBWN - 155520 - VARNA - - BU - 43.20 - 27.92 - 43 - 0 - - - - LCLK - 176090 - LARNACA/LARNAX_ARPT - - CY - 34.88 - 33.63 - 2 - 0 - - - - LDZA - 131310 - ZAGREB/PLESO - - RH - 45.73 - 16.07 - 107 - 0 - - - - LDZO - 999999 - ZAGREB/PLESO - - RH - 45.73 - 16.07 - 107 - 0 - - - - LECB - 081810 - BARCELONA - - SP - 41.28 - 2.07 - 6 - 0 - - - - LEMM - 999999 - MADRID_CNM - - SP - 40.12 - -3.53 - -9999 - 0 - - - - LFBD - 075100 - BORDEAUX/MERIGNAC - - FR - 44.83 - -.70 - 61 - 0 - - - - LFMM - 076500 - MARSEILLE - - FR - 43.45 - 5.22 - 20 - 0 - - - - LFPW - 999999 - PARIS_MET_CENTER - - FR - 48.83 - 2.33 - 75 - 0 - - - - LFRN - 071300 - RENNES/ST.JACQUES - - FR - 48.07 - -1.73 - 37 - 0 - - - - LFST - 071900 - STRASBOURG/ENTZHEIM - - FR - 48.55 - 7.63 - 154 - 0 - - - - LGAT - 167160 - ATHENS/HELLENKION - - GR - 37.90 - 23.73 - 15 - 0 - - - - LHBP - 128390 - BUDAPEST/FERIHEGY - - HU - 47.43 - 19.27 - 185 - 0 - - - - LIMM - 160800 - MILANO/LINATE - - IY - 45.43 - 9.27 - 103 - 0 - - - - LJLJ - 130140 - LJUBLJANA/BRNIK - - LJ - 46.22 - 14.48 - 385 - 0 - - - - LKPR - 115180 - PRAGUE/RUZYNE - - CZ - 50.10 - 14.28 - 365 - 0 - - - - LLBG - 401800 - BEN-GURION(CIV/MIL) - - IS - 32.00 - 34.90 - 49 - 0 - - - - LMML - 165970 - LUQA/MALTA - - ML - 35.85 - 14.48 - 91 - 0 - - - - LOWW - 110360 - VIENNA/SCHWECHAT - - OS - 48.12 - 16.57 - 190 - 0 - - - - LPPT - 085360 - LISBON/PORTELA - - PO - 38.78 - -9.13 - 123 - 0 - - - - LROM - 154210 - BUCHAREST/OTOPENI - - RO - 44.55 - 26.10 - 95 - 0 - - - - LROP - 154210 - BUCHAREST/OTOPENI - - RO - 44.55 - 26.10 - 95 - 0 - - - - LSZH - 066700 - ZURICH-KLOTEN_(AUT) - - SW - 47.48 - 8.53 - 432 - 0 - - - - LTAC - 171280 - ANKARA/ESENBOGA - - TU - 40.11 - 32.97 - 949 - 0 - - - - LTBA - 170600 - ISTANBUL/ATATURK_AB - - TU - 40.97 - 28.82 - 37 - 0 - - - - LUKK - 338387 - KISHINAU - - UR - 46.93 - 28.93 - 122 - 0 - - - - LWSK - 135860 - SKOPJE/PETROVAC - - MK - 41.97 - 21.65 - 239 - 0 - - - - LYBE - 132720 - BELGRADE/SURCIN - - YG - 44.82 - 20.28 - 99 - 0 - - - - LZIB - 118160 - BRATISLAVA_IVANKA - - CZ - 48.20 - 17.20 - 130 - 0 - - - - NFFN - 916800 - NANDI/NADI_INTL - - FJ - -17.75 - 177.45 - 18 - 0 - - - - NZDT - 999999 - NEW_ZEALAND - - NZ - -41.00 - 172.50 - -9999 - 0 - - - - NZKL - 999999 - AUCKLAND - - NZ - -37.02 - 174.80 - 6 - 0 - - - - MHTG - 787200 - TEGUCIGALPA/TONCONT - - HO - 14.05 - -87.22 - 994 - 0 - - - - MPTO - 787920 - TOCUMEN/GEN._OMAR - - PM - 9.05 - -79.37 - 11 - 0 - - - - OBBB - 999999 - BAHRAIN_INTL_ARPT - - BN - 26.27 - 50.65 - 2 - 0 - - - - OBBI - 411500 - BAHRAIN_INTL_ARPT - - BN - 26.27 - 50.65 - 2 - 0 - - - - OEJD - 999999 - JEDDAH - - SD - 21.30 - 39.20 - -9999 - 0 - - - - OEJN - 410240 - JEDDAH/KING_ABD - - SD - 21.67 - 39.15 - 12 - 0 - - - - OIII - 407540 - TEHRAN/MEHRABAD_AFB - - IR - 35.68 - 51.35 - 1191 - 0 - - - - OIIX - 999999 - TEHRAN - - IR - 35.68 - 51.35 - 1191 - 0 - - - - OLBA - 401000 - BEIRUT_(CIV/MIL) - - LB - 33.82 - 35.48 - 19 - 0 - - - - OPKC - 417800 - KARACHI_INTL_ARPT - - PK - 24.90 - 67.13 - 22 - 0 - - - - OPLA - 416410 - LAHORE(CIV/MIL) - - PK - 31.52 - 74.40 - 217 - 0 - - - - OYSN - 413440 - SANA'A - - YE - 15.52 - 44.18 - 2190 - 0 - - - - PAFA - 702610 - FAIRBANKS_INTL_ARPT_(ASOS) - AK - US - 64.82 - -147.87 - 138 - 0 - - - - PAJN - 703810 - JUNEAU_INTL_AIRPORT_(ASOS) - AK - US - 58.37 - -134.58 - 7 - 0 - - - - PANC - 702730 - ANCHORAGE_INTL_ARPT_(ASOS) - AK - US - 61.17 - -150.02 - 40 - 0 - - - - RKSI - 470699 - CHAJANG_NI_(K-ARMY) - - KO - 37.87 - 127.18 - 100 - 0 - - - - RCTP - 466860 - TAIPEI/CHIANG_KAI_SHEK - - TW - 25.08 - 121.22 - 33 - 0 - - - - SABE - 875820 - AEROPARQUE(CIV/MIL) - - AG - -34.57 - -58.42 - 6 - 0 - - - - SACO - 873440 - CORDOBA_AIRPORT - - AG - -31.32 - -64.22 - 474 - 0 - - - - SAEZ - 875760 - BUENOS_AIRES/EZEIZA - - AG - -34.82 - -58.53 - 20 - 0 - - - - SAME - 874180 - MENDOZA/EL_PLUMERIL - - AG - -32.83 - -68.78 - 704 - 0 - - - - SARE - 871550 - RESISTENCIA_AIRPORT - - AG - -27.45 - -59.05 - 52 - 0 - - - - SBBE - 821930 - BELEM/VAL_DE_CAES - - BZ - -1.38 - -48.48 - 16 - 0 - - - - SBBR - 833780 - BRASILIA_(CIV/MIL) - - BZ - -15.87 - -47.93 - 1061 - 0 - - - - SBBS - 833780 - BRASILIA - - BZ - -15.87 - -47.93 - 1061 - 0 - - - - SBCT - 838400 - CURITIBA/AFONSO_PEN - - BZ - -25.52 - -49.17 - 908 - 0 - - - - SBCW - 838400 - CURITIBA/AFONSO_PEN - - BZ - -25.52 - -49.17 - 908 - 0 - - - - SBEG - 821110 - EDUARDO_GOMES_INTL - - BZ - -3.03 - -60.05 - 2 - 0 - - - - SBGL - 837460 - GALEAO/RIO(CIV/MIL) - - BZ - -22.82 - -43.25 - 6 - 0 - - - - SBGR - 837753 - GUARULHOS_(CIV/MIL) - - BZ - -23.43 - -46.47 - 750 - 0 - - - - SBRF - 828990 - RECIFE/GUARARAPES - - BZ - -8.07 - -34.85 - 19 - 0 - - - - SCCI - 859340 - PUNTA_ARENAS/PRES_C - - CH - -53.00 - -70.85 - 37 - 0 - - - - SCEL - 855740 - PUDAHUEL/ARTURO_MER - - CH - -33.38 - -70.78 - 476 - 0 - - - - SCFA - 854420 - ANTOFAGASTA/CERRO - - CH - -23.43 - -70.43 - 120 - 0 - - - - SCTE - 857990 - PUERTO_MONTT/TEPUAL - - CH - -41.42 - -73.08 - 86 - 0 - - - - SLLP - 852010 - LA_PAZ/JFK_INTL - - BO - -16.52 - -68.18 - 4014 - 0 - - - - SOCA - 814050 - CAYENNE/ROCHAMBEAU - - FG - 4.83 - -52.37 - 9 - 0 - - - - SPIM - 846280 - LIMA/JORGE_CHAVEZ - - PR - -12.00 - -77.12 - 13 - 0 - - - - TNCC - 789880 - HATO_ARPT_(CIV/MIL) - - NU - 12.20 - -68.97 - 67 - 0 - - - - TTPP - 789700 - PIARCO_INTL_AIRPORT - - TD - 10.62 - -61.35 - 15 - 0 - - - - UAAA - 368700 - ALMA-ATA - AL - RA - 43.23 - 76.93 - 847 - 0 - - - - UAFM - 835300 - FRUNZE - - RA - 42.85 - 74.53 - 760 - 0 - - - - UATT - 352290 - AKTJUBINSK - AL - KZ - 50.30 - 57.23 - 227 - 0 - - - - UBBB - 378640 - BAKU/BINE_ARPT - TB - AJ - 40.45 - 50.07 - -1 - 0 - - - - UGEE - 377890 - YEREVAN/ZAPADNY - TB - RS - 40.13 - 44.47 - 907 - 0 - - - - UGGG - 375490 - TBILISI/NOVO-AL - TB - RS - 41.68 - 44.95 - 490 - 0 - - - - UHBB - 315100 - BLAGOVESHCHENSK - HA - RA - 50.27 - 127.50 - 137 - 0 - - - - UHHH - 317350 - KHABAROVSK/NOVY - HA - RA - 48.52 - 135.16 - 72 - 0 - - - - UHNN - 999999 - NIKOLAEVSK-NA-AMURE_CENTER - HA - RA - 53.15 - 140.70 - 68 - 0 - - - - UHWW - 319600 - VLADIVOSTOK - HA - RA - 43.12 - 131.94 - 184 - 0 - - - - UHPP - 325400 - PETROPAVLOVSK-KAMCA - HA - RA - 52.97 - 158.75 - 24 - 0 - - - - UHSS - 321500 - JUZNO-SAHALINSK - HA - RA - 46.92 - 142.73 - 31 - 0 - - - - UIBB - 303090 - BRATSK - - RA - 56.07 - 101.83 - 489 - 0 - - - - UIII - 307100 - IRKUTSK - IR - RA - 52.27 - 104.35 - 513 - 0 - - - - UIKK - 302300 - KIRENSK - IR - RA - 57.77 - 108.07 - 258 - 0 - - - - UKBB - 333470 - BORISPOL'/KIEV - KV - UR - 50.33 - 30.97 - 119 - 0 - - - - UKFF - 339460 - SIMFEROPOL - - UR - 44.68 - 34.13 - 180 - 0 - - - - UKHH - 343000 - KHARKIV - KI - UR - 49.96 - 36.13 - 1550 - 0 - - - - UKLL - 333930 - LVOV - KI - UR - 49.82 - 23.95 - 325 - 0 - - - - UKOO - 338370 - ODESSA/TSENTRALNY - KI - UR - 46.43 - 30.77 - 35 - 0 - - - - ULAA - 225500 - ARHANGELSK - AR - RS - 64.53 - 40.47 - 13 - 0 - - - - ULLI - 260630 - ST.PETERSBURG(VOEJKOVO) - LE - RS - 59.95 - 30.70 - 78 - 0 - - - - ULLL - 260630 - ST.PETERSBURG - LE - RS - 59.95 - 30.70 - 78 - 0 - - - - ULWW - 270370 - VOLOGDA - AR - RS - 59.23 - 39.87 - 131 - 0 - - - - ULMM - 221130 - MURMANSK - AR - RS - 68.97 - 33.05 - 51 - 0 - - - - UMKK - 267020 - KALININGRAD - - BY - 54.70 - 20.62 - 27 - 0 - - - - UMMS - 268500 - MINSK - MI - BY - 53.87 - 27.53 - 234 - 0 - - - - UNBB - 298380 - BARNAUL - NO - RA - 53.40 - 83.70 - 252 - 0 - - - - UNIT - 245070 - TURA - NO - RA - 64.27 - 100.23 - 186 - 0 - - - - UNKB - 292820 - BOGUCHANY - NO - RA - 58.42 - 97.40 - 134 - 0 - - - - UNKL - 284935 - KRASNOYARSK - - RS - 56.18 - 92.52 - -9999 - 0 - - - - UNLL - 999999 - KOLPASHEVO - NO - RA - 58.30 - 82.90 - 76 - 0 - - - - UNNT - 296340 - NOVOSIBIRSK/TOLMACH - - RA - 55.03 - 82.90 - 177 - 0 - - - - UNOO - 286980 - OMSK - NO - RA - 54.93 - 73.40 - 123 - 0 - - - - UODD - 206740 - DIKSON_ISLAND - DK - RA - 73.53 - 80.40 - 47 - 0 - - - - UOHH - 208910 - KHATANGA - DK - RA - 71.98 - 102.47 - 24 - 0 - - - - UOTT - 234720 - TURUKHANSK - - RA - 65.78 - 087.95 - 37 - 0 - - - - URRV - 273290 - ROSTOV - MS - RS - 57.20 - 39.42 - 102 - 0 - - - - URWA - 999999 - ASTRAKHAN - - RS - 46.35 - 47.97 - -22 - 0 - - - - URWW - 345600 - VOLGOGRAD - TB - RS - 48.68 - 44.35 - 145 - 0 - - - - USCC - 286420 - CHELYABINSK/BALANDI - SV - RA - 55.18 - 61.32 - -9999 - 0 - - - - USDD - 999999 - SALEKHARD - NO - RA - 66.53 - 66.53 - 358 - 0 - - - - USDS - 235520 - TARKO-SALE - NO - RA - 64.92 - 77.82 - 27 - 0 - - - - USHB - 236310 - BEREZOVO - NO - RA - 63.93 - 65.05 - 27 - 0 - - - - USHH - 239330 - HANTY-MANSIJSK - NO - RA - 60.97 - 69.07 - 40 - 0 - - - - USKK - 999999 - KIROV - MS - RS - 58.60 - 49.63 - 158 - 0 - - - - USPP - 282250 - PERM - SV - RA - 58.02 - 56.30 - 172 - 0 - - - - USRR - 238490 - SURGUT - NO - RA - 61.25 - 73.50 - 44 - 0 - - - - USSS - 284400 - SVERDLOVSK - SV - RA - 56.80 - 60.63 - 237 - 0 - - - - USUU - 286610 - KURGAN - SV - RA - 55.47 - 65.40 - 79 - 0 - - - - UTAA - 388800 - ASHABAD - TA - RA - 37.97 - 58.33 - 210 - 0 - - - - UTTT - 384570 - TASHKENT/YUZNI - TA - RA - 41.27 - 69.27 - 489 - 0 - - - - UUWW - 275185 - MOSCOW/VNUKOVO - MS - RS - 55.65 - 37.27 - 203 - 0 - - - - UUYP - 234180 - PECHORA - AR - RS - 65.11 - 57.10 - 61 - 0 - - - - UUYW - 232260 - VORKUTA - AR - RA - 67.48 - 64.02 - 180 - 0 - - - - UUYY - 238040 - SYKTYVKAR - AR - RA - 61.72 - 50.83 - 119 - 0 - - - - UWKD - 275950 - KAZAN' - MS - RS - 55.78 - 49.18 - 116 - 0 - - - - UWUU - 287220 - UFA - SV - RA - 54.75 - 56.00 - 105 - 0 - - - - VABB - 430030 - BOMBAY/SANTA_CR - - IN - 19.12 - 72.84 - 14 - 0 - - - - VCBI - 434500 - COLOMBO/KATUNAYAKE - - SB - 7.17 - 79.88 - 8 - 0 - - - - VGZR - 419220 - KURMITOLA/ZIA_INTL - - BW - 23.85 - 90.40 - 10 - 0 - - - - VHHH - 450070 - HONG_KONG_INTL_ARPT - - HK - 22.33 - 114.18 - 24 - 0 - - - - VIDP - 421810 - INDIRA_GANDHI/DELHI - - IN - 28.57 - 77.12 - 233 - 0 - - - - WSSS - 486980 - SINGAPORE/CHANG - - SR - 1.37 - 103.98 - 16 - 0 - - - - YBRF - 945780 - BRISBANE - QU - AU - -27.43 - 153.08 - 2 - 0 - - - - YBTL - 942940 - TOWNSVILLE(CIV/MIL) - QU - AU - -19.25 - 146.75 - 6 - 0 - - - - YMHF - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YMMB - 948700 - MOORABBIN_AIRPORT - VC - AU - -37.98 - 145.10 - 13 - 0 - - - - YMMC - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YMRF - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YPDM - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YPRF - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YPRM - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - YSRF - 948640 - MELBOURNE - VC - AU - -37.73 - 144.90 - 81 - 0 - - - - ZPPP - 567780 - KUNMING/WUJIABA - CD - CI - 25.02 - 102.68 - 1892 - 0 - - - + + + + + YSJ + 000395 + ST_JOHN + NB + CN + 45.32 + -65.88 + 0 + 0 + + + + HUL + 000341 + HOULTON + ME + US + 46.04 + -67.83 + 0 + 0 + + + + PQI + 000367 + PRESQUE_ISLE + ME + US + 46.77 + -68.09 + 0 + 0 + + + + MLT + 000183 + MILLINOCKET + ME + US + 45.58 + -68.52 + 0 + 0 + + + + BGR + 000029 + BANGOR + ME + US + 44.84 + -68.87 + 0 + 0 + + + + ACK + 000005 + NANTUCKET + MA + US + 41.28 + -70.03 + 0 + 0 + + + + ENE + 000322 + KENNEBUNK + ME + US + 43.43 + -70.61 + 0 + 0 + + + + BOS + 000289 + BOSTON + MA + US + 42.36 + -70.99 + 0 + 0 + + + + YQB + 000391 + QUEBEC + QB + CN + 46.80 + -71.38 + 0 + 0 + + + + PVD + 000221 + PROVIDENCE + RI + US + 41.72 + -71.43 + 0 + 0 + + + + CON + 000062 + CONCORD + NH + US + 43.22 + -71.58 + 0 + 0 + + + + YSC + 000394 + SHERBROOKE + QB + CN + 45.43 + -71.68 + 0 + 0 + + + + HTO + 000340 + EAST_HAMPTON + NY + US + 40.92 + -72.32 + 0 + 0 + + + + MPV + 000188 + MONTPELIER + VT + US + 44.22 + -72.57 + 0 + 0 + + + + BDL + 000287 + WINSOR_LOCKS + CT + US + 41.94 + -72.69 + 0 + 0 + + + + PLB + 000365 + PLATTSBURGH + NY + US + 44.69 + -73.52 + 0 + 0 + + + + JFK + 000345 + NEW_YORK/JF_KENNEDY + NY + US + 40.63 + -73.77 + 0 + 0 + + + + ALB + 000012 + ALBANY + NY + US + 42.75 + -73.80 + 0 + 0 + + + + CYN + 000300 + COYLE + NJ + US + 39.82 + -74.43 + 0 + 0 + + + + SAX + 000376 + SPARTA + NJ + US + 41.07 + -74.54 + 0 + 0 + + + + MSS + 000353 + MASSENA + NY + US + 44.91 + -74.72 + 0 + 0 + + + + SIE + 000377 + SEA_ISLE + NJ + US + 39.10 + -74.80 + 0 + 0 + + + + HNK + 000338 + HANCOCK + NY + US + 42.06 + -75.32 + 0 + 0 + + + + SBY + 000242 + SALISBURY + MD + US + 38.35 + -75.52 + 0 + 0 + + + + YOW + 000390 + OTTAWA + ON + CN + 45.32 + -75.67 + 0 + 0 + + + + ETX + 000325 + EAST_TEXAS + PA + US + 40.58 + -75.68 + 0 + 0 + + + + ECG + 000086 + ELIZABETH_CITY + NC + US + 36.25 + -76.18 + 0 + 0 + + + + SYR + 000259 + SYRACUSE + NY + US + 43.16 + -76.20 + 0 + 0 + + + + ORF + 000203 + NORFOLK + VA + US + 36.89 + -76.20 + 0 + 0 + + + + EMI + 000320 + WESTMINSTER + MD + US + 39.50 + -76.98 + 0 + 0 + + + + HAR + 000126 + HARRISBURG + PA + US + 40.23 + -77.02 + 0 + 0 + + + + DCA + 000306 + WASHINGTON + DC + US + 38.86 + -77.04 + 0 + 0 + + + + RIC + 000229 + RICHMOND + VA + US + 37.50 + -77.32 + 0 + 0 + + + + CSN + 000299 + CASSANOVA + VA + US + 38.64 + -77.87 + 0 + 0 + + + + ILM + 000135 + WILMINGTON + NC + US + 34.35 + -77.87 + 0 + 0 + + + + SLT + 000252 + SLATE_RUN + PA + US + 41.51 + -77.97 + 0 + 0 + + + + PSB + 000368 + PHILLIPSBURG + PA + US + 40.92 + -77.99 + 0 + 0 + + + + BUF + 000044 + BUFFALO + NY + US + 42.93 + -78.65 + 0 + 0 + + + + RDU + 000372 + RALEIGH-DURHAM + NC + US + 35.87 + -78.78 + 0 + 0 + + + + JST + 000145 + JOHNSTOWN + PA + US + 40.32 + -78.83 + 0 + 0 + + + + JHW + 000346 + JAMESTOWN + NY + US + 42.19 + -79.12 + 0 + 0 + + + + LYH + 000166 + LYNCHBURG + VA + US + 37.25 + -79.23 + 0 + 0 + + + + YYZ + 000401 + TORONTO + ON + CN + 43.67 + -79.63 + 0 + 0 + + + + FLO + 000102 + FLORENCE + SC + US + 34.23 + -79.66 + 0 + 0 + + + + GSO + 000122 + GREENSBORO + NC + US + 36.05 + -79.98 + 0 + 0 + + + + CHS + 000056 + CHARLESTON + SC + US + 32.89 + -80.04 + 0 + 0 + + + + PBI + 000206 + WEST_PALM_BEACH + FL + US + 26.68 + -80.09 + 0 + 0 + + + + EKN + 000088 + ELKINS + WV + US + 38.92 + -80.10 + 0 + 0 + + + + EWC + 000326 + ELLWOOD_CITY + PA + US + 40.83 + -80.21 + 0 + 0 + + + + ERI + 000092 + ERIE + PA + US + 42.02 + -80.30 + 0 + 0 + + + + MIA + 000176 + MIAMI + FL + US + 25.80 + -80.30 + 0 + 0 + + + + VRB + 000276 + VERO_BEACH + FL + US + 27.68 + -80.49 + 0 + 0 + + + + PSK + 000369 + DUBLIN + VA + US + 37.09 + -80.71 + 0 + 0 + + + + AIR + 000280 + BELLAIRE + OH + US + 40.02 + -80.82 + 0 + 0 + + + + CLT + 000059 + CHARLOTTE + NC + US + 35.22 + -80.93 + 0 + 0 + + + + CAE + 000295 + COLUMBIA + SC + US + 33.86 + -81.05 + 0 + 0 + + + + YVV + 000396 + WIARTON + ON + CN + 44.75 + -81.10 + 0 + 0 + + + + SAV + 000239 + SAVANNAH + GA + US + 32.16 + -81.11 + 0 + 0 + + + + OMN + 000363 + ORMOND_BEACH + FL + US + 29.30 + -81.11 + 0 + 0 + + + + BKW + 000034 + BECKLEY + WV + US + 37.78 + -81.12 + 0 + 0 + + + + ORL + 000204 + ORLANDO + FL + US + 28.54 + -81.34 + 0 + 0 + + + + CRG + 000298 + JACKSONVILLE + FL + US + 30.34 + -81.51 + 0 + 0 + + + + EYW + 000096 + KEY_WEST + FL + US + 24.59 + -81.80 + 0 + 0 + + + + FMY + 000104 + FT_MEYERS + FL + US + 26.58 + -81.87 + 0 + 0 + + + + SPA + 000380 + SPARTANBURG + SC + US + 35.03 + -81.93 + 0 + 0 + + + + HNN + 000339 + HENDERSON + WV + US + 38.75 + -82.03 + 0 + 0 + + + + HMV + 000337 + HOLSTON_MOUNTAIN + TN + US + 36.44 + -82.13 + 0 + 0 + + + + CLE + 000058 + CLEVELAND + OH + US + 41.42 + -81.85 + 0 + 0 + + + + IRQ + 000344 + COLLIERS + SC + US + 33.71 + -82.16 + 0 + 0 + + + + AMG + 000015 + ALMA + GA + US + 31.54 + -82.51 + 0 + 0 + + + + SRQ + 000382 + SARASOTA + FL + US + 27.40 + -82.55 + 0 + 0 + + + + APE + 000283 + APPLETON + OH + US + 40.15 + -82.59 + 0 + 0 + + + + PIE + 000212 + SAINT_PETERSBURG + FL + US + 27.91 + -82.68 + 0 + 0 + + + + ECK + 000316 + PECK + MI + US + 43.26 + -82.72 + 0 + 0 + + + + CTY + 000066 + CROSS_CITY + FL + US + 29.60 + -83.05 + 0 + 0 + + + + ODF + 000360 + TOCCOA + GA + US + 34.70 + -83.30 + 0 + 0 + + + + DXO + 000315 + DETROIT + MI + US + 42.21 + -83.37 + 0 + 0 + + + + ASP + 000284 + OSCODA + MI + US + 44.45 + -83.39 + 0 + 0 + + + + MCN + 000170 + MACON + GA + US + 32.69 + -83.65 + 0 + 0 + + + + FNT + 000328 + FLINT + MI + US + 42.97 + -83.74 + 0 + 0 + + + + VXV + 000388 + KNOXVILLE + TN + US + 35.90 + -83.89 + 0 + 0 + + + + ROD + 000373 + ROSEWOOD + OH + US + 40.29 + -84.04 + 0 + 0 + + + + MBS + 000168 + SAGINAW + MI + US + 43.53 + -84.08 + 0 + 0 + + + + LOZ + 000160 + LONDON + KY + US + 37.03 + -84.12 + 0 + 0 + + + + ABY + 000004 + ALBANY + GA + US + 31.65 + -84.30 + 0 + 0 + + + + SSM + 000255 + SAULT_STE_MARIE + MI + US + 46.41 + -84.31 + 0 + 0 + + + + TLH + 000264 + TALLAHASSEE + FL + US + 30.56 + -84.37 + 0 + 0 + + + + ATL + 000019 + ATLANTA + GA + US + 33.63 + -84.44 + 0 + 0 + + + + CVG + 000067 + COVINGTON + KY + US + 39.02 + -84.70 + 0 + 0 + + + + GQO + 000331 + CHATTANOOGA + TN + US + 34.96 + -85.15 + 0 + 0 + + + + FWA + 000109 + FT_WAYNE + IN + US + 40.98 + -85.19 + 0 + 0 + + + + LGC + 000350 + LA_GRANGE + GA + US + 33.05 + -85.21 + 0 + 0 + + + + GRR + 000332 + GRAND_RAPIDS + MI + US + 42.79 + -85.50 + 0 + 0 + + + + TVC + 000270 + TRAVERSE_CITY + MI + US + 44.67 + -85.55 + 0 + 0 + + + + LOU + 000159 + LOUISVILLE + KY + US + 38.10 + -85.58 + 0 + 0 + + + + MKG + 000179 + MUSKEGON + MI + US + 43.17 + -86.04 + 0 + 0 + + + + PMM + 000366 + PULLMAN + MI + US + 42.47 + -86.11 + 0 + 0 + + + + GIJ + 000330 + NILES + MI + US + 41.77 + -86.32 + 0 + 0 + + + + MGM + 000175 + MONTGOMERY + AL + US + 32.22 + -86.32 + 0 + 0 + + + + IND + 000136 + INDIANAPOLIS + IN + US + 39.81 + -86.37 + 0 + 0 + + + + BWG + 000047 + BOWLING_GREEN + KY + US + 36.93 + -86.44 + 0 + 0 + + + + BNA + 000037 + NASHVILLE + TN + US + 36.14 + -86.68 + 0 + 0 + + + + CEW + 000052 + CRESTVIEW + FL + US + 30.83 + -86.68 + 0 + 0 + + + + VUZ + 000387 + VULCAN + AL + US + 33.67 + -86.90 + 0 + 0 + + + + BVT + 000293 + LAFAYETTE + IN + US + 40.56 + -87.07 + 0 + 0 + + + + TTH + 000384 + TERRE_HAUTE + IN + US + 39.49 + -87.25 + 0 + 0 + + + + MSL + 000191 + MUSCLE_SHOALS + AL + US + 34.70 + -87.48 + 0 + 0 + + + + SAW + 000189 + SAWYER + MI + US + 46.35 + -87.38 + 0 + 0 + + + + PXV + 000370 + POCKET_CITY + IN + US + 37.93 + -87.76 + 0 + 0 + + + + ORD + 000202 + O'HARE_INTERNATIONAL + IL + US + 41.98 + -87.90 + 0 + 0 + + + + GRB + 000119 + GREEN_BAY + WI + US + 44.56 + -88.19 + 0 + 0 + + + + BAE + 000285 + MILWAUKEE + WI + US + 43.12 + -88.28 + 0 + 0 + + + + JOT + 000348 + JOLIET + IL + US + 41.55 + -88.32 + 0 + 0 + + + + SJI + 000378 + SEMMNES + AL + US + 30.73 + -88.36 + 0 + 0 + + + + IGB + 000133 + BIGBEE + MS + US + 33.48 + -88.52 + 0 + 0 + + + + MEI + 000172 + MERIDIAN + MS + US + 32.38 + -88.80 + 0 + 0 + + + + DEC + 000070 + DECATUR + IL + US + 39.74 + -88.86 + 0 + 0 + + + + YQT + 000393 + THUNDER_BAY + ON + CN + 48.37 + -89.32 + 0 + 0 + + + + DYR + 000083 + DYERSBURG + TN + US + 36.02 + -89.32 + 0 + 0 + + + + RHI + 000228 + RHINELANDER + WI + US + 45.63 + -89.45 + 0 + 0 + + + + BDF + 000024 + BRADFORD + IL + US + 41.16 + -89.59 + 0 + 0 + + + + DLL + 000310 + DELLS + WI + US + 43.55 + -89.76 + 0 + 0 + + + + MEM + 000173 + MEMPHIS + TN + US + 35.06 + -89.98 + 0 + 0 + + + + LEV + 000349 + GRAND_ISLE + LA + US + 29.18 + -90.10 + 0 + 0 + + + + JAN + 000142 + JACKSON + MS + US + 32.51 + -90.17 + 0 + 0 + + + + MSY + 000195 + NEW_ORLEANS + LA + US + 30.00 + -90.27 + 0 + 0 + + + + FAM + 000097 + FARMINGTON + MO + US + 37.67 + -90.23 + 0 + 0 + + + + MCB + 000169 + MC_COMB + MS + US + 31.30 + -90.26 + 0 + 0 + + + + SQS + 000381 + SIDON + MS + US + 33.46 + -90.28 + 0 + 0 + + + + STL + 000257 + ST_LOUIS + MO + US + 38.86 + -90.48 + 0 + 0 + + + + DBQ + 000069 + DUBUQUE + IA + US + 42.40 + -90.71 + 0 + 0 + + + + ARG + 000018 + WALNUT_RIDGE + AR + US + 36.11 + -90.95 + 0 + 0 + + + + UIN + 000386 + QUINCY + IL + US + 39.85 + -91.28 + 0 + 0 + + + + BTR + 000042 + BATON_ROUGE + LA + US + 30.48 + -91.30 + 0 + 0 + + + + ODI + 000361 + NODINE + MN + US + 43.91 + -91.47 + 0 + 0 + + + + EAU + 000085 + EAU_CLAIRE + WI + US + 44.90 + -91.48 + 0 + 0 + + + + IOW + 000343 + IOWA_CITY + IA + US + 41.52 + -91.61 + 0 + 0 + + + + MLU + 000184 + MONROE + LA + US + 32.52 + -92.03 + 0 + 0 + + + + LIT + 000156 + LITTLE_ROCK + AR + US + 34.68 + -92.18 + 0 + 0 + + + + DLH + 000075 + DULUTH + MN + US + 46.80 + -92.20 + 0 + 0 + + + + COU + 000063 + COLUMBIA + MO + US + 38.82 + -92.22 + 0 + 0 + + + + AEX + 000009 + ALEXANDRIA + LA + US + 31.26 + -92.50 + 0 + 0 + + + + IRK + 000139 + KIRKSVILLE + MO + US + 40.14 + -92.59 + 0 + 0 + + + + ELD + 000319 + EL_DORADO + AR + US + 33.26 + -92.74 + 0 + 0 + + + + LCH + 000154 + LAKE_CHARLES + LA + US + 30.14 + -93.11 + 0 + 0 + + + + MSP + 000194 + MINNEAPOLIS + MN + US + 44.88 + -93.23 + 0 + 0 + + + + MCW + 000171 + MASON_CITY + IA + US + 43.09 + -93.33 + 0 + 0 + + + + SGF + 000245 + SPRINGFIELD + MO + US + 37.36 + -93.33 + 0 + 0 + + + + INL + 000137 + INTERNATIONAL_FALLS + MN + US + 48.57 + -93.40 + 0 + 0 + + + + DSM + 000079 + DES_MOINES + IA + US + 41.44 + -93.65 + 0 + 0 + + + + EIC + 000318 + SHREVEPORT + LA + US + 32.77 + -93.81 + 0 + 0 + + + + BRD + 000292 + BRAINERD + MN + US + 46.35 + -94.03 + 0 + 0 + + + + TXK + 000272 + TEXARKANA + AR + US + 33.51 + -94.07 + 0 + 0 + + + + RZC + 000374 + RAZORBACK + AR + US + 36.25 + -94.12 + 0 + 0 + + + + FSM + 000108 + FT_SMITH + AR + US + 35.38 + -94.27 + 0 + 0 + + + + FOD + 000105 + FT_DODGE + IA + US + 42.61 + -94.29 + 0 + 0 + + + + BUM + 000045 + BUTLER + MO + US + 38.27 + -94.49 + 0 + 0 + + + + MKC + 000177 + KANSAS_CITY + MO + US + 39.28 + -94.59 + 0 + 0 + + + + LFK + 000155 + LUFKIN + TX + US + 31.16 + -94.72 + 0 + 0 + + + + GGG + 000115 + LONGVIEW + TX + US + 32.42 + -94.75 + 0 + 0 + + + + BJI + 000033 + BEMIDJI + MN + US + 47.58 + -95.02 + 0 + 0 + + + + RWF + 000234 + REDWWOD_FALLS + MN + US + 44.47 + -95.13 + 0 + 0 + + + + OSW + 000205 + OSWEGO + KS + US + 37.15 + -95.20 + 0 + 0 + + + + IAH + 000131 + HOUSTON_INTERNATIONAL + TX + US + 29.96 + -95.35 + 0 + 0 + + + + OVR + 000364 + OMAHA + NE + US + 41.17 + -95.74 + 0 + 0 + + + + MLC + 000180 + MC_CALESTER + OK + US + 34.85 + -95.78 + 0 + 0 + + + + TUL + 000268 + TULSA + OK + US + 36.20 + -95.79 + 0 + 0 + + + + PWE + 000222 + PAWNEE_CITY + NE + US + 40.20 + -96.21 + 0 + 0 + + + + PSX + 000219 + PALACIOS + TX + US + 28.76 + -96.31 + 0 + 0 + + + + FSD + 000107 + SIOUX_FALLS + SD + US + 43.65 + -96.78 + 0 + 0 + + + + FAR + 000098 + FARGO + ND + US + 46.75 + -96.85 + 0 + 0 + + + + DFW + 000072 + DALLAS-FT_WORTH + TX + US + 32.87 + -97.03 + 0 + 0 + + + + ADM + 000008 + ARDMORE + OK + US + 34.21 + -97.17 + 0 + 0 + + + + GFK + 000114 + GRAND_FORKS + ND + US + 47.95 + -97.19 + 0 + 0 + + + + YWG + 000397 + WINNIPEG + MB + CN + 49.90 + -97.23 + 0 + 0 + + + + ACT + 000006 + WACO + TX + US + 31.66 + -97.27 + 0 + 0 + + + + BRO + 000041 + BROWNSVILLE + TX + US + 25.92 + -97.38 + 0 + 0 + + + + CRP + 000065 + CORPUS_CHRISTI + TX + US + 27.90 + -97.45 + 0 + 0 + + + + ICT + 000132 + WICHITA + KS + US + 37.75 + -97.58 + 0 + 0 + + + + OKC + 000198 + OKLAHOMA_CITY + OK + US + 35.36 + -97.61 + 0 + 0 + + + + SLN + 000251 + SALINA + KS + US + 38.93 + -97.62 + 0 + 0 + + + + AUS + 000020 + AUSTIN + TX + US + 30.30 + -97.70 + 0 + 0 + + + + END + 000321 + VANCE_AFB + OK + US + 36.35 + -97.92 + 0 + 0 + + + + OBH + 000358 + WOLBACH + NE + US + 41.38 + -98.35 + 0 + 0 + + + + ABR + 000003 + ABERDEEN + SD + US + 45.42 + -98.37 + 0 + 0 + + + + SAT + 000238 + SAN_ANTONIO + TX + US + 29.64 + -98.46 + 0 + 0 + + + + SPS + 000254 + WICHITA_FALLS + TX + US + 33.99 + -98.59 + 0 + 0 + + + + ONL + 000200 + ONEILL + NE + US + 42.47 + -98.69 + 0 + 0 + + + + LRD + 000161 + LAREDO + TX + US + 27.48 + -99.42 + 0 + 0 + + + + JCT + 000144 + JUNCTION + TX + US + 30.60 + -99.82 + 0 + 0 + + + + ABI + 000001 + ABILENE + TX + US + 32.48 + -99.86 + 0 + 0 + + + + GAG + 000110 + GAGE + OK + US + 36.34 + -99.88 + 0 + 0 + + + + ANW + 000282 + AINSWORTH + NE + US + 42.57 + -99.99 + 0 + 0 + + + + PIR + 000214 + PIERRE + SD + US + 44.40 + -100.17 + 0 + 0 + + + + HLC + 000335 + HILL_CITY + KS + US + 39.26 + -100.23 + 0 + 0 + + + + CDS + 000051 + CHILDRESS + TX + US + 34.37 + -100.28 + 0 + 0 + + + + SJT + 000248 + SAN_ANGELO + TX + US + 31.38 + -100.46 + 0 + 0 + + + + MCK + 000351 + MC_COOK + NE + US + 40.20 + -100.59 + 0 + 0 + + + + BIS + 000032 + BISMARK + ND + US + 46.77 + -100.67 + 0 + 0 + + + + LBF + 000152 + NORTH_PLATTE + NE + US + 41.13 + -100.72 + 0 + 0 + + + + GCK + 000112 + GARDEN_CITY + KS + US + 37.92 + -100.73 + 0 + 0 + + + + DLF + 000309 + LAUGHLIN_AFB + TX + US + 29.36 + -100.77 + 0 + 0 + + + + LBL + 000153 + LIBERAL + KS + US + 37.04 + -100.97 + 0 + 0 + + + + MOT + 000187 + MINOT + ND + US + 48.26 + -101.29 + 0 + 0 + + + + AMA + 000014 + AMARILLO + TX + US + 35.29 + -101.64 + 0 + 0 + + + + GLD + 000118 + GOODLAND + KS + US + 39.39 + -101.69 + 0 + 0 + + + + DPR + 000077 + DUPREE + SD + US + 45.08 + -101.72 + 0 + 0 + + + + LBB + 000151 + LUBBOCK_INTERNATIONAL + TX + US + 33.70 + -101.92 + 0 + 0 + + + + MAF + 000167 + MIDLAND + TX + US + 32.02 + -102.18 + 0 + 0 + + + + LAA + 000146 + LAMAR + CO + US + 38.20 + -102.69 + 0 + 0 + + + + DIK + 000074 + DICKINSIN + ND + US + 46.86 + -102.77 + 0 + 0 + + + + TXO + 000385 + TEXICO_NM/BOVINA + TX + US + 34.50 + -102.84 + 0 + 0 + + + + SNY + 000379 + SIDNEY + NE + US + 41.10 + -102.98 + 0 + 0 + + + + FST + 000329 + FT_STOCKTON + TX + US + 30.95 + -102.98 + 0 + 0 + + + + RAP + 000224 + RAPID_CITY + SD + US + 43.98 + -103.01 + 0 + 0 + + + + AKO + 000011 + AKRON + CO + US + 40.16 + -103.18 + 0 + 0 + + + + INK + 000342 + WINK + TX + US + 31.87 + -103.24 + 0 + 0 + + + + BFF + 000026 + SCOTTSBLUFF + NE + US + 41.89 + -103.48 + 0 + 0 + + + + TBE + 000261 + TOBE + CO + US + 37.27 + -103.60 + 0 + 0 + + + + TCC + 000262 + TUCUMCARI + NM + US + 35.18 + -103.60 + 0 + 0 + + + + ISN + 000140 + WILLISTON + ND + US + 48.18 + -103.63 + 0 + 0 + + + + MRF + 000190 + MARFA + TX + US + 30.30 + -103.95 + 0 + 0 + + + + PUB + 000220 + PUEBLO + CO + US + 38.29 + -104.43 + 0 + 0 + + + + ROW + 000233 + ROSWELL + NM + US + 33.34 + -104.62 + 0 + 0 + + + + DEN + 000071 + DENVER + CO + US + 39.81 + -104.66 + 0 + 0 + + + + CYS + 000301 + CHEYENNE + WY + US + 41.21 + -104.77 + 0 + 0 + + + + CIM + 000297 + CIMARRON + NM + US + 36.49 + -104.87 + 0 + 0 + + + + LVS + 000163 + LAS_VEGAS + NM + US + 35.66 + -105.14 + 0 + 0 + + + + LAR + 000148 + LARAMIE + WY + US + 41.33 + -105.72 + 0 + 0 + + + + ALS + 000013 + ALAMOSA + CO + US + 37.35 + -105.82 + 0 + 0 + + + + MLS + 000182 + MILES_CITY + MT + US + 46.38 + -105.95 + 0 + 0 + + + + DDY + 000307 + CASPER + WY + US + 43.09 + -106.28 + 0 + 0 + + + + ELP + 000090 + EL_PASO + TX + US + 31.82 + -106.28 + 0 + 0 + + + + CZI + 000302 + CRAZY_WOMAN + WY + US + 44.00 + -106.44 + 0 + 0 + + + + GGW + 000116 + GLASGOW + MT + US + 48.22 + -106.63 + 0 + 0 + + + + ABQ + 000002 + ALBUQUERQUE + NM + US + 35.04 + -106.82 + 0 + 0 + + + + DBL + 000304 + EAGLE + CO + US + 39.44 + -106.90 + 0 + 0 + + + + HBU + 000333 + GUNNISON + CO + US + 38.45 + -107.04 + 0 + 0 + + + + SHR + 000246 + SHERIDAN + WY + US + 44.84 + -107.06 + 0 + 0 + + + + TCS + 000263 + TRUTH_OR_CONSEQUENCES + NM + US + 33.28 + -107.28 + 0 + 0 + + + + CHE + 000054 + HAYDEN + CO + US + 40.52 + -107.31 + 0 + 0 + + + + DMN + 000076 + DEMING + NM + US + 32.28 + -107.60 + 0 + 0 + + + + YYN + 000400 + SWIFT_CURRENT + SA + CN + 50.28 + -107.68 + 0 + 0 + + + + FMN + 000103 + FARMINGTON + NM + US + 36.75 + -108.10 + 0 + 0 + + + + BOY + 000290 + BOYSEN_RESV. + WY + US + 43.46 + -108.30 + 0 + 0 + + + + BIL + 000031 + BILLINGS + MT + US + 45.81 + -108.63 + 0 + 0 + + + + JNC + 000347 + GRAND_JUNCTION + CO + US + 39.06 + -108.79 + 0 + 0 + + + + DVC + 000082 + DOVE_CREEK + CO + US + 37.81 + -108.93 + 0 + 0 + + + + OCS + 000359 + ROCKSPRINGS + WY + US + 41.59 + -109.02 + 0 + 0 + + + + SJN + 000247 + ST_JOHNS + AZ + US + 34.42 + -109.14 + 0 + 0 + + + + SSO + 000256 + SAN_SIMON + AZ + US + 32.27 + -109.26 + 0 + 0 + + + + LWT + 000165 + LEWISTOWN + MT + US + 47.05 + -109.61 + 0 + 0 + + + + HVR + 000129 + HAVRE + MT + US + 48.54 + -109.77 + 0 + 0 + + + + BPI + 000291 + BIG_PINEY + WY + US + 42.58 + -110.11 + 0 + 0 + + + + MTU + 000196 + MYTON + UT + US + 40.15 + -110.13 + 0 + 0 + + + + HVE + 000128 + HANKSVILLE + UT + US + 38.42 + -110.70 + 0 + 0 + + + + YXH + 000399 + MEDICINE_HAT + AB + CN + 50.02 + -110.72 + 0 + 0 + + + + JAC + 000141 + JACKSON + WY + US + 43.62 + -110.73 + 0 + 0 + + + + INW + 000138 + WINSLOW + AZ + US + 35.06 + -110.80 + 0 + 0 + + + + TUS + 000269 + TUCSON + AZ + US + 32.10 + -110.92 + 0 + 0 + + + + TBC + 000260 + TUBA_CITY + AZ + US + 36.12 + -111.27 + 0 + 0 + + + + GTF + 000123 + GREAT_FALLS + MT + US + 47.45 + -111.41 + 0 + 0 + + + + HLN + 000336 + HELENA + MT + US + 46.61 + -111.95 + 0 + 0 + + + + PHX + 000211 + PHOENIX + AZ + US + 33.43 + -112.02 + 0 + 0 + + + + SLC + 000249 + SALT_LAKE_CITY + UT + US + 40.85 + -111.98 + 0 + 0 + + + + DBS + 000305 + DUBOIS + ID + US + 44.09 + -112.21 + 0 + 0 + + + + BCE + 000023 + BRYCE_CANYON + UT + US + 37.69 + -112.30 + 0 + 0 + + + + MLD + 000352 + MALAD_CITY + ID + US + 42.20 + -112.45 + 0 + 0 + + + + DRK + 000313 + PRESCOTT + AZ + US + 34.70 + -112.48 + 0 + 0 + + + + DTA + 000080 + DELTA + UT + US + 39.30 + -112.51 + 0 + 0 + + + + DLN + 000311 + DILLON + MT + US + 45.25 + -112.55 + 0 + 0 + + + + PIH + 000213 + POCATELLO + ID + US + 42.87 + -112.65 + 0 + 0 + + + + YQL + 000392 + LETHBRIDGE + AB + CN + 49.63 + -112.80 + 0 + 0 + + + + PGS + 000210 + PEACH_SPRINGS + AZ + US + 35.62 + -113.54 + 0 + 0 + + + + BVL + 000046 + BOONEVILLE + UT + US + 40.73 + -113.76 + 0 + 0 + + + + LKT + 000157 + SALMON + ID + US + 45.02 + -114.08 + 0 + 0 + + + + FCA + 000100 + KALISPELL + MT + US + 48.21 + -114.18 + 0 + 0 + + + + ILC + 000134 + WILSON_CREEK + NV + US + 38.25 + -114.39 + 0 + 0 + + + + EED + 000087 + NEEDLES + CA + US + 34.77 + -114.47 + 0 + 0 + + + + TWF + 000271 + TWIN_FALLS + ID + US + 42.48 + -114.49 + 0 + 0 + + + + BZA + 000294 + YUMA + AZ + US + 32.77 + -114.60 + 0 + 0 + + + + ELY + 000091 + ELY + NV + US + 39.30 + -114.85 + 0 + 0 + + + + LAS + 000149 + LAS_VEGAS + NV + US + 36.08 + -115.16 + 0 + 0 + + + + MLP + 000181 + MULLAN_PASS + ID + US + 47.46 + -115.65 + 0 + 0 + + + + YXC + 000398 + CRANBROOK + BC + CN + 49.60 + -115.78 + 0 + 0 + + + + TRM + 000383 + THERMAL + CA + US + 33.63 + -116.16 + 0 + 0 + + + + BOI + 000039 + BOISE + ID + US + 43.55 + -116.19 + 0 + 0 + + + + DNJ + 000312 + MC_CALL + ID + US + 44.77 + -116.21 + 0 + 0 + + + + HEC + 000334 + HECTOR + CA + US + 34.80 + -116.46 + 0 + 0 + + + + BTY + 000043 + BEATTY + NV + US + 36.80 + -116.75 + 0 + 0 + + + + BAM + 000286 + BATTLE_MOUNTAIN + NV + US + 40.57 + -116.92 + 0 + 0 + + + + MZB + 000354 + MISSION_BAY + CA + US + 32.78 + -117.23 + 0 + 0 + + + + GEG + 000113 + SPOKANE + WA + US + 47.56 + -117.63 + 0 + 0 + + + + OAL + 000357 + COALDALE + NV + US + 38.00 + -117.77 + 0 + 0 + + + + BKE + 000288 + BAKER + OR + US + 44.84 + -117.81 + 0 + 0 + + + + REO + 000227 + ROME + OR + US + 42.59 + -117.87 + 0 + 0 + + + + LAX + 000150 + LOS_ANGELES_INTL + CA + US + 33.93 + -118.43 + 0 + 0 + + + + PDT + 000207 + PENDLETON + OR + US + 45.70 + -118.94 + 0 + 0 + + + + EHF + 000317 + BAKERSFIELD + CA + US + 35.48 + -119.10 + 0 + 0 + + + + EPH + 000324 + EPHRATA + WA + US + 47.38 + -119.42 + 0 + 0 + + + + FMG + 000327 + RENO + NV + US + 39.53 + -119.66 + 0 + 0 + + + + RZS + 000375 + SANTA_BARBARA + CA + US + 34.51 + -119.77 + 0 + 0 + + + + CZQ + 000303 + FRESNO + CA + US + 36.88 + -119.82 + 0 + 0 + + + + YKM + 000279 + YAKIMA + WA + US + 46.57 + -120.45 + 0 + 0 + + + + LKV + 000158 + LAKEVIEW + OR + US + 42.49 + -120.51 + 0 + 0 + + + + YDC + 000389 + PRINCETON + BC + CN + 49.47 + -120.52 + 0 + 0 + + + + MOD + 000186 + MODESTO + CA + US + 37.63 + -120.96 + 0 + 0 + + + + DSD + 000314 + REDMOND + WA + US + 44.25 + -121.30 + 0 + 0 + + + + SAC + 000236 + SACRAMENTO + CA + US + 38.44 + -121.55 + 0 + 0 + + + + SNS + 000253 + SALINAS + CA + US + 36.66 + -121.60 + 0 + 0 + + + + OAK + 000356 + OAKLAND + CA + US + 37.73 + -122.22 + 0 + 0 + + + + RBL + 000225 + RED_BLUFF + CA + US + 40.10 + -122.24 + 0 + 0 + + + + SEA + 000243 + SEATTLE + WA + US + 47.44 + -122.31 + 0 + 0 + + + + BLI + 000035 + BELLINGHAM + WA + US + 48.95 + -122.58 + 0 + 0 + + + + PDX + 000208 + PORTLAND + OR + US + 45.58 + -122.60 + 0 + 0 + + + + PYE + 000371 + POINT_REYES + CA + US + 38.08 + -122.87 + 0 + 0 + + + + OED + 000362 + MEDFORD + OR + US + 42.48 + -122.91 + 0 + 0 + + + + EUG + 000093 + EUGENE + OR + US + 44.12 + -123.22 + 0 + 0 + + + + ENI + 000323 + UKIAH + CA + US + 39.05 + -123.27 + 0 + 0 + + + + ONP + 000201 + NEWPORT + OR + US + 44.58 + -124.06 + 0 + 0 + + + + HQM + 000127 + HOQUIAM + WA + US + 46.95 + -124.15 + 0 + 0 + + + + FOT + 000106 + FORTUNA + CA + US + 40.67 + -124.23 + 0 + 0 + + + + TOU + 000265 + NEAH_BAY + WA + US + 48.30 + -124.63 + 0 + 0 + + + + YQV + 000402 + YORKTON + SA + CN + 51.27 + -102.47 + 0 + 0 + + + + ANN + 0 + ANNETTE_ISLAND + AK + US + 55.05 + -131.57 + 0 + 0 + + + + LVD + 0 + LEVEL_ISLAND + AK + US + 56.47 + -133.08 + 0 + 0 + + + + BKA + 0 + BIORKA_ISLAND + AK + US + 56.86 + -135.55 + 0 + 0 + + + + SSR + 0 + SISTERS_ISLAND + AK + US + 58.17 + -135.25 + 0 + 0 + + + + JNU + 0 + JUNEAU + AK + US + 58.35 + -134.58 + 0 + 0 + + + + YAK + 0 + YAKUTAT + AK + US + 59.50 + -139.67 + 0 + 0 + + + + MDO + 0 + MIDDLETON_ISLAND + AK + US + 59.45 + -146.30 + 0 + 0 + + + + JOH + 0 + JOHNSTONE_POINT + AK + US + 60.48 + -146.60 + 0 + 0 + + + + ODK + 0 + KODIAK + AK + US + 57.75 + -152.50 + 0 + 0 + + + + HOM + 0 + HOMER + AK + US + 59.65 + -151.48 + 0 + 0 + + + + ENA + 0 + KENAI + AK + US + 60.57 + -151.25 + 0 + 0 + + + + ANC + 0 + ANCHORAGE + AK + US + 61.17 + -150.00 + 0 + 0 + + + + BGQ + 0 + BIG_LAKE + AK + US + 61.53 + -149.82 + 0 + 0 + + + + ORT + 0 + NORTHWAY + AK + US + 62.97 + -141.93 + 0 + 0 + + + + GKN + 0 + GULKANA + AK + US + 62.15 + -145.45 + 0 + 0 + + + + TKA + 0 + TALKEETNA + AK + US + 62.32 + -150.10 + 0 + 0 + + + + SQA + 0 + SPARREVOHN + AK + US + 61.10 + -155.63 + 0 + 0 + + + + DLG + 0 + DILLINGHAM + AK + US + 59.05 + -158.50 + 0 + 0 + + + + AKN + 0 + KING_SALMON + AK + US + 58.68 + -156.65 + 0 + 0 + + + + PDN + 0 + PORT_HEIDEN + AK + US + 56.95 + -158.65 + 0 + 0 + + + + CDB + 0 + COLD_BAY + AK + US + 55.20 + -162.73 + 0 + 0 + + + + DUT + 0 + DUTCH_HARBOR + AK + US + 53.90 + -166.55 + 0 + 0 + + + + NUD + 0 + ADAK + AK + US + 51.88 + -176.65 + 0 + 0 + + + + SYA + 0 + SHEMYA + AK + US + 52.72 + 174.12 + 0 + 0 + + + + SPY + 0 + ST_PAUL_ISLAND + AK + US + 57.17 + -170.22 + 0 + 0 + + + + EHM + 0 + CAPE_NEWENHAM + AK + US + 58.66 + -162.07 + 0 + 0 + + + + HPB + 0 + HOOPER_BAY + AK + US + 61.52 + -166.14 + 0 + 0 + + + + BET + 0 + BETHEL + AK + US + 60.78 + -161.83 + 0 + 0 + + + + ANI + 0 + ANIAK + AK + US + 61.59 + -159.61 + 0 + 0 + + + + SMA + 0 + ST_MARYS + AK + US + 62.06 + -163.30 + 0 + 0 + + + + UNK + 0 + UNALAKLEET + AK + US + 63.88 + -160.80 + 0 + 0 + + + + ULL + 0 + KUKULIAK + AK + US + 63.70 + -170.48 + 0 + 0 + + + + MCG + 0 + MC_GRATH + AK + US + 62.95 + -155.60 + 0 + 0 + + + + ENN + 0 + NENANA + AK + US + 64.55 + -149.07 + 0 + 0 + + + + FAI + 0 + FAIRBANKS + AK + US + 64.82 + -147.85 + 0 + 0 + + + + BIG + 0 + BIG_DELTA + AK + US + 64.00 + -145.72 + 0 + 0 + + + + FYU + 0 + FORT_YUKON + AK + US + 66.57 + -145.25 + 0 + 0 + + + + BTT + 0 + BETTLES + AK + US + 66.92 + -151.53 + 0 + 0 + + + + TAL + 0 + TANANA + AK + US + 65.18 + -152.18 + 0 + 0 + + + + CQR + 0 + CHANDALAR_LAKE + AK + US + 67.50 + -148.47 + 0 + 0 + + + + SCC + 0 + DEADHORSE + AK + US + 70.20 + -148.47 + 0 + 0 + + + + BTI + 0 + BARTER_ISLAND + AK + US + 70.13 + -143.57 + 0 + 0 + + + + BRW + 0 + BARROW + AK + US + 71.28 + -156.77 + 0 + 0 + + + + GAL + 0 + GALENA + AK + US + 64.73 + -156.93 + 0 + 0 + + + + OME + 0 + NOME + AK + US + 64.52 + -165.45 + 0 + 0 + + + + OTZ + 0 + KOTZEBUE + AK + US + 66.88 + -162.60 + 0 + 0 + + + + WLK + 0 + SELAWIK + AK + US + 66.60 + -160.00 + 0 + 0 + + + + HSL + 0 + HUSLIA + AK + US + 65.71 + -156.37 + 0 + 0 + + + + BSF + 0 + BRADSHAW + HI + US + 19.76 + -155.39 + 0 + 0 + + + + UPP + 0 + UPOLU_POINT + HI + US + 20.20 + -155.84 + 0 + 0 + + + + ITO + 0 + HILO + HI + US + 19.72 + -155.01 + 0 + 0 + + + + HNL + 0 + HONOLULU + HI + US + 21.33 + -157.93 + 0 + 0 + + + + OGG + 0 + MAUI + HI + US + 20.91 + -156.42 + 0 + 0 + + + + NDB + 0 + VALLEY_ISLAND + HI + US + 20.88 + -156.44 + 0 + 0 + + + + MUE + 0 + KAMUELA + HI + US + 20.00 + -155.67 + 0 + 0 + + + + NGF + 0 + KANEOHE_BAY + HI + US + 21.45 + -157.76 + 0 + 0 + + + + MKK + 0 + MOLOKAI + HI + US + 21.14 + -157.17 + 0 + 0 + + + + NBS + 0 + BARKING_SANDS + HI + US + 22.04 + -159.79 + 0 + 0 + + + + CKH + 0 + KOKO_HEAD + HI + US + 21.27 + -157.70 + 0 + 0 + + + + IAI + 0 + KONA + HI + US + 19.65 + -156.02 + 0 + 0 + + + + LLD + 0 + LANAI + HI + US + 20.77 + -156.97 + 0 + 0 + + + + LNY + 0 + LANAI_CITY + HI + US + 20.76 + -156.97 + 0 + 0 + + + + LIH + 0 + LIHUE + HI + US + 21.97 + -159.34 + 0 + 0 + + + + SOK + 0 + SOUTH_KAUAI + HI + US + 21.90 + -159.53 + 0 + 0 + + + + RSW + 0 + LEE_COUNTY + FL + US + 26.53 + -81.78 + 0 + 0 + + + + PZD + 0 + PECAN + GA + US + 31.66 + -84.29 + 0 + 0 + + + + IIU + 0 + LOUISVILLE + KY + US + 38.10 + -85.58 + 0 + 0 + + + + HRV + 0 + HARVEY + LA + US + 29.85 + -90.00 + 0 + 0 + + + + MCI + 0 + KANSAS_CITY + MO + US + 39.29 + -94.74 + 0 + 0 + + + + TTT + 0 + MAVERICK + TX + US + 32.87 + -97.04 + 0 + 0 + + + + CWK + 0 + CENTEX + TX + US + 30.38 + -97.53 + 0 + 0 + + + + CME + 0 + CHISUM + NM + US + 33.34 + -104.62 + 0 + 0 + + + + FTI + 0 + FT_UNION + NM + US + 35.66 + -105.14 + 0 + 0 + + + + RSK + 0 + RATTLESNAKE + NM + US + 36.75 + -108.10 + 0 + 0 + + + + HUH + 0 + WHATCOM + WA + US + 48.95 + -122.58 + 0 + 0 + + + + ASRF + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + AYPY + 940350 + PORT_MORESBY_INTL + + NG + -9.43 + 147.22 + 47 + 0 + + + + BGSF + 042310 + SONDRE_STROMFJORD + + GL + 67.00 + -50.80 + 53 + 0 + + + + BIRK + 040300 + REYKJAVIK + + IL + 64.13 + -21.90 + 61 + 0 + + + + CWEG + 999999 + ALBERTA_WEATHER_CENTRE + + CN + 53.50 + -113.50 + -9999 + 0 + + + + CWLW + 712030 + KELOWNA + BC + CN + 49.95 + -119.40 + 456 + 0 + + + + CWNT + 712500 + TURTLE_MOUNTAIN + AB + CN + 49.58 + -114.42 + 2164 + 0 + + + + CWTO + 716380 + TORONTO_A_E_S__HQ + ON + CN + 43.78 + -79.47 + 187 + 0 + + + + CWUL + 999999 + QUEBEC_FCST_OFFICE + + CN + 45.50 + -73.68 + -9999 + 0 + + + + CYQX + 718030 + GANDER_INTL_AIRPORT + NF + CN + 48.95 + -54.57 + 151 + 0 + + + + DTTA + 607150 + TUNIS/CARTHAGE + + TS + 36.83 + 10.23 + 4 + 0 + + + + EBBR + 064510 + BRUSSELS_NATIONAL + + BX + 50.90 + 4.53 + 58 + 0 + + + + EDMM + 108680 + MUENCHEN + + DL + 48.25 + 11.58 + 484 + 0 + + + + EDZB + 102380 + BERGEN/HOHNE + + DL + 52.82 + 9.93 + 70 + 0 + + + + EDZE + 104100 + ESSEN/MULHEIM + + DL + 51.40 + 6.97 + 161 + 0 + + + + EDZF + 106370 + FRANKFURT/MAIN + + DL + 50.05 + 8.58 + 112 + 0 + + + + EDZH + 107710 + GAERMERSDORF + + DL + 49.43 + 11.90 + 419 + 0 + + + + EDZM + 108680 + MUENCHEN + + DL + 48.25 + 11.58 + 484 + 0 + + + + EETN + 260380 + TALLIN + + BY + 59.35 + 24.80 + 44 + 0 + + + + EFHK + 029740 + HELSINKI/VANTAA + + FI + 60.32 + 24.97 + 56 + 0 + + + + EFRO + 028450 + ROVANIEMI(CIV/MIL) + + FI + 66.57 + 25.83 + 201 + 0 + + + + EGJJ + 038950 + JERSEY_AIRPORT + + UK + 49.22 + -2.20 + 84 + 0 + + + + EHAM + 062400 + AMSTERDAM/SCHIPHOL + + NL + 52.30 + 4.77 + -2 + 0 + + + + EHDB + 062600 + DE_BILT + + NL + 52.10 + 5.18 + 4 + 0 + + + + EINN + 039620 + SHANNON_AIRPORT + + IE + 52.70 + -8.92 + 20 + 0 + + + + EKCH + 061800 + COPENHAGEN/KASTRUP + + DN + 55.63 + 12.67 + 5 + 0 + + + + ENMI + 999999 + OSLO + + NO + 59.50 + 10.70 + -9999 + 0 + + + + ENVN + 011520 + BODO + + NO + 67.25 + 14.40 + 8 + 0 + + + + ENVV + 014150 + STAVANGER + + NO + 58.87 + 5.67 + 34 + 0 + + + + EPWA + 123750 + WARSAW/OKECIE + + PL + 52.17 + 20.97 + 107 + 0 + + + + ESNN + 023660 + SUNDSVALL/HARNOSAND + + SN + 62.53 + 17.45 + 10 + 0 + + + + ESSA + 024600 + STOCKHOLM/ARLANDA + + SN + 59.65 + 17.95 + 61 + 0 + + + + EVRA + 999999 + RIGA_AIRPORT + LE + BY + 56.92 + 23.97 + 10 + 0 + + + + EYVI + 267300 + VILNIUS_INTL + MI + BY + 54.63 + 25.28 + 156 + 0 + + + + FAJS + 683680 + JAN_SMUTS + + ZA + -26.13 + 28.23 + 1700 + 0 + + + + FCBB + 644500 + BRAZZAVILLE/MAYA-MA + + CG + -4.25 + 15.25 + 316 + 0 + + + + FTTJ + 647000 + NDJAMENA(CIV/MIL) + + CD + 12.13 + 15.03 + 295 + 0 + + + + GCGC + 999999 + CANARY_ISLANDS + + CR + 28.50 + -16.00 + -9999 + 0 + + + + GMMC + 601550 + CASABLANCA + + MC + 33.57 + -7.67 + 62 + 0 + + + + HECA + 623660 + CAIRO_INTL_AIRPORT + + EG + 30.13 + 31.40 + 74 + 0 + + + + LBSF + 156140 + SOFIA + + BU + 42.65 + 23.38 + 595 + 0 + + + + LBWN + 155520 + VARNA + + BU + 43.20 + 27.92 + 43 + 0 + + + + LCLK + 176090 + LARNACA/LARNAX_ARPT + + CY + 34.88 + 33.63 + 2 + 0 + + + + LDZA + 131310 + ZAGREB/PLESO + + RH + 45.73 + 16.07 + 107 + 0 + + + + LDZO + 999999 + ZAGREB/PLESO + + RH + 45.73 + 16.07 + 107 + 0 + + + + LECB + 081810 + BARCELONA + + SP + 41.28 + 2.07 + 6 + 0 + + + + LEMM + 999999 + MADRID_CNM + + SP + 40.12 + -3.53 + -9999 + 0 + + + + LFBD + 075100 + BORDEAUX/MERIGNAC + + FR + 44.83 + -.70 + 61 + 0 + + + + LFMM + 076500 + MARSEILLE + + FR + 43.45 + 5.22 + 20 + 0 + + + + LFPW + 999999 + PARIS_MET_CENTER + + FR + 48.83 + 2.33 + 75 + 0 + + + + LFRN + 071300 + RENNES/ST.JACQUES + + FR + 48.07 + -1.73 + 37 + 0 + + + + LFST + 071900 + STRASBOURG/ENTZHEIM + + FR + 48.55 + 7.63 + 154 + 0 + + + + LGAT + 167160 + ATHENS/HELLENKION + + GR + 37.90 + 23.73 + 15 + 0 + + + + LHBP + 128390 + BUDAPEST/FERIHEGY + + HU + 47.43 + 19.27 + 185 + 0 + + + + LIMM + 160800 + MILANO/LINATE + + IY + 45.43 + 9.27 + 103 + 0 + + + + LJLJ + 130140 + LJUBLJANA/BRNIK + + LJ + 46.22 + 14.48 + 385 + 0 + + + + LKPR + 115180 + PRAGUE/RUZYNE + + CZ + 50.10 + 14.28 + 365 + 0 + + + + LLBG + 401800 + BEN-GURION(CIV/MIL) + + IS + 32.00 + 34.90 + 49 + 0 + + + + LMML + 165970 + LUQA/MALTA + + ML + 35.85 + 14.48 + 91 + 0 + + + + LOWW + 110360 + VIENNA/SCHWECHAT + + OS + 48.12 + 16.57 + 190 + 0 + + + + LPPT + 085360 + LISBON/PORTELA + + PO + 38.78 + -9.13 + 123 + 0 + + + + LROM + 154210 + BUCHAREST/OTOPENI + + RO + 44.55 + 26.10 + 95 + 0 + + + + LROP + 154210 + BUCHAREST/OTOPENI + + RO + 44.55 + 26.10 + 95 + 0 + + + + LSZH + 066700 + ZURICH-KLOTEN_(AUT) + + SW + 47.48 + 8.53 + 432 + 0 + + + + LTAC + 171280 + ANKARA/ESENBOGA + + TU + 40.11 + 32.97 + 949 + 0 + + + + LTBA + 170600 + ISTANBUL/ATATURK_AB + + TU + 40.97 + 28.82 + 37 + 0 + + + + LUKK + 338387 + KISHINAU + + UR + 46.93 + 28.93 + 122 + 0 + + + + LWSK + 135860 + SKOPJE/PETROVAC + + MK + 41.97 + 21.65 + 239 + 0 + + + + LYBE + 132720 + BELGRADE/SURCIN + + YG + 44.82 + 20.28 + 99 + 0 + + + + LZIB + 118160 + BRATISLAVA_IVANKA + + CZ + 48.20 + 17.20 + 130 + 0 + + + + NFFN + 916800 + NANDI/NADI_INTL + + FJ + -17.75 + 177.45 + 18 + 0 + + + + NZDT + 999999 + NEW_ZEALAND + + NZ + -41.00 + 172.50 + -9999 + 0 + + + + NZKL + 999999 + AUCKLAND + + NZ + -37.02 + 174.80 + 6 + 0 + + + + MHTG + 787200 + TEGUCIGALPA/TONCONT + + HO + 14.05 + -87.22 + 994 + 0 + + + + MPTO + 787920 + TOCUMEN/GEN._OMAR + + PM + 9.05 + -79.37 + 11 + 0 + + + + OBBB + 999999 + BAHRAIN_INTL_ARPT + + BN + 26.27 + 50.65 + 2 + 0 + + + + OBBI + 411500 + BAHRAIN_INTL_ARPT + + BN + 26.27 + 50.65 + 2 + 0 + + + + OEJD + 999999 + JEDDAH + + SD + 21.30 + 39.20 + -9999 + 0 + + + + OEJN + 410240 + JEDDAH/KING_ABD + + SD + 21.67 + 39.15 + 12 + 0 + + + + OIII + 407540 + TEHRAN/MEHRABAD_AFB + + IR + 35.68 + 51.35 + 1191 + 0 + + + + OIIX + 999999 + TEHRAN + + IR + 35.68 + 51.35 + 1191 + 0 + + + + OLBA + 401000 + BEIRUT_(CIV/MIL) + + LB + 33.82 + 35.48 + 19 + 0 + + + + OPKC + 417800 + KARACHI_INTL_ARPT + + PK + 24.90 + 67.13 + 22 + 0 + + + + OPLA + 416410 + LAHORE(CIV/MIL) + + PK + 31.52 + 74.40 + 217 + 0 + + + + OYSN + 413440 + SANA'A + + YE + 15.52 + 44.18 + 2190 + 0 + + + + PAFA + 702610 + FAIRBANKS_INTL_ARPT_(ASOS) + AK + US + 64.82 + -147.87 + 138 + 0 + + + + PAJN + 703810 + JUNEAU_INTL_AIRPORT_(ASOS) + AK + US + 58.37 + -134.58 + 7 + 0 + + + + PANC + 702730 + ANCHORAGE_INTL_ARPT_(ASOS) + AK + US + 61.17 + -150.02 + 40 + 0 + + + + RKSI + 470699 + CHAJANG_NI_(K-ARMY) + + KO + 37.87 + 127.18 + 100 + 0 + + + + RCTP + 466860 + TAIPEI/CHIANG_KAI_SHEK + + TW + 25.08 + 121.22 + 33 + 0 + + + + SABE + 875820 + AEROPARQUE(CIV/MIL) + + AG + -34.57 + -58.42 + 6 + 0 + + + + SACO + 873440 + CORDOBA_AIRPORT + + AG + -31.32 + -64.22 + 474 + 0 + + + + SAEZ + 875760 + BUENOS_AIRES/EZEIZA + + AG + -34.82 + -58.53 + 20 + 0 + + + + SAME + 874180 + MENDOZA/EL_PLUMERIL + + AG + -32.83 + -68.78 + 704 + 0 + + + + SARE + 871550 + RESISTENCIA_AIRPORT + + AG + -27.45 + -59.05 + 52 + 0 + + + + SBBE + 821930 + BELEM/VAL_DE_CAES + + BZ + -1.38 + -48.48 + 16 + 0 + + + + SBBR + 833780 + BRASILIA_(CIV/MIL) + + BZ + -15.87 + -47.93 + 1061 + 0 + + + + SBBS + 833780 + BRASILIA + + BZ + -15.87 + -47.93 + 1061 + 0 + + + + SBCT + 838400 + CURITIBA/AFONSO_PEN + + BZ + -25.52 + -49.17 + 908 + 0 + + + + SBCW + 838400 + CURITIBA/AFONSO_PEN + + BZ + -25.52 + -49.17 + 908 + 0 + + + + SBEG + 821110 + EDUARDO_GOMES_INTL + + BZ + -3.03 + -60.05 + 2 + 0 + + + + SBGL + 837460 + GALEAO/RIO(CIV/MIL) + + BZ + -22.82 + -43.25 + 6 + 0 + + + + SBGR + 837753 + GUARULHOS_(CIV/MIL) + + BZ + -23.43 + -46.47 + 750 + 0 + + + + SBRF + 828990 + RECIFE/GUARARAPES + + BZ + -8.07 + -34.85 + 19 + 0 + + + + SCCI + 859340 + PUNTA_ARENAS/PRES_C + + CH + -53.00 + -70.85 + 37 + 0 + + + + SCEL + 855740 + PUDAHUEL/ARTURO_MER + + CH + -33.38 + -70.78 + 476 + 0 + + + + SCFA + 854420 + ANTOFAGASTA/CERRO + + CH + -23.43 + -70.43 + 120 + 0 + + + + SCTE + 857990 + PUERTO_MONTT/TEPUAL + + CH + -41.42 + -73.08 + 86 + 0 + + + + SLLP + 852010 + LA_PAZ/JFK_INTL + + BO + -16.52 + -68.18 + 4014 + 0 + + + + SOCA + 814050 + CAYENNE/ROCHAMBEAU + + FG + 4.83 + -52.37 + 9 + 0 + + + + SPIM + 846280 + LIMA/JORGE_CHAVEZ + + PR + -12.00 + -77.12 + 13 + 0 + + + + TNCC + 789880 + HATO_ARPT_(CIV/MIL) + + NU + 12.20 + -68.97 + 67 + 0 + + + + TTPP + 789700 + PIARCO_INTL_AIRPORT + + TD + 10.62 + -61.35 + 15 + 0 + + + + UAAA + 368700 + ALMA-ATA + AL + RA + 43.23 + 76.93 + 847 + 0 + + + + UAFM + 835300 + FRUNZE + + RA + 42.85 + 74.53 + 760 + 0 + + + + UATT + 352290 + AKTJUBINSK + AL + KZ + 50.30 + 57.23 + 227 + 0 + + + + UBBB + 378640 + BAKU/BINE_ARPT + TB + AJ + 40.45 + 50.07 + -1 + 0 + + + + UGEE + 377890 + YEREVAN/ZAPADNY + TB + RS + 40.13 + 44.47 + 907 + 0 + + + + UGGG + 375490 + TBILISI/NOVO-AL + TB + RS + 41.68 + 44.95 + 490 + 0 + + + + UHBB + 315100 + BLAGOVESHCHENSK + HA + RA + 50.27 + 127.50 + 137 + 0 + + + + UHHH + 317350 + KHABAROVSK/NOVY + HA + RA + 48.52 + 135.16 + 72 + 0 + + + + UHNN + 999999 + NIKOLAEVSK-NA-AMURE_CENTER + HA + RA + 53.15 + 140.70 + 68 + 0 + + + + UHWW + 319600 + VLADIVOSTOK + HA + RA + 43.12 + 131.94 + 184 + 0 + + + + UHPP + 325400 + PETROPAVLOVSK-KAMCA + HA + RA + 52.97 + 158.75 + 24 + 0 + + + + UHSS + 321500 + JUZNO-SAHALINSK + HA + RA + 46.92 + 142.73 + 31 + 0 + + + + UIBB + 303090 + BRATSK + + RA + 56.07 + 101.83 + 489 + 0 + + + + UIII + 307100 + IRKUTSK + IR + RA + 52.27 + 104.35 + 513 + 0 + + + + UIKK + 302300 + KIRENSK + IR + RA + 57.77 + 108.07 + 258 + 0 + + + + UKBB + 333470 + BORISPOL'/KIEV + KV + UR + 50.33 + 30.97 + 119 + 0 + + + + UKFF + 339460 + SIMFEROPOL + + UR + 44.68 + 34.13 + 180 + 0 + + + + UKHH + 343000 + KHARKIV + KI + UR + 49.96 + 36.13 + 1550 + 0 + + + + UKLL + 333930 + LVOV + KI + UR + 49.82 + 23.95 + 325 + 0 + + + + UKOO + 338370 + ODESSA/TSENTRALNY + KI + UR + 46.43 + 30.77 + 35 + 0 + + + + ULAA + 225500 + ARHANGELSK + AR + RS + 64.53 + 40.47 + 13 + 0 + + + + ULLI + 260630 + ST.PETERSBURG(VOEJKOVO) + LE + RS + 59.95 + 30.70 + 78 + 0 + + + + ULLL + 260630 + ST.PETERSBURG + LE + RS + 59.95 + 30.70 + 78 + 0 + + + + ULWW + 270370 + VOLOGDA + AR + RS + 59.23 + 39.87 + 131 + 0 + + + + ULMM + 221130 + MURMANSK + AR + RS + 68.97 + 33.05 + 51 + 0 + + + + UMKK + 267020 + KALININGRAD + + BY + 54.70 + 20.62 + 27 + 0 + + + + UMMS + 268500 + MINSK + MI + BY + 53.87 + 27.53 + 234 + 0 + + + + UNBB + 298380 + BARNAUL + NO + RA + 53.40 + 83.70 + 252 + 0 + + + + UNIT + 245070 + TURA + NO + RA + 64.27 + 100.23 + 186 + 0 + + + + UNKB + 292820 + BOGUCHANY + NO + RA + 58.42 + 97.40 + 134 + 0 + + + + UNKL + 284935 + KRASNOYARSK + + RS + 56.18 + 92.52 + -9999 + 0 + + + + UNLL + 999999 + KOLPASHEVO + NO + RA + 58.30 + 82.90 + 76 + 0 + + + + UNNT + 296340 + NOVOSIBIRSK/TOLMACH + + RA + 55.03 + 82.90 + 177 + 0 + + + + UNOO + 286980 + OMSK + NO + RA + 54.93 + 73.40 + 123 + 0 + + + + UODD + 206740 + DIKSON_ISLAND + DK + RA + 73.53 + 80.40 + 47 + 0 + + + + UOHH + 208910 + KHATANGA + DK + RA + 71.98 + 102.47 + 24 + 0 + + + + UOTT + 234720 + TURUKHANSK + + RA + 65.78 + 087.95 + 37 + 0 + + + + URRV + 273290 + ROSTOV + MS + RS + 57.20 + 39.42 + 102 + 0 + + + + URWA + 999999 + ASTRAKHAN + + RS + 46.35 + 47.97 + -22 + 0 + + + + URWW + 345600 + VOLGOGRAD + TB + RS + 48.68 + 44.35 + 145 + 0 + + + + USCC + 286420 + CHELYABINSK/BALANDI + SV + RA + 55.18 + 61.32 + -9999 + 0 + + + + USDD + 999999 + SALEKHARD + NO + RA + 66.53 + 66.53 + 358 + 0 + + + + USDS + 235520 + TARKO-SALE + NO + RA + 64.92 + 77.82 + 27 + 0 + + + + USHB + 236310 + BEREZOVO + NO + RA + 63.93 + 65.05 + 27 + 0 + + + + USHH + 239330 + HANTY-MANSIJSK + NO + RA + 60.97 + 69.07 + 40 + 0 + + + + USKK + 999999 + KIROV + MS + RS + 58.60 + 49.63 + 158 + 0 + + + + USPP + 282250 + PERM + SV + RA + 58.02 + 56.30 + 172 + 0 + + + + USRR + 238490 + SURGUT + NO + RA + 61.25 + 73.50 + 44 + 0 + + + + USSS + 284400 + SVERDLOVSK + SV + RA + 56.80 + 60.63 + 237 + 0 + + + + USUU + 286610 + KURGAN + SV + RA + 55.47 + 65.40 + 79 + 0 + + + + UTAA + 388800 + ASHABAD + TA + RA + 37.97 + 58.33 + 210 + 0 + + + + UTTT + 384570 + TASHKENT/YUZNI + TA + RA + 41.27 + 69.27 + 489 + 0 + + + + UUWW + 275185 + MOSCOW/VNUKOVO + MS + RS + 55.65 + 37.27 + 203 + 0 + + + + UUYP + 234180 + PECHORA + AR + RS + 65.11 + 57.10 + 61 + 0 + + + + UUYW + 232260 + VORKUTA + AR + RA + 67.48 + 64.02 + 180 + 0 + + + + UUYY + 238040 + SYKTYVKAR + AR + RA + 61.72 + 50.83 + 119 + 0 + + + + UWKD + 275950 + KAZAN' + MS + RS + 55.78 + 49.18 + 116 + 0 + + + + UWUU + 287220 + UFA + SV + RA + 54.75 + 56.00 + 105 + 0 + + + + VABB + 430030 + BOMBAY/SANTA_CR + + IN + 19.12 + 72.84 + 14 + 0 + + + + VCBI + 434500 + COLOMBO/KATUNAYAKE + + SB + 7.17 + 79.88 + 8 + 0 + + + + VGZR + 419220 + KURMITOLA/ZIA_INTL + + BW + 23.85 + 90.40 + 10 + 0 + + + + VHHH + 450070 + HONG_KONG_INTL_ARPT + + HK + 22.33 + 114.18 + 24 + 0 + + + + VIDP + 421810 + INDIRA_GANDHI/DELHI + + IN + 28.57 + 77.12 + 233 + 0 + + + + WSSS + 486980 + SINGAPORE/CHANG + + SR + 1.37 + 103.98 + 16 + 0 + + + + YBRF + 945780 + BRISBANE + QU + AU + -27.43 + 153.08 + 2 + 0 + + + + YBTL + 942940 + TOWNSVILLE(CIV/MIL) + QU + AU + -19.25 + 146.75 + 6 + 0 + + + + YMHF + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YMMB + 948700 + MOORABBIN_AIRPORT + VC + AU + -37.98 + 145.10 + 13 + 0 + + + + YMMC + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YMRF + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YPDM + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YPRF + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YPRM + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + YSRF + 948640 + MELBOURNE + VC + AU + -37.73 + 144.90 + 81 + 0 + + + + ZPPP + 567780 + KUNMING/WUJIABA + CD + CI + 25.02 + 102.68 + 1892 + 0 + + + diff --git a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/zones.xml b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/zones.xml old mode 100755 new mode 100644 index fb26a34d6f..662ba89deb --- a/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/zones.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/utility/edex_static/base/ncep/stns/zones.xml @@ -1,47189 +1,47189 @@ - - - - - AKZ187 - 21870 - Central_Aleutians - AK - US - 52.22 - -174.23 - 0 - 0 - AFC - - - AKZ213 - 22130 - St_Lawrence_I_and_Bering_St_Cst - AK - US - 63.36 - -170.27 - 0 - 0 - AFG - - - AKZ195 - 21950 - Pribilof_Islands - AK - US - 57.18 - -170.26 - 0 - 0 - AFC - - - AKZ185 - 21850 - Eastern_Aleutians - AK - US - 53.63 - -166.66 - 0 - 0 - AFC - - - AKZ207 - 22070 - Chukchi_Sea_Coast - AK - US - 67.98 - -165.11 - 0 - 0 - AFG - - - AKZ211 - 22110 - Southern_Seward_Peninsula_Coast - AK - US - 64.58 - -164.56 - 0 - 0 - AFG - - - AKZ214 - 22140 - Yukon_Delta - AK - US - 62.24 - -164.37 - 0 - 0 - AFG - - - AKZ155 - 21550 - Kuskokwim_Delta - AK - US - 60.18 - -163.61 - 0 - 0 - AFC - - - AKZ208 - 22080 - Lower_Kobuk_and_Noatak_Valleys - AK - US - 67.77 - -162.75 - 0 - 0 - AFG - - - AKZ210 - 22100 - Nrn_and_Interior_Seward_Penin - AK - US - 65.40 - -162.41 - 0 - 0 - AFG - - - AKZ201 - 22010 - Western_Arctic_Coast - AK - US - 69.84 - -161.53 - 0 - 0 - AFG - - - AKZ181 - 21810 - Alaska_Peninsula - AK - US - 55.82 - -161.44 - 0 - 0 - AFC - - - AKZ209 - 22090 - Baldwin_Penin_and_Selawik_Vly - AK - US - 66.69 - -161.06 - 0 - 0 - AFG - - - AKZ212 - 22120 - Ern_Norton_Snd_and_Nulato_Hills - AK - US - 63.74 - -160.39 - 0 - 0 - AFG - - - HIZ001 - 110010 - Niihau - HI - US - 21.89 - -160.15 - 0 - 0 - HFO - - - AKZ215 - 22150 - Lower_Yukon_Valley - AK - US - 62.56 - -159.94 - 0 - 0 - AFG - - - HIZ003 - 110030 - Kauai_Leeward - HI - US - 22.02 - -159.67 - 0 - 0 - HFO - - - HIZ004 - 110040 - Kauai_Mountains - HI - US - 22.07 - -159.54 - 0 - 0 - HFO - - - HIZ002 - 110020 - Kauai_Windward - HI - US - 22.05 - -159.40 - 0 - 0 - HFO - - - AKZ205 - 22050 - Northwestern_Brooks_Range - AK - US - 69.06 - -158.44 - 0 - 0 - AFG - - - HIZ006 - 110060 - Waianae_Coast - HI - US - 21.48 - -158.21 - 0 - 0 - HFO - - - HIZ011 - 110110 - Waianae_Mountains - HI - US - 21.46 - -158.10 - 0 - 0 - HFO - - - HIZ007 - 110070 - Oahu_North_Shore - HI - US - 21.59 - -158.08 - 0 - 0 - HFO - - - HIZ005 - 110050 - Oahu_South_Shore - HI - US - 21.33 - -158.05 - 0 - 0 - HFO - - - HIZ010 - 110100 - Central_Oahu - HI - US - 21.50 - -158.01 - 0 - 0 - HFO - - - HIZ008 - 110080 - Oahu_Koolau - HI - US - 21.50 - -157.89 - 0 - 0 - HFO - - - HIZ009 - 110090 - Olomana - HI - US - 21.39 - -157.73 - 0 - 0 - HFO - - - HIZ013 - 110130 - Molokai_Leeward - HI - US - 21.14 - -157.09 - 0 - 0 - HFO - - - AKZ217 - 22170 - Upper_Kobuk_and_Noatak_Valleys - AK - US - 67.41 - -156.95 - 0 - 0 - AFG - - - HIZ015 - 110150 - Lanai_Mauka - HI - US - 20.82 - -156.92 - 0 - 0 - HFO - - - HIZ012 - 110120 - Molokai_Windward - HI - US - 21.14 - -156.85 - 0 - 0 - HFO - - - HIZ014 - 110140 - Lanai_Makai - HI - US - 20.83 - -156.84 - 0 - 0 - HFO - - - HIZ018 - 110180 - Maui_Leeward_West - HI - US - 20.89 - -156.67 - 0 - 0 - HFO - - - HIZ016 - 110160 - Kahoolawe - HI - US - 20.56 - -156.62 - 0 - 0 - HFO - - - AKZ216 - 22160 - Lwr_Koyukuk_and_Middle_Yukon_Vly - AK - US - 64.44 - -156.58 - 0 - 0 - AFG - - - HIZ017 - 110170 - Maui_Windward_West - HI - US - 20.92 - -156.58 - 0 - 0 - HFO - - - HIZ019 - 110190 - Maui_Central_Valley - HI - US - 20.85 - -156.45 - 0 - 0 - HFO - - - HIZ021 - 110210 - Leeward_Haleakala - HI - US - 20.72 - -156.31 - 0 - 0 - HFO - - - HIZ022 - 110220 - Haleakala_Summit - HI - US - 20.72 - -156.23 - 0 - 0 - HFO - - - HIZ020 - 110200 - Windward_Haleakala - HI - US - 20.80 - -156.18 - 0 - 0 - HFO - - - AKZ151 - 21510 - Kuskokwim_Valley - AK - US - 62.26 - -156.04 - 0 - 0 - AFC - - - HIZ023 - 110230 - Kona - HI - US - 19.45 - -155.86 - 0 - 0 - HFO - - - HIZ026 - 110260 - Kohala - HI - US - 20.02 - -155.74 - 0 - 0 - HFO - - - AKZ161 - 21610 - Bristol_Bay - AK - US - 58.67 - -155.70 - 0 - 0 - AFC - - - HIZ027 - 110270 - Big_Island_Interior - HI - US - 19.56 - -155.61 - 0 - 0 - HFO - - - HIZ028 - 110280 - Big_Island_Summit - HI - US - 19.44 - -155.58 - 0 - 0 - HFO - - - HIZ024 - 110240 - South_Big_Island - HI - US - 19.19 - -155.42 - 0 - 0 - HFO - - - AKZ202 - 22020 - Northern_Arctic_Coast - AK - US - 70.78 - -155.25 - 0 - 0 - AFG - - - HIZ025 - 110250 - Big_Island_North_and_East - HI - US - 19.81 - -155.19 - 0 - 0 - HFO - - - AKZ171 - 21710 - Kodiak_Island - AK - US - 58.65 - -154.17 - 0 - 0 - AFC - - - AKZ219 - 22190 - Upper_Koyukuk_Valley - AK - US - 66.28 - -152.42 - 0 - 0 - AFG - - - AKZ221 - 22210 - Central_Interior - AK - US - 64.61 - -151.55 - 0 - 0 - AFG - - - AKZ145 - 21450 - Susitna_Valley - AK - US - 61.95 - -150.71 - 0 - 0 - AFC - - - AKZ121 - 21210 - Western_Kenai_Peninsula - AK - US - 60.12 - -150.69 - 0 - 0 - AFC - - - AKZ225 - 22250 - Denali - AK - US - 63.51 - -150.21 - 0 - 0 - AFG - - - AKZ101 - 21010 - Anchorage - AK - US - 61.20 - -149.71 - 0 - 0 - AFC - - - AKZ203 - 22030 - Central_Beaufort_Sea_Coast - AK - US - 70.34 - -149.66 - 0 - 0 - AFG - - - AKZ111 - 21110 - Matanuska_Valley - AK - US - 61.60 - -149.43 - 0 - 0 - AFC - - - AKZ125 - 21250 - Western_Prince_William_Sound - AK - US - 60.28 - -149.43 - 0 - 0 - AFC - - - AKZ218 - 22180 - Southeastern_Brooks_Range - AK - US - 67.94 - -147.78 - 0 - 0 - AFG - - - AKZ206 - 22060 - Northeastern_Brooks_Range - AK - US - 68.97 - -147.55 - 0 - 0 - AFG - - - AKZ222 - 22220 - Middle_Tanana_Valley - AK - US - 64.97 - -147.45 - 0 - 0 - AFG - - - AKZ223 - 22230 - Deltana_and_Tanana_Flats - AK - US - 64.13 - -146.62 - 0 - 0 - AFG - - - AKZ131 - 21310 - Northeast_Prince_William_Sound - AK - US - 61.14 - -146.39 - 0 - 0 - AFC - - - AKZ220 - 22200 - Yukon_Flats_and_Surrounding_Upla - AK - US - 66.46 - -146.25 - 0 - 0 - AFG - - - AKZ135 - 21350 - Southeast_Prince_William_Sound - AK - US - 60.65 - -145.32 - 0 - 0 - AFC - - - AKZ141 - 21410 - Copper_River_Basin - AK - US - 61.88 - -144.85 - 0 - 0 - AFC - - - AKZ204 - 22040 - Eastern_Beaufort_Sea_Coast - AK - US - 69.85 - -143.75 - 0 - 0 - AFG - - - AKZ224 - 22240 - Upr_Tanana_Vly_and_the_Ftymile_C - AK - US - 64.21 - -143.50 - 0 - 0 - AFG - - - AKZ226 - 22260 - Eastern_Alaska_Range - AK - US - 62.77 - -142.76 - 0 - 0 - AFG - - - AKZ017 - 20170 - C_Fairweather_to_C_Suckling_Csta - AK - US - 59.74 - -140.70 - 0 - 0 - AJK - - - AKZ022 - 20220 - Salisbury_Snd_to_C_Fairweather_C - AK - US - 58.68 - -137.66 - 0 - 0 - AJK - - - AKZ020 - 20200 - Glacier_Bay - AK - US - 58.79 - -136.99 - 0 - 0 - AJK - - - AKZ021 - 20210 - Eastern_Chichagof_Island - AK - US - 57.88 - -135.51 - 0 - 0 - AJK - - - AKZ019 - 20190 - Haines_Borough_and_Lynn_Canal - AK - US - 58.95 - -135.41 - 0 - 0 - AJK - - - AKZ018 - 20180 - Taiya_Inlet_and_Klondike_Hiway - AK - US - 59.57 - -135.35 - 0 - 0 - AJK - - - AKZ023 - 20230 - C_Decision_to_Salisbury_Snd_Csta - AK - US - 56.85 - -135.25 - 0 - 0 - AJK - - - AKZ024 - 20240 - Ern_Baranof_I_and_Srn_Admty_I - AK - US - 57.31 - -134.27 - 0 - 0 - AJK - - - AKZ025 - 20250 - Juneau_Borough_and_Nrn_Admty_I - AK - US - 58.08 - -133.64 - 0 - 0 - AJK - - - AKZ027 - 20270 - Dixon_Entr_to_C_Decision_Cstal_A - AK - US - 55.36 - -133.19 - 0 - 0 - AJK - - - AKZ026 - 20260 - Inr_Chnls_fr_Kupreanof_I_to_Etol - AK - US - 56.53 - -133.00 - 0 - 0 - AJK - - - AKZ028 - 20280 - Southern_Inner_Channels - AK - US - 55.71 - -132.71 - 0 - 0 - AJK - - - AKZ029 - 20290 - Misty_Fjords - AK - US - 55.67 - -130.98 - 0 - 0 - AJK - - - WAZ516 - 475160 - North_Coast - WA - US - 47.95 - -124.39 - 0 - 0 - SEW - - - ORZ022 - 370220 - Curry_County_Coast - OR - US - 42.35 - -124.27 - 0 - 0 - MFR - - - WAZ515 - 475150 - Western_Strait_of_Juan_De_Fuca - WA - US - 48.19 - -124.25 - 0 - 0 - SEW - - - ORZ021 - 370210 - South_Central_Oregon_Coast - OR - US - 43.28 - -124.24 - 0 - 0 - MFR - - - WAZ517 - 475170 - Central_Coast - WA - US - 47.16 - -124.06 - 0 - 0 - SEW - - - CAZ001 - 50010 - Redwood_Coast - CA - US - 41.02 - -124.03 - 0 - 0 - EKA - - - ORZ002 - 370020 - Central_Oregon_Coast - OR - US - 44.44 - -124.01 - 0 - 0 - PQR - - - ORZ001 - 370010 - North_Oregon_Coast - OR - US - 45.64 - -123.92 - 0 - 0 - PQR - - - ORZ024 - 370240 - Ern_Curry_Cnty_and_Josephine_Cnt - OR - US - 42.39 - -123.75 - 0 - 0 - MFR - - - CAZ003 - 50030 - North_Coast_Interior - CA - US - 40.99 - -123.72 - 0 - 0 - EKA - - - WAZ021 - 470210 - South_Washington_Coast - WA - US - 46.47 - -123.71 - 0 - 0 - PQR - - - CAZ002 - 50020 - Mendocino_Coast - CA - US - 39.40 - -123.64 - 0 - 0 - EKA - - - ORZ004 - 370040 - Ctrl_Coast_Range_of_Wrn_Oregon - OR - US - 44.42 - -123.62 - 0 - 0 - PQR - - - WAZ513 - 475130 - Olympics - WA - US - 47.71 - -123.61 - 0 - 0 - SEW - - - WAZ512 - 475120 - Lower_Chehalis_Valley_Area - WA - US - 47.09 - -123.52 - 0 - 0 - SEW - - - WAZ020 - 470200 - Willapa_Hills - WA - US - 46.52 - -123.51 - 0 - 0 - PQR - - - ORZ003 - 370030 - Coast_Range_of_Northwest_Oregon - OR - US - 45.59 - -123.40 - 0 - 0 - PQR - - - CAZ076 - 50760 - Mendocino_Interior - CA - US - 39.40 - -123.39 - 0 - 0 - EKA - - - ORZ023 - 370230 - Central_Douglas_County - OR - US - 43.32 - -123.35 - 0 - 0 - MFR - - - WAZ514 - 475140 - Eastern_Strait_of_Juan_de_Fuca - WA - US - 48.07 - -123.28 - 0 - 0 - SEW - - - CAZ080 - 50800 - Western_Siskiyou_County - CA - US - 41.49 - -123.13 - 0 - 0 - MFR - - - ORZ008 - 370080 - South__Willamette_Valley - OR - US - 44.32 - -123.11 - 0 - 0 - PQR - - - CAZ004 - 50040 - Upper_Trinity_River - CA - US - 40.44 - -123.07 - 0 - 0 - EKA - - - CAZ505 - 55050 - Cstal_N_Bay_Incl_Pt_Reyes_Natl_S - CA - US - 38.30 - -122.99 - 0 - 0 - MTR - - - WAZ001 - 470010 - San_Juan_County - WA - US - 48.60 - -122.99 - 0 - 0 - SEW - - - ORZ007 - 370070 - Central_Willamette_Valley - OR - US - 45.05 - -122.94 - 0 - 0 - PQR - - - WAZ511 - 475110 - Hood_Canal_Area - WA - US - 47.52 - -122.94 - 0 - 0 - SEW - - - WAZ022 - 470220 - Lwr_Columbia_and_I_-_5_Corridor_ - WA - US - 46.11 - -122.88 - 0 - 0 - PQR - - - ORZ005 - 370050 - Lower_Columbia - OR - US - 45.97 - -122.87 - 0 - 0 - PQR - - - WAZ504 - 475040 - Southwest_Interior - WA - US - 46.78 - -122.87 - 0 - 0 - SEW - - - ORZ026 - 370260 - Jackson_County - OR - US - 42.48 - -122.86 - 0 - 0 - MFR - - - ORZ006 - 370060 - Greater_Portland_Metro_Area - OR - US - 45.52 - -122.83 - 0 - 0 - PQR - - - CAZ506 - 55060 - North_Bay_Interior_Valleys - CA - US - 38.34 - -122.78 - 0 - 0 - MTR - - - ORZ012 - 370120 - Cascade_Foothills_in_Lane_Cnty - OR - US - 43.91 - -122.77 - 0 - 0 - PQR - - - ORZ025 - 370250 - Ern_Douglas_County_Foothills - OR - US - 43.18 - -122.75 - 0 - 0 - MFR - - - CAZ063 - 50630 - Mtns_SWrn_Shasta_Cnty_to_Nrn_L_C - CA - US - 39.91 - -122.73 - 0 - 0 - STO - - - CAZ064 - 50640 - Clear_Lake/Southern_Lake_County - CA - US - 38.96 - -122.67 - 0 - 0 - STO - - - CAZ081 - 50810 - Central_Siskiyou_County - CA - US - 41.68 - -122.60 - 0 - 0 - MFR - - - WAZ503 - 475030 - Western_Whatcom_County - WA - US - 48.82 - -122.59 - 0 - 0 - SEW - - - WAZ039 - 470390 - Greater_Vancouver_Area - WA - US - 45.73 - -122.54 - 0 - 0 - PQR - - - ORZ010 - 370100 - Nrn_Oregon_Cascade_Foothills - OR - US - 44.86 - -122.52 - 0 - 0 - PQR - - - WAZ509 - 475090 - Tacoma_Area - WA - US - 47.17 - -122.52 - 0 - 0 - SEW - - - WAZ510 - 475100 - Admiralty_Inlet_Area - WA - US - 48.15 - -122.50 - 0 - 0 - SEW - - - WAZ040 - 470400 - S_Washington_Cascade_Foothills - WA - US - 46.00 - -122.48 - 0 - 0 - PQR - - - CAZ006 - 50060 - San_Francisco - CA - US - 37.75 - -122.42 - 0 - 0 - MTR - - - WAZ506 - 475060 - Western_Skagit_County - WA - US - 48.47 - -122.42 - 0 - 0 - SEW - - - CAZ509 - 55090 - San_Francisco_Peninsula_Coast - CA - US - 37.36 - -122.38 - 0 - 0 - MTR - - - WAZ508 - 475080 - Seattle/Bremerton_Area - WA - US - 47.51 - -122.29 - 0 - 0 - SEW - - - CAZ507 - 55070 - North_Bay_Mountains - CA - US - 38.54 - -122.27 - 0 - 0 - MTR - - - CAZ015 - 50150 - Northern_Sacramento_Valley - CA - US - 40.26 - -122.25 - 0 - 0 - STO - - - ORZ013 - 370130 - Cascades_in_Lane_County - OR - US - 43.84 - -122.25 - 0 - 0 - PQR - - - ORZ028 - 370280 - Siskiyou_Mtns_and_Srn_Oregon_Cas - OR - US - 42.41 - -122.24 - 0 - 0 - MFR - - - CAZ013 - 50130 - Shasta_L_Area_/_Nrn_Shasta_Cnty - CA - US - 40.87 - -122.21 - 0 - 0 - STO - - - ORZ027 - 370270 - South_Central_Oregon_Cascades - OR - US - 43.21 - -122.21 - 0 - 0 - MFR - - - CAZ082 - 50820 - South_Central_Siskiyou_County - CA - US - 41.30 - -122.14 - 0 - 0 - MFR - - - WAZ507 - 475070 - Everett_and_Vicinity - WA - US - 48.03 - -122.14 - 0 - 0 - SEW - - - CAZ508 - 55080 - San_Francisco_Bay_Shoreline - CA - US - 37.64 - -122.08 - 0 - 0 - MTR - - - WAZ505 - 475050 - East_Puget_Sound_Lowlands - WA - US - 47.53 - -122.05 - 0 - 0 - SEW - - - WAZ019 - 470190 - South_Washington_Cascades - WA - US - 46.00 - -122.04 - 0 - 0 - PQR - - - CAZ512 - 55120 - Santa_Cruz_Mountains - CA - US - 37.20 - -121.98 - 0 - 0 - MTR - - - CAZ510 - 55100 - East_Bay_Interior_Valleys - CA - US - 37.82 - -121.97 - 0 - 0 - MTR - - - ORZ009 - 370090 - Western_Columbia_River_Gorge - OR - US - 45.61 - -121.96 - 0 - 0 - PQR - - - ORZ011 - 370110 - Northern_Oregon_Cascades - OR - US - 44.93 - -121.94 - 0 - 0 - PQR - - - WAZ023 - 470230 - Western_Columbia_River_Gorge - WA - US - 45.66 - -121.92 - 0 - 0 - PQR - - - CAZ016 - 50160 - Central_Sacramento_Valley - CA - US - 39.40 - -121.90 - 0 - 0 - STO - - - CAZ083 - 50830 - N_Ctrl_and_SE_Siskiyou_County - CA - US - 41.59 - -121.90 - 0 - 0 - MFR - - - CAZ530 - 55300 - Srn_Monterey_Bay_and_Big_Sur_Cst - CA - US - 36.35 - -121.90 - 0 - 0 - MTR - - - WAZ519 - 475190 - W_Slopes_Ctrl_Cascades_and_Passe - WA - US - 47.08 - -121.89 - 0 - 0 - SEW - - - CAZ018 - 50180 - Carquinez_Strait_and_Delta - CA - US - 38.07 - -121.80 - 0 - 0 - STO - - - CAZ529 - 55290 - Northern_Monterey_Bay - CA - US - 36.96 - -121.79 - 0 - 0 - MTR - - - CAZ511 - 55110 - E_Bay_Hills_and_the_Diablo_Rng - CA - US - 37.48 - -121.73 - 0 - 0 - MTR - - - CAZ513 - 55130 - Santa_Clara_Vly_Incl_San_Jose - CA - US - 37.17 - -121.69 - 0 - 0 - MTR - - - CAZ066 - 50660 - NE_Foothills/Sacramento_Valley - CA - US - 40.13 - -121.65 - 0 - 0 - STO - - - CAZ017 - 50170 - Southern_Sacramento_Valley - CA - US - 38.64 - -121.63 - 0 - 0 - STO - - - CAZ084 - 50840 - NE_Siskiyou_and_NW_Modoc_Cnties - CA - US - 41.86 - -121.63 - 0 - 0 - MFR - - - ORZ029 - 370290 - Klamath_Basin - OR - US - 42.47 - -121.63 - 0 - 0 - MFR - - - ORZ014 - 370140 - Upper_Hood_River_Valley - OR - US - 45.56 - -121.58 - 0 - 0 - PQR - - - CAZ528 - 55280 - Nrn_Salinas_Vly/Hollister_Vly_an - CA - US - 36.67 - -121.56 - 0 - 0 - MTR - - - CAZ014 - 50140 - Burney_Basin_/_Ern_Shasta_Cnty - CA - US - 40.88 - -121.52 - 0 - 0 - STO - - - WAZ518 - 475180 - W_Slopes_Nrn_Cascades_and_Passes - WA - US - 48.39 - -121.49 - 0 - 0 - SEW - - - CAZ517 - 55170 - Sta_Lucia_Mtns_and_Los_Padres_Na - CA - US - 36.19 - -121.39 - 0 - 0 - MTR - - - CAZ068 - 50680 - Wrn_Plumas_County/Lassen_Park - CA - US - 40.22 - -121.32 - 0 - 0 - STO - - - ORZ030 - 370300 - Nrn_and_Ern_Klamath_Cnty_and_Wrn - OR - US - 42.80 - -121.24 - 0 - 0 - MFR - - - ORZ042 - 370420 - North_Central_Oregon - OR - US - 45.04 - -121.10 - 0 - 0 - PDT - - - CAZ516 - 55160 - Srn_Salinas_Vly/Arroyo_Seco_and_ - CA - US - 36.09 - -121.09 - 0 - 0 - MTR - - - WAZ024 - 470240 - East_Columbia_River_Gorge - WA - US - 45.70 - -121.06 - 0 - 0 - PDT - - - ORZ041 - 370410 - East_Columbia_River_Gorge - OR - US - 45.64 - -121.02 - 0 - 0 - PDT - - - WAZ501 - 475010 - E_Slopes_of_the_Ctrl_Cascades - WA - US - 47.05 - -120.96 - 0 - 0 - PDT - - - ORZ043 - 370430 - Central_Oregon - OR - US - 44.00 - -120.95 - 0 - 0 - PDT - - - CAZ019 - 50190 - Northern_San_Joaquin_Valley - CA - US - 37.76 - -120.93 - 0 - 0 - STO - - - CAZ518 - 55180 - Mtns_Of_Sn_Benito_Cnty_And_Int_M - CA - US - 36.39 - -120.89 - 0 - 0 - MTR - - - CAZ034 - 50340 - San_Luis_Obispo_Cnty_Ctrl_Coast - CA - US - 35.35 - -120.78 - 0 - 0 - LOX - - - WAZ502 - 475020 - East_Slopes_of_the_Srn_Cascades - WA - US - 46.10 - -120.78 - 0 - 0 - PDT - - - CAZ085 - 50850 - Modoc_County - CA - US - 41.58 - -120.74 - 0 - 0 - MFR - - - CAZ067 - 50670 - Motherlode - CA - US - 38.63 - -120.71 - 0 - 0 - STO - - - CAZ071 - 50710 - Lassen-Ern_Plumas-Ern_Sierra_Cnt - CA - US - 40.31 - -120.66 - 0 - 0 - REV - - - WAZ027 - 470270 - Yakima_Valley - WA - US - 46.43 - -120.45 - 0 - 0 - PDT - - - CAZ035 - 50350 - Santa_Barbara_County_Ctrl_Coast - CA - US - 34.72 - -120.41 - 0 - 0 - LOX - - - CAZ089 - 50890 - West-Central_San_Joaquin_Valley - CA - US - 36.62 - -120.39 - 0 - 0 - HNX - - - WAZ026 - 470260 - Kittitas_Valley - WA - US - 47.00 - -120.39 - 0 - 0 - PDT - - - WAZ042 - 470420 - East_Slopes_Northern_Cascades - WA - US - 48.13 - -120.38 - 0 - 0 - OTX - - - CAZ069 - 50690 - West_Slope_Nrn_Sierra_Nevada - CA - US - 38.76 - -120.37 - 0 - 0 - STO - - - CAZ037 - 50370 - San_Luis_Obispo_Cnty_Int_Vlys - CA - US - 35.41 - -120.31 - 0 - 0 - LOX - - - ORZ031 - 370310 - Central_and_Eastern_Lake_County - OR - US - 42.80 - -120.24 - 0 - 0 - MFR - - - ORZ506 - 375060 - Ochoco-John_Day_Highlands - OR - US - 44.34 - -120.20 - 0 - 0 - PDT - - - WAZ041 - 470410 - Wenatchee_Area - WA - US - 47.61 - -120.18 - 0 - 0 - OTX - - - CAZ051 - 50510 - San_Luis_Obispo_County_Mtns - CA - US - 35.16 - -120.17 - 0 - 0 - LOX - - - CAZ036 - 50360 - Santa_Ynez_Valley - CA - US - 34.72 - -120.14 - 0 - 0 - LOX - - - CAZ070 - 50700 - Surprise_Valley_California - CA - US - 41.58 - -120.11 - 0 - 0 - REV - - - CAZ090 - 50900 - East-Central_San_Joaquin_Valley - CA - US - 37.11 - -120.11 - 0 - 0 - HNX - - - ORZ504 - 375040 - Nrn_Wheeler_and_Srn_Gilliam_Cnti - OR - US - 45.01 - -120.10 - 0 - 0 - PDT - - - CAZ072 - 50720 - Greater_Lake_Tahoe_Area - CA - US - 38.89 - -119.96 - 0 - 0 - REV - - - CAZ039 - 50390 - Santa_Barbara_County_S_Coast - CA - US - 34.45 - -119.95 - 0 - 0 - LOX - - - NVZ002 - 280020 - Greater_Lake_Tahoe_Area - NV - US - 39.19 - -119.90 - 0 - 0 - REV - - - CAZ052 - 50520 - Santa_Barbara_County_Mountains - CA - US - 34.77 - -119.88 - 0 - 0 - LOX - - - CAZ091 - 50910 - Southwestern_San_Joaquin_Valley - CA - US - 35.75 - -119.78 - 0 - 0 - HNX - - - CAZ038 - 50380 - Cuyama_Valley - CA - US - 34.96 - -119.77 - 0 - 0 - LOX - - - NVZ005 - 280050 - Northern_Washoe_County - NV - US - 41.01 - -119.65 - 0 - 0 - REV - - - ORZ044 - 370440 - Lower_Columbia_Basin - OR - US - 45.60 - -119.65 - 0 - 0 - PDT - - - WAZ044 - 470440 - Waterville_Plateau - WA - US - 47.68 - -119.65 - 0 - 0 - OTX - - - CAZ093 - 50930 - Mariposa_Madera_and_Fresno_Cnty_ - CA - US - 37.24 - -119.64 - 0 - 0 - HNX - - - NVZ003 - 280030 - Gter_Reno-Carson_Cty-Minden_Area - NV - US - 39.36 - -119.63 - 0 - 0 - REV - - - ORZ505 - 375050 - John_Day_Basin - OR - US - 44.63 - -119.49 - 0 - 0 - PDT - - - WAZ034 - 470340 - Moses_Lake_Area - WA - US - 47.03 - -119.48 - 0 - 0 - OTX - - - WAZ043 - 470430 - Okanogan_Valley - WA - US - 48.47 - -119.47 - 0 - 0 - OTX - - - WAZ028 - 470280 - Lower_Columbia_Basin - WA - US - 46.21 - -119.43 - 0 - 0 - PDT - - - CAZ044 - 50440 - Ventura_County_Interior_Valleys - CA - US - 34.44 - -119.25 - 0 - 0 - LOX - - - CAZ040 - 50400 - Ventura_County_Coast - CA - US - 34.22 - -119.19 - 0 - 0 - LOX - - - CAZ092 - 50920 - Southeastern_San_Joaquin_Valley - CA - US - 35.82 - -119.14 - 0 - 0 - HNX - - - CAZ096 - 50960 - Sierra_NV_fr_Yosemite_to_Kings_C - CA - US - 37.43 - -119.12 - 0 - 0 - HNX - - - CAZ053 - 50530 - Ventura_County_Mountains - CA - US - 34.65 - -119.10 - 0 - 0 - LOX - - - ORZ501 - 375010 - Foothills_of_the_Blue_Mountains - OR - US - 45.53 - -119.07 - 0 - 0 - PDT - - - ORZ061 - 370610 - Harney_County - OR - US - 43.01 - -119.06 - 0 - 0 - BOI - - - CAZ094 - 50940 - Tulare_County_Foothills - CA - US - 36.23 - -118.96 - 0 - 0 - HNX - - - WAZ035 - 470350 - Upper_Columbia_Basin - WA - US - 47.41 - -118.91 - 0 - 0 - OTX - - - ORZ503 - 375030 - Southern_Blue_Mtns_of_Oregon - OR - US - 45.23 - -118.88 - 0 - 0 - PDT - - - CAZ045 - 50450 - Ventura_County_Coastal_Valleys - CA - US - 34.23 - -118.87 - 0 - 0 - LOX - - - WAZ038 - 470380 - Okanogan_Highlands - WA - US - 48.42 - -118.75 - 0 - 0 - OTX - - - CAZ073 - 50730 - Mono - CA - US - 38.08 - -118.74 - 0 - 0 - REV - - - CAZ095 - 50950 - Kern_County_Mountains - CA - US - 35.30 - -118.71 - 0 - 0 - HNX - - - CAZ046 - 50460 - Santa_Monica_Mtns_Recnl_Area - CA - US - 34.09 - -118.58 - 0 - 0 - LOX - - - CAZ088 - 50880 - Santa_Clarita_Valley - CA - US - 34.46 - -118.55 - 0 - 0 - LOX - - - NVZ001 - 280010 - Mineral_and_Srn_Lyon_Counties - NV - US - 38.56 - -118.55 - 0 - 0 - REV - - - NVZ004 - 280040 - Wrn_NV_Bsn_and_Rng_including_Pyr - NV - US - 40.01 - -118.53 - 0 - 0 - REV - - - CAZ547 - 55470 - Los_Angeles_Cnty_Sn_Fernando_Vly - CA - US - 34.21 - -118.51 - 0 - 0 - LOX - - - CAZ097 - 50970 - Tulare_County_Mountains - CA - US - 36.27 - -118.48 - 0 - 0 - HNX - - - CAZ087 - 50870 - Catalina_Island - CA - US - 33.39 - -118.45 - 0 - 0 - LOX - - - CAZ054 - 50540 - Los_Angeles_Cnty_Mtns_excluding_ - CA - US - 34.48 - -118.26 - 0 - 0 - LOX - - - CAZ519 - 55190 - Ern_Sierra_Slopes_of_Inyo_Cnty - CA - US - 36.63 - -118.26 - 0 - 0 - VEF - - - CAZ041 - 50410 - Los_Angeles_Cnty_Cst_including_D - CA - US - 33.92 - -118.24 - 0 - 0 - LOX - - - CAZ059 - 50590 - Antelope_Valley - CA - US - 34.62 - -118.22 - 0 - 0 - LOX - - - ORZ502 - 375020 - Northern_Blue_Mtns_of_Oregon - OR - US - 45.65 - -118.19 - 0 - 0 - PDT - - - NVZ030 - 280300 - Humboldt_County - NV - US - 41.26 - -118.16 - 0 - 0 - LKN - - - WAZ029 - 470290 - Foothills_of_the_Blue_Mountains - WA - US - 46.31 - -118.16 - 0 - 0 - PDT - - - CAZ520 - 55200 - Owens_Valley - CA - US - 36.63 - -118.08 - 0 - 0 - VEF - - - CAZ521 - 55210 - White_Mountains_of_Inyo_County - CA - US - 36.92 - -118.00 - 0 - 0 - VEF - - - CAZ548 - 55480 - Los_Angeles_Cnty_Sn_Gabriel_Vly - CA - US - 34.05 - -117.96 - 0 - 0 - LOX - - - CAZ099 - 50990 - Southeastern_Kern_County_Desert - CA - US - 35.15 - -117.93 - 0 - 0 - HNX - - - WAZ030 - 470300 - Northwest_Blue_Mountains - WA - US - 46.17 - -117.87 - 0 - 0 - PDT - - - CAZ098 - 50980 - Indian_Wells_Valley - CA - US - 35.62 - -117.82 - 0 - 0 - HNX - - - CAZ042 - 50420 - Orange_County_Coastal_Areas - CA - US - 33.67 - -117.79 - 0 - 0 - SGX - - - WAZ037 - 470370 - Northeast_Mountains - WA - US - 48.36 - -117.71 - 0 - 0 - OTX - - - WAZ036 - 470360 - Spokane_Area - WA - US - 47.60 - -117.70 - 0 - 0 - OTX - - - ORZ049 - 370490 - Grande_Ronde_Valley - OR - US - 45.39 - -117.69 - 0 - 0 - PDT - - - ORZ062 - 370620 - Baker_County - OR - US - 44.66 - -117.65 - 0 - 0 - BOI - - - WAZ033 - 470330 - Washington_Palouse - WA - US - 46.89 - -117.64 - 0 - 0 - OTX - - - ORZ063 - 370630 - Malheur_County - OR - US - 43.21 - -117.62 - 0 - 0 - BOI - - - CAZ057 - 50570 - Santa_Ana_Mtns_and_Foothills - CA - US - 33.63 - -117.45 - 0 - 0 - SGX - - - WAZ031 - 470310 - Northeast_Blue_Mountains - WA - US - 46.21 - -117.37 - 0 - 0 - OTX - - - CAZ043 - 50430 - San_Diego_County_Coastal_Areas - CA - US - 33.00 - -117.28 - 0 - 0 - SGX - - - CAZ048 - 50480 - Sn_Bernardino_and_Rivside_Cnty_V - CA - US - 33.85 - -117.28 - 0 - 0 - SGX - - - ORZ050 - 370500 - Wallowa_County - OR - US - 45.54 - -117.17 - 0 - 0 - PDT - - - WAZ032 - 470320 - Lwr_Garfield_and_Asotin_Cnties - WA - US - 46.35 - -117.16 - 0 - 0 - OTX - - - NVZ014 - 280140 - Esmeralda_and_Ctrl_Nye_County - NV - US - 37.65 - -117.15 - 0 - 0 - VEF - - - CAZ055 - 50550 - San_Bernardino_County_Mountains - CA - US - 34.23 - -117.13 - 0 - 0 - SGX - - - ORZ064 - 370640 - Oregon_Lower_Treasure_Valley - OR - US - 44.02 - -117.11 - 0 - 0 - BOI - - - CAZ050 - 50500 - San_Diego_County_Valleys - CA - US - 33.03 - -117.06 - 0 - 0 - SGX - - - CAZ060 - 50600 - Apple_and_Lucerne_Valleys - CA - US - 34.43 - -117.03 - 0 - 0 - SGX - - - CAZ523 - 55230 - Western_Mojave_Desert - CA - US - 35.27 - -116.98 - 0 - 0 - VEF - - - IDZ003 - 120030 - Idaho_Palouse - ID - US - 46.96 - -116.96 - 0 - 0 - OTX - - - CAZ522 - 55220 - Death_Valley_National_Park - CA - US - 36.63 - -116.85 - 0 - 0 - VEF - - - IDZ002 - 120020 - Coeur_d'Alene_Area - ID - US - 47.62 - -116.83 - 0 - 0 - OTX - - - NVZ037 - 280370 - Srn_Lander_Cnty_and_Srn_Eureka_C - NV - US - 39.62 - -116.78 - 0 - 0 - LKN - - - NVZ036 - 280360 - Nrn_Lander_Cnty_and_Nrn_Eureka_C - NV - US - 40.51 - -116.76 - 0 - 0 - LKN - - - IDZ012 - 120120 - Lower_Treasure_Valley - ID - US - 43.82 - -116.75 - 0 - 0 - BOI - - - IDZ026 - 120260 - Lewiston_Area - ID - US - 46.47 - -116.71 - 0 - 0 - OTX - - - IDZ029 - 120290 - Owyhee_Mountains - ID - US - 43.07 - -116.70 - 0 - 0 - BOI - - - CAZ056 - 50560 - Riverside_County_Mountains - CA - US - 33.73 - -116.60 - 0 - 0 - SGX - - - NVZ013 - 280130 - Northern_Nye_County - NV - US - 38.60 - -116.59 - 0 - 0 - LKN - - - CAZ058 - 50580 - San_Diego_County_Mountains - CA - US - 33.00 - -116.57 - 0 - 0 - SGX - - - IDZ001 - 120010 - Northern_Panhandle - ID - US - 48.36 - -116.55 - 0 - 0 - OTX - - - IDZ027 - 120270 - Lewis_and_Srn_Nez_Perce_Cnties - ID - US - 46.16 - -116.51 - 0 - 0 - OTX - - - IDZ008 - 120080 - Lwr_Hells_Canyon/Salmon_Riv_Rgn - ID - US - 45.65 - -116.49 - 0 - 0 - MSO - - - CAZ061 - 50610 - Coachella_Valley - CA - US - 33.73 - -116.36 - 0 - 0 - SGX - - - CAZ062 - 50620 - San_Diego_County_Deserts - CA - US - 33.02 - -116.31 - 0 - 0 - SGX - - - CAZ525 - 55250 - Morongo_Basin - CA - US - 34.39 - -116.15 - 0 - 0 - VEF - - - NVZ017 - 280170 - Wrn_Clark_and_Srn_Nye_County - NV - US - 36.28 - -116.11 - 0 - 0 - VEF - - - IDZ015 - 120150 - Southwest_Highlands - ID - US - 42.51 - -116.02 - 0 - 0 - BOI - - - IDZ011 - 120110 - West_Central_Mountains - ID - US - 44.70 - -115.94 - 0 - 0 - BOI - - - IDZ004 - 120040 - Central_Panhandle_Mountains - ID - US - 47.34 - -115.93 - 0 - 0 - OTX - - - CAZ030 - 50300 - Joshua_Tree_National_Park - CA - US - 33.93 - -115.89 - 0 - 0 - PSR - - - IDZ007 - 120070 - Orofino/Grangeville_Region - ID - US - 46.24 - -115.85 - 0 - 0 - MSO - - - IDZ014 - 120140 - Upper_Treasure_Valley - ID - US - 43.16 - -115.77 - 0 - 0 - BOI - - - CAZ524 - 55240 - Ern_Mojave_Dsrt,_Incl_the_Mojave - CA - US - 35.17 - -115.61 - 0 - 0 - VEF - - - NVZ019 - 280190 - Spring_Mtns-Red_Rock_Canyon - NV - US - 36.13 - -115.57 - 0 - 0 - VEF - - - NVZ031 - 280310 - Northern_Elko_County - NV - US - 41.49 - -115.52 - 0 - 0 - LKN - - - IDZ005 - 120050 - Northern_Clearwater_Mountains - ID - US - 46.65 - -115.47 - 0 - 0 - MSO - - - CAZ033 - 50330 - Imperial_County - CA - US - 33.02 - -115.41 - 0 - 0 - PSR - - - IDZ013 - 120130 - Boise_Mountains - ID - US - 43.79 - -115.39 - 0 - 0 - BOI - - - CAZ032 - 50320 - Riverside_County/Ern_Deserts - CA - US - 33.75 - -115.33 - 0 - 0 - PSR - - - IDZ006 - 120060 - Southern_Clearwater_Mountains - ID - US - 45.88 - -115.33 - 0 - 0 - MSO - - - NVZ034 - 280340 - Ruby_Mtns/East_Humboldt_Range - NV - US - 40.56 - -115.33 - 0 - 0 - LKN - - - MTZ001 - 260010 - Kootenai/Cabinet_Region - MT - US - 48.18 - -115.15 - 0 - 0 - MSO - - - NVZ018 - 280180 - Sheep_Range - NV - US - 36.84 - -115.15 - 0 - 0 - VEF - - - NVZ020 - 280200 - Las_Vegas_Valley - NV - US - 36.11 - -115.12 - 0 - 0 - VEF - - - NVZ022 - 280220 - Southern_Clark_County - NV - US - 35.50 - -115.09 - 0 - 0 - VEF - - - CAZ526 - 55260 - Cadiz_Basin - CA - US - 34.45 - -115.08 - 0 - 0 - VEF - - - MTZ004 - 260040 - Lower_Clark_Fork_Region - MT - US - 47.38 - -115.02 - 0 - 0 - MSO - - - NVZ035 - 280350 - White_Pine_County - NV - US - 39.40 - -114.97 - 0 - 0 - LKN - - - NVZ015 - 280150 - Lincoln_County - NV - US - 37.76 - -114.96 - 0 - 0 - VEF - - - IDZ028 - 120280 - Camas_Prairie - ID - US - 43.34 - -114.86 - 0 - 0 - BOI - - - NVZ032 - 280320 - SW_and_South_Ctrl_Elko_County - NV - US - 40.64 - -114.83 - 0 - 0 - LKN - - - CAZ031 - 50310 - Lower_Colorado_River_Valley_CA - CA - US - 33.39 - -114.79 - 0 - 0 - PSR - - - NVZ021 - 280210 - L_Mead_National_Recreation_Area - NV - US - 35.79 - -114.78 - 0 - 0 - VEF - - - IDZ030 - 120300 - Southern_Twin__Falls_County - ID - US - 42.26 - -114.65 - 0 - 0 - BOI - - - AZZ036 - 30360 - L_Mead_National_Recreation_Area - AZ - US - 35.67 - -114.61 - 0 - 0 - VEF - - - AZZ025 - 30250 - Yuma/Martinez_Lake_and_Vicinity - AZ - US - 32.69 - -114.58 - 0 - 0 - PSR - - - NVZ016 - 280160 - Northeast_Clark_County - NV - US - 36.55 - -114.53 - 0 - 0 - VEF - - - IDZ016 - 120160 - Western_Magic_Valley - ID - US - 42.80 - -114.50 - 0 - 0 - BOI - - - IDZ018 - 120180 - Sawtooth_Mountains - ID - US - 44.18 - -114.49 - 0 - 0 - PIH - - - CAZ527 - 55270 - Sn_Bernardino_Cnty-Upr_CO_Riv_Vl - CA - US - 34.58 - -114.44 - 0 - 0 - VEF - - - AZZ020 - 30200 - Lower_Colorado_River_Valley_AZ - AZ - US - 33.65 - -114.43 - 0 - 0 - PSR - - - IDZ009 - 120090 - Western_Lemhi_County - ID - US - 45.10 - -114.39 - 0 - 0 - MSO - - - AZZ002 - 30020 - Lake_Havasu_and_Fort_Mohave - AZ - US - 34.63 - -114.37 - 0 - 0 - VEF - - - MTZ003 - 260030 - Flathead/Mission_Valleys - MT - US - 47.82 - -114.31 - 0 - 0 - MSO - - - IDZ031 - 120310 - Big_and_Little_Wood_River_Rgn - ID - US - 43.59 - -114.29 - 0 - 0 - PIH - - - NVZ033 - 280330 - Extreme_Eastern_Elko_County - NV - US - 40.64 - -114.23 - 0 - 0 - LKN - - - MTZ005 - 260050 - Missoula/Bitterroot_Valleys - MT - US - 46.44 - -114.10 - 0 - 0 - MSO - - - MTZ006 - 260060 - Bitterroot/Sapphire_Mountains - MT - US - 46.16 - -113.95 - 0 - 0 - MSO - - - MTZ002 - 260020 - West_Glacier_Region - MT - US - 48.30 - -113.94 - 0 - 0 - MSO - - - AZZ003 - 30030 - Northwest_Deserts - AZ - US - 35.14 - -113.92 - 0 - 0 - VEF - - - AZZ021 - 30210 - West_Central_Deserts - AZ - US - 33.86 - -113.90 - 0 - 0 - PSR - - - AZZ026 - 30260 - Southwest_Deserts - AZ - US - 32.75 - -113.90 - 0 - 0 - PSR - - - IDZ017 - 120170 - Eastern_Magic_Valley - ID - US - 42.94 - -113.79 - 0 - 0 - PIH - - - MTZ043 - 260430 - Potomac/Seeley_Lake_Region - MT - US - 47.12 - -113.60 - 0 - 0 - MSO - - - IDZ032 - 120320 - Lost_River/Pashimeroi - ID - US - 44.17 - -113.54 - 0 - 0 - PIH - - - IDZ010 - 120100 - Eastern_Lemhi_County - ID - US - 44.96 - -113.48 - 0 - 0 - MSO - - - UTZ019 - 440190 - Utah's_Dixie_and_Zion_Natl_Pk - UT - US - 37.20 - -113.47 - 0 - 0 - SLC - - - UTZ016 - 440160 - Southwest_Utah - UT - US - 37.98 - -113.33 - 0 - 0 - SLC - - - AZZ001 - 30010 - Northwest_Plateau - AZ - US - 36.49 - -113.28 - 0 - 0 - VEF - - - IDZ022 - 120220 - South_Central_Highlands - ID - US - 42.39 - -113.17 - 0 - 0 - PIH - - - MTZ009 - 260090 - Northern_Rocky_Mountain_Front - MT - US - 48.56 - -113.12 - 0 - 0 - TFX - - - AZZ037 - 30370 - Yavapai_County_Vlys_and_Basins - AZ - US - 34.56 - -113.07 - 0 - 0 - FGZ - - - UTZ005 - 440050 - Great_Salt_Lake_Desert_and_Mtns - UT - US - 40.95 - -113.00 - 0 - 0 - SLC - - - UTZ015 - 440150 - West_Central_Utah - UT - US - 39.29 - -112.99 - 0 - 0 - SLC - - - AZZ008 - 30080 - Yavapai_County__Mountains - AZ - US - 34.82 - -112.97 - 0 - 0 - FGZ - - - AZZ031 - 30310 - Western_Pima_County - AZ - US - 32.14 - -112.87 - 0 - 0 - TWC - - - MTZ007 - 260070 - Butte/Blackfoot_Region - MT - US - 46.40 - -112.84 - 0 - 0 - MSO - - - AZZ027 - 30270 - Southwest_Maricopa_County - AZ - US - 32.94 - -112.77 - 0 - 0 - PSR - - - AZZ022 - 30220 - Northwest_Maricopa_County - AZ - US - 33.67 - -112.70 - 0 - 0 - PSR - - - MTZ008 - 260080 - Beaverhead - MT - US - 45.15 - -112.69 - 0 - 0 - TFX - - - MTZ010 - 260100 - Eastern_Glacier - MT - US - 48.65 - -112.67 - 0 - 0 - TFX - - - IDZ020 - 120200 - Upper_Snake_River_Plain - ID - US - 43.66 - -112.62 - 0 - 0 - PIH - - - MTZ048 - 260480 - Southern_Rocky_Mountain_Front - MT - US - 47.73 - -112.60 - 0 - 0 - TFX - - - IDZ021 - 120210 - Lower_Snake_River_Plain - ID - US - 42.94 - -112.55 - 0 - 0 - PIH - - - AZZ007 - 30070 - Coconino_Plateau - AZ - US - 35.71 - -112.43 - 0 - 0 - FGZ - - - UTZ003 - 440030 - Salt_Lake_and_Tooele_Valleys - UT - US - 40.45 - -112.42 - 0 - 0 - SLC - - - UTZ518 - 445180 - Southern_Utah_Mountains - UT - US - 37.79 - -112.33 - 0 - 0 - SLC - - - AZZ006 - 30060 - Grand_Canyon_Country - AZ - US - 36.22 - -112.32 - 0 - 0 - FGZ - - - MTZ014 - 260140 - Central_and_Srn_Lewis_and_Clark - MT - US - 46.87 - -112.28 - 0 - 0 - TFX - - - UTZ002 - 440020 - Northern_Wasatch_Front - UT - US - 41.39 - -112.16 - 0 - 0 - SLC - - - AZZ004 - 30040 - Kaibab_Plateau - AZ - US - 36.56 - -112.14 - 0 - 0 - FGZ - - - MTZ052 - 260520 - Jefferson - MT - US - 46.15 - -112.13 - 0 - 0 - TFX - - - AZZ023 - 30230 - Greater_Phoenix_Area - AZ - US - 33.57 - -112.09 - 0 - 0 - PSR - - - UTZ020 - 440200 - South_Central_Utah - UT - US - 37.50 - -112.04 - 0 - 0 - SLC - - - MTZ015 - 260150 - Madison - MT - US - 45.28 - -112.02 - 0 - 0 - TFX - - - IDZ019 - 120190 - Upper_Snake_Highlands - ID - US - 44.13 - -112.01 - 0 - 0 - PIH - - - MTZ046 - 260460 - Eastern_Pondera - MT - US - 48.23 - -112.00 - 0 - 0 - TFX - - - IDZ024 - 120240 - Cache_Valley/Idaho_Portion - ID - US - 42.14 - -111.94 - 0 - 0 - PIH - - - UTZ001 - 440010 - Cache_Valley/Utah_Portion - UT - US - 41.73 - -111.93 - 0 - 0 - SLC - - - AZZ038 - 30380 - Oak_Creek_and_Sycamore_Canyons - AZ - US - 34.93 - -111.89 - 0 - 0 - FGZ - - - AZZ005 - 30050 - Marble_and_Glen_Canyons - AZ - US - 36.63 - -111.87 - 0 - 0 - FGZ - - - UTZ004 - 440040 - Southern_Wasatch_Front - UT - US - 40.01 - -111.87 - 0 - 0 - SLC - - - UTZ014 - 440140 - Sanpete/Sevier_Valleys - UT - US - 39.17 - -111.84 - 0 - 0 - SLC - - - AZZ032 - 30320 - Tohono_Oodham_Nation - AZ - US - 31.98 - -111.83 - 0 - 0 - TWC - - - AZZ015 - 30150 - Western_Mogollon_Rim - AZ - US - 35.20 - -111.80 - 0 - 0 - FGZ - - - MTZ049 - 260490 - Eastern_Teton - MT - US - 47.80 - -111.80 - 0 - 0 - TFX - - - IDZ023 - 120230 - Caribou_Highlands - ID - US - 42.94 - -111.78 - 0 - 0 - PIH - - - MTZ044 - 260440 - Toole - MT - US - 48.60 - -111.74 - 0 - 0 - TFX - - - AZZ028 - 30280 - NW_and_North_Ctrl_Pinal_County - AZ - US - 33.08 - -111.67 - 0 - 0 - PSR - - - UTZ007 - 440070 - Wasatch_Mountains_I-80_North - UT - US - 41.36 - -111.61 - 0 - 0 - SLC - - - IDZ025 - 120250 - Wasatch_Mountains/Idaho_Portion - ID - US - 42.30 - -111.47 - 0 - 0 - PIH - - - UTZ008 - 440080 - Wasatch_Mountains_South_of_I-80 - UT - US - 40.17 - -111.45 - 0 - 0 - SLC - - - UTZ517 - 445170 - Central_Utah_Mountains - UT - US - 39.02 - -111.44 - 0 - 0 - SLC - - - MTZ053 - 260530 - Broadwater - MT - US - 46.31 - -111.42 - 0 - 0 - TFX - - - UTZ006 - 440060 - Wasatch_Mountain_Valleys - UT - US - 40.86 - -111.39 - 0 - 0 - SLC - - - MTZ012 - 260120 - Cascade - MT - US - 47.26 - -111.34 - 0 - 0 - TFX - - - AZZ029 - 30290 - Southeast_Pinal_County - AZ - US - 32.88 - -111.33 - 0 - 0 - TWC - - - MTZ055 - 260550 - Gallatin - MT - US - 45.34 - -111.29 - 0 - 0 - TFX - - - AZZ012 - 30120 - Ltl_CO_Riv_Vly_in_Coconino_Cnty - AZ - US - 35.44 - -111.25 - 0 - 0 - FGZ - - - MTZ045 - 260450 - Liberty - MT - US - 48.56 - -111.08 - 0 - 0 - TFX - - - AZZ024 - 30240 - Srn_Gila/Tonto_NF_Foothills - AZ - US - 33.51 - -111.03 - 0 - 0 - PSR - - - MTZ054 - 260540 - Meagher - MT - US - 46.63 - -110.97 - 0 - 0 - TFX - - - WYZ023 - 500230 - Star_Valley - WY - US - 42.89 - -110.96 - 0 - 0 - RIW - - - AZZ009 - 30090 - NE_Plateaus_and_Mesas_Hwy_264_Nw - AZ - US - 36.39 - -110.92 - 0 - 0 - FGZ - - - AZZ033 - 30330 - Tucson_Metro/Marana/Grn_Valley - AZ - US - 32.13 - -110.92 - 0 - 0 - TWC - - - AZZ034 - 30340 - Santa_Cruz_County - AZ - US - 31.54 - -110.91 - 0 - 0 - TWC - - - AZZ018 - 30180 - Northern_Gila_County - AZ - US - 34.06 - -110.85 - 0 - 0 - FGZ - - - UTZ012 - 440120 - Castle_Country - UT - US - 39.29 - -110.85 - 0 - 0 - SLC - - - AZZ016 - 30160 - Eastern_Mogollon_Rim - AZ - US - 34.49 - -110.77 - 0 - 0 - FGZ - - - MTZ064 - 260640 - Paradise_Valley - MT - US - 45.33 - -110.73 - 0 - 0 - BYZ - - - UTZ010 - 440100 - Wasatch_Plateau/Book_Cliffs - UT - US - 39.76 - -110.73 - 0 - 0 - SLC - - - UTZ009 - 440090 - Western_Uinta_Mountains - UT - US - 40.70 - -110.70 - 0 - 0 - SLC - - - UTZ021 - 440210 - Glen_Canyon_Rec_Area/L_Powell - UT - US - 37.54 - -110.70 - 0 - 0 - SLC - - - WYZ024 - 500240 - Salt_River_and_Wyoming_Ranges - WY - US - 42.55 - -110.65 - 0 - 0 - RIW - - - UTZ013 - 440130 - San_Rafael_Swell - UT - US - 38.54 - -110.64 - 0 - 0 - SLC - - - WYZ013 - 500130 - Jackson_Hole - WY - US - 43.63 - -110.62 - 0 - 0 - RIW - - - MTZ040 - 260400 - Northern_Park - MT - US - 45.98 - -110.55 - 0 - 0 - BYZ - - - WYZ012 - 500120 - Teton_and_Gros_Ventre_Mountains - WY - US - 43.64 - -110.55 - 0 - 0 - RIW - - - WYZ021 - 500210 - Southwest_Wyoming - WY - US - 41.29 - -110.55 - 0 - 0 - SLC - - - WYZ027 - 500270 - South_Lincoln_County - WY - US - 41.93 - -110.55 - 0 - 0 - RIW - - - MTZ065 - 260650 - Livingston_Area - MT - US - 45.65 - -110.51 - 0 - 0 - BYZ - - - WYZ001 - 500010 - Yellowstone_National_Park - WY - US - 44.62 - -110.49 - 0 - 0 - RIW - - - MTZ013 - 260130 - Chouteau - MT - US - 47.86 - -110.48 - 0 - 0 - TFX - - - UTZ011 - 440110 - Western_Uinta_Basin - UT - US - 40.22 - -110.46 - 0 - 0 - SLC - - - MTZ068 - 260680 - Crazy_Mountains - MT - US - 46.10 - -110.32 - 0 - 0 - BYZ - - - AZZ040 - 30400 - NE_Plateaus_and_Mesas_S_of_Hwy_2 - AZ - US - 35.52 - -110.30 - 0 - 0 - FGZ - - - AZZ013 - 30130 - Ltl_CO_Riv_Vly_in_Navajo_Cnty - AZ - US - 34.88 - -110.29 - 0 - 0 - FGZ - - - MTZ050 - 260500 - Judith_Basin - MT - US - 47.05 - -110.27 - 0 - 0 - TFX - - - AZZ039 - 30390 - Black_Mesa_Area - AZ - US - 36.37 - -110.25 - 0 - 0 - FGZ - - - MTZ067 - 260670 - Absaroka/Beartooth_Mountains - MT - US - 45.33 - -110.13 - 0 - 0 - BYZ - - - MTZ011 - 260110 - Hill - MT - US - 48.57 - -110.11 - 0 - 0 - TFX - - - UTZ029 - 440290 - Canyonlands/Natural_Bridges - UT - US - 37.87 - -110.03 - 0 - 0 - GJT - - - WYZ025 - 500250 - Upper_Grn_River_Basin_Foothills - WY - US - 42.98 - -110.03 - 0 - 0 - RIW - - - MTZ041 - 260410 - Northern_Sweet_Grass - MT - US - 45.93 - -109.86 - 0 - 0 - BYZ - - - MTZ028 - 260280 - Southern_Wheatland - MT - US - 46.38 - -109.84 - 0 - 0 - BYZ - - - MTZ066 - 260660 - Beartooth_Foothills - MT - US - 45.54 - -109.81 - 0 - 0 - BYZ - - - AZZ010 - 30100 - Chinle_Valley - AZ - US - 36.36 - -109.76 - 0 - 0 - FGZ - - - AZZ030 - 30300 - Upper_Gila_River_Valley - AZ - US - 33.05 - -109.75 - 0 - 0 - TWC - - - AZZ035 - 30350 - Cochise_County - AZ - US - 31.89 - -109.75 - 0 - 0 - TWC - - - WYZ014 - 500140 - Wind_River_Mountains_West - WY - US - 43.00 - -109.70 - 0 - 0 - RIW - - - WYZ026 - 500260 - Upper_Green_River_Basin - WY - US - 42.42 - -109.68 - 0 - 0 - RIW - - - AZZ017 - 30170 - White_Mountains - AZ - US - 33.89 - -109.65 - 0 - 0 - FGZ - - - MTZ063 - 260630 - Judith_Gap - MT - US - 46.65 - -109.65 - 0 - 0 - BYZ - - - UTZ027 - 440270 - Arches/Grand_Flat - UT - US - 38.95 - -109.61 - 0 - 0 - GJT - - - WYZ028 - 500280 - Rock_Springs_and_Green_River - WY - US - 41.51 - -109.60 - 0 - 0 - RIW - - - UTZ025 - 440250 - Tavaputs_Plateau - UT - US - 39.50 - -109.58 - 0 - 0 - GJT - - - UTZ028 - 440280 - La_Sal_and_Abajo_Mountains - UT - US - 38.15 - -109.53 - 0 - 0 - GJT - - - UTZ023 - 440230 - Eastern_Uinta_Mountains - UT - US - 40.68 - -109.52 - 0 - 0 - GJT - - - UTZ024 - 440240 - Eastern_Uinta_Basin - UT - US - 40.21 - -109.51 - 0 - 0 - GJT - - - WYZ002 - 500020 - Absaroka_Mountains - WY - US - 44.24 - -109.49 - 0 - 0 - RIW - - - AZZ014 - 30140 - Ltl_CO_Riv_Vly_in_Apache_Cnty - AZ - US - 34.58 - -109.45 - 0 - 0 - FGZ - - - UTZ022 - 440220 - Southeast_Utah - UT - US - 37.40 - -109.45 - 0 - 0 - GJT - - - WYZ029 - 500290 - Flaming_Gorge - WY - US - 41.25 - -109.42 - 0 - 0 - RIW - - - WYZ016 - 500160 - Upper_Wind_River_Basin - WY - US - 43.44 - -109.41 - 0 - 0 - RIW - - - MTZ056 - 260560 - Red_Lodge_Foothills - MT - US - 45.23 - -109.32 - 0 - 0 - BYZ - - - AZZ011 - 30110 - Chuska_Mtns_and_Defiance_Plateay - AZ - US - 35.98 - -109.31 - 0 - 0 - FGZ - - - WYZ015 - 500150 - Wind_River_Mountains_East - WY - US - 43.09 - -109.31 - 0 - 0 - RIW - - - AZZ019 - 30190 - Northern_Greenlee - AZ - US - 33.42 - -109.27 - 0 - 0 - TWC - - - MTZ051 - 260510 - Fergus - MT - US - 47.25 - -109.26 - 0 - 0 - TFX - - - MTZ042 - 260420 - Golden_Valley - MT - US - 46.36 - -109.22 - 0 - 0 - BYZ - - - MTZ034 - 260340 - Northern_Stillwater - MT - US - 45.78 - -109.21 - 0 - 0 - BYZ - - - WYZ003 - 500030 - Cody_Foothills - WY - US - 44.46 - -109.04 - 0 - 0 - RIW - - - MTZ047 - 260470 - Blaine - MT - US - 48.37 - -108.90 - 0 - 0 - TFX - - - MTZ039 - 260390 - Eastern_Carbon - MT - US - 45.32 - -108.71 - 0 - 0 - BYZ - - - COZ006 - 60060 - Grand_Valley - CO - US - 39.16 - -108.65 - 0 - 0 - GJT - - - COZ021 - 60210 - Four_Corners/Upper_Dolores_Riv - CO - US - 37.49 - -108.64 - 0 - 0 - GJT - - - NMZ030 - 310300 - Southwest_Desert/Bootheel - NM - US - 31.93 - -108.63 - 0 - 0 - EPZ - - - COZ020 - 60200 - Paradox_Vly/Little_Dolores_Riv - CO - US - 38.28 - -108.61 - 0 - 0 - GJT - - - WYZ007 - 500070 - Owl_Creek_and_Bridger_Mountains - WY - US - 43.62 - -108.61 - 0 - 0 - RIW - - - WYZ018 - 500180 - Lander_Foothills - WY - US - 42.81 - -108.61 - 0 - 0 - RIW - - - MTZ060 - 260600 - Southwest_Phillips - MT - US - 47.83 - -108.55 - 0 - 0 - GGW - - - COZ001 - 60010 - Lower_Yampa_River_Basin - CO - US - 40.30 - -108.49 - 0 - 0 - GJT - - - COZ003 - 60030 - Roan_and_Tavaputs_Plateaus - CO - US - 39.63 - -108.44 - 0 - 0 - GJT - - - MTZ029 - 260290 - Musselshell - MT - US - 46.44 - -108.40 - 0 - 0 - BYZ - - - WYZ030 - 500300 - East_Sweetwater_County - WY - US - 41.61 - -108.37 - 0 - 0 - RIW - - - COZ017 - 60170 - Uncompahgre_Plateau/Dallas_Divid - CO - US - 38.58 - -108.35 - 0 - 0 - GJT - - - WYZ017 - 500170 - Wind_River_Basin - WY - US - 43.13 - -108.34 - 0 - 0 - RIW - - - MTZ021 - 260210 - Petroleum - MT - US - 47.18 - -108.28 - 0 - 0 - GGW - - - WYZ005 - 500050 - Southwest_Big_Horn_Basin - WY - US - 43.81 - -108.25 - 0 - 0 - RIW - - - NMZ001 - 310010 - Northwest_Plateau - NM - US - 36.35 - -108.23 - 0 - 0 - ABQ - - - MTZ035 - 260350 - Yellowstone - MT - US - 45.98 - -108.20 - 0 - 0 - BYZ - - - WYZ004 - 500040 - North_Big_Horn_Basin - WY - US - 44.57 - -108.19 - 0 - 0 - RIW - - - NMZ022 - 310220 - SW_Mtns/Lower_Gila_Region - NM - US - 33.00 - -108.17 - 0 - 0 - EPZ - - - NMZ014 - 310140 - SW_Mtns/Upper_Gila_Region - NM - US - 33.77 - -108.13 - 0 - 0 - ABQ - - - NMZ008 - 310080 - West_Central_Mountains - NM - US - 35.06 - -108.09 - 0 - 0 - ABQ - - - COZ007 - 60070 - Debeque_to_Silt_Corridor - CO - US - 39.43 - -108.05 - 0 - 0 - GJT - - - WYZ019 - 500190 - Grn_Mtns_and_Rattlesnake_Range - WY - US - 42.40 - -107.96 - 0 - 0 - RIW - - - COZ011 - 60110 - Ctrl_Gunnison_and_Uncompahgre_Ri - CO - US - 38.64 - -107.94 - 0 - 0 - GJT - - - COZ022 - 60220 - Animas_River_Basin - CO - US - 37.25 - -107.92 - 0 - 0 - GJT - - - WYZ006 - 500060 - Southeast_Big_Horn_Basin - WY - US - 43.87 - -107.90 - 0 - 0 - RIW - - - COZ002 - 60020 - Central_Yampa_River_Basin - CO - US - 40.34 - -107.85 - 0 - 0 - GJT - - - COZ009 - 60090 - Grand_and_Battlement_Mesas - CO - US - 39.17 - -107.85 - 0 - 0 - GJT - - - MTZ016 - 260160 - Central_and_Southeast_Phillips - MT - US - 48.02 - -107.82 - 0 - 0 - GGW - - - MTZ059 - 260590 - Northern_Phillips - MT - US - 48.79 - -107.75 - 0 - 0 - GGW - - - NMZ031 - 310310 - Southwest_Desert/Mimbres_Basin - NM - US - 32.20 - -107.75 - 0 - 0 - EPZ - - - COZ018 - 60180 - Northwestern_San_Juan_Mountains - CO - US - 38.08 - -107.64 - 0 - 0 - GJT - - - COZ019 - 60190 - Southwest_San_Juan_Mountains - CO - US - 37.48 - -107.64 - 0 - 0 - GJT - - - COZ013 - 60130 - Flattops - CO - US - 39.98 - -107.53 - 0 - 0 - GJT - - - MTZ038 - 260380 - Southern_Big_Horn - MT - US - 45.26 - -107.48 - 0 - 0 - BYZ - - - WYZ098 - 500980 - Northeast_Big_Horn_Mountains - WY - US - 44.78 - -107.43 - 0 - 0 - BYZ - - - MTZ057 - 260570 - Northern_Big_Horn - MT - US - 45.78 - -107.40 - 0 - 0 - BYZ - - - MTZ030 - 260300 - Treasure - MT - US - 46.18 - -107.34 - 0 - 0 - BYZ - - - COZ023 - 60230 - San_Juan_River_Basin - CO - US - 37.20 - -107.30 - 0 - 0 - GJT - - - WYZ008 - 500080 - Bighorn_Mountains_West - WY - US - 44.21 - -107.28 - 0 - 0 - RIW - - - WYZ061 - 500610 - Southwest_Carbon - WY - US - 41.53 - -107.28 - 0 - 0 - CYS - - - COZ014 - 60140 - Upper_Gunnison_River_Valley - CO - US - 38.51 - -107.17 - 0 - 0 - GJT - - - NMZ002 - 310020 - Northwest_Mtns_including_Jemez - NM - US - 36.16 - -107.10 - 0 - 0 - ABQ - - - WYZ009 - 500090 - Bighorn_Mountains_Southeast - WY - US - 43.88 - -107.07 - 0 - 0 - RIW - - - MTZ022 - 260220 - Garfield - MT - US - 47.41 - -107.03 - 0 - 0 - GGW - - - COZ008 - 60080 - Central_Colorado_River_Basin - CO - US - 39.60 - -106.99 - 0 - 0 - GJT - - - MTZ031 - 260310 - Northern_Rosebud - MT - US - 46.27 - -106.99 - 0 - 0 - BYZ - - - NMZ023 - 310230 - Sierra_County_Lakes_Region - NM - US - 33.04 - -106.97 - 0 - 0 - EPZ - - - COZ005 - 60050 - Upper_Yampa_River_Basin - CO - US - 40.41 - -106.96 - 0 - 0 - GJT - - - COZ012 - 60120 - West_Elk_and_Sawatch_Mountains - CO - US - 38.84 - -106.93 - 0 - 0 - GJT - - - COZ010 - 60100 - Gore_and_Elk_Mtns/Ctrl_Mtn_Vlys - CO - US - 39.45 - -106.92 - 0 - 0 - GJT - - - NMZ032 - 310320 - Southern_Desert - NM - US - 32.37 - -106.87 - 0 - 0 - EPZ - - - NMZ015 - 310150 - Lower_Rio_Grande_Valley - NM - US - 34.03 - -106.86 - 0 - 0 - ABQ - - - NMZ009 - 310090 - Middle_Rio_Gnde_Vly/Albuquerque_ - NM - US - 34.90 - -106.85 - 0 - 0 - ABQ - - - WYZ062 - 500620 - North_Carbon - WY - US - 42.03 - -106.80 - 0 - 0 - CYS - - - WYZ020 - 500200 - Natrona_County_Lower_Elevations - WY - US - 42.97 - -106.79 - 0 - 0 - RIW - - - WYZ099 - 500990 - Sheridan_Foothills - WY - US - 44.78 - -106.77 - 0 - 0 - BYZ - - - COZ004 - 60040 - Elkhead_and_Park_Mountains - CO - US - 40.46 - -106.73 - 0 - 0 - GJT - - - COZ066 - 60660 - La_Garita_Mtns_Above_10000_Ft - CO - US - 38.05 - -106.72 - 0 - 0 - PUB - - - COZ064 - 60640 - Saguache_Cnty_W_of_Continental_D - CO - US - 38.24 - -106.64 - 0 - 0 - PUB - - - COZ031 - 60310 - W_Jackson_and_W_Gnd_Cnties_Above - CO - US - 40.48 - -106.62 - 0 - 0 - BOU - - - MTZ017 - 260170 - Central_and_Southern_Valley - MT - US - 48.12 - -106.62 - 0 - 0 - GGW - - - MTZ061 - 260610 - Northern_Valley - MT - US - 48.79 - -106.62 - 0 - 0 - GGW - - - COZ068 - 60680 - Ern_Sn_Juan_Mtns_Above_10000_Ft - CO - US - 37.40 - -106.61 - 0 - 0 - PUB - - - MTZ058 - 260580 - Southern_Rosebud - MT - US - 45.43 - -106.50 - 0 - 0 - BYZ - - - WYZ011 - 500110 - Southeast_Johnson_County - WY - US - 43.83 - -106.48 - 0 - 0 - RIW - - - WYZ010 - 500100 - Northeast_Johnson_County - WY - US - 44.36 - -106.46 - 0 - 0 - RIW - - - NMZ010 - 310100 - Sandia/Manzano_Mountains - NM - US - 34.76 - -106.40 - 0 - 0 - ABQ - - - COZ060 - 60600 - Ern_Sawatch_Mtns_Above_11000_Ft - CO - US - 38.81 - -106.39 - 0 - 0 - PUB - - - COZ059 - 60590 - Leadvl_Vic/L_Cnty_Below_11000_Ft - CO - US - 39.20 - -106.38 - 0 - 0 - PUB - - - WYZ063 - 500630 - Snowy_Range - WY - US - 41.39 - -106.37 - 0 - 0 - CYS - - - COZ065 - 60650 - Saguache_Cnty_E_of_Continental_D - CO - US - 38.07 - -106.36 - 0 - 0 - PUB - - - TXZ055 - 430550 - El_Paso - TX - US - 31.70 - -106.30 - 0 - 0 - EPZ - - - COZ030 - 60300 - Jackson_County_Below_9000_Feet - CO - US - 40.69 - -106.28 - 0 - 0 - BOU - - - WYZ022 - 500220 - Casper_Mountain - WY - US - 42.61 - -106.24 - 0 - 0 - RIW - - - COZ067 - 60670 - Upr_Rio_Gnde_Vly/Ern_Sn_Juan_Mtn - CO - US - 37.45 - -106.23 - 0 - 0 - PUB - - - COZ058 - 60580 - Wrn_Mosquito_Rng/E_L_Cnty_Above_ - CO - US - 39.21 - -106.21 - 0 - 0 - PUB - - - COZ061 - 60610 - Wrn_Chaffee_Cnty_Between_9000_an - CO - US - 38.74 - -106.20 - 0 - 0 - PUB - - - NMZ024 - 310240 - Tularosa_Basin/Southern_Desert - NM - US - 32.70 - -106.18 - 0 - 0 - EPZ - - - COZ032 - 60320 - Gnd_and_Summit_Cnties_Below_9000 - CO - US - 40.00 - -106.17 - 0 - 0 - BOU - - - COZ062 - 60620 - Ctrl_Chaffee_Cnty_Below_9000_Ft - CO - US - 38.74 - -106.12 - 0 - 0 - PUB - - - NMZ003 - 310030 - Upper_Rio_Grande_Valley - NM - US - 35.80 - -106.07 - 0 - 0 - ABQ - - - COZ069 - 60690 - Del_Norte_Vic/Nrn_Sn_Luis_Vly_Be - CO - US - 37.97 - -106.04 - 0 - 0 - PUB - - - COZ063 - 60630 - Wrn_Mosquito_Rng/E_Chaffee_Cnty_ - CO - US - 38.79 - -105.96 - 0 - 0 - PUB - - - COZ033 - 60330 - S_and_E_Jackson/Larimer/N_and_NE - CO - US - 40.55 - -105.94 - 0 - 0 - BOU - - - COZ034 - 60340 - S_and_SE_Gnd/W_Ctrl_and_SW_Bould - CO - US - 39.55 - -105.91 - 0 - 0 - BOU - - - COZ070 - 60700 - Alamosa_Vic/Ctrl_Sn_Luis_Vly_Bel - CO - US - 37.54 - -105.91 - 0 - 0 - PUB - - - NMZ011 - 310110 - Ctrl_Hi_Plains/Estancia_Valley - NM - US - 34.77 - -105.83 - 0 - 0 - ABQ - - - MTZ023 - 260230 - McCone - MT - US - 47.59 - -105.82 - 0 - 0 - GGW - - - WYZ065 - 500650 - Laramie_Valley - WY - US - 41.59 - -105.81 - 0 - 0 - CYS - - - COZ071 - 60710 - Southern_San_Luis_Valley - CO - US - 37.27 - -105.78 - 0 - 0 - PUB - - - WYZ064 - 500640 - North_Laramie_Range - WY - US - 42.32 - -105.68 - 0 - 0 - CYS - - - COZ037 - 60370 - Central_and_SE_Park_County - CO - US - 39.05 - -105.66 - 0 - 0 - BOU - - - COZ077 - 60770 - Wrn/Ctrl_Fremt_Cnty_Below_8500_F - CO - US - 38.46 - -105.63 - 0 - 0 - PUB - - - MTZ036 - 260360 - Powder_River - MT - US - 45.40 - -105.63 - 0 - 0 - BYZ - - - NMZ025 - 310250 - Southern_Sacramento_Mountains - NM - US - 32.91 - -105.63 - 0 - 0 - EPZ - - - COZ076 - 60760 - NWrn_Fremt_County_above_8500_Ft - CO - US - 38.55 - -105.61 - 0 - 0 - PUB - - - COZ073 - 60730 - Nrn_Sngre_De_Cristo_Mtns_Above_1 - CO - US - 38.00 - -105.59 - 0 - 0 - PUB - - - NMZ017 - 310170 - Capitan/Nrn_Sacramento_Mtns - NM - US - 33.71 - -105.58 - 0 - 0 - ABQ - - - MTZ018 - 260180 - Daniels - MT - US - 48.79 - -105.57 - 0 - 0 - GGW - - - NMZ004 - 310040 - Sangre_de_Cristo_Mountains - NM - US - 36.25 - -105.57 - 0 - 0 - ABQ - - - WYZ054 - 500540 - Northern_Campbell - WY - US - 44.60 - -105.55 - 0 - 0 - UNR - - - WYZ055 - 500550 - Southern_Campbell - WY - US - 43.84 - -105.55 - 0 - 0 - UNR - - - COZ072 - 60720 - Nrn_Sngre_De_Cristo_Mtns_Between - CO - US - 37.98 - -105.49 - 0 - 0 - PUB - - - WYZ059 - 500590 - Converse - WY - US - 43.02 - -105.49 - 0 - 0 - CYS - - - MTZ032 - 260320 - Custer - MT - US - 46.33 - -105.47 - 0 - 0 - BYZ - - - COZ078 - 60780 - Wet_Mtn_Valley_Below_8500_Feet - CO - US - 38.08 - -105.45 - 0 - 0 - PUB - - - TXZ056 - 430560 - Hudspeth - TX - US - 31.32 - -105.45 - 0 - 0 - EPZ - - - MTZ020 - 260200 - Western_Roosevelt - MT - US - 48.29 - -105.41 - 0 - 0 - GGW - - - COZ035 - 60350 - Larimer_and_Boulder_Cnties_Betwe - CO - US - 40.46 - -105.39 - 0 - 0 - BOU - - - MTZ026 - 260260 - Prairie - MT - US - 46.86 - -105.34 - 0 - 0 - GGW - - - COZ036 - 60360 - Jefferson_and_W_Douglas_Cnties_A - CO - US - 39.53 - -105.32 - 0 - 0 - BOU - - - WYZ066 - 500660 - Laramie_Range - WY - US - 41.45 - -105.31 - 0 - 0 - CYS - - - COZ081 - 60810 - Teller_Cnty/Rampart_Rng_above_75 - CO - US - 38.82 - -105.22 - 0 - 0 - PUB - - - COZ039 - 60390 - Boulder_And_Jefferson_Cnties_Bel - CO - US - 39.87 - -105.19 - 0 - 0 - BOU - - - COZ075 - 60750 - Srn_Sngre_De_Cristo_Mtns_Above_1 - CO - US - 37.20 - -105.17 - 0 - 0 - PUB - - - COZ079 - 60790 - Wet_Mtns_Between_6300_and_10000_ - CO - US - 38.08 - -105.14 - 0 - 0 - PUB - - - COZ080 - 60800 - Wet_Mountains_Above_10000_Ft - CO - US - 37.98 - -105.14 - 0 - 0 - PUB - - - COZ083 - 60830 - Canon_City_Vic/Ern_Fremt_County - CO - US - 38.44 - -105.14 - 0 - 0 - PUB - - - NMZ026 - 310260 - Guadalupe_Mtns_of_Chaves_County - NM - US - 32.83 - -105.08 - 0 - 0 - ABQ - - - NMZ016 - 310160 - Lincoln_Cnty_Hi_Plns/Hondo_Vly - NM - US - 33.74 - -105.07 - 0 - 0 - ABQ - - - COZ082 - 60820 - PIkes_Peak_above_11000_Ft - CO - US - 38.82 - -105.04 - 0 - 0 - PUB - - - WYZ067 - 500670 - Platte - WY - US - 42.13 - -104.97 - 0 - 0 - CYS - - - COZ087 - 60870 - Walsenbg_Vic/Upr_Huerfano_Riv_Bs - CO - US - 37.67 - -104.87 - 0 - 0 - PUB - - - MTZ025 - 260250 - Dawson - MT - US - 47.32 - -104.86 - 0 - 0 - GGW - - - COZ074 - 60740 - Srn_Sngre_De_Cristo_Mtns_Between - CO - US - 37.26 - -104.83 - 0 - 0 - PUB - - - COZ040 - 60400 - N_Douglas_Cnty_Below_6000_Feet/D - CO - US - 39.73 - -104.81 - 0 - 0 - BOU - - - COZ038 - 60380 - Larimer_Cnty_Below_6000_Feet/NW_ - CO - US - 40.63 - -104.80 - 0 - 0 - BOU - - - WYZ069 - 500690 - Cheyenne_Foothills - WY - US - 41.33 - -104.75 - 0 - 0 - CYS - - - WYZ056 - 500560 - Western_Crook - WY - US - 44.59 - -104.72 - 0 - 0 - UNR - - - TXZ258 - 432580 - Guadalupe_Mountains - TX - US - 31.90 - -104.71 - 0 - 0 - MAF - - - NMZ027 - 310270 - Guadalupe_Mtns_of_Eddy_County - NM - US - 32.30 - -104.67 - 0 - 0 - MAF - - - MTZ024 - 260240 - Richland - MT - US - 47.75 - -104.64 - 0 - 0 - GGW - - - TXZ079 - 430790 - Presidio_Valley - TX - US - 29.95 - -104.61 - 0 - 0 - MAF - - - COZ043 - 60430 - Central_and_South_Weld_County - CO - US - 40.29 - -104.59 - 0 - 0 - BOU - - - WYZ058 - 500580 - Weston - WY - US - 43.84 - -104.57 - 0 - 0 - UNR - - - MTZ019 - 260190 - Sheridan - MT - US - 48.70 - -104.55 - 0 - 0 - GGW - - - TXZ057 - 430570 - Van_Horn_and_Hiway_54_Corridor - TX - US - 31.24 - -104.55 - 0 - 0 - MAF - - - COZ086 - 60860 - Pueblo_and_Vic/Pueblo_Cnty_Below - CO - US - 38.12 - -104.54 - 0 - 0 - PUB - - - MTZ037 - 260370 - Carter - MT - US - 45.57 - -104.54 - 0 - 0 - BYZ - - - NMZ005 - 310050 - Northeast_Highlands - NM - US - 36.10 - -104.54 - 0 - 0 - ABQ - - - COZ085 - 60850 - CO_Spgs_Vic/Srn_El_Paso_Cnty/Ram - CO - US - 38.74 - -104.51 - 0 - 0 - PUB - - - MTZ062 - 260620 - Eastern_Roosevelt - MT - US - 48.28 - -104.51 - 0 - 0 - GGW - - - COZ088 - 60880 - Trinidad_Vic/Wrn_Las_Animas_Cnty - CO - US - 37.40 - -104.50 - 0 - 0 - PUB - - - COZ084 - 60840 - Nrn_El_Paso_Cnty/Monument_Ridge/ - CO - US - 38.99 - -104.49 - 0 - 0 - PUB - - - WYZ060 - 500600 - Niobrara - WY - US - 43.06 - -104.49 - 0 - 0 - CYS - - - MTZ033 - 260330 - Fallon - MT - US - 46.29 - -104.48 - 0 - 0 - BYZ - - - NMZ012 - 310120 - Conchas_Lake/Guadalupe_County - NM - US - 35.08 - -104.46 - 0 - 0 - ABQ - - - COZ041 - 60410 - Elbert/Ctrl_and_E_Douglas_Cnties - CO - US - 39.28 - -104.43 - 0 - 0 - BOU - - - NMZ018 - 310180 - De_Baca_County - NM - US - 34.39 - -104.41 - 0 - 0 - ABQ - - - TXZ080 - 430800 - Marfa_Plateau - TX - US - 30.16 - -104.39 - 0 - 0 - MAF - - - WYZ057 - 500570 - Wyoming_Black_Hills - WY - US - 44.38 - -104.37 - 0 - 0 - UNR - - - WYZ068 - 500680 - Goshen - WY - US - 42.09 - -104.35 - 0 - 0 - CYS - - - MTZ027 - 260270 - Wibaux - MT - US - 47.02 - -104.33 - 0 - 0 - GGW - - - WYZ070 - 500700 - Pine_Bluffs - WY - US - 41.28 - -104.28 - 0 - 0 - CYS - - - NMZ028 - 310280 - Eddy_County_Plains - NM - US - 32.49 - -104.27 - 0 - 0 - MAF - - - WYZ071 - 500710 - Northeastern_Crook - WY - US - 44.79 - -104.21 - 0 - 0 - UNR - - - NMZ019 - 310190 - Chaves_County_Plains - NM - US - 33.53 - -104.19 - 0 - 0 - ABQ - - - COZ042 - 60420 - Northeast_Weld_County - CO - US - 40.75 - -104.10 - 0 - 0 - BOU - - - COZ045 - 60450 - Ctrl_and_E_Adams_and_Arapahoe_Cn - CO - US - 39.78 - -104.10 - 0 - 0 - BOU - - - NMZ006 - 310060 - Harding_County - NM - US - 35.81 - -103.89 - 0 - 0 - ABQ - - - NDZ031 - 340310 - Golden_Valley - ND - US - 46.94 - -103.83 - 0 - 0 - BIS - - - COZ046 - 60460 - N_and_NE_Elbert_Cnty_Below_6000_ - CO - US - 39.33 - -103.81 - 0 - 0 - BOU - - - COZ044 - 60440 - Morgan_County - CO - US - 40.25 - -103.80 - 0 - 0 - BOU - - - TXZ074 - 430740 - Davis/Apache_Mountains_Area - TX - US - 30.71 - -103.80 - 0 - 0 - MAF - - - TXZ058 - 430580 - Reeves_Cnty_and_Upr_Trans_Pecos - TX - US - 31.39 - -103.78 - 0 - 0 - MAF - - - COZ089 - 60890 - Crowley_County - CO - US - 38.31 - -103.77 - 0 - 0 - PUB - - - NEZ001 - 270010 - Sioux - NE - US - 42.50 - -103.73 - 0 - 0 - CYS - - - COZ093 - 60930 - La_Junta_Vicinity/Otero_County - CO - US - 37.95 - -103.72 - 0 - 0 - PUB - - - SDZ024 - 410240 - Northern_Black_Hills - SD - US - 44.31 - -103.72 - 0 - 0 - UNR - - - NEZ019 - 270190 - Scotts_Bluff - NE - US - 41.85 - -103.71 - 0 - 0 - CYS - - - NEZ020 - 270200 - Banner - NE - US - 41.54 - -103.71 - 0 - 0 - CYS - - - NEZ054 - 270540 - Kimball - NE - US - 41.20 - -103.71 - 0 - 0 - CYS - - - SDZ028 - 410280 - Central_Black_Hills - SD - US - 44.00 - -103.69 - 0 - 0 - UNR - - - SDZ029 - 410290 - Southern_Black_Hills - SD - US - 43.67 - -103.69 - 0 - 0 - UNR - - - NMZ007 - 310070 - Far_Northeast_Plains - NM - US - 36.37 - -103.67 - 0 - 0 - ABQ - - - TXZ059 - 430590 - Loving - TX - US - 31.83 - -103.66 - 0 - 0 - MAF - - - SDZ025 - 410250 - Northern_Foot_Hills - SD - US - 44.44 - -103.64 - 0 - 0 - UNR - - - SDZ027 - 410270 - Southern_Foot_Hills - SD - US - 43.36 - -103.64 - 0 - 0 - UNR - - - COZ047 - 60470 - SE_Elbert_Cnty_Below_6000_Feet/S - CO - US - 38.80 - -103.60 - 0 - 0 - BOU - - - NMZ013 - 310130 - Quay_County - NM - US - 35.17 - -103.57 - 0 - 0 - ABQ - - - COZ094 - 60940 - Eastern_Las_Animas_County - CO - US - 37.32 - -103.56 - 0 - 0 - PUB - - - SDZ041 - 410410 - Fall_River - SD - US - 43.24 - -103.53 - 0 - 0 - UNR - - - NDZ043 - 340430 - Bowman - ND - US - 46.11 - -103.52 - 0 - 0 - BIS - - - SDZ012 - 410120 - Butte - SD - US - 44.89 - -103.51 - 0 - 0 - UNR - - - SDZ001 - 410010 - Harding - SD - US - 45.58 - -103.50 - 0 - 0 - UNR - - - NDZ040 - 340400 - Slope - ND - US - 46.45 - -103.49 - 0 - 0 - BIS - - - NMZ020 - 310200 - Roosevelt_County - NM - US - 34.08 - -103.49 - 0 - 0 - ABQ - - - NDZ001 - 340010 - Divide - ND - US - 48.82 - -103.47 - 0 - 0 - BIS - - - NDZ009 - 340090 - Williams - ND - US - 48.30 - -103.44 - 0 - 0 - BIS - - - NMZ033 - 310330 - Central_Lea_County - NM - US - 32.75 - -103.43 - 0 - 0 - MAF - - - NMZ029 - 310290 - Northern_Lea_County - NM - US - 33.28 - -103.40 - 0 - 0 - MAF - - - NMZ034 - 310340 - Southern_Lea_County - NM - US - 32.25 - -103.39 - 0 - 0 - MAF - - - NMZ021 - 310210 - Curry_County - NM - US - 34.64 - -103.38 - 0 - 0 - ABQ - - - NDZ032 - 340320 - Billings - ND - US - 46.98 - -103.35 - 0 - 0 - BIS - - - SDZ072 - 410720 - Sturgis/Piedmont_Foot_Hills - SD - US - 44.38 - -103.35 - 0 - 0 - UNR - - - NDZ017 - 340170 - McKenzie - ND - US - 47.74 - -103.31 - 0 - 0 - BIS - - - SDZ074 - 410740 - Hermosa_Foot_Hills - SD - US - 43.67 - -103.27 - 0 - 0 - UNR - - - COZ049 - 60490 - Washington_County - CO - US - 40.00 - -103.24 - 0 - 0 - BOU - - - SDZ026 - 410260 - Rapid_City - SD - US - 44.00 - -103.23 - 0 - 0 - UNR - - - TXZ067 - 430670 - Ward - TX - US - 31.46 - -103.18 - 0 - 0 - MAF - - - NEZ002 - 270020 - Dawes - NE - US - 42.72 - -103.14 - 0 - 0 - CYS - - - COZ048 - 60480 - Logan_County - CO - US - 40.72 - -103.11 - 0 - 0 - BOU - - - COZ095 - 60950 - Western_Kiowa_County - CO - US - 38.43 - -103.11 - 0 - 0 - PUB - - - NEZ003 - 270030 - Box_Butte - NE - US - 42.22 - -103.07 - 0 - 0 - CYS - - - TXZ060 - 430600 - Winkler - TX - US - 31.87 - -103.07 - 0 - 0 - MAF - - - TXZ081 - 430810 - Big_Bend_Area - TX - US - 29.69 - -103.06 - 0 - 0 - MAF - - - COZ097 - 60970 - Las_Animas_Vicinity/Bent_County - CO - US - 37.95 - -103.05 - 0 - 0 - PUB - - - NEZ021 - 270210 - Morrill - NE - US - 41.72 - -103.00 - 0 - 0 - CYS - - - NEZ055 - 270550 - Cheyenne - NE - US - 41.22 - -102.99 - 0 - 0 - CYS - - - SDZ030 - 410300 - Custer_Co_Plains - SD - US - 43.67 - -102.96 - 0 - 0 - UNR - - - TXZ027 - 430270 - Bailey - TX - US - 34.07 - -102.82 - 0 - 0 - LUB - - - TXZ033 - 430330 - Cochran - TX - US - 33.61 - -102.82 - 0 - 0 - LUB - - - TXZ039 - 430390 - Yoakum - TX - US - 33.17 - -102.82 - 0 - 0 - LUB - - - SDZ073 - 410730 - Southern_Meade_Co_Plains - SD - US - 44.38 - -102.78 - 0 - 0 - UNR - - - TXZ021 - 430210 - Parmer - TX - US - 34.53 - -102.78 - 0 - 0 - LUB - - - TXZ075 - 430750 - Pecos - TX - US - 30.72 - -102.67 - 0 - 0 - MAF - - - NDZ033 - 340330 - Stark - ND - US - 46.82 - -102.66 - 0 - 0 - BIS - - - NDZ018 - 340180 - Dunn - ND - US - 47.40 - -102.63 - 0 - 0 - BIS - - - TXZ050 - 430500 - Andrews - TX - US - 32.30 - -102.63 - 0 - 0 - MAF - - - TXZ045 - 430450 - Gaines - TX - US - 32.74 - -102.62 - 0 - 0 - MAF - - - COZ092 - 60920 - Cheyenne_County - CO - US - 38.82 - -102.61 - 0 - 0 - GLD - - - COZ091 - 60910 - Kit_Carson_County - CO - US - 39.30 - -102.60 - 0 - 0 - GLD - - - TXZ001 - 430010 - Dallam - TX - US - 36.27 - -102.60 - 0 - 0 - AMA - - - TXZ006 - 430060 - Hartley - TX - US - 35.84 - -102.59 - 0 - 0 - AMA - - - TXZ011 - 430110 - Oldham - TX - US - 35.40 - -102.59 - 0 - 0 - AMA - - - TXZ016 - 430160 - Deaf_Smith - TX - US - 34.97 - -102.59 - 0 - 0 - AMA - - - COZ099 - 60990 - Springfield_Vic/Baca_County - CO - US - 37.32 - -102.56 - 0 - 0 - PUB - - - SDZ031 - 410310 - Pennington_Co_Plains - SD - US - 44.10 - -102.56 - 0 - 0 - UNR - - - SDZ042 - 410420 - Shannon - SD - US - 43.35 - -102.54 - 0 - 0 - UNR - - - TXZ061 - 430610 - Ector - TX - US - 31.87 - -102.54 - 0 - 0 - MAF - - - TXZ068 - 430680 - Crane - TX - US - 31.37 - -102.54 - 0 - 0 - MAF - - - OKZ001 - 360010 - Cimarron - OK - US - 36.74 - -102.51 - 0 - 0 - AMA - - - NDZ044 - 340440 - Adams - ND - US - 46.11 - -102.50 - 0 - 0 - BIS - - - NDZ002 - 340020 - Burke - ND - US - 48.78 - -102.48 - 0 - 0 - BIS - - - SDZ002 - 410020 - Perkins - SD - US - 45.49 - -102.48 - 0 - 0 - UNR - - - SDZ013 - 410130 - Northern_Meade_Co_Plains - SD - US - 44.82 - -102.48 - 0 - 0 - UNR - - - NDZ041 - 340410 - Hettinger - ND - US - 46.42 - -102.46 - 0 - 0 - BIS - - - COZ090 - 60900 - Yuma_County - CO - US - 40.00 - -102.42 - 0 - 0 - GLD - - - NEZ004 - 270040 - Sheridan - NE - US - 42.50 - -102.40 - 0 - 0 - LBF - - - COZ096 - 60960 - Eastern_Kiowa_County - CO - US - 38.44 - -102.39 - 0 - 0 - PUB - - - COZ098 - 60980 - Lamar_Vicinity/Prowers_County - CO - US - 37.95 - -102.39 - 0 - 0 - PUB - - - NDZ010 - 340100 - Mountrail - ND - US - 48.16 - -102.38 - 0 - 0 - BIS - - - COZ050 - 60500 - Sedgwick_County - CO - US - 40.87 - -102.35 - 0 - 0 - BOU - - - COZ051 - 60510 - Phillips_County - CO - US - 40.59 - -102.35 - 0 - 0 - BOU - - - TXZ028 - 430280 - Lamb - TX - US - 34.07 - -102.35 - 0 - 0 - LUB - - - TXZ034 - 430340 - Hockley - TX - US - 33.61 - -102.34 - 0 - 0 - LUB - - - NEZ022 - 270220 - Garden - NE - US - 41.61 - -102.33 - 0 - 0 - LBF - - - NEZ056 - 270560 - Deuel - NE - US - 41.11 - -102.33 - 0 - 0 - LBF - - - TXZ040 - 430400 - Terry - TX - US - 33.17 - -102.33 - 0 - 0 - LUB - - - TXZ022 - 430220 - Castro - TX - US - 34.53 - -102.26 - 0 - 0 - LUB - - - TXZ082 - 430820 - Terrell - TX - US - 30.22 - -102.11 - 0 - 0 - MAF - - - TXZ069 - 430690 - Upton - TX - US - 31.37 - -102.04 - 0 - 0 - MAF - - - TXZ062 - 430620 - Midland - TX - US - 31.87 - -102.03 - 0 - 0 - MAF - - - TXZ051 - 430510 - Martin - TX - US - 32.30 - -101.95 - 0 - 0 - MAF - - - TXZ046 - 430460 - Dawson - TX - US - 32.74 - -101.94 - 0 - 0 - MAF - - - TXZ017 - 430170 - Randall - TX - US - 34.97 - -101.90 - 0 - 0 - AMA - - - TXZ002 - 430020 - Sherman - TX - US - 36.27 - -101.89 - 0 - 0 - AMA - - - TXZ007 - 430070 - Moore - TX - US - 35.84 - -101.89 - 0 - 0 - AMA - - - TXZ012 - 430120 - Potter - TX - US - 35.40 - -101.89 - 0 - 0 - AMA - - - TXZ029 - 430290 - Hale - TX - US - 34.07 - -101.82 - 0 - 0 - LUB - - - TXZ035 - 430350 - Lubbock - TX - US - 33.61 - -101.82 - 0 - 0 - LUB - - - TXZ041 - 430410 - Lynn - TX - US - 33.17 - -101.82 - 0 - 0 - LUB - - - KSZ041 - 160410 - Greeley - KS - US - 38.47 - -101.80 - 0 - 0 - GLD - - - KSZ084 - 160840 - Morton - KS - US - 37.19 - -101.80 - 0 - 0 - DDC - - - KSZ061 - 160610 - Hamilton - KS - US - 37.99 - -101.78 - 0 - 0 - DDC - - - KSZ074 - 160740 - Stanton - KS - US - 37.56 - -101.78 - 0 - 0 - DDC - - - KSZ027 - 160270 - Wallace - KS - US - 38.91 - -101.76 - 0 - 0 - GLD - - - NEZ023 - 270230 - Grant - NE - US - 41.91 - -101.75 - 0 - 0 - LBF - - - KSZ001 - 160010 - Cheyenne - KS - US - 39.78 - -101.73 - 0 - 0 - GLD - - - NDZ019 - 340190 - Mercer - ND - US - 47.28 - -101.73 - 0 - 0 - BIS - - - TXZ023 - 430230 - Swisher - TX - US - 34.53 - -101.73 - 0 - 0 - LUB - - - KSZ013 - 160130 - Sherman - KS - US - 39.35 - -101.72 - 0 - 0 - GLD - - - NEZ035 - 270350 - Arthur - NE - US - 41.56 - -101.70 - 0 - 0 - LBF - - - NEZ069 - 270690 - Chase - NE - US - 40.52 - -101.69 - 0 - 0 - LBF - - - NEZ079 - 270790 - Dundy - NE - US - 40.17 - -101.69 - 0 - 0 - GLD - - - SDZ044 - 410440 - Bennett - SD - US - 43.19 - -101.67 - 0 - 0 - UNR - - - TXZ076 - 430760 - Crockett - TX - US - 30.69 - -101.67 - 0 - 0 - SJT - - - NEZ057 - 270570 - Keith - NE - US - 41.19 - -101.65 - 0 - 0 - LBF - - - NEZ058 - 270580 - Perkins - NE - US - 40.85 - -101.65 - 0 - 0 - LBF - - - SDZ043 - 410430 - Jackson - SD - US - 43.69 - -101.61 - 0 - 0 - UNR - - - NDZ011 - 340110 - Ward - ND - US - 48.33 - -101.60 - 0 - 0 - BIS - - - NDZ042 - 340420 - Grant - ND - US - 46.37 - -101.58 - 0 - 0 - BIS - - - SDZ014 - 410140 - Ziebach - SD - US - 45.00 - -101.57 - 0 - 0 - UNR - - - NDZ003 - 340030 - Renville - ND - US - 48.73 - -101.54 - 0 - 0 - BIS - - - SDZ032 - 410320 - Haakon - SD - US - 44.37 - -101.53 - 0 - 0 - UNR - - - TXZ063 - 430630 - Glasscock - TX - US - 31.87 - -101.52 - 0 - 0 - MAF - - - TXZ070 - 430700 - Reagan - TX - US - 31.37 - -101.52 - 0 - 0 - MAF - - - OKZ002 - 360020 - Texas - OK - US - 36.74 - -101.49 - 0 - 0 - AMA - - - TXZ047 - 430470 - Borden - TX - US - 32.74 - -101.43 - 0 - 0 - MAF - - - TXZ052 - 430520 - Howard - TX - US - 32.30 - -101.43 - 0 - 0 - MAF - - - NEZ094 - 270940 - Western_Cherry - NE - US - 42.54 - -101.42 - 0 - 0 - LBF - - - TXZ013 - 430130 - Carson - TX - US - 35.40 - -101.36 - 0 - 0 - AMA - - - TXZ018 - 430180 - Armstrong - TX - US - 34.97 - -101.36 - 0 - 0 - AMA - - - TXZ003 - 430030 - Hansford - TX - US - 36.27 - -101.35 - 0 - 0 - AMA - - - TXZ008 - 430080 - Hutchinson - TX - US - 35.84 - -101.35 - 0 - 0 - AMA - - - KSZ042 - 160420 - Wichita - KS - US - 38.48 - -101.34 - 0 - 0 - GLD - - - NDZ034 - 340340 - Morton - ND - US - 46.63 - -101.33 - 0 - 0 - BIS - - - NDZ020 - 340200 - Oliver - ND - US - 47.14 - -101.32 - 0 - 0 - BIS - - - KSZ062 - 160620 - Kearny - KS - US - 37.99 - -101.31 - 0 - 0 - DDC - - - KSZ085 - 160850 - Stevens - KS - US - 37.19 - -101.31 - 0 - 0 - DDC - - - KSZ075 - 160750 - Grant - KS - US - 37.56 - -101.30 - 0 - 0 - DDC - - - TXZ030 - 430300 - Floyd - TX - US - 34.07 - -101.30 - 0 - 0 - LUB - - - TXZ036 - 430360 - Crosby - TX - US - 33.61 - -101.30 - 0 - 0 - LUB - - - TXZ042 - 430420 - Garza - TX - US - 33.17 - -101.30 - 0 - 0 - LUB - - - TXZ183 - 431830 - Val_Verde - TX - US - 29.76 - -101.22 - 0 - 0 - EWX - - - TXZ024 - 430240 - Briscoe - TX - US - 34.53 - -101.21 - 0 - 0 - LUB - - - SDZ003 - 410030 - Corson - SD - US - 45.71 - -101.15 - 0 - 0 - ABR - - - KSZ028 - 160280 - Logan - KS - US - 38.91 - -101.14 - 0 - 0 - GLD - - - NEZ024 - 270240 - Hooker - NE - US - 41.91 - -101.13 - 0 - 0 - LBF - - - KSZ002 - 160020 - Rawlins - KS - US - 39.78 - -101.07 - 0 - 0 - GLD - - - NEZ036 - 270360 - McPherson - NE - US - 41.56 - -101.06 - 0 - 0 - LBF - - - NEZ070 - 270700 - Hayes - NE - US - 40.52 - -101.06 - 0 - 0 - LBF - - - KSZ014 - 160140 - Thomas - KS - US - 39.35 - -101.05 - 0 - 0 - GLD - - - NDZ021 - 340210 - McLean - ND - US - 47.51 - -101.04 - 0 - 0 - BIS - - - NEZ080 - 270800 - Hitchcock - NE - US - 40.17 - -101.04 - 0 - 0 - GLD - - - TXZ064 - 430640 - Sterling - TX - US - 31.83 - -101.04 - 0 - 0 - SJT - - - TXZ071 - 430710 - Irion - TX - US - 31.31 - -100.98 - 0 - 0 - SJT - - - TXZ048 - 430480 - Scurry - TX - US - 32.74 - -100.92 - 0 - 0 - MAF - - - TXZ053 - 430530 - Mitchell - TX - US - 32.30 - -100.92 - 0 - 0 - MAF - - - KSZ043 - 160430 - Scott - KS - US - 38.48 - -100.90 - 0 - 0 - DDC - - - NDZ045 - 340450 - Sioux - ND - US - 46.19 - -100.90 - 0 - 0 - BIS - - - SDZ015 - 410150 - Dewey - SD - US - 45.10 - -100.89 - 0 - 0 - ABR - - - SDZ033 - 410330 - Stanley - SD - US - 44.48 - -100.88 - 0 - 0 - ABR - - - KSZ076 - 160760 - Haskell - KS - US - 37.56 - -100.86 - 0 - 0 - DDC - - - KSZ086 - 160860 - Seward - KS - US - 37.19 - -100.85 - 0 - 0 - DDC - - - NDZ004 - 340040 - Bottineau - ND - US - 48.77 - -100.82 - 0 - 0 - BIS - - - TXZ004 - 430040 - Ochiltree - TX - US - 36.27 - -100.82 - 0 - 0 - AMA - - - TXZ009 - 430090 - Roberts - TX - US - 35.84 - -100.82 - 0 - 0 - AMA - - - TXZ014 - 430140 - Gray - TX - US - 35.40 - -100.81 - 0 - 0 - AMA - - - TXZ019 - 430190 - Donley - TX - US - 34.96 - -100.81 - 0 - 0 - AMA - - - TXZ031 - 430310 - Motley - TX - US - 34.08 - -100.78 - 0 - 0 - LUB - - - TXZ037 - 430370 - Dickens - TX - US - 33.62 - -100.78 - 0 - 0 - LUB - - - TXZ043 - 430430 - Kent - TX - US - 33.18 - -100.78 - 0 - 0 - LUB - - - NEZ059 - 270590 - Lincoln - NE - US - 41.04 - -100.74 - 0 - 0 - LBF - - - SDZ046 - 410460 - Mellette - SD - US - 43.63 - -100.72 - 0 - 0 - UNR - - - SDZ047 - 410470 - Todd - SD - US - 43.19 - -100.72 - 0 - 0 - UNR - - - SDZ045 - 410450 - Jones - SD - US - 43.95 - -100.71 - 0 - 0 - ABR - - - TXZ025 - 430250 - Hall - TX - US - 34.53 - -100.68 - 0 - 0 - LUB - - - KSZ063 - 160630 - Finney - KS - US - 37.99 - -100.66 - 0 - 0 - DDC - - - NDZ012 - 340120 - McHenry - ND - US - 48.24 - -100.63 - 0 - 0 - BIS - - - NEZ025 - 270250 - Thomas - NE - US - 41.91 - -100.55 - 0 - 0 - LBF - - - TXZ077 - 430770 - Schleicher - TX - US - 30.89 - -100.54 - 0 - 0 - SJT - - - TXZ078 - 430780 - Sutton - TX - US - 30.49 - -100.54 - 0 - 0 - SJT - - - NEZ005 - 270050 - Eastern_Cherry - NE - US - 42.53 - -100.53 - 0 - 0 - LBF - - - TXZ065 - 430650 - Coke - TX - US - 31.89 - -100.53 - 0 - 0 - SJT - - - NDZ035 - 340350 - Burleigh - ND - US - 46.98 - -100.52 - 0 - 0 - BIS - - - KSZ029 - 160290 - Gove - KS - US - 38.91 - -100.48 - 0 - 0 - GLD - - - NEZ037 - 270370 - Logan - NE - US - 41.57 - -100.48 - 0 - 0 - LBF - - - OKZ003 - 360030 - Beaver - OK - US - 36.74 - -100.48 - 0 - 0 - AMA - - - NEZ081 - 270810 - Red_Willow - NE - US - 40.17 - -100.47 - 0 - 0 - GLD - - - KSZ003 - 160030 - Decatur - KS - US - 39.78 - -100.46 - 0 - 0 - GLD - - - KSZ044 - 160440 - Lane - KS - US - 38.47 - -100.46 - 0 - 0 - DDC - - - TXZ202 - 432020 - Kinney - TX - US - 29.35 - -100.45 - 0 - 0 - EWX - - - KSZ015 - 160150 - Sheridan - KS - US - 39.35 - -100.44 - 0 - 0 - GLD - - - KSZ077 - 160770 - Gray - KS - US - 37.73 - -100.43 - 0 - 0 - DDC - - - TXZ049 - 430490 - Fisher - TX - US - 32.74 - -100.41 - 0 - 0 - SJT - - - TXZ054 - 430540 - Nolan - TX - US - 32.30 - -100.41 - 0 - 0 - SJT - - - TXZ072 - 430720 - Tom_Green - TX - US - 31.39 - -100.40 - 0 - 0 - SJT - - - TXZ217 - 432170 - Maverick - TX - US - 28.65 - -100.39 - 0 - 0 - EWX - - - KSZ087 - 160870 - Meade - KS - US - 37.23 - -100.37 - 0 - 0 - DDC - - - NEZ071 - 270710 - Frontier - NE - US - 40.52 - -100.37 - 0 - 0 - LBF - - - NDZ022 - 340220 - Sheridan - ND - US - 47.59 - -100.36 - 0 - 0 - BIS - - - TXZ005 - 430050 - Lipscomb - TX - US - 36.28 - -100.27 - 0 - 0 - AMA - - - TXZ010 - 430100 - Hemphill - TX - US - 35.84 - -100.27 - 0 - 0 - AMA - - - TXZ015 - 430150 - Wheeler - TX - US - 35.40 - -100.27 - 0 - 0 - AMA - - - TXZ020 - 430200 - Collingsworth - TX - US - 34.96 - -100.27 - 0 - 0 - AMA - - - NDZ046 - 340460 - Emmons - ND - US - 46.29 - -100.26 - 0 - 0 - BIS - - - TXZ032 - 430320 - Cottle - TX - US - 34.08 - -100.26 - 0 - 0 - LUB - - - TXZ038 - 430380 - King - TX - US - 33.62 - -100.26 - 0 - 0 - LUB - - - TXZ044 - 430440 - Stonewall - TX - US - 33.18 - -100.26 - 0 - 0 - LUB - - - TXZ184 - 431840 - Edwards - TX - US - 29.96 - -100.22 - 0 - 0 - EWX - - - TXZ026 - 430260 - Childress - TX - US - 34.53 - -100.21 - 0 - 0 - LUB - - - SDZ034 - 410340 - Sully - SD - US - 44.72 - -100.20 - 0 - 0 - ABR - - - SDZ004 - 410040 - Campbell - SD - US - 45.77 - -100.12 - 0 - 0 - ABR - - - SDZ009 - 410090 - Walworth - SD - US - 45.43 - -100.10 - 0 - 0 - ABR - - - SDZ035 - 410350 - Hughes - SD - US - 44.33 - -100.10 - 0 - 0 - ABR - - - SDZ016 - 410160 - Potter - SD - US - 45.07 - -100.00 - 0 - 0 - ABR - - - NEZ026 - 270260 - Blaine - NE - US - 41.91 - -99.97 - 0 - 0 - LBF - - - TXZ066 - 430660 - Runnels - TX - US - 31.83 - -99.97 - 0 - 0 - SJT - - - NEZ008 - 270080 - Brown - NE - US - 42.46 - -99.93 - 0 - 0 - LBF - - - KSZ045 - 160450 - Ness - KS - US - 38.47 - -99.91 - 0 - 0 - DDC - - - NEZ082 - 270820 - Furnas - NE - US - 40.17 - -99.91 - 0 - 0 - GID - - - KSZ004 - 160040 - Norton - KS - US - 39.78 - -99.90 - 0 - 0 - GLD - - - KSZ064 - 160640 - Hodgeman - KS - US - 38.08 - -99.89 - 0 - 0 - DDC - - - KSZ078 - 160780 - Ford - KS - US - 37.69 - -99.89 - 0 - 0 - DDC - - - NDZ013 - 340130 - Pierce - ND - US - 48.20 - -99.89 - 0 - 0 - BIS - - - TXZ127 - 431270 - Taylor - TX - US - 32.30 - -99.89 - 0 - 0 - SJT - - - KSZ016 - 160160 - Graham - KS - US - 39.34 - -99.88 - 0 - 0 - GLD - - - SDZ049 - 410490 - Tripp - SD - US - 43.38 - -99.88 - 0 - 0 - UNR - - - TXZ113 - 431130 - Jones - TX - US - 32.74 - -99.88 - 0 - 0 - SJT - - - KSZ030 - 160300 - Trego - KS - US - 38.91 - -99.87 - 0 - 0 - DDC - - - NEZ072 - 270720 - Gosper - NE - US - 40.52 - -99.86 - 0 - 0 - GID - - - TXZ073 - 430730 - Concho - TX - US - 31.34 - -99.86 - 0 - 0 - SJT - - - NDZ005 - 340050 - Rolette - ND - US - 48.77 - -99.84 - 0 - 0 - BIS - - - OKZ033 - 360330 - Harmon - OK - US - 34.77 - -99.83 - 0 - 0 - OUN - - - SDZ048 - 410480 - Lyman - SD - US - 43.86 - -99.83 - 0 - 0 - ABR - - - TXZ185 - 431850 - Real - TX - US - 29.86 - -99.83 - 0 - 0 - EWX - - - KSZ088 - 160880 - Clark - KS - US - 37.23 - -99.82 - 0 - 0 - DDC - - - NEZ060 - 270600 - Dawson - NE - US - 40.86 - -99.81 - 0 - 0 - GID - - - TXZ168 - 431680 - Menard - TX - US - 30.90 - -99.80 - 0 - 0 - SJT - - - NDZ036 - 340360 - Kidder - ND - US - 46.98 - -99.79 - 0 - 0 - BIS - - - TXZ203 - 432030 - Uvalde - TX - US - 29.36 - -99.77 - 0 - 0 - EWX - - - TXZ084 - 430840 - Foard - TX - US - 33.99 - -99.76 - 0 - 0 - OUN - - - TXZ218 - 432180 - Zavala - TX - US - 28.87 - -99.76 - 0 - 0 - EWX - - - TXZ228 - 432280 - Dimmit - TX - US - 28.42 - -99.75 - 0 - 0 - EWX - - - TXZ083 - 430830 - Hardeman - TX - US - 34.32 - -99.74 - 0 - 0 - OUN - - - NEZ006 - 270060 - Keya_Paha - NE - US - 42.85 - -99.73 - 0 - 0 - LBF - - - TXZ087 - 430870 - Knox - TX - US - 33.61 - -99.73 - 0 - 0 - OUN - - - TXZ098 - 430980 - Haskell - TX - US - 33.18 - -99.73 - 0 - 0 - SJT - - - NEZ038 - 270380 - Custer - NE - US - 41.39 - -99.72 - 0 - 0 - LBF - - - TXZ169 - 431690 - Kimble - TX - US - 30.50 - -99.71 - 0 - 0 - SJT - - - OKZ009 - 360090 - Ellis - OK - US - 36.22 - -99.69 - 0 - 0 - OUN - - - OKZ014 - 360140 - Roger_Mills - OK - US - 35.72 - -99.68 - 0 - 0 - OUN - - - OKZ021 - 360210 - Beckham - OK - US - 35.27 - -99.68 - 0 - 0 - OUN - - - NDZ023 - 340230 - Wells - ND - US - 47.59 - -99.67 - 0 - 0 - BIS - - - OKZ004 - 360040 - Harper - OK - US - 36.79 - -99.65 - 0 - 0 - OUN - - - OKZ034 - 360340 - Greer - OK - US - 34.92 - -99.56 - 0 - 0 - OUN - - - TXZ239 - 432390 - Webb - TX - US - 27.73 - -99.51 - 0 - 0 - CRP - - - SDZ036 - 410360 - Hyde - SD - US - 44.55 - -99.49 - 0 - 0 - ABR - - - NDZ047 - 340470 - Logan - ND - US - 46.46 - -99.48 - 0 - 0 - BIS - - - TXZ139 - 431390 - Coleman - TX - US - 31.75 - -99.46 - 0 - 0 - SJT - - - NEZ009 - 270090 - Rock - NE - US - 42.44 - -99.45 - 0 - 0 - LBF - - - NEZ027 - 270270 - Loup - NE - US - 41.91 - -99.45 - 0 - 0 - LBF - - - NDZ050 - 340500 - McIntosh - ND - US - 46.11 - -99.44 - 0 - 0 - BIS - - - OKZ036 - 360360 - Jackson - OK - US - 34.59 - -99.44 - 0 - 0 - OUN - - - NEZ073 - 270730 - Phelps - NE - US - 40.51 - -99.41 - 0 - 0 - GID - - - NEZ083 - 270830 - Harlan - NE - US - 40.17 - -99.40 - 0 - 0 - GID - - - TXZ128 - 431280 - Callahan - TX - US - 32.30 - -99.37 - 0 - 0 - SJT - - - TXZ114 - 431140 - Shackelford - TX - US - 32.74 - -99.36 - 0 - 0 - SJT - - - TXZ154 - 431540 - McCulloch - TX - US - 31.22 - -99.35 - 0 - 0 - SJT - - - KSZ005 - 160050 - Phillips - KS - US - 39.78 - -99.34 - 0 - 0 - GID - - - TXZ186 - 431860 - Kerr - TX - US - 30.04 - -99.34 - 0 - 0 - EWX - - - KSZ017 - 160170 - Rooks - KS - US - 39.35 - -99.32 - 0 - 0 - GID - - - KSZ031 - 160310 - Ellis - KS - US - 38.91 - -99.31 - 0 - 0 - DDC - - - KSZ046 - 160460 - Rush - KS - US - 38.52 - -99.30 - 0 - 0 - DDC - - - KSZ079 - 160790 - Edwards - KS - US - 37.90 - -99.29 - 0 - 0 - DDC - - - KSZ080 - 160800 - Kiowa - KS - US - 37.55 - -99.28 - 0 - 0 - DDC - - - OKZ010 - 360100 - Woodward - OK - US - 36.48 - -99.28 - 0 - 0 - OUN - - - KSZ089 - 160890 - Comanche - KS - US - 37.19 - -99.27 - 0 - 0 - DDC - - - NDZ006 - 340060 - Towner - ND - US - 48.69 - -99.25 - 0 - 0 - FGF - - - SDZ051 - 410510 - Buffalo - SD - US - 44.06 - -99.25 - 0 - 0 - ABR - - - KSZ065 - 160650 - Pawnee - KS - US - 38.17 - -99.24 - 0 - 0 - DDC - - - SDZ005 - 410050 - McPherson - SD - US - 45.77 - -99.23 - 0 - 0 - ABR - - - SDZ010 - 410100 - Edmunds - SD - US - 45.42 - -99.22 - 0 - 0 - ABR - - - TXZ085 - 430850 - Wilbarger - TX - US - 34.14 - -99.22 - 0 - 0 - OUN - - - TXZ170 - 431700 - Mason - TX - US - 30.72 - -99.22 - 0 - 0 - SJT - - - TXZ088 - 430880 - Baylor - TX - US - 33.62 - -99.21 - 0 - 0 - OUN - - - TXZ099 - 430990 - Throckmorton - TX - US - 33.18 - -99.21 - 0 - 0 - SJT - - - TXZ187 - 431870 - Bandera - TX - US - 29.74 - -99.21 - 0 - 0 - EWX - - - TXZ248 - 432480 - Zapata - TX - US - 26.94 - -99.21 - 0 - 0 - BRO - - - NDZ014 - 340140 - Benson - ND - US - 48.11 - -99.19 - 0 - 0 - FGF - - - SDZ017 - 410170 - Faulk - SD - US - 45.07 - -99.15 - 0 - 0 - ABR - - - SDZ057 - 410570 - Brule - SD - US - 43.72 - -99.13 - 0 - 0 - FSD - - - TXZ204 - 432040 - Medina - TX - US - 29.39 - -99.11 - 0 - 0 - EWX - - - TXZ219 - 432190 - Frio - TX - US - 28.87 - -99.11 - 0 - 0 - EWX - - - TXZ229 - 432290 - La_Salle - TX - US - 28.34 - -99.10 - 0 - 0 - CRP - - - NEZ061 - 270610 - Buffalo - NE - US - 40.85 - -99.07 - 0 - 0 - GID - - - SDZ050 - 410500 - Gregory - SD - US - 43.25 - -99.02 - 0 - 0 - FSD - - - OKZ015 - 360150 - Dewey - OK - US - 35.99 - -99.01 - 0 - 0 - OUN - - - OKZ035 - 360350 - Kiowa - OK - US - 34.86 - -99.01 - 0 - 0 - OUN - - - SDZ037 - 410370 - Hand - SD - US - 44.55 - -99.01 - 0 - 0 - ABR - - - OKZ016 - 360160 - Custer - OK - US - 35.64 - -99.00 - 0 - 0 - OUN - - - NEZ028 - 270280 - Garfield - NE - US - 41.91 - -98.99 - 0 - 0 - LBF - - - NEZ039 - 270390 - Valley - NE - US - 41.56 - -98.98 - 0 - 0 - GID - - - OKZ005 - 360050 - Woods - OK - US - 36.69 - -98.98 - 0 - 0 - OUN - - - OKZ022 - 360220 - Washita - OK - US - 35.29 - -98.98 - 0 - 0 - OUN - - - NEZ046 - 270460 - Sherman - NE - US - 41.22 - -98.97 - 0 - 0 - GID - - - NDZ037 - 340370 - Stutsman - ND - US - 46.98 - -98.96 - 0 - 0 - BIS - - - NEZ074 - 270740 - Kearney - NE - US - 40.51 - -98.95 - 0 - 0 - GID - - - NEZ084 - 270840 - Franklin - NE - US - 40.17 - -98.95 - 0 - 0 - GID - - - TXZ188 - 431880 - Gillespie - TX - US - 30.32 - -98.95 - 0 - 0 - EWX - - - TXZ140 - 431400 - Brown - TX - US - 31.77 - -98.94 - 0 - 0 - SJT - - - OKZ037 - 360370 - Tillman - OK - US - 34.38 - -98.92 - 0 - 0 - OUN - - - NDZ024 - 340240 - Eddy - ND - US - 47.72 - -98.90 - 0 - 0 - FGF - - - NDZ025 - 340250 - Foster - ND - US - 47.46 - -98.89 - 0 - 0 - BIS - - - TXZ115 - 431150 - Stephens - TX - US - 32.74 - -98.83 - 0 - 0 - FWD - - - TXZ129 - 431290 - Eastland - TX - US - 32.30 - -98.80 - 0 - 0 - FWD - - - KSZ006 - 160060 - Smith - KS - US - 39.78 - -98.78 - 0 - 0 - GID - - - NEZ007 - 270070 - Boyd - NE - US - 42.88 - -98.77 - 0 - 0 - LBF - - - NEZ010 - 270100 - Holt - NE - US - 42.49 - -98.77 - 0 - 0 - LBF - - - KSZ018 - 160180 - Osborne - KS - US - 39.34 - -98.76 - 0 - 0 - GID - - - KSZ032 - 160320 - Russell - KS - US - 38.91 - -98.76 - 0 - 0 - ICT - - - TXZ252 - 432520 - Starr - TX - US - 26.52 - -98.76 - 0 - 0 - BRO - - - KSZ047 - 160470 - Barton - KS - US - 38.47 - -98.75 - 0 - 0 - ICT - - - NDZ015 - 340150 - Ramsey - ND - US - 48.23 - -98.75 - 0 - 0 - FGF - - - TXZ155 - 431550 - San_Saba - TX - US - 31.21 - -98.75 - 0 - 0 - SJT - - - KSZ066 - 160660 - Stafford - KS - US - 38.03 - -98.74 - 0 - 0 - DDC - - - KSZ081 - 160810 - Pratt - KS - US - 37.64 - -98.73 - 0 - 0 - DDC - - - TXZ249 - 432490 - Jim_Hogg - TX - US - 27.08 - -98.70 - 0 - 0 - BRO - - - SDZ063 - 410630 - Charles_Mix - SD - US - 43.17 - -98.69 - 0 - 0 - FSD - - - TXZ086 - 430860 - Wichita - TX - US - 34.01 - -98.69 - 0 - 0 - OUN - - - KSZ090 - 160900 - Barber - KS - US - 37.23 - -98.68 - 0 - 0 - DDC - - - TXZ089 - 430890 - Archer - TX - US - 33.62 - -98.68 - 0 - 0 - OUN - - - TXZ100 - 431000 - Young - TX - US - 33.18 - -98.68 - 0 - 0 - FWD - - - TXZ189 - 431890 - Kendall - TX - US - 29.93 - -98.67 - 0 - 0 - EWX - - - TXZ171 - 431710 - Llano - TX - US - 30.71 - -98.65 - 0 - 0 - EWX - - - SDZ052 - 410520 - Jerauld - SD - US - 44.07 - -98.63 - 0 - 0 - FSD - - - TXZ142 - 431420 - Mills - TX - US - 31.48 - -98.63 - 0 - 0 - FWD - - - SDZ058 - 410580 - Aurora - SD - US - 43.72 - -98.57 - 0 - 0 - FSD - - - TXZ230 - 432300 - McMullen - TX - US - 28.35 - -98.57 - 0 - 0 - CRP - - - NDZ048 - 340480 - La_Moure - ND - US - 46.46 - -98.54 - 0 - 0 - BIS - - - TXZ141 - 431410 - Comanche - TX - US - 31.98 - -98.54 - 0 - 0 - FWD - - - OKZ011 - 360110 - Major - OK - US - 36.33 - -98.53 - 0 - 0 - OUN - - - NEZ029 - 270290 - Wheeler - NE - US - 41.91 - -98.52 - 0 - 0 - LBF - - - NEZ040 - 270400 - Greeley - NE - US - 41.57 - -98.52 - 0 - 0 - GID - - - TXZ240 - 432400 - Duval - TX - US - 27.66 - -98.52 - 0 - 0 - CRP - - - NDZ051 - 340510 - Dickey - ND - US - 46.11 - -98.51 - 0 - 0 - BIS - - - NEZ047 - 270470 - Howard - NE - US - 41.22 - -98.51 - 0 - 0 - GID - - - NEZ062 - 270620 - Hall - NE - US - 40.87 - -98.50 - 0 - 0 - GID - - - NEZ075 - 270750 - Adams - NE - US - 40.52 - -98.50 - 0 - 0 - GID - - - NEZ085 - 270850 - Webster - NE - US - 40.17 - -98.49 - 0 - 0 - GID - - - TXZ205 - 432050 - Bexar - TX - US - 29.44 - -98.47 - 0 - 0 - EWX - - - NDZ007 - 340070 - Cavalier - ND - US - 48.77 - -98.46 - 0 - 0 - FGF - - - OKZ038 - 360380 - Comanche - OK - US - 34.63 - -98.46 - 0 - 0 - OUN - - - TXZ220 - 432200 - Atascosa - TX - US - 28.93 - -98.45 - 0 - 0 - EWX - - - OKZ017 - 360170 - Blaine - OK - US - 35.86 - -98.42 - 0 - 0 - OUN - - - SDZ064 - 410640 - Douglas - SD - US - 43.35 - -98.41 - 0 - 0 - FSD - - - OKZ044 - 360440 - Cotton - OK - US - 34.28 - -98.40 - 0 - 0 - OUN - - - SDZ006 - 410060 - Brown - SD - US - 45.59 - -98.36 - 0 - 0 - ABR - - - TXZ190 - 431900 - Blanco - TX - US - 30.23 - -98.36 - 0 - 0 - EWX - - - OKZ023 - 360230 - Caddo - OK - US - 35.21 - -98.35 - 0 - 0 - OUN - - - SDZ018 - 410180 - Spink - SD - US - 44.94 - -98.35 - 0 - 0 - ABR - - - TXZ206 - 432060 - Comal - TX - US - 29.82 - -98.33 - 0 - 0 - EWX - - - OKZ006 - 360060 - Alfalfa - OK - US - 36.73 - -98.32 - 0 - 0 - OUN - - - TXZ116 - 431160 - Palo_Pinto - TX - US - 32.76 - -98.31 - 0 - 0 - FWD - - - SDZ038 - 410380 - Beadle - SD - US - 44.41 - -98.28 - 0 - 0 - FSD - - - TXZ250 - 432500 - Brooks - TX - US - 27.03 - -98.26 - 0 - 0 - BRO - - - TXZ156 - 431560 - Lampasas - TX - US - 31.25 - -98.24 - 0 - 0 - FWD - - - NDZ028 - 340280 - Griggs - ND - US - 47.46 - -98.23 - 0 - 0 - FGF - - - TXZ253 - 432530 - Hidalgo - TX - US - 26.41 - -98.23 - 0 - 0 - BRO - - - KSZ007 - 160070 - Jewell - KS - US - 39.78 - -98.22 - 0 - 0 - GID - - - KSZ033 - 160330 - Lincoln - KS - US - 39.04 - -98.21 - 0 - 0 - ICT - - - TXZ130 - 431300 - Erath - TX - US - 32.22 - -98.21 - 0 - 0 - FWD - - - KSZ019 - 160190 - Mitchell - KS - US - 39.39 - -98.20 - 0 - 0 - GID - - - KSZ048 - 160480 - Ellsworth - KS - US - 38.69 - -98.20 - 0 - 0 - ICT - - - KSZ050 - 160500 - Rice - KS - US - 38.33 - -98.20 - 0 - 0 - ICT - - - NDZ026 - 340260 - Nelson - ND - US - 47.94 - -98.20 - 0 - 0 - FGF - - - TXZ090 - 430900 - Clay - TX - US - 33.81 - -98.18 - 0 - 0 - OUN - - - TXZ101 - 431010 - Jack - TX - US - 33.24 - -98.17 - 0 - 0 - FWD - - - SDZ059 - 410590 - Davison - SD - US - 43.67 - -98.15 - 0 - 0 - FSD - - - TXZ172 - 431720 - Burnet - TX - US - 30.74 - -98.15 - 0 - 0 - EWX - - - KSZ082 - 160820 - Kingman - KS - US - 37.55 - -98.13 - 0 - 0 - ICT - - - TXZ143 - 431430 - Hamilton - TX - US - 31.72 - -98.11 - 0 - 0 - FWD - - - SDZ053 - 410530 - Sanborn - SD - US - 44.02 - -98.10 - 0 - 0 - FSD - - - NDZ054 - 340540 - Western_Walsh_County - ND - US - 48.37 - -98.09 - 0 - 0 - FGF - - - KSZ067 - 160670 - Reno - KS - US - 37.95 - -98.08 - 0 - 0 - ICT - - - NDZ038 - 340380 - Barnes - ND - US - 46.94 - -98.08 - 0 - 0 - FGF - - - TXZ221 - 432210 - Wilson - TX - US - 29.16 - -98.08 - 0 - 0 - EWX - - - TXZ231 - 432310 - Live_Oak - TX - US - 28.42 - -98.08 - 0 - 0 - CRP - - - KSZ091 - 160910 - Harper - KS - US - 37.19 - -98.07 - 0 - 0 - ICT - - - NEZ016 - 270160 - Antelope - NE - US - 42.17 - -98.07 - 0 - 0 - OAX - - - NEZ030 - 270300 - Boone - NE - US - 41.70 - -98.06 - 0 - 0 - OAX - - - NEZ063 - 270630 - Hamilton - NE - US - 40.93 - -98.05 - 0 - 0 - GID - - - NEZ076 - 270760 - Clay - NE - US - 40.52 - -98.05 - 0 - 0 - GID - - - NEZ086 - 270860 - Nuckolls - NE - US - 40.17 - -98.04 - 0 - 0 - GID - - - TXZ191 - 431910 - Hays - TX - US - 30.05 - -98.02 - 0 - 0 - EWX - - - TXZ241 - 432410 - Jim_Wells - TX - US - 27.66 - -98.02 - 0 - 0 - CRP - - - NEZ041 - 270410 - Nance - NE - US - 41.39 - -97.99 - 0 - 0 - GID - - - OKZ024 - 360240 - Canadian - OK - US - 35.53 - -97.99 - 0 - 0 - OUN - - - TXZ207 - 432070 - Guadalupe - TX - US - 29.62 - -97.98 - 0 - 0 - EWX - - - NEZ048 - 270480 - Merrick - NE - US - 41.13 - -97.94 - 0 - 0 - GID - - - OKZ018 - 360180 - Kingfisher - OK - US - 35.95 - -97.94 - 0 - 0 - OUN - - - NEZ011 - 270110 - Knox - NE - US - 42.66 - -97.90 - 0 - 0 - OAX - - - SDZ068 - 410680 - Bon_Homme - SD - US - 42.97 - -97.90 - 0 - 0 - FSD - - - OKZ027 - 360270 - Grady - OK - US - 35.03 - -97.88 - 0 - 0 - OUN - - - TXZ222 - 432220 - Karnes - TX - US - 28.95 - -97.88 - 0 - 0 - EWX - - - OKZ039 - 360390 - Stephens - OK - US - 34.49 - -97.85 - 0 - 0 - OUN - - - TXZ131 - 431310 - Hood - TX - US - 32.40 - -97.84 - 0 - 0 - FWD - - - OKZ045 - 360450 - Jefferson - OK - US - 34.07 - -97.83 - 0 - 0 - OUN - - - TXZ117 - 431170 - Parker - TX - US - 32.78 - -97.80 - 0 - 0 - FWD - - - TXZ157 - 431570 - Coryell - TX - US - 31.39 - -97.80 - 0 - 0 - FWD - - - SDZ060 - 410600 - Hanson - SD - US - 43.67 - -97.79 - 0 - 0 - FSD - - - OKZ007 - 360070 - Grant - OK - US - 36.79 - -97.78 - 0 - 0 - OUN - - - OKZ012 - 360120 - Garfield - OK - US - 36.38 - -97.78 - 0 - 0 - OUN - - - TXZ132 - 431320 - Somervell - TX - US - 32.21 - -97.78 - 0 - 0 - FWD - - - TXZ192 - 431920 - Travis - TX - US - 30.33 - -97.77 - 0 - 0 - EWX - - - SDZ065 - 410650 - Hutchinson - SD - US - 43.33 - -97.76 - 0 - 0 - FSD - - - SDZ019 - 410190 - Clark - SD - US - 44.85 - -97.74 - 0 - 0 - ABR - - - TXZ091 - 430910 - Montague - TX - US - 33.71 - -97.73 - 0 - 0 - FWD - - - TXZ232 - 432320 - Bee - TX - US - 28.42 - -97.73 - 0 - 0 - CRP - - - TXZ254 - 432540 - Inland_Willacy - TX - US - 26.46 - -97.73 - 0 - 0 - BRO - - - NDZ029 - 340290 - Steele - ND - US - 47.46 - -97.72 - 0 - 0 - FGF - - - NDZ049 - 340490 - Ransom - ND - US - 46.46 - -97.66 - 0 - 0 - FGF - - - TXZ102 - 431020 - Wise - TX - US - 33.22 - -97.65 - 0 - 0 - FWD - - - KSZ008 - 160080 - Republic - KS - US - 39.82 - -97.64 - 0 - 0 - TOP - - - KSZ020 - 160200 - Cloud - KS - US - 39.48 - -97.64 - 0 - 0 - TOP - - - KSZ034 - 160340 - Ottawa - KS - US - 39.13 - -97.64 - 0 - 0 - TOP - - - KSZ049 - 160490 - Saline - KS - US - 38.78 - -97.64 - 0 - 0 - ICT - - - KSZ051 - 160510 - McPherson - KS - US - 38.38 - -97.64 - 0 - 0 - ICT - - - TXZ144 - 431440 - Bosque - TX - US - 31.90 - -97.64 - 0 - 0 - FWD - - - TXZ242 - 432420 - Kleberg - TX - US - 27.43 - -97.64 - 0 - 0 - CRP - - - TXZ251 - 432510 - Kenedy - TX - US - 26.94 - -97.64 - 0 - 0 - BRO - - - NDZ052 - 340520 - Sargent - ND - US - 46.11 - -97.62 - 0 - 0 - FGF - - - TXZ208 - 432080 - Caldwell - TX - US - 29.86 - -97.62 - 0 - 0 - EWX - - - SDZ011 - 410110 - Day - SD - US - 45.37 - -97.61 - 0 - 0 - ABR - - - SDZ054 - 410540 - Miner - SD - US - 44.02 - -97.61 - 0 - 0 - FSD - - - NEZ017 - 270170 - Pierce - NE - US - 42.26 - -97.60 - 0 - 0 - OAX - - - NEZ031 - 270310 - Madison - NE - US - 41.91 - -97.60 - 0 - 0 - OAX - - - SDZ007 - 410070 - Marshall - SD - US - 45.75 - -97.60 - 0 - 0 - ABR - - - TXZ173 - 431730 - Williamson - TX - US - 30.66 - -97.60 - 0 - 0 - EWX - - - NEZ049 - 270490 - Polk - NE - US - 41.22 - -97.59 - 0 - 0 - GID - - - NEZ064 - 270640 - York - NE - US - 40.87 - -97.59 - 0 - 0 - GID - - - NEZ077 - 270770 - Fillmore - NE - US - 40.52 - -97.59 - 0 - 0 - GID - - - NEZ087 - 270870 - Thayer - NE - US - 40.17 - -97.59 - 0 - 0 - GID - - - TXZ255 - 432550 - Inland_Cameron - TX - US - 26.10 - -97.56 - 0 - 0 - BRO - - - NEZ042 - 270420 - Platte - NE - US - 41.54 - -97.54 - 0 - 0 - OAX - - - OKZ028 - 360280 - McClain - OK - US - 35.10 - -97.54 - 0 - 0 - OUN - - - NDZ008 - 340080 - Pembina - ND - US - 48.77 - -97.52 - 0 - 0 - FGF - - - TXZ244 - 432440 - San_Patricio - TX - US - 27.99 - -97.52 - 0 - 0 - CRP - - - TXZ158 - 431580 - Bell - TX - US - 31.05 - -97.50 - 0 - 0 - FWD - - - TXZ223 - 432230 - Gonzales - TX - US - 29.45 - -97.50 - 0 - 0 - EWX - - - TXZ243 - 432430 - Nueces - TX - US - 27.78 - -97.50 - 0 - 0 - CRP - - - NDZ016 - 340160 - Eastern_Walsh_County - ND - US - 48.37 - -97.49 - 0 - 0 - FGF - - - SDZ039 - 410390 - Kingsbury - SD - US - 44.37 - -97.49 - 0 - 0 - FSD - - - TXZ256 - 432560 - Coastal_Willacy - TX - US - 26.47 - -97.49 - 0 - 0 - BRO - - - KSZ083 - 160830 - Sedgwick - KS - US - 37.69 - -97.47 - 0 - 0 - ICT - - - KSZ092 - 160920 - Sumner - KS - US - 37.23 - -97.47 - 0 - 0 - ICT - - - TXZ233 - 432330 - Goliad - TX - US - 28.65 - -97.47 - 0 - 0 - CRP - - - KSZ068 - 160680 - Harvey - KS - US - 38.04 - -97.42 - 0 - 0 - ICT - - - OKZ019 - 360190 - Logan - OK - US - 35.95 - -97.41 - 0 - 0 - OUN - - - NDZ027 - 340270 - Grand_Forks - ND - US - 47.93 - -97.40 - 0 - 0 - FGF - - - OKZ025 - 360250 - Oklahoma - OK - US - 35.55 - -97.40 - 0 - 0 - OUN - - - OKZ029 - 360290 - Cleveland - OK - US - 35.16 - -97.40 - 0 - 0 - OUN - - - SDZ069 - 410690 - Yankton - SD - US - 42.99 - -97.40 - 0 - 0 - FSD - - - SDZ061 - 410610 - McCook - SD - US - 43.67 - -97.37 - 0 - 0 - FSD - - - TXZ224 - 432240 - DeWitt - TX - US - 29.10 - -97.37 - 0 - 0 - EWX - - - TXZ133 - 431330 - Johnson - TX - US - 32.35 - -97.35 - 0 - 0 - FWD - - - TXZ193 - 431930 - Bastrop - TX - US - 30.10 - -97.35 - 0 - 0 - EWX - - - TXZ257 - 432570 - Coastal_Cameron - TX - US - 26.20 - -97.34 - 0 - 0 - BRO - - - OKZ040 - 360400 - Garvin - OK - US - 34.69 - -97.30 - 0 - 0 - OUN - - - TXZ118 - 431180 - Tarrant - TX - US - 32.78 - -97.29 - 0 - 0 - FWD - - - NEZ012 - 270120 - Cedar - NE - US - 42.61 - -97.25 - 0 - 0 - OAX - - - OKZ046 - 360460 - Carter - OK - US - 34.29 - -97.24 - 0 - 0 - OUN - - - OKZ050 - 360500 - Love - OK - US - 33.90 - -97.24 - 0 - 0 - OUN - - - NDZ039 - 340390 - Cass - ND - US - 46.94 - -97.23 - 0 - 0 - FGF - - - TXZ092 - 430920 - Cooke - TX - US - 33.69 - -97.21 - 0 - 0 - FWD - - - TXZ159 - 431590 - McLennan - TX - US - 31.56 - -97.20 - 0 - 0 - FWD - - - NEZ032 - 270320 - Stanton - NE - US - 41.92 - -97.19 - 0 - 0 - OAX - - - SDZ020 - 410200 - Codington - SD - US - 44.98 - -97.19 - 0 - 0 - ABR - - - SDZ022 - 410220 - Hamlin - SD - US - 44.67 - -97.19 - 0 - 0 - ABR - - - OKZ013 - 360130 - Noble - OK - US - 36.39 - -97.17 - 0 - 0 - OUN - - - KSZ021 - 160210 - Clay - KS - US - 39.35 - -97.16 - 0 - 0 - TOP - - - NDZ030 - 340300 - Traill - ND - US - 47.46 - -97.16 - 0 - 0 - FGF - - - SDZ066 - 410660 - Turner - SD - US - 43.29 - -97.16 - 0 - 0 - FSD - - - TXZ246 - 432460 - Refugio - TX - US - 28.30 - -97.15 - 0 - 0 - CRP - - - KSZ035 - 160350 - Dickinson - KS - US - 38.86 - -97.14 - 0 - 0 - TOP - - - NEZ088 - 270880 - Jefferson - NE - US - 40.17 - -97.14 - 0 - 0 - OAX - - - NEZ050 - 270500 - Butler - NE - US - 41.25 - -97.13 - 0 - 0 - OAX - - - NEZ065 - 270650 - Seward - NE - US - 40.87 - -97.13 - 0 - 0 - OAX - - - NEZ078 - 270780 - Saline - NE - US - 40.52 - -97.13 - 0 - 0 - OAX - - - SDZ055 - 410550 - Lake - SD - US - 44.02 - -97.13 - 0 - 0 - FSD - - - OKZ008 - 360080 - Kay - OK - US - 36.79 - -97.11 - 0 - 0 - OUN - - - TXZ103 - 431030 - Denton - TX - US - 33.21 - -97.11 - 0 - 0 - FWD - - - TXZ145 - 431450 - Hill - TX - US - 32.00 - -97.11 - 0 - 0 - FWD - - - NEZ018 - 270180 - Wayne - NE - US - 42.22 - -97.10 - 0 - 0 - OAX - - - KSZ052 - 160520 - Marion - KS - US - 38.34 - -97.09 - 0 - 0 - ICT - - - OKZ041 - 360410 - Murray - OK - US - 34.49 - -97.09 - 0 - 0 - OUN - - - KSZ009 - 160090 - Washington - KS - US - 39.78 - -97.08 - 0 - 0 - TOP - - - NEZ043 - 270430 - Colfax - NE - US - 41.56 - -97.08 - 0 - 0 - OAX - - - OKZ020 - 360200 - Payne - OK - US - 36.10 - -96.99 - 0 - 0 - OUN - - - SDZ070 - 410700 - Clay - SD - US - 42.90 - -96.99 - 0 - 0 - FSD - - - TXZ194 - 431940 - Lee - TX - US - 30.30 - -96.99 - 0 - 0 - EWX - - - TXZ234 - 432340 - Victoria - TX - US - 28.80 - -96.98 - 0 - 0 - CRP - - - TXZ174 - 431740 - Milam - TX - US - 30.80 - -96.97 - 0 - 0 - FWD - - - TXZ209 - 432090 - Fayette - TX - US - 29.90 - -96.95 - 0 - 0 - EWX - - - TXZ160 - 431600 - Falls - TX - US - 31.26 - -96.94 - 0 - 0 - FWD - - - NDZ053 - 340530 - Richland - ND - US - 46.28 - -96.92 - 0 - 0 - FGF - - - TXZ225 - 432250 - Lavaca - TX - US - 29.35 - -96.91 - 0 - 0 - EWX - - - OKZ026 - 360260 - Lincoln - OK - US - 35.71 - -96.88 - 0 - 0 - OUN - - - OKZ030 - 360300 - Pottawatomie - OK - US - 35.19 - -96.88 - 0 - 0 - OUN - - - TXZ245 - 432450 - Aransas - TX - US - 28.21 - -96.87 - 0 - 0 - CRP - - - SDZ008 - 410080 - Roberts - SD - US - 45.62 - -96.86 - 0 - 0 - ABR - - - SDZ021 - 410210 - Grant - SD - US - 45.15 - -96.84 - 0 - 0 - ABR - - - KSZ069 - 160690 - Butler - KS - US - 37.78 - -96.83 - 0 - 0 - ICT - - - KSZ093 - 160930 - Cowley - KS - US - 37.23 - -96.83 - 0 - 0 - ICT - - - NEZ013 - 270130 - Dixon - NE - US - 42.51 - -96.82 - 0 - 0 - FSD - - - MNZ004 - 230040 - Kittson - MN - US - 48.77 - -96.81 - 0 - 0 - FGF - - - NEZ033 - 270330 - Cuming - NE - US - 41.92 - -96.79 - 0 - 0 - OAX - - - SDZ040 - 410400 - Brookings - SD - US - 44.37 - -96.79 - 0 - 0 - FSD - - - SDZ062 - 410620 - Minnehaha - SD - US - 43.67 - -96.79 - 0 - 0 - FSD - - - MNZ007 - 230070 - West_Marshall - MN - US - 48.36 - -96.78 - 0 - 0 - FGF - - - TXZ119 - 431190 - Dallas - TX - US - 32.77 - -96.77 - 0 - 0 - FWD - - - OKZ051 - 360510 - Marshall - OK - US - 34.01 - -96.76 - 0 - 0 - OUN - - - MNZ001 - 230010 - West_Polk - MN - US - 47.84 - -96.75 - 0 - 0 - FGF - - - TXZ134 - 431340 - Ellis - TX - US - 32.31 - -96.74 - 0 - 0 - FWD - - - KSZ036 - 160360 - Geary - KS - US - 39.04 - -96.72 - 0 - 0 - TOP - - - SDZ067 - 410670 - Lincoln - SD - US - 43.29 - -96.69 - 0 - 0 - FSD - - - NEZ066 - 270660 - Lancaster - NE - US - 40.78 - -96.68 - 0 - 0 - OAX - - - NEZ089 - 270890 - Gage - NE - US - 40.26 - -96.68 - 0 - 0 - OAX - - - KSZ022 - 160220 - Riley - KS - US - 39.30 - -96.67 - 0 - 0 - TOP - - - OKZ047 - 360470 - Johnston - OK - US - 34.32 - -96.67 - 0 - 0 - OUN - - - SDZ023 - 410230 - Deuel - SD - US - 44.76 - -96.67 - 0 - 0 - ABR - - - SDZ056 - 410560 - Moody - SD - US - 44.02 - -96.67 - 0 - 0 - FSD - - - OKZ042 - 360420 - Pontotoc - OK - US - 34.74 - -96.66 - 0 - 0 - OUN - - - TXZ093 - 430930 - Grayson - TX - US - 33.68 - -96.65 - 0 - 0 - FWD - - - KSZ037 - 160370 - Morris - KS - US - 38.69 - -96.64 - 0 - 0 - TOP - - - OKZ059 - 360590 - Pawnee - OK - US - 36.37 - -96.64 - 0 - 0 - TSA - - - SDZ071 - 410710 - Union - SD - US - 42.79 - -96.64 - 0 - 0 - FSD - - - TXZ247 - 432470 - Calhoun - TX - US - 28.39 - -96.63 - 0 - 0 - CRP - - - NEZ044 - 270440 - Dodge - NE - US - 41.57 - -96.62 - 0 - 0 - OAX - - - TXZ195 - 431950 - Burleson - TX - US - 30.52 - -96.62 - 0 - 0 - HGX - - - TXZ235 - 432350 - Jackson - TX - US - 28.96 - -96.62 - 0 - 0 - HGX - - - NEZ051 - 270510 - Saunders - NE - US - 41.24 - -96.61 - 0 - 0 - OAX - - - OKZ031 - 360310 - Seminole - OK - US - 35.16 - -96.61 - 0 - 0 - OUN - - - KSZ053 - 160530 - Chase - KS - US - 38.30 - -96.59 - 0 - 0 - ICT - - - TXZ161 - 431610 - Limestone - TX - US - 31.53 - -96.58 - 0 - 0 - FWD - - - MNZ039 - 230390 - Traverse - MN - US - 45.80 - -96.56 - 0 - 0 - ABR - - - TXZ104 - 431040 - Collin - TX - US - 33.20 - -96.56 - 0 - 0 - FWD - - - NEZ015 - 270150 - Thurston - NE - US - 42.15 - -96.55 - 0 - 0 - OAX - - - OKZ054 - 360540 - Osage - OK - US - 36.58 - -96.54 - 0 - 0 - TSA - - - TXZ175 - 431750 - Robertson - TX - US - 31.04 - -96.54 - 0 - 0 - FWD - - - NEZ014 - 270140 - Dakota - NE - US - 42.40 - -96.53 - 0 - 0 - FSD - - - TXZ210 - 432100 - Colorado - TX - US - 29.60 - -96.53 - 0 - 0 - HGX - - - KSZ010 - 160100 - Marshall - KS - US - 39.78 - -96.52 - 0 - 0 - TOP - - - MNZ029 - 230290 - Wilkin - MN - US - 46.33 - -96.52 - 0 - 0 - FGF - - - MNZ003 - 230030 - Clay - MN - US - 46.89 - -96.51 - 0 - 0 - FGF - - - MNZ046 - 230460 - Big_Stone - MN - US - 45.38 - -96.48 - 0 - 0 - ABR - - - MNZ002 - 230020 - Norman - MN - US - 47.33 - -96.47 - 0 - 0 - FGF - - - TXZ146 - 431460 - Navarro - TX - US - 32.07 - -96.47 - 0 - 0 - FWD - - - TXZ197 - 431970 - Washington - TX - US - 30.23 - -96.44 - 0 - 0 - HGX - - - TXZ120 - 431200 - Rockwall - TX - US - 32.91 - -96.40 - 0 - 0 - FWD - - - KSZ023 - 160230 - Pottawatomie - KS - US - 39.34 - -96.37 - 0 - 0 - TOP - - - TXZ196 - 431960 - Brazos - TX - US - 30.66 - -96.34 - 0 - 0 - HGX - - - OKZ064 - 360640 - Creek - OK - US - 35.91 - -96.33 - 0 - 0 - TSA - - - TXZ211 - 432110 - Austin - TX - US - 29.85 - -96.32 - 0 - 0 - HGX - - - NEZ034 - 270340 - Burt - NE - US - 41.87 - -96.31 - 0 - 0 - OAX - - - OKZ043 - 360430 - Coal - OK - US - 34.60 - -96.30 - 0 - 0 - OUN - - - OKZ065 - 360650 - Okfuskee - OK - US - 35.47 - -96.30 - 0 - 0 - TSA - - - TXZ121 - 431210 - Kaufman - TX - US - 32.61 - -96.30 - 0 - 0 - FWD - - - MNZ071 - 230710 - Lincoln - MN - US - 44.41 - -96.27 - 0 - 0 - FSD - - - MNZ097 - 230970 - Pipestone - MN - US - 44.02 - -96.26 - 0 - 0 - FSD - - - MNZ098 - 230980 - Rock - MN - US - 43.67 - -96.26 - 0 - 0 - FSD - - - NEZ090 - 270900 - Johnson - NE - US - 40.39 - -96.26 - 0 - 0 - OAX - - - IAZ020 - 150200 - Plymouth - IA - US - 42.74 - -96.25 - 0 - 0 - FSD - - - TXZ226 - 432260 - Wharton - TX - US - 29.30 - -96.25 - 0 - 0 - HGX - - - KSZ070 - 160700 - Greenwood - KS - US - 37.88 - -96.24 - 0 - 0 - ICT - - - KSZ094 - 160940 - Elk - KS - US - 37.45 - -96.24 - 0 - 0 - ICT - - - KSZ098 - 160980 - Chautauqua - KS - US - 37.15 - -96.24 - 0 - 0 - ICT - - - IAZ001 - 150010 - Lyon - IA - US - 43.38 - -96.23 - 0 - 0 - FSD - - - NEZ092 - 270920 - Pawnee - NE - US - 40.13 - -96.23 - 0 - 0 - OAX - - - OKZ032 - 360320 - Hughes - OK - US - 35.03 - -96.23 - 0 - 0 - OUN - - - IAZ012 - 150120 - Sioux - IA - US - 43.09 - -96.22 - 0 - 0 - FSD - - - KSZ038 - 160380 - Wabaunsee - KS - US - 38.97 - -96.22 - 0 - 0 - TOP - - - OKZ052 - 360520 - Bryan - OK - US - 33.93 - -96.19 - 0 - 0 - OUN - - - NEZ045 - 270450 - Washington - NE - US - 41.54 - -96.18 - 0 - 0 - OAX - - - NEZ052 - 270520 - Douglas - NE - US - 41.29 - -96.18 - 0 - 0 - OAX - - - KSZ054 - 160540 - Lyon - KS - US - 38.45 - -96.15 - 0 - 0 - TOP - - - NEZ067 - 270670 - Cass - NE - US - 40.93 - -96.15 - 0 - 0 - OAX - - - TXZ147 - 431470 - Freestone - TX - US - 31.72 - -96.14 - 0 - 0 - FWD - - - TXZ094 - 430940 - Fannin - TX - US - 33.62 - -96.11 - 0 - 0 - FWD - - - MNZ014 - 230140 - Red_Lake - MN - US - 47.86 - -96.10 - 0 - 0 - FGF - - - MNZ054 - 230540 - Lac_qui_Parle - MN - US - 45.04 - -96.09 - 0 - 0 - MPX - - - NEZ053 - 270530 - Sarpy - NE - US - 41.09 - -96.09 - 0 - 0 - OAX - - - NEZ068 - 270680 - Otoe - NE - US - 40.66 - -96.09 - 0 - 0 - OAX - - - IAZ031 - 150310 - Woodbury - IA - US - 42.39 - -96.08 - 0 - 0 - FSD - - - TXZ105 - 431050 - Hunt - TX - US - 33.13 - -96.07 - 0 - 0 - FWD - - - MNZ013 - 230130 - Pennington - MN - US - 48.05 - -96.04 - 0 - 0 - FGF - - - OKZ048 - 360480 - Atoka - OK - US - 34.43 - -96.04 - 0 - 0 - OUN - - - OKZ060 - 360600 - Tulsa - OK - US - 36.15 - -96.03 - 0 - 0 - TSA - - - IAZ043 - 150430 - Monona - IA - US - 42.04 - -96.02 - 0 - 0 - OAX - - - MNZ030 - 230300 - West_Otter_Tail - MN - US - 46.41 - -96.02 - 0 - 0 - FGF - - - KSZ011 - 160110 - Nemaha - KS - US - 39.78 - -96.01 - 0 - 0 - TOP - - - MNZ040 - 230400 - Grant - MN - US - 45.93 - -96.01 - 0 - 0 - FGF - - - MNZ047 - 230470 - Stevens - MN - US - 45.59 - -96.00 - 0 - 0 - MPX - - - TXZ212 - 432120 - Waller - TX - US - 29.99 - -96.00 - 0 - 0 - HGX - - - MNZ008 - 230080 - East_Marshall - MN - US - 48.36 - -95.99 - 0 - 0 - FGF - - - TXZ162 - 431620 - Leon - TX - US - 31.32 - -95.99 - 0 - 0 - FWD - - - TXZ198 - 431980 - Grimes - TX - US - 30.55 - -95.99 - 0 - 0 - HGX - - - MNZ015 - 230150 - East_Polk - MN - US - 47.72 - -95.95 - 0 - 0 - FGF - - - OKZ066 - 360660 - Okmulgee - OK - US - 35.62 - -95.95 - 0 - 0 - TSA - - - TXZ135 - 431350 - Henderson - TX - US - 32.19 - -95.94 - 0 - 0 - FWD - - - TXZ236 - 432360 - Matagorda - TX - US - 28.81 - -95.94 - 0 - 0 - HGX - - - MNZ027 - 230270 - West_Becker - MN - US - 46.94 - -95.93 - 0 - 0 - FGF - - - TXZ176 - 431760 - Madison - TX - US - 30.97 - -95.93 - 0 - 0 - HGX - - - MNZ064 - 230640 - Yellow_Medicine - MN - US - 44.74 - -95.91 - 0 - 0 - MPX - - - OKZ055 - 360550 - Washington - OK - US - 36.71 - -95.90 - 0 - 0 - TSA - - - MNZ072 - 230720 - Lyon - MN - US - 44.41 - -95.84 - 0 - 0 - FSD - - - IAZ055 - 150550 - Harrison - IA - US - 41.69 - -95.82 - 0 - 0 - OAX - - - MNZ022 - 230220 - Mahnomen - MN - US - 47.33 - -95.81 - 0 - 0 - FGF - - - NEZ091 - 270910 - Nemaha - NE - US - 40.41 - -95.80 - 0 - 0 - OAX - - - TXZ123 - 431230 - Rains - TX - US - 32.85 - -95.80 - 0 - 0 - FWD - - - KSZ024 - 160240 - Jackson - KS - US - 39.43 - -95.79 - 0 - 0 - TOP - - - MNZ080 - 230800 - Murray - MN - US - 44.02 - -95.77 - 0 - 0 - FSD - - - KSZ039 - 160390 - Shawnee - KS - US - 39.04 - -95.76 - 0 - 0 - TOP - - - MNZ089 - 230890 - Nobles - MN - US - 43.67 - -95.76 - 0 - 0 - FSD - - - TXZ122 - 431220 - Van_Zandt - TX - US - 32.61 - -95.76 - 0 - 0 - FWD - - - MNZ005 - 230050 - Roseau - MN - US - 48.77 - -95.75 - 0 - 0 - FGF - - - TXZ227 - 432270 - Fort_Bend - TX - US - 29.53 - -95.75 - 0 - 0 - HGX - - - KSZ095 - 160950 - Wilson - KS - US - 37.56 - -95.74 - 0 - 0 - ICT - - - KSZ099 - 160990 - Montgomery - KS - US - 37.19 - -95.74 - 0 - 0 - ICT - - - KSZ058 - 160580 - Coffey - KS - US - 38.23 - -95.73 - 0 - 0 - TOP - - - KSZ071 - 160710 - Woodson - KS - US - 37.88 - -95.73 - 0 - 0 - ICT - - - KSZ055 - 160550 - Osage - KS - US - 38.65 - -95.72 - 0 - 0 - TOP - - - OKZ073 - 360730 - Pittsburg - OK - US - 34.95 - -95.72 - 0 - 0 - TSA - - - MNZ055 - 230550 - Swift - MN - US - 45.28 - -95.69 - 0 - 0 - MPX - - - OKZ071 - 360710 - McIntosh - OK - US - 35.35 - -95.66 - 0 - 0 - TSA - - - TXZ148 - 431480 - Anderson - TX - US - 31.80 - -95.66 - 0 - 0 - FWD - - - MNZ056 - 230560 - Chippewa - MN - US - 44.96 - -95.65 - 0 - 0 - MPX - - - NEZ093 - 270930 - Richardson - NE - US - 40.13 - -95.65 - 0 - 0 - OAX - - - IAZ079 - 150790 - Mills - IA - US - 41.03 - -95.64 - 0 - 0 - OAX - - - IAZ002 - 150020 - Osceola - IA - US - 43.38 - -95.63 - 0 - 0 - FSD - - - IAZ013 - 150130 - O'Brien - IA - US - 43.09 - -95.63 - 0 - 0 - FSD - - - IAZ021 - 150210 - Cherokee - IA - US - 42.74 - -95.63 - 0 - 0 - FSD - - - IAZ090 - 150900 - Fremont - IA - US - 40.75 - -95.63 - 0 - 0 - OAX - - - OKZ056 - 360560 - Nowata - OK - US - 36.80 - -95.61 - 0 - 0 - TSA - - - TXZ177 - 431770 - Walker - TX - US - 30.79 - -95.60 - 0 - 0 - HGX - - - IAZ069 - 150690 - Pottawattamie - IA - US - 41.34 - -95.59 - 0 - 0 - OAX - - - TXZ095 - 430950 - Lamar - TX - US - 33.66 - -95.58 - 0 - 0 - FWD - - - TXZ106 - 431060 - Delta - TX - US - 33.36 - -95.58 - 0 - 0 - FWD - - - TXZ107 - 431070 - Hopkins - TX - US - 33.18 - -95.58 - 0 - 0 - FWD - - - OKZ053 - 360530 - Choctaw - OK - US - 34.02 - -95.57 - 0 - 0 - TSA - - - OKZ061 - 360610 - Rogers - OK - US - 36.34 - -95.57 - 0 - 0 - TSA - - - KSZ012 - 160120 - Brown - KS - US - 39.82 - -95.56 - 0 - 0 - TOP - - - IAZ032 - 150320 - Ida - IA - US - 42.39 - -95.54 - 0 - 0 - FSD - - - OKZ067 - 360670 - Wagoner - OK - US - 35.97 - -95.51 - 0 - 0 - TSA - - - MOZ001 - 250010 - Atchison - MO - US - 40.43 - -95.48 - 0 - 0 - EAX - - - TXZ237 - 432370 - Brazoria - TX - US - 29.21 - -95.47 - 0 - 0 - HGX - - - MNZ031 - 230310 - East_Otter_Tail - MN - US - 46.41 - -95.46 - 0 - 0 - FGF - - - TXZ199 - 431990 - Montgomery - TX - US - 30.33 - -95.46 - 0 - 0 - HGX - - - MNZ041 - 230410 - Douglas - MN - US - 45.93 - -95.45 - 0 - 0 - MPX - - - MNZ048 - 230480 - Pope - MN - US - 45.58 - -95.44 - 0 - 0 - MPX - - - TXZ213 - 432130 - Harris - TX - US - 29.84 - -95.44 - 0 - 0 - HGX - - - OKZ070 - 360700 - Muskogee - OK - US - 35.57 - -95.42 - 0 - 0 - TSA - - - MNZ028 - 230280 - East_Becker - MN - US - 46.93 - -95.41 - 0 - 0 - FGF - - - TXZ124 - 431240 - Wood - TX - US - 32.78 - -95.40 - 0 - 0 - SHV - - - IAZ044 - 150440 - Crawford - IA - US - 42.04 - -95.39 - 0 - 0 - DMX - - - MNZ016 - 230160 - North_Clearwater - MN - US - 47.76 - -95.39 - 0 - 0 - FGF - - - KSZ026 - 160260 - Jefferson - KS - US - 39.22 - -95.38 - 0 - 0 - TOP - - - TXZ163 - 431630 - Houston - TX - US - 31.27 - -95.37 - 0 - 0 - HGX - - - MNZ023 - 230230 - South_Clearwater - MN - US - 47.32 - -95.36 - 0 - 0 - FGF - - - OKZ049 - 360490 - Pushmataha - OK - US - 34.42 - -95.36 - 0 - 0 - TSA - - - IAZ056 - 150560 - Shelby - IA - US - 41.68 - -95.31 - 0 - 0 - OAX - - - KSZ072 - 160720 - Allen - KS - US - 37.88 - -95.30 - 0 - 0 - ICT - - - KSZ096 - 160960 - Neosho - KS - US - 37.56 - -95.30 - 0 - 0 - ICT - - - KSZ059 - 160590 - Anderson - KS - US - 38.21 - -95.29 - 0 - 0 - TOP - - - KSZ100 - 161000 - Labette - KS - US - 37.19 - -95.29 - 0 - 0 - ICT - - - TXZ136 - 431360 - Smith - TX - US - 32.42 - -95.29 - 0 - 0 - SHV - - - KSZ056 - 160560 - Franklin - KS - US - 38.56 - -95.28 - 0 - 0 - TOP - - - KSZ040 - 160400 - Douglas - KS - US - 38.90 - -95.27 - 0 - 0 - TOP - - - KSZ025 - 160250 - Atchison - KS - US - 39.53 - -95.26 - 0 - 0 - EAX - - - MOZ011 - 250110 - Holt - MO - US - 40.07 - -95.26 - 0 - 0 - EAX - - - MNZ073 - 230730 - Redwood - MN - US - 44.45 - -95.23 - 0 - 0 - MPX - - - OKZ062 - 360620 - Mayes - OK - US - 36.30 - -95.23 - 0 - 0 - TSA - - - OKZ057 - 360570 - Craig - OK - US - 36.76 - -95.22 - 0 - 0 - TSA - - - OKZ075 - 360750 - Latimer - OK - US - 34.88 - -95.22 - 0 - 0 - TSA - - - TXZ108 - 431080 - Franklin - TX - US - 33.18 - -95.21 - 0 - 0 - SHV - - - MNZ081 - 230810 - Cottonwood - MN - US - 44.02 - -95.17 - 0 - 0 - FSD - - - TXZ149 - 431490 - Cherokee - TX - US - 31.79 - -95.17 - 0 - 0 - SHV - - - IAZ003 - 150030 - Dickinson - IA - US - 43.38 - -95.16 - 0 - 0 - FSD - - - IAZ014 - 150140 - Clay - IA - US - 43.08 - -95.16 - 0 - 0 - FSD - - - IAZ022 - 150220 - Buena_Vista - IA - US - 42.74 - -95.16 - 0 - 0 - FSD - - - IAZ080 - 150800 - Montgomery - IA - US - 41.04 - -95.16 - 0 - 0 - OAX - - - IAZ091 - 150910 - Page - IA - US - 40.74 - -95.16 - 0 - 0 - OAX - - - MNZ090 - 230900 - Jackson - MN - US - 43.67 - -95.16 - 0 - 0 - FSD - - - IAZ033 - 150330 - Sac - IA - US - 42.39 - -95.13 - 0 - 0 - DMX - - - OKZ074 - 360740 - Haskell - OK - US - 35.27 - -95.13 - 0 - 0 - TSA - - - TXZ164 - 431640 - Trinity - TX - US - 31.11 - -95.13 - 0 - 0 - HGX - - - KSZ102 - 161020 - Doniphan - KS - US - 39.81 - -95.10 - 0 - 0 - EAX - - - TXZ178 - 431780 - San_Jacinto - TX - US - 30.62 - -95.10 - 0 - 0 - HGX - - - OKZ068 - 360680 - Cherokee - OK - US - 35.91 - -95.04 - 0 - 0 - TSA - - - TXZ096 - 430960 - Red_River - TX - US - 33.65 - -95.02 - 0 - 0 - SHV - - - MNZ009 - 230090 - North_Beltrami - MN - US - 48.20 - -95.01 - 0 - 0 - FGF - - - MNZ057 - 230570 - Kandiyohi - MN - US - 45.15 - -95.01 - 0 - 0 - MPX - - - KSZ103 - 161030 - Leavenworth - KS - US - 39.19 - -94.99 - 0 - 0 - EAX - - - MNZ065 - 230650 - Renville - MN - US - 44.67 - -94.99 - 0 - 0 - MPX - - - TXZ109 - 431090 - Titus - TX - US - 33.19 - -94.97 - 0 - 0 - SHV - - - MNZ032 - 230320 - Wadena - MN - US - 46.59 - -94.95 - 0 - 0 - FGF - - - IAZ070 - 150700 - Cass - IA - US - 41.33 - -94.94 - 0 - 0 - DMX - - - TXZ110 - 431100 - Camp - TX - US - 33.00 - -94.94 - 0 - 0 - SHV - - - MNZ024 - 230240 - Hubbard - MN - US - 47.11 - -94.92 - 0 - 0 - FGF - - - TXZ125 - 431250 - Upshur - TX - US - 32.72 - -94.92 - 0 - 0 - SHV - - - IAZ057 - 150570 - Audubon - IA - US - 41.68 - -94.91 - 0 - 0 - DMX - - - MOZ002 - 250020 - Nodaway - MO - US - 40.36 - -94.91 - 0 - 0 - EAX - - - MNZ042 - 230420 - Todd - MN - US - 46.07 - -94.90 - 0 - 0 - MPX - - - MNZ006 - 230060 - Lake_of_The_Woods - MN - US - 48.87 - -94.89 - 0 - 0 - FGF - - - IAZ045 - 150450 - Carroll - IA - US - 42.03 - -94.87 - 0 - 0 - DMX - - - TXZ179 - 431790 - Polk - TX - US - 30.82 - -94.87 - 0 - 0 - HGX - - - MOZ020 - 250200 - Buchanan - MO - US - 39.68 - -94.86 - 0 - 0 - EAX - - - KSZ073 - 160730 - Bourbon - KS - US - 37.85 - -94.85 - 0 - 0 - SGF - - - KSZ097 - 160970 - Crawford - KS - US - 37.50 - -94.85 - 0 - 0 - SGF - - - KSZ101 - 161010 - Cherokee - KS - US - 37.16 - -94.85 - 0 - 0 - SGF - - - MOZ028 - 250280 - Platte - MO - US - 39.34 - -94.85 - 0 - 0 - EAX - - - KSZ057 - 160570 - Miami - KS - US - 38.56 - -94.84 - 0 - 0 - EAX - - - KSZ060 - 160600 - Linn - KS - US - 38.21 - -94.84 - 0 - 0 - EAX - - - MOZ012 - 250120 - Andrew - MO - US - 39.97 - -94.84 - 0 - 0 - EAX - - - KSZ105 - 161050 - Johnson - KS - US - 38.89 - -94.83 - 0 - 0 - EAX - - - OKZ058 - 360580 - Ottawa - OK - US - 36.83 - -94.83 - 0 - 0 - TSA - - - MNZ017 - 230170 - South_Beltrami - MN - US - 47.63 - -94.81 - 0 - 0 - FGF - - - OKZ077 - 360770 - McCurtain - OK - US - 34.07 - -94.81 - 0 - 0 - SHV - - - TXZ200 - 432000 - Liberty - TX - US - 30.19 - -94.81 - 0 - 0 - HGX - - - TXZ238 - 432380 - Galveston - TX - US - 29.34 - -94.81 - 0 - 0 - HGX - - - OKZ063 - 360630 - Delaware - OK - US - 36.42 - -94.79 - 0 - 0 - TSA - - - OKZ072 - 360720 - Sequoyah - OK - US - 35.46 - -94.78 - 0 - 0 - TSA - - - TXZ137 - 431370 - Gregg - TX - US - 32.51 - -94.78 - 0 - 0 - SHV - - - KSZ104 - 161040 - Wyandotte - KS - US - 39.09 - -94.75 - 0 - 0 - EAX - - - MNZ074 - 230740 - Brown - MN - US - 44.30 - -94.74 - 0 - 0 - MPX - - - OKZ076 - 360760 - Le_Flore - OK - US - 34.95 - -94.74 - 0 - 0 - TSA - - - TXZ111 - 431110 - Morris - TX - US - 33.13 - -94.74 - 0 - 0 - SHV - - - TXZ150 - 431500 - Rusk - TX - US - 32.13 - -94.72 - 0 - 0 - SHV - - - IAZ081 - 150810 - Adams - IA - US - 41.03 - -94.71 - 0 - 0 - DMX - - - IAZ092 - 150920 - Taylor - IA - US - 40.74 - -94.71 - 0 - 0 - DMX - - - IAZ004 - 150040 - Emmet - IA - US - 43.38 - -94.69 - 0 - 0 - DMX - - - IAZ015 - 150150 - Palo_Alto - IA - US - 43.08 - -94.69 - 0 - 0 - DMX - - - IAZ023 - 150230 - Pocahontas - IA - US - 42.74 - -94.69 - 0 - 0 - DMX - - - TXZ214 - 432140 - Chambers - TX - US - 29.71 - -94.67 - 0 - 0 - HGX - - - IAZ034 - 150340 - Calhoun - IA - US - 42.38 - -94.66 - 0 - 0 - DMX - - - OKZ069 - 360690 - Adair - OK - US - 35.91 - -94.64 - 0 - 0 - TSA - - - TXZ152 - 431520 - Nacogdoches - TX - US - 31.54 - -94.64 - 0 - 0 - SHV - - - MNZ082 - 230820 - Watonwan - MN - US - 43.98 - -94.62 - 0 - 0 - MPX - - - MNZ049 - 230490 - Stearns - MN - US - 45.53 - -94.59 - 0 - 0 - MPX - - - TXZ165 - 431650 - Angelina - TX - US - 31.28 - -94.57 - 0 - 0 - SHV - - - MNZ033 - 230330 - South_Cass - MN - US - 46.54 - -94.56 - 0 - 0 - DLH - - - MNZ091 - 230910 - Martin - MN - US - 43.67 - -94.55 - 0 - 0 - MPX - - - MNZ058 - 230580 - Meeker - MN - US - 45.11 - -94.51 - 0 - 0 - MPX - - - IAZ058 - 150580 - Guthrie - IA - US - 41.68 - -94.50 - 0 - 0 - DMX - - - IAZ071 - 150710 - Adair - IA - US - 41.33 - -94.48 - 0 - 0 - DMX - - - MOZ003 - 250030 - Worth - MO - US - 40.48 - -94.43 - 0 - 0 - EAX - - - MOZ004 - 250040 - Gentry - MO - US - 40.21 - -94.42 - 0 - 0 - EAX - - - MOZ021 - 250210 - Clinton - MO - US - 39.60 - -94.42 - 0 - 0 - EAX - - - MOZ029 - 250290 - Clay - MO - US - 39.28 - -94.42 - 0 - 0 - EAX - - - IAZ046 - 150460 - Greene - IA - US - 42.03 - -94.41 - 0 - 0 - DMX - - - MOZ013 - 250130 - De_Kalb - MO - US - 39.89 - -94.41 - 0 - 0 - EAX - - - TXZ201 - 432010 - Hardin - TX - US - 30.31 - -94.40 - 0 - 0 - LCH - - - TXZ097 - 430970 - Bowie - TX - US - 33.47 - -94.39 - 0 - 0 - SHV - - - TXZ126 - 431260 - Marion - TX - US - 32.79 - -94.38 - 0 - 0 - SHV - - - TXZ138 - 431380 - Harrison - TX - US - 32.56 - -94.37 - 0 - 0 - SHV - - - MNZ075 - 230750 - Nicollet - MN - US - 44.31 - -94.36 - 0 - 0 - MPX - - - MOZ037 - 250370 - Jackson - MO - US - 39.03 - -94.36 - 0 - 0 - EAX - - - MOZ077 - 250770 - Barton - MO - US - 37.50 - -94.35 - 0 - 0 - SGF - - - MOZ101 - 251010 - McDonald - MO - US - 36.63 - -94.35 - 0 - 0 - SGF - - - TXZ112 - 431120 - Cass - TX - US - 33.10 - -94.35 - 0 - 0 - SHV - - - TXZ180 - 431800 - Tyler - TX - US - 30.79 - -94.35 - 0 - 0 - LCH - - - MOZ043 - 250430 - Cass - MO - US - 38.64 - -94.34 - 0 - 0 - EAX - - - MOZ053 - 250530 - Bates - MO - US - 38.25 - -94.34 - 0 - 0 - EAX - - - MOZ066 - 250660 - Vernon - MO - US - 37.85 - -94.34 - 0 - 0 - SGF - - - MOZ088 - 250880 - Jasper - MO - US - 37.21 - -94.34 - 0 - 0 - SGF - - - MOZ093 - 250930 - Newton - MO - US - 36.90 - -94.34 - 0 - 0 - SGF - - - TXZ151 - 431510 - Panola - TX - US - 32.18 - -94.30 - 0 - 0 - SHV - - - MNZ066 - 230660 - McLeod - MN - US - 44.81 - -94.26 - 0 - 0 - MPX - - - IAZ082 - 150820 - Union - IA - US - 41.03 - -94.25 - 0 - 0 - DMX - - - IAZ093 - 150930 - Ringgold - IA - US - 40.74 - -94.25 - 0 - 0 - DMX - - - ARZ001 - 40010 - Benton - AR - US - 36.30 - -94.24 - 0 - 0 - TSA - - - ARZ029 - 40290 - Sebastian - AR - US - 35.19 - -94.24 - 0 - 0 - TSA - - - ARZ010 - 40100 - Washington - AR - US - 36.00 - -94.22 - 0 - 0 - TSA - - - ARZ050 - 40500 - Sevier - AR - US - 33.97 - -94.22 - 0 - 0 - SHV - - - IAZ005 - 150050 - Kossuth - IA - US - 43.21 - -94.22 - 0 - 0 - DMX - - - IAZ024 - 150240 - Humboldt - IA - US - 42.78 - -94.22 - 0 - 0 - DMX - - - MNZ025 - 230250 - North_Cass - MN - US - 47.14 - -94.22 - 0 - 0 - DLH - - - MNZ043 - 230430 - Morrison - MN - US - 46.06 - -94.21 - 0 - 0 - MPX - - - ARZ040 - 40400 - Polk - AR - US - 34.47 - -94.20 - 0 - 0 - LZK - - - MNZ067 - 230670 - Sibley - MN - US - 44.59 - -94.20 - 0 - 0 - MPX - - - ARZ019 - 40190 - Crawford - AR - US - 35.56 - -94.19 - 0 - 0 - TSA - - - IAZ035 - 150350 - Webster - IA - US - 42.43 - -94.19 - 0 - 0 - DMX - - - TXZ166 - 431660 - San_Augustine - TX - US - 31.38 - -94.19 - 0 - 0 - SHV - - - TXZ153 - 431530 - Shelby - TX - US - 31.78 - -94.15 - 0 - 0 - SHV - - - ARZ059 - 40590 - Little_River - AR - US - 33.74 - -94.14 - 0 - 0 - SHV - - - TXZ215 - 432150 - Jefferson - TX - US - 29.87 - -94.14 - 0 - 0 - LCH - - - ARZ037 - 40370 - Scott - AR - US - 34.89 - -94.08 - 0 - 0 - LZK - - - MNZ034 - 230340 - Crow_Wing - MN - US - 46.48 - -94.08 - 0 - 0 - DLH - - - MNZ083 - 230830 - Blue_Earth - MN - US - 44.06 - -94.07 - 0 - 0 - MPX - - - MNZ050 - 230500 - Benton - MN - US - 45.69 - -94.06 - 0 - 0 - MPX - - - IAZ059 - 150590 - Dallas - IA - US - 41.68 - -94.04 - 0 - 0 - DMX - - - ARZ051 - 40510 - Howard - AR - US - 34.05 - -94.03 - 0 - 0 - SHV - - - IAZ072 - 150720 - Madison - IA - US - 41.34 - -94.02 - 0 - 0 - DMX - - - MOZ005 - 250050 - Harrison - MO - US - 40.36 - -94.00 - 0 - 0 - EAX - - - MOZ014 - 250140 - Daviess - MO - US - 39.96 - -94.00 - 0 - 0 - EAX - - - TXZ181 - 431810 - Jasper - TX - US - 30.70 - -94.00 - 0 - 0 - LCH - - - MOZ022 - 250220 - Caldwell - MO - US - 39.66 - -93.99 - 0 - 0 - EAX - - - MOZ030 - 250300 - Ray - MO - US - 39.33 - -93.99 - 0 - 0 - EAX - - - MNZ092 - 230920 - Faribault - MN - US - 43.67 - -93.95 - 0 - 0 - MPX - - - IAZ047 - 150470 - Boone - IA - US - 42.03 - -93.94 - 0 - 0 - DMX - - - TXZ216 - 432160 - Orange - TX - US - 30.10 - -93.90 - 0 - 0 - LCH - - - MNZ059 - 230590 - Wright - MN - US - 45.20 - -93.89 - 0 - 0 - MPX - - - ARZ020 - 40200 - Franklin - AR - US - 35.49 - -93.88 - 0 - 0 - TSA - - - MOZ089 - 250890 - Dade - MO - US - 37.43 - -93.86 - 0 - 0 - SGF - - - ARZ070 - 40700 - Miller - AR - US - 33.31 - -93.85 - 0 - 0 - SHV - - - MOZ078 - 250780 - Cedar - MO - US - 37.73 - -93.85 - 0 - 0 - SGF - - - MOZ094 - 250940 - Lawrence - MO - US - 37.11 - -93.84 - 0 - 0 - SGF - - - MNZ051 - 230510 - Sherburne - MN - US - 45.41 - -93.83 - 0 - 0 - MPX - - - MOZ102 - 251020 - Barry - MO - US - 36.71 - -93.83 - 0 - 0 - SGF - - - MOZ044 - 250440 - Johnson - MO - US - 38.75 - -93.82 - 0 - 0 - EAX - - - TXZ167 - 431670 - Sabine - TX - US - 31.37 - -93.82 - 0 - 0 - SHV - - - MOZ038 - 250380 - Lafayette - MO - US - 39.09 - -93.80 - 0 - 0 - EAX - - - IAZ083 - 150830 - Clarke - IA - US - 41.03 - -93.79 - 0 - 0 - DMX - - - IAZ094 - 150940 - Decatur - IA - US - 40.74 - -93.79 - 0 - 0 - DMX - - - MOZ054 - 250540 - Henry - MO - US - 38.38 - -93.79 - 0 - 0 - EAX - - - MOZ067 - 250670 - St._Clair - MO - US - 38.02 - -93.79 - 0 - 0 - SGF - - - MNZ076 - 230760 - Le_Sueur - MN - US - 44.37 - -93.78 - 0 - 0 - MPX - - - LAZ001 - 180010 - Caddo - LA - US - 32.61 - -93.77 - 0 - 0 - SHV - - - MNZ068 - 230680 - Carver - MN - US - 44.81 - -93.77 - 0 - 0 - MPX - - - MNZ010 - 230100 - Koochiching - MN - US - 48.28 - -93.76 - 0 - 0 - DLH - - - IAZ006 - 150060 - Winnebago - IA - US - 43.38 - -93.74 - 0 - 0 - DMX - - - IAZ016 - 150160 - Hancock - IA - US - 43.08 - -93.74 - 0 - 0 - DMX - - - IAZ025 - 150250 - Wright - IA - US - 42.73 - -93.74 - 0 - 0 - DMX - - - MNZ018 - 230180 - North_Itasca - MN - US - 47.66 - -93.74 - 0 - 0 - DLH - - - IAZ036 - 150360 - Hamilton - IA - US - 42.38 - -93.72 - 0 - 0 - DMX - - - ARZ030 - 40300 - Logan - AR - US - 35.22 - -93.71 - 0 - 0 - LZK - - - ARZ060 - 40600 - Hempstead - AR - US - 33.75 - -93.71 - 0 - 0 - SHV - - - TXZ182 - 431820 - Newton - TX - US - 30.72 - -93.71 - 0 - 0 - LCH - - - ARZ011 - 40110 - Madison - AR - US - 36.03 - -93.70 - 0 - 0 - TSA - - - LAZ010 - 180100 - De_Soto - LA - US - 32.10 - -93.69 - 0 - 0 - SHV - - - ARZ041 - 40410 - Montgomery - AR - US - 34.55 - -93.66 - 0 - 0 - LZK - - - ARZ052 - 40520 - Pike - AR - US - 34.15 - -93.65 - 0 - 0 - LZK - - - MNZ044 - 230440 - Mille_Lacs - MN - US - 45.90 - -93.62 - 0 - 0 - MPX - - - ARZ071 - 40710 - Lafayette - AR - US - 33.25 - -93.61 - 0 - 0 - SHV - - - LAZ002 - 180020 - Bossier - LA - US - 32.63 - -93.61 - 0 - 0 - SHV - - - MNZ069 - 230690 - Scott - MN - US - 44.68 - -93.60 - 0 - 0 - MPX - - - MNZ084 - 230840 - Waseca - MN - US - 44.02 - -93.59 - 0 - 0 - MPX - - - ARZ002 - 40020 - Carroll - AR - US - 36.31 - -93.58 - 0 - 0 - TSA - - - MOZ006 - 250060 - Mercer - MO - US - 40.42 - -93.58 - 0 - 0 - EAX - - - IAZ060 - 150600 - Polk - IA - US - 41.68 - -93.57 - 0 - 0 - DMX - - - MNZ026 - 230260 - South_Itasca - MN - US - 47.24 - -93.57 - 0 - 0 - DLH - - - MOZ015 - 250150 - Grundy - MO - US - 40.11 - -93.57 - 0 - 0 - EAX - - - IAZ073 - 150730 - Warren - IA - US - 41.34 - -93.56 - 0 - 0 - DMX - - - LAZ017 - 180170 - Sabine - LA - US - 31.51 - -93.55 - 0 - 0 - SHV - - - MOZ023 - 250230 - Livingston - MO - US - 39.79 - -93.52 - 0 - 0 - EAX - - - IAZ048 - 150480 - Story - IA - US - 42.03 - -93.47 - 0 - 0 - DMX - - - MNZ060 - 230600 - Hennepin - MN - US - 45.02 - -93.47 - 0 - 0 - MPX - - - MOZ103 - 251030 - Stone - MO - US - 36.74 - -93.47 - 0 - 0 - SGF - - - MOZ031 - 250310 - Carroll - MO - US - 39.41 - -93.44 - 0 - 0 - EAX - - - ARZ021 - 40210 - Johnson - AR - US - 35.55 - -93.43 - 0 - 0 - LZK - - - MNZ036 - 230360 - South_Aitkin - MN - US - 46.39 - -93.43 - 0 - 0 - DLH - - - MNZ035 - 230350 - Northern_Aitkin - MN - US - 46.83 - -93.42 - 0 - 0 - DLH - - - MOZ079 - 250790 - Polk - MO - US - 37.62 - -93.41 - 0 - 0 - SGF - - - LAZ011 - 180110 - Red_River - LA - US - 32.07 - -93.36 - 0 - 0 - SHV - - - LAZ030 - 180300 - Beauregard - LA - US - 30.65 - -93.36 - 0 - 0 - LCH - - - MNZ093 - 230930 - Freeborn - MN - US - 43.67 - -93.35 - 0 - 0 - MPX - - - MOZ090 - 250900 - Greene - MO - US - 37.26 - -93.35 - 0 - 0 - SGF - - - IAZ084 - 150840 - Lucas - IA - US - 41.03 - -93.33 - 0 - 0 - DMX - - - IAZ095 - 150950 - Wayne - IA - US - 40.74 - -93.33 - 0 - 0 - DMX - - - LAZ003 - 180030 - Webster - LA - US - 32.72 - -93.33 - 0 - 0 - SHV - - - ARZ038 - 40380 - Yell - AR - US - 35.03 - -93.32 - 0 - 0 - LZK - - - LAZ041 - 180410 - Calcasieu - LA - US - 30.27 - -93.32 - 0 - 0 - LCH - - - MOZ068 - 250680 - Hickory - MO - US - 37.93 - -93.32 - 0 - 0 - SGF - - - ARZ061 - 40610 - Nevada - AR - US - 33.70 - -93.29 - 0 - 0 - SHV - - - MNZ045 - 230450 - Kanabec - MN - US - 45.95 - -93.29 - 0 - 0 - MPX - - - MNZ077 - 230770 - Rice - MN - US - 44.37 - -93.29 - 0 - 0 - MPX - - - MOZ045 - 250450 - Pettis - MO - US - 38.72 - -93.29 - 0 - 0 - EAX - - - MOZ055 - 250550 - Benton - MO - US - 38.30 - -93.29 - 0 - 0 - SGF - - - MNZ052 - 230520 - Isanti - MN - US - 45.57 - -93.27 - 0 - 0 - MPX - - - MNZ061 - 230610 - Anoka - MN - US - 45.23 - -93.27 - 0 - 0 - MPX - - - IAZ007 - 150070 - Worth - IA - US - 43.38 - -93.26 - 0 - 0 - DMX - - - IAZ017 - 150170 - Cerro_Gordo - IA - US - 43.08 - -93.26 - 0 - 0 - DMX - - - IAZ026 - 150260 - Franklin - IA - US - 42.73 - -93.26 - 0 - 0 - DMX - - - MOZ095 - 250950 - Christian - MO - US - 36.95 - -93.26 - 0 - 0 - SGF - - - IAZ037 - 150370 - Hardin - IA - US - 42.38 - -93.25 - 0 - 0 - DMX - - - LAZ051 - 180510 - Cameron - LA - US - 29.83 - -93.25 - 0 - 0 - LCH - - - MNZ085 - 230850 - Steele - MN - US - 44.02 - -93.23 - 0 - 0 - MPX - - - ARZ012 - 40120 - Newton - AR - US - 35.93 - -93.22 - 0 - 0 - LZK - - - ARZ072 - 40720 - Columbia - AR - US - 33.24 - -93.22 - 0 - 0 - SHV - - - ARZ053 - 40530 - Clark - AR - US - 34.06 - -93.19 - 0 - 0 - LZK - - - LAZ027 - 180270 - Vernon - LA - US - 31.12 - -93.19 - 0 - 0 - LCH - - - MOZ039 - 250390 - Saline - MO - US - 39.17 - -93.18 - 0 - 0 - EAX - - - MNZ062 - 230620 - Ramsey - MN - US - 45.01 - -93.11 - 0 - 0 - MPX - - - MOZ016 - 250160 - Sullivan - MO - US - 40.21 - -93.11 - 0 - 0 - EAX - - - MOZ024 - 250240 - Linn - MO - US - 39.87 - -93.11 - 0 - 0 - EAX - - - IAZ074 - 150740 - Marion - IA - US - 41.34 - -93.10 - 0 - 0 - DMX - - - LAZ012 - 180120 - Bienville - LA - US - 32.37 - -93.10 - 0 - 0 - SHV - - - ARZ042 - 40420 - Garland - AR - US - 34.58 - -93.09 - 0 - 0 - LZK - - - LAZ018 - 180180 - Natchitoches - LA - US - 31.75 - -93.08 - 0 - 0 - SHV - - - ARZ003 - 40030 - Boone - AR - US - 36.31 - -93.07 - 0 - 0 - LZK - - - IAZ061 - 150610 - Jasper - IA - US - 41.69 - -93.06 - 0 - 0 - DMX - - - ARZ022 - 40220 - Pope - AR - US - 35.43 - -93.05 - 0 - 0 - LZK - - - MOZ104 - 251040 - Taney - MO - US - 36.66 - -93.05 - 0 - 0 - SGF - - - ARZ054 - 40540 - Hot_Spring - AR - US - 34.33 - -93.04 - 0 - 0 - LZK - - - MNZ070 - 230700 - Dakota - MN - US - 44.71 - -93.03 - 0 - 0 - MPX - - - MOZ007 - 250070 - Putnam - MO - US - 40.46 - -93.02 - 0 - 0 - EAX - - - MOZ080 - 250800 - Dallas - MO - US - 37.66 - -93.02 - 0 - 0 - SGF - - - IAZ049 - 150490 - Marshall - IA - US - 42.04 - -93.01 - 0 - 0 - DMX - - - MOZ032 - 250320 - Chariton - MO - US - 39.46 - -92.99 - 0 - 0 - EAX - - - LAZ004 - 180040 - Claiborne - LA - US - 32.80 - -92.97 - 0 - 0 - SHV - - - ARZ039 - 40390 - Perry - AR - US - 34.94 - -92.92 - 0 - 0 - LZK - - - MNZ053 - 230530 - Chisago - MN - US - 45.52 - -92.89 - 0 - 0 - MPX - - - MNZ063 - 230630 - Washington - MN - US - 45.02 - -92.88 - 0 - 0 - MPX - - - MOZ091 - 250910 - Webster - MO - US - 37.28 - -92.88 - 0 - 0 - SGF - - - IAZ085 - 150850 - Monroe - IA - US - 41.03 - -92.87 - 0 - 0 - DMX - - - IAZ096 - 150960 - Appanoose - IA - US - 40.74 - -92.87 - 0 - 0 - DMX - - - MNZ086 - 230860 - Dodge - MN - US - 44.02 - -92.87 - 0 - 0 - ARX - - - LAZ031 - 180310 - Allen - LA - US - 30.66 - -92.85 - 0 - 0 - LCH - - - LAZ042 - 180420 - Jefferson_Davis - LA - US - 30.27 - -92.85 - 0 - 0 - LCH - - - MOZ056 - 250560 - Morgan - MO - US - 38.44 - -92.85 - 0 - 0 - SGF - - - ARZ066 - 40660 - Ouachita - AR - US - 33.60 - -92.83 - 0 - 0 - LZK - - - IAZ008 - 150080 - Mitchell - IA - US - 43.36 - -92.79 - 0 - 0 - ARX - - - IAZ018 - 150180 - Floyd - IA - US - 43.06 - -92.79 - 0 - 0 - ARX - - - IAZ027 - 150270 - Butler - IA - US - 42.73 - -92.79 - 0 - 0 - DMX - - - IAZ038 - 150380 - Grundy - IA - US - 42.38 - -92.79 - 0 - 0 - DMX - - - MOZ046 - 250460 - Cooper - MO - US - 38.87 - -92.78 - 0 - 0 - EAX - - - ARZ031 - 40310 - Conway - AR - US - 35.27 - -92.76 - 0 - 0 - LZK - - - MNZ094 - 230940 - Mower - MN - US - 43.67 - -92.75 - 0 - 0 - ARX - - - MOZ069 - 250690 - Camden - MO - US - 38.03 - -92.74 - 0 - 0 - SGF - - - MNZ038 - 230380 - Pine - MN - US - 46.07 - -92.71 - 0 - 0 - DLH - - - MOZ040 - 250400 - Howard - MO - US - 39.16 - -92.69 - 0 - 0 - EAX - - - ARZ013 - 40130 - Searcy - AR - US - 35.92 - -92.68 - 0 - 0 - LZK - - - ARZ004 - 40040 - Marion - AR - US - 36.28 - -92.65 - 0 - 0 - LZK - - - ARZ043 - 40430 - Saline - AR - US - 34.64 - -92.65 - 0 - 0 - LZK - - - ARZ062 - 40620 - Dallas - AR - US - 33.98 - -92.65 - 0 - 0 - LZK - - - IAZ075 - 150750 - Mahaska - IA - US - 41.34 - -92.65 - 0 - 0 - DMX - - - MNZ078 - 230780 - Goodhue - MN - US - 44.45 - -92.65 - 0 - 0 - MPX - - - LAZ005 - 180050 - Lincoln - LA - US - 32.61 - -92.64 - 0 - 0 - SHV - - - LAZ019 - 180190 - Winn - LA - US - 31.93 - -92.64 - 0 - 0 - SHV - - - MOZ047 - 250470 - Moniteau - MO - US - 38.67 - -92.62 - 0 - 0 - LSX - - - MOZ017 - 250170 - Adair - MO - US - 40.19 - -92.61 - 0 - 0 - EAX - - - LAZ020 - 180200 - Grant - LA - US - 31.60 - -92.58 - 0 - 0 - SHV - - - MOZ025 - 250250 - Macon - MO - US - 39.82 - -92.57 - 0 - 0 - EAX - - - LAZ013 - 180130 - Jackson - LA - US - 32.33 - -92.56 - 0 - 0 - SHV - - - MOZ081 - 250810 - Laclede - MO - US - 37.69 - -92.56 - 0 - 0 - SGF - - - ARZ023 - 40230 - Van_Buren - AR - US - 35.58 - -92.54 - 0 - 0 - LZK - - - ARZ067 - 40670 - Calhoun - AR - US - 33.54 - -92.54 - 0 - 0 - LZK - - - IAZ050 - 150500 - Tama - IA - US - 42.08 - -92.54 - 0 - 0 - DMX - - - IAZ062 - 150620 - Poweshiek - IA - US - 41.69 - -92.54 - 0 - 0 - DMX - - - MOZ008 - 250080 - Schuyler - MO - US - 40.47 - -92.54 - 0 - 0 - EAX - - - ARZ073 - 40730 - Union - AR - US - 33.20 - -92.52 - 0 - 0 - SHV - - - LAZ028 - 180280 - Rapides - LA - US - 31.21 - -92.52 - 0 - 0 - LCH - - - WIZ014 - 490140 - Polk - WI - US - 45.47 - -92.52 - 0 - 0 - MPX - - - MOZ033 - 250330 - Randolph - MO - US - 39.43 - -92.51 - 0 - 0 - EAX - - - MOZ096 - 250960 - Douglas - MO - US - 36.93 - -92.50 - 0 - 0 - SGF - - - MOZ092 - 250920 - Wright - MO - US - 37.27 - -92.47 - 0 - 0 - SGF - - - WIZ023 - 490230 - St._Croix - WI - US - 45.04 - -92.47 - 0 - 0 - MPX - - - WIZ024 - 490240 - Pierce - WI - US - 44.70 - -92.47 - 0 - 0 - MPX - - - WIZ006 - 490060 - Burnett - WI - US - 45.90 - -92.46 - 0 - 0 - DLH - - - MOZ105 - 251050 - Ozark - MO - US - 36.65 - -92.45 - 0 - 0 - SGF - - - ARZ055 - 40550 - Grant - AR - US - 34.28 - -92.44 - 0 - 0 - LZK - - - MNZ011 - 230110 - North_St._Louis - MN - US - 48.24 - -92.44 - 0 - 0 - DLH - - - MNZ019 - 230190 - Central_St._Louis - MN - US - 47.43 - -92.44 - 0 - 0 - DLH - - - MOZ057 - 250570 - Miller - MO - US - 38.22 - -92.44 - 0 - 0 - SGF - - - MNZ037 - 230370 - Carlton/South_St._Louis - MN - US - 46.72 - -92.43 - 0 - 0 - DLH - - - IAZ097 - 150970 - Davis - IA - US - 40.75 - -92.42 - 0 - 0 - DMX - - - IAZ086 - 150860 - Wapello - IA - US - 41.03 - -92.41 - 0 - 0 - DMX - - - ARZ044 - 40440 - Pulaski - AR - US - 34.76 - -92.39 - 0 - 0 - LZK - - - LAZ032 - 180320 - Evangeline - LA - US - 30.74 - -92.39 - 0 - 0 - LCH - - - MNZ087 - 230870 - Olmsted - MN - US - 44.01 - -92.39 - 0 - 0 - ARX - - - LAZ006 - 180060 - Union - LA - US - 32.80 - -92.38 - 0 - 0 - SHV - - - LAZ043 - 180430 - Acadia - LA - US - 30.28 - -92.38 - 0 - 0 - LCH - - - ARZ005 - 40050 - Baxter - AR - US - 36.24 - -92.37 - 0 - 0 - LZK - - - ARZ032 - 40320 - Faulkner - AR - US - 35.12 - -92.36 - 0 - 0 - LZK - - - LAZ052 - 180520 - Vermilion - LA - US - 29.85 - -92.34 - 0 - 0 - LCH - - - MOZ041 - 250410 - Boone - MO - US - 38.94 - -92.34 - 0 - 0 - LSX - - - IAZ009 - 150090 - Howard - IA - US - 43.36 - -92.32 - 0 - 0 - ARX - - - IAZ019 - 150190 - Chickasaw - IA - US - 43.07 - -92.32 - 0 - 0 - ARX - - - IAZ028 - 150280 - Bremer - IA - US - 42.78 - -92.32 - 0 - 0 - DMX - - - IAZ039 - 150390 - Black_Hawk - IA - US - 42.47 - -92.31 - 0 - 0 - DMX - - - MOZ048 - 250480 - Cole - MO - US - 38.53 - -92.22 - 0 - 0 - LSX - - - MOZ070 - 250700 - Pulaski - MO - US - 37.81 - -92.22 - 0 - 0 - SGF - - - ARZ063 - 40630 - Cleveland - AR - US - 33.89 - -92.20 - 0 - 0 - LZK - - - MNZ079 - 230790 - Wabasha - MN - US - 44.28 - -92.20 - 0 - 0 - ARX - - - LAZ022 - 180220 - La_Salle - LA - US - 31.63 - -92.19 - 0 - 0 - SHV - - - IAZ076 - 150760 - Keokuk - IA - US - 41.33 - -92.18 - 0 - 0 - DVN - - - ARZ068 - 40680 - Bradley - AR - US - 33.44 - -92.16 - 0 - 0 - LZK - - - LAZ014 - 180140 - Ouachita - LA - US - 32.50 - -92.16 - 0 - 0 - SHV - - - MOZ009 - 250090 - Scotland - MO - US - 40.46 - -92.15 - 0 - 0 - DVN - - - MOZ018 - 250180 - Knox - MO - US - 40.13 - -92.15 - 0 - 0 - LSX - - - ARZ014 - 40140 - Stone - AR - US - 35.91 - -92.12 - 0 - 0 - LZK - - - LAZ021 - 180210 - Caldwell - LA - US - 32.11 - -92.09 - 0 - 0 - SHV - - - LAZ044 - 180440 - Lafayette - LA - US - 30.22 - -92.09 - 0 - 0 - LCH - - - MNZ095 - 230950 - Fillmore - MN - US - 43.67 - -92.09 - 0 - 0 - ARX - - - WIZ026 - 490260 - Pepin - WI - US - 44.55 - -92.09 - 0 - 0 - MPX - - - LAZ033 - 180330 - St._Landry - LA - US - 30.58 - -92.08 - 0 - 0 - LCH - - - IAZ051 - 150510 - Benton - IA - US - 42.08 - -92.07 - 0 - 0 - DVN - - - MOZ026 - 250260 - Shelby - MO - US - 39.78 - -92.07 - 0 - 0 - LSX - - - IAZ063 - 150630 - Iowa - IA - US - 41.68 - -92.06 - 0 - 0 - DVN - - - ARZ024 - 40240 - Cleburne - AR - US - 35.54 - -92.02 - 0 - 0 - LZK - - - MOZ034 - 250340 - Monroe - MO - US - 39.50 - -92.01 - 0 - 0 - LSX - - - LAZ029 - 180290 - Avoyelles - LA - US - 31.10 - -91.97 - 0 - 0 - LCH - - - MOZ082 - 250820 - Texas - MO - US - 37.33 - -91.96 - 0 - 0 - SGF - - - IAZ087 - 150870 - Jefferson - IA - US - 41.03 - -91.95 - 0 - 0 - DVN - - - IAZ098 - 150980 - Van_Buren - IA - US - 40.75 - -91.95 - 0 - 0 - DVN - - - ARZ015 - 40150 - Izard - AR - US - 36.06 - -91.94 - 0 - 0 - LZK - - - MOZ050 - 250500 - Callaway - MO - US - 38.81 - -91.93 - 0 - 0 - LSX - - - MOZ049 - 250490 - Osage - MO - US - 38.50 - -91.92 - 0 - 0 - LSX - - - MOZ058 - 250580 - Maries - MO - US - 38.15 - -91.92 - 0 - 0 - SGF - - - WIZ001 - 490010 - Douglas - WI - US - 46.46 - -91.92 - 0 - 0 - DLH - - - LAZ024 - 180240 - Catahoula - LA - US - 31.60 - -91.91 - 0 - 0 - JAN - - - WIZ025 - 490250 - Dunn - WI - US - 44.95 - -91.91 - 0 - 0 - MPX - - - MOZ097 - 250970 - Howell - MO - US - 36.78 - -91.90 - 0 - 0 - SGF - - - ARZ045 - 40450 - Lonoke - AR - US - 34.78 - -91.88 - 0 - 0 - LZK - - - MOZ042 - 250420 - Audrain - MO - US - 39.21 - -91.87 - 0 - 0 - LSX - - - IAZ010 - 150100 - Winneshiek - IA - US - 43.29 - -91.85 - 0 - 0 - ARX - - - IAZ029 - 150290 - Fayette - IA - US - 42.86 - -91.85 - 0 - 0 - ARX - - - WIZ015 - 490150 - Barron - WI - US - 45.43 - -91.85 - 0 - 0 - MPX - - - IAZ040 - 150400 - Buchanan - IA - US - 42.47 - -91.84 - 0 - 0 - DVN - - - ARZ056 - 40560 - Jefferson - AR - US - 34.28 - -91.83 - 0 - 0 - LZK - - - LAZ053 - 180530 - Iberia - LA - US - 29.93 - -91.81 - 0 - 0 - LCH - - - WIZ032 - 490320 - Buffalo - WI - US - 44.32 - -91.81 - 0 - 0 - ARX - - - ARZ006 - 40060 - Fulton - AR - US - 36.38 - -91.80 - 0 - 0 - LZK - - - ARZ074 - 40740 - Ashley - AR - US - 33.20 - -91.79 - 0 - 0 - JAN - - - WIZ007 - 490070 - Washburn - WI - US - 45.90 - -91.79 - 0 - 0 - DLH - - - MOZ071 - 250710 - Phelps - MO - US - 37.88 - -91.78 - 0 - 0 - SGF - - - LAZ007 - 180070 - Morehouse - LA - US - 32.77 - -91.75 - 0 - 0 - JAN - - - ARZ033 - 40330 - White - AR - US - 35.28 - -91.73 - 0 - 0 - LZK - - - LAZ015 - 180150 - Richland - LA - US - 32.42 - -91.73 - 0 - 0 - JAN - - - ARZ069 - 40690 - Drew - AR - US - 33.59 - -91.72 - 0 - 0 - LZK - - - IAZ077 - 150770 - Washington - IA - US - 41.34 - -91.71 - 0 - 0 - DVN - - - MOZ010 - 250100 - Clark - MO - US - 40.43 - -91.70 - 0 - 0 - DVN - - - MOZ019 - 250190 - Lewis - MO - US - 40.10 - -91.70 - 0 - 0 - LSX - - - ARZ064 - 40640 - Lincoln - AR - US - 33.98 - -91.69 - 0 - 0 - LZK - - - MNZ088 - 230880 - Winona - MN - US - 44.02 - -91.69 - 0 - 0 - ARX - - - LAZ023 - 180230 - Franklin - LA - US - 32.14 - -91.68 - 0 - 0 - JAN - - - LAZ034 - 180340 - Pointe_Coupee - LA - US - 30.76 - -91.67 - 0 - 0 - LIX - - - LAZ045 - 180450 - Upper_St._Martin - LA - US - 30.27 - -91.67 - 0 - 0 - LCH - - - LAZ026 - 180260 - Concordia - LA - US - 31.37 - -91.61 - 0 - 0 - JAN - - - IAZ052 - 150520 - Linn - IA - US - 42.07 - -91.60 - 0 - 0 - DVN - - - IAZ064 - 150640 - Johnson - IA - US - 41.64 - -91.60 - 0 - 0 - DVN - - - MOZ027 - 250270 - Marion - MO - US - 39.80 - -91.58 - 0 - 0 - LSX - - - ARZ046 - 40460 - Prairie - AR - US - 34.79 - -91.57 - 0 - 0 - LZK - - - ARZ016 - 40160 - Independence - AR - US - 35.73 - -91.54 - 0 - 0 - LZK - - - IAZ088 - 150880 - Henry - IA - US - 40.99 - -91.54 - 0 - 0 - DVN - - - MNZ020 - 230200 - Southern_Lake/North_Shore - MN - US - 47.31 - -91.51 - 0 - 0 - DLH - - - MOZ059 - 250590 - Gasconade - MO - US - 38.44 - -91.51 - 0 - 0 - LSX - - - ARZ007 - 40070 - Sharp - AR - US - 36.19 - -91.49 - 0 - 0 - LZK - - - MOZ083 - 250830 - Dent - MO - US - 37.60 - -91.49 - 0 - 0 - SGF - - - MNZ096 - 230960 - Houston - MN - US - 43.67 - -91.48 - 0 - 0 - ARX - - - LAZ054 - 180540 - St._Mary - LA - US - 29.72 - -91.47 - 0 - 0 - LCH - - - LAZ035 - 180350 - West_Feliciana - LA - US - 30.86 - -91.46 - 0 - 0 - LIX - - - MOZ035 - 250350 - Ralls - MO - US - 39.50 - -91.46 - 0 - 0 - LSX - - - MOZ051 - 250510 - Montgomery - MO - US - 38.91 - -91.46 - 0 - 0 - LSX - - - LAZ008 - 180080 - West_Carroll - LA - US - 32.80 - -91.44 - 0 - 0 - JAN - - - IAZ099 - 150990 - Lee - IA - US - 40.59 - -91.42 - 0 - 0 - DVN - - - MNZ012 - 230120 - Northern_Cook/Northern_Lake - MN - US - 47.70 - -91.41 - 0 - 0 - DLH - - - MOZ106 - 251060 - Oregon - MO - US - 36.69 - -91.40 - 0 - 0 - SGF - - - MSZ060 - 240600 - Adams - MS - US - 31.49 - -91.40 - 0 - 0 - JAN - - - WIZ033 - 490330 - Trempealeau - WI - US - 44.29 - -91.38 - 0 - 0 - ARX - - - ARZ057 - 40570 - Arkansas - AR - US - 34.25 - -91.37 - 0 - 0 - LZK - - - IAZ041 - 150410 - Delaware - IA - US - 42.47 - -91.37 - 0 - 0 - DVN - - - LAZ046 - 180460 - Iberville - LA - US - 30.27 - -91.35 - 0 - 0 - LIX - - - MOZ098 - 250980 - Shannon - MO - US - 37.15 - -91.35 - 0 - 0 - SGF - - - IAZ011 - 150110 - Allamakee - IA - US - 43.29 - -91.34 - 0 - 0 - ARX - - - MSZ068 - 240680 - Wilkinson - MS - US - 31.19 - -91.34 - 0 - 0 - LIX - - - MOZ072 - 250720 - Crawford - MO - US - 37.95 - -91.32 - 0 - 0 - LSX - - - ARZ025 - 40250 - Jackson - AR - US - 35.63 - -91.31 - 0 - 0 - LZK - - - LAZ047 - 180470 - West_Baton_Rouge - LA - US - 30.49 - -91.31 - 0 - 0 - LIX - - - LAZ025 - 180250 - Tensas - LA - US - 32.00 - -91.30 - 0 - 0 - JAN - - - WIZ027 - 490270 - Chippewa - WI - US - 45.07 - -91.29 - 0 - 0 - MPX - - - WIZ028 - 490280 - Eau_Claire - WI - US - 44.73 - -91.29 - 0 - 0 - MPX - - - LAZ055 - 180550 - Lower_St._Martin - LA - US - 29.85 - -91.28 - 0 - 0 - LCH - - - ARZ034 - 40340 - Woodruff - AR - US - 35.18 - -91.26 - 0 - 0 - LZK - - - ARZ075 - 40750 - Chicot - AR - US - 33.29 - -91.25 - 0 - 0 - JAN - - - IAZ030 - 150300 - Clayton - IA - US - 42.86 - -91.25 - 0 - 0 - ARX - - - LAZ009 - 180090 - East_Carroll - LA - US - 32.78 - -91.23 - 0 - 0 - JAN - - - IAZ078 - 150780 - Louisa - IA - US - 41.25 - -91.22 - 0 - 0 - DVN - - - ILZ095 - 130950 - Adams - IL - US - 39.98 - -91.22 - 0 - 0 - LSX - - - ARZ047 - 40470 - Monroe - AR - US - 34.67 - -91.21 - 0 - 0 - LZK - - - ARZ065 - 40650 - Desha - AR - US - 33.82 - -91.21 - 0 - 0 - LZK - - - ILZ034 - 130340 - Hancock - IL - US - 40.42 - -91.21 - 0 - 0 - DVN - - - LAZ016 - 180160 - Madison - LA - US - 32.35 - -91.21 - 0 - 0 - JAN - - - MOZ060 - 250600 - Warren - MO - US - 38.77 - -91.19 - 0 - 0 - LSX - - - IAZ089 - 150890 - Des_Moines - IA - US - 40.89 - -91.18 - 0 - 0 - DVN - - - WIZ041 - 490410 - La_Crosse - WI - US - 43.91 - -91.17 - 0 - 0 - ARX - - - WIZ002 - 490020 - Bayfield - WI - US - 46.58 - -91.15 - 0 - 0 - DLH - - - IAZ065 - 150650 - Cedar - IA - US - 41.77 - -91.14 - 0 - 0 - DVN - - - IAZ053 - 150530 - Jones - IA - US - 42.12 - -91.13 - 0 - 0 - DVN - - - WIZ008 - 490080 - Sawyer - WI - US - 45.90 - -91.12 - 0 - 0 - DLH - - - WIZ016 - 490160 - Rusk - WI - US - 45.47 - -91.11 - 0 - 0 - MPX - - - MOZ036 - 250360 - Pike - MO - US - 39.37 - -91.10 - 0 - 0 - LSX - - - ARZ008 - 40080 - Randolph - AR - US - 36.32 - -91.08 - 0 - 0 - MEG - - - IAZ067 - 150670 - Muscatine - IA - US - 41.47 - -91.08 - 0 - 0 - DVN - - - LAZ048 - 180480 - East_Baton_Rouge - LA - US - 30.52 - -91.08 - 0 - 0 - LIX - - - LAZ036 - 180360 - East_Feliciana - LA - US - 30.83 - -91.07 - 0 - 0 - LIX - - - LAZ056 - 180560 - Assumption - LA - US - 29.86 - -91.07 - 0 - 0 - LIX - - - MOZ062 - 250620 - Franklin - MO - US - 38.45 - -91.06 - 0 - 0 - LSX - - - ARZ017 - 40170 - Lawrence - AR - US - 36.07 - -91.05 - 0 - 0 - MEG - - - MSZ059 - 240590 - Jefferson - MS - US - 31.75 - -91.05 - 0 - 0 - JAN - - - MOZ099 - 250990 - Reynolds - MO - US - 37.33 - -91.03 - 0 - 0 - LSX - - - MSZ040 - 240400 - Issaquena - MS - US - 32.73 - -91.01 - 0 - 0 - JAN - - - ILZ025 - 130250 - Henderson - IL - US - 40.85 - -91.00 - 0 - 0 - DVN - - - MSZ053 - 240530 - Claiborne - MS - US - 32.01 - -90.98 - 0 - 0 - JAN - - - ILZ097 - 130970 - Pike - IL - US - 39.62 - -90.97 - 0 - 0 - LSX - - - MOZ052 - 250520 - Lincoln - MO - US - 39.05 - -90.97 - 0 - 0 - LSX - - - MOZ107 - 251070 - Carter - MO - US - 36.96 - -90.95 - 0 - 0 - PAH - - - MSZ034 - 240340 - Washington - MS - US - 33.28 - -90.95 - 0 - 0 - JAN - - - MSZ018 - 240180 - Bolivar - MS - US - 33.83 - -90.94 - 0 - 0 - JAN - - - WIZ054 - 490540 - Crawford - WI - US - 43.21 - -90.94 - 0 - 0 - ARX - - - MSZ061 - 240610 - Franklin - MS - US - 31.47 - -90.89 - 0 - 0 - JAN - - - LAZ049 - 180490 - Ascension - LA - US - 30.21 - -90.87 - 0 - 0 - LIX - - - MOZ073 - 250730 - Washington - MO - US - 37.97 - -90.87 - 0 - 0 - LSX - - - LAZ066 - 180660 - Lower_Terrebonne - LA - US - 29.34 - -90.86 - 0 - 0 - LIX - - - MOZ108 - 251080 - Ripley - MO - US - 36.66 - -90.86 - 0 - 0 - PAH - - - MSZ047 - 240470 - Warren - MS - US - 32.34 - -90.86 - 0 - 0 - JAN - - - ARZ058 - 40580 - Phillips - AR - US - 34.39 - -90.82 - 0 - 0 - MEG - - - IAZ042 - 150420 - Dubuque - IA - US - 42.49 - -90.82 - 0 - 0 - DVN - - - LAZ065 - 180650 - Upper_Terrebonne - LA - US - 29.67 - -90.82 - 0 - 0 - LIX - - - MSZ069 - 240690 - Amite - MS - US - 31.18 - -90.82 - 0 - 0 - LIX - - - MSZ041 - 240410 - Sharkey - MS - US - 32.89 - -90.81 - 0 - 0 - JAN - - - LAZ057 - 180570 - St._James - LA - US - 30.03 - -90.80 - 0 - 0 - LIX - - - WIZ053 - 490530 - Vernon - WI - US - 43.58 - -90.79 - 0 - 0 - ARX - - - WIZ061 - 490610 - Grant - WI - US - 42.86 - -90.79 - 0 - 0 - ARX - - - ARZ035 - 40350 - Cross - AR - US - 35.30 - -90.77 - 0 - 0 - MEG - - - ARZ048 - 40480 - St._Francis - AR - US - 35.01 - -90.77 - 0 - 0 - MEG - - - ILZ024 - 130240 - Mercer - IL - US - 41.20 - -90.77 - 0 - 0 - DVN - - - ARZ049 - 40490 - Lee - AR - US - 34.77 - -90.75 - 0 - 0 - MEG - - - WIZ034 - 490340 - Jackson - WI - US - 44.33 - -90.74 - 0 - 0 - ARX - - - LAZ037 - 180370 - St._Helena - LA - US - 30.83 - -90.73 - 0 - 0 - LIX - - - ILZ096 - 130960 - Brown - IL - US - 39.98 - -90.72 - 0 - 0 - LSX - - - LAZ050 - 180500 - Livingston - LA - US - 30.42 - -90.72 - 0 - 0 - LIX - - - ILZ098 - 130980 - Calhoun - IL - US - 39.14 - -90.71 - 0 - 0 - LSX - - - ILZ035 - 130350 - McDonough - IL - US - 40.46 - -90.68 - 0 - 0 - DVN - - - MOZ084 - 250840 - Iron - MO - US - 37.51 - -90.67 - 0 - 0 - LSX - - - MSZ010 - 240100 - Coahoma - MS - US - 34.26 - -90.67 - 0 - 0 - MEG - - - ARZ026 - 40260 - Craighead - AR - US - 35.85 - -90.66 - 0 - 0 - MEG - - - ARZ027 - 40270 - Poinsett - AR - US - 35.58 - -90.66 - 0 - 0 - MEG - - - WIZ042 - 490420 - Monroe - WI - US - 43.94 - -90.64 - 0 - 0 - ARX - - - ILZ026 - 130260 - Warren - IL - US - 40.85 - -90.62 - 0 - 0 - DVN - - - MNZ021 - 230210 - Southern_Cook/North_Shore - MN - US - 47.75 - -90.62 - 0 - 0 - DLH - - - WIZ003 - 490030 - Ashland - WI - US - 46.53 - -90.62 - 0 - 0 - DLH - - - WIZ029 - 490290 - Clark - WI - US - 44.73 - -90.62 - 0 - 0 - ARX - - - IAZ068 - 150680 - Scott - IA - US - 41.61 - -90.61 - 0 - 0 - DVN - - - MSZ019 - 240190 - Sunflower - MS - US - 33.63 - -90.61 - 0 - 0 - JAN - - - ILZ040 - 130400 - Schuyler - IL - US - 40.13 - -90.57 - 0 - 0 - ILX - - - LAZ059 - 180590 - Upper_Lafourche - LA - US - 29.74 - -90.57 - 0 - 0 - LIX - - - MOZ061 - 250610 - St._Charles - MO - US - 38.75 - -90.54 - 0 - 0 - LSX - - - MOZ074 - 250740 - St._Francois - MO - US - 37.86 - -90.54 - 0 - 0 - LSX - - - MSZ035 - 240350 - Humphreys - MS - US - 33.13 - -90.53 - 0 - 0 - JAN - - - IAZ054 - 150540 - Jackson - IA - US - 42.21 - -90.52 - 0 - 0 - DVN - - - IAZ066 - 150660 - Clinton - IA - US - 41.88 - -90.52 - 0 - 0 - DVN - - - MOZ065 - 250650 - Jefferson - MO - US - 38.25 - -90.52 - 0 - 0 - LSX - - - ARZ018 - 40180 - Greene - AR - US - 36.12 - -90.51 - 0 - 0 - MEG - - - LAZ058 - 180580 - St._John_The_Baptist - LA - US - 30.09 - -90.50 - 0 - 0 - LIX - - - MSZ062 - 240620 - Lincoln - MS - US - 31.54 - -90.49 - 0 - 0 - JAN - - - WIZ017 - 490170 - Taylor - WI - US - 45.21 - -90.48 - 0 - 0 - ARX - - - ILZ049 - 130490 - Scott - IL - US - 39.66 - -90.47 - 0 - 0 - ILX - - - MOZ100 - 251000 - Wayne - MO - US - 37.12 - -90.45 - 0 - 0 - PAH - - - ARZ009 - 40090 - Clay - AR - US - 36.35 - -90.43 - 0 - 0 - MEG - - - MOZ063 - 250630 - St._Louis - MO - US - 38.64 - -90.43 - 0 - 0 - LSX - - - WIZ055 - 490550 - Richland - WI - US - 43.36 - -90.43 - 0 - 0 - ARX - - - MSZ054 - 240540 - Copiah - MS - US - 31.87 - -90.42 - 0 - 0 - JAN - - - MOZ109 - 251090 - Butler - MO - US - 36.71 - -90.41 - 0 - 0 - PAH - - - LAZ038 - 180380 - Tangipahoa - LA - US - 30.65 - -90.40 - 0 - 0 - LIX - - - MSZ070 - 240700 - Pike - MS - US - 31.18 - -90.40 - 0 - 0 - LIX - - - ILZ058 - 130580 - Greene - IL - US - 39.32 - -90.39 - 0 - 0 - LSX - - - MSZ007 - 240070 - Tunica - MS - US - 34.66 - -90.39 - 0 - 0 - MEG - - - MSZ048 - 240480 - Hinds - MS - US - 32.31 - -90.39 - 0 - 0 - JAN - - - ILZ099 - 130990 - Jersey - IL - US - 39.09 - -90.38 - 0 - 0 - LSX - - - MSZ042 - 240420 - Yazoo - MS - US - 32.77 - -90.36 - 0 - 0 - JAN - - - WIZ009 - 490090 - Price - WI - US - 45.68 - -90.36 - 0 - 0 - DLH - - - MOZ085 - 250850 - Madison - MO - US - 37.48 - -90.35 - 0 - 0 - LSX - - - LAZ060 - 180600 - St._Charles - LA - US - 29.89 - -90.34 - 0 - 0 - LIX - - - ILZ015 - 130150 - Rock_Island - IL - US - 41.56 - -90.31 - 0 - 0 - DVN - - - ILZ001 - 130010 - Jo_Daviess - IL - US - 42.35 - -90.29 - 0 - 0 - DVN - - - ILZ047 - 130470 - Cass - IL - US - 40.00 - -90.29 - 0 - 0 - ILX - - - LAZ067 - 180670 - Lower_Lafourche - LA - US - 29.31 - -90.29 - 0 - 0 - LIX - - - MSZ011 - 240110 - Quitman - MS - US - 34.30 - -90.29 - 0 - 0 - MEG - - - ARZ036 - 40360 - Crittenden - AR - US - 35.14 - -90.28 - 0 - 0 - MEG - - - ILZ050 - 130500 - Morgan - IL - US - 39.70 - -90.27 - 0 - 0 - ILX - - - MSZ025 - 240250 - Leflore - MS - US - 33.53 - -90.27 - 0 - 0 - JAN - - - MOZ064 - 250640 - St._Louis_City - MO - US - 38.65 - -90.24 - 0 - 0 - LSX - - - WIZ004 - 490040 - Iron - WI - US - 46.29 - -90.23 - 0 - 0 - DLH - - - ILZ027 - 130270 - Knox - IL - US - 40.93 - -90.22 - 0 - 0 - ILX - - - MOZ075 - 250750 - Ste._Genevieve - MO - US - 37.90 - -90.20 - 0 - 0 - LSX - - - MSZ020 - 240200 - Tallahatchie - MS - US - 33.93 - -90.19 - 0 - 0 - MEG - - - ILZ036 - 130360 - Fulton - IL - US - 40.45 - -90.16 - 0 - 0 - ILX - - - ILZ016 - 130160 - Henry - IL - US - 41.37 - -90.15 - 0 - 0 - DVN - - - ILZ102 - 131020 - Monroe - IL - US - 38.30 - -90.14 - 0 - 0 - LSX - - - LAZ061 - 180610 - Upper_Jefferson - LA - US - 29.81 - -90.14 - 0 - 0 - LIX - - - WIZ062 - 490620 - Iowa - WI - US - 43.01 - -90.13 - 0 - 0 - MKX - - - WIZ067 - 490670 - Lafayette - WI - US - 42.66 - -90.13 - 0 - 0 - MKX - - - MSZ063 - 240630 - Lawrence - MS - US - 31.55 - -90.10 - 0 - 0 - JAN - - - MSZ036 - 240360 - Holmes - MS - US - 33.13 - -90.09 - 0 - 0 - JAN - - - MSZ043 - 240430 - Madison - MS - US - 32.65 - -90.08 - 0 - 0 - JAN - - - LAZ068 - 180680 - Lower_Jefferson - LA - US - 29.56 - -90.07 - 0 - 0 - LIX - - - MSZ071 - 240710 - Walthall - MS - US - 31.18 - -90.05 - 0 - 0 - LIX - - - WIZ043 - 490430 - Juneau - WI - US - 43.95 - -90.05 - 0 - 0 - ARX - - - MOZ086 - 250860 - Bollinger - MO - US - 37.32 - -90.04 - 0 - 0 - PAH - - - LAZ039 - 180390 - Washington - LA - US - 30.84 - -90.03 - 0 - 0 - LIX - - - WIZ035 - 490350 - Wood - WI - US - 44.47 - -90.02 - 0 - 0 - GRB - - - ILZ007 - 130070 - Carroll - IL - US - 42.06 - -90.01 - 0 - 0 - DVN - - - MOZ113 - 251130 - Dunklin - MO - US - 36.31 - -90.01 - 0 - 0 - MEG - - - MSZ001 - 240010 - De_Soto - MS - US - 34.86 - -90.01 - 0 - 0 - MEG - - - ILZ101 - 131010 - St._Clair - IL - US - 38.44 - -89.99 - 0 - 0 - LSX - - - ILZ041 - 130410 - Mason - IL - US - 40.25 - -89.98 - 0 - 0 - ILX - - - MOZ110 - 251100 - Stoddard - MO - US - 36.88 - -89.98 - 0 - 0 - PAH - - - MSZ049 - 240490 - Rankin - MS - US - 32.33 - -89.98 - 0 - 0 - JAN - - - TNZ088 - 420880 - Shelby - TN - US - 35.21 - -89.97 - 0 - 0 - MEG - - - ARZ028 - 40280 - Mississippi - AR - US - 35.71 - -89.96 - 0 - 0 - MEG - - - LAZ063 - 180630 - Upper_Plaquemines - LA - US - 29.77 - -89.96 - 0 - 0 - LIX - - - MSZ012 - 240120 - Panola - MS - US - 34.36 - -89.96 - 0 - 0 - MEG - - - WIZ056 - 490560 - Sauk - WI - US - 43.40 - -89.96 - 0 - 0 - MKX - - - ILZ009 - 130090 - Whiteside - IL - US - 41.76 - -89.95 - 0 - 0 - DVN - - - MSZ008 - 240080 - Tate - MS - US - 34.67 - -89.95 - 0 - 0 - MEG - - - ILZ100 - 131000 - Madison - IL - US - 38.83 - -89.94 - 0 - 0 - LSX - - - MSZ055 - 240550 - Simpson - MS - US - 31.91 - -89.94 - 0 - 0 - JAN - - - ILZ059 - 130590 - Macoupin - IL - US - 39.26 - -89.93 - 0 - 0 - LSX - - - MSZ027 - 240270 - Carroll - MS - US - 33.45 - -89.91 - 0 - 0 - JAN - - - ILZ079 - 130790 - Randolph - IL - US - 38.01 - -89.90 - 0 - 0 - LSX - - - LAZ040 - 180400 - St._Tammany - LA - US - 30.44 - -89.89 - 0 - 0 - LIX - - - LAZ062 - 180620 - Orleans - LA - US - 30.03 - -89.88 - 0 - 0 - LIX - - - LAZ064 - 180640 - Upper_St._Bernard - LA - US - 29.91 - -89.86 - 0 - 0 - LIX - - - MSZ072 - 240720 - Marion - MS - US - 31.22 - -89.85 - 0 - 0 - JAN - - - MOZ076 - 250760 - Perry - MO - US - 37.74 - -89.83 - 0 - 0 - PAH - - - ILZ028 - 130280 - Stark - IL - US - 41.11 - -89.82 - 0 - 0 - ILX - - - MSZ026 - 240260 - Grenada - MS - US - 33.79 - -89.82 - 0 - 0 - JAN - - - TNZ049 - 420490 - Tipton - TN - US - 35.51 - -89.82 - 0 - 0 - MEG - - - WIZ044 - 490440 - Adams - WI - US - 43.95 - -89.81 - 0 - 0 - ARX - - - ILZ048 - 130480 - Menard - IL - US - 40.04 - -89.79 - 0 - 0 - ILX - - - MSZ064 - 240640 - Jefferson_Davis - MS - US - 31.59 - -89.78 - 0 - 0 - JAN - - - WIZ030 - 490300 - Marathon - WI - US - 44.90 - -89.76 - 0 - 0 - GRB - - - MOZ115 - 251150 - Pemiscot - MO - US - 36.21 - -89.75 - 0 - 0 - MEG - - - WIZ018 - 490180 - Lincoln - WI - US - 45.34 - -89.73 - 0 - 0 - GRB - - - ILZ029 - 130290 - Peoria - IL - US - 40.75 - -89.72 - 0 - 0 - ILX - - - MSZ021 - 240210 - Yalobusha - MS - US - 34.03 - -89.72 - 0 - 0 - MEG - - - MIZ009 - 220090 - Gogebic - MI - US - 46.44 - -89.70 - 0 - 0 - MQT - - - ILZ002 - 130020 - Stephenson - IL - US - 42.35 - -89.66 - 0 - 0 - DVN - - - MOZ114 - 251140 - New_Madrid - MO - US - 36.61 - -89.66 - 0 - 0 - PAH - - - MOZ087 - 250870 - Cape_Girardeau - MO - US - 37.37 - -89.65 - 0 - 0 - PAH - - - TNZ048 - 420480 - Lauderdale - TN - US - 35.75 - -89.65 - 0 - 0 - MEG - - - MSZ037 - 240370 - Attala - MS - US - 33.09 - -89.64 - 0 - 0 - JAN - - - ILZ051 - 130510 - Sangamon - IL - US - 39.75 - -89.61 - 0 - 0 - ILX - - - ILZ037 - 130370 - Tazewell - IL - US - 40.54 - -89.60 - 0 - 0 - ILX - - - WIZ068 - 490680 - Green - WI - US - 42.68 - -89.60 - 0 - 0 - MKX - - - LAZ070 - 180700 - Lower_St._Bernard - LA - US - 29.85 - -89.59 - 0 - 0 - LIX - - - MSZ077 - 240770 - Pearl_River - MS - US - 30.74 - -89.59 - 0 - 0 - LIX - - - MSZ028 - 240280 - Montgomery - MS - US - 33.49 - -89.58 - 0 - 0 - JAN - - - MSZ065 - 240650 - Covington - MS - US - 31.62 - -89.57 - 0 - 0 - JAN - - - MOZ111 - 251110 - Scott - MO - US - 37.06 - -89.55 - 0 - 0 - PAH - - - MSZ050 - 240500 - Scott - MS - US - 32.43 - -89.55 - 0 - 0 - JAN - - - WIZ010 - 490100 - Oneida - WI - US - 45.68 - -89.54 - 0 - 0 - GRB - - - MSZ056 - 240560 - Smith - MS - US - 32.01 - -89.53 - 0 - 0 - JAN - - - WIZ036 - 490360 - Portage - WI - US - 44.46 - -89.53 - 0 - 0 - GRB - - - ILZ017 - 130170 - Bureau - IL - US - 41.37 - -89.52 - 0 - 0 - DVN - - - MSZ044 - 240440 - Leake - MS - US - 32.76 - -89.52 - 0 - 0 - JAN - - - TNZ001 - 420010 - Lake - TN - US - 36.34 - -89.52 - 0 - 0 - MEG - - - MSZ073 - 240730 - Lamar - MS - US - 31.21 - -89.50 - 0 - 0 - JAN - - - MSZ080 - 240800 - Hancock - MS - US - 30.42 - -89.50 - 0 - 0 - LIX - - - LAZ069 - 180690 - Lower_Plaquemines - LA - US - 29.37 - -89.48 - 0 - 0 - LIX - - - MSZ002 - 240020 - Marshall - MS - US - 34.75 - -89.48 - 0 - 0 - MEG - - - MSZ013 - 240130 - Lafayette - MS - US - 34.37 - -89.48 - 0 - 0 - MEG - - - WIZ005 - 490050 - Vilas - WI - US - 46.08 - -89.48 - 0 - 0 - GRB - - - ILZ064 - 130640 - Bond - IL - US - 38.88 - -89.45 - 0 - 0 - LSX - - - TNZ019 - 420190 - Dyer - TN - US - 36.05 - -89.44 - 0 - 0 - MEG - - - ILZ069 - 130690 - Clinton - IL - US - 38.58 - -89.43 - 0 - 0 - LSX - - - ILZ074 - 130740 - Washington - IL - US - 38.36 - -89.43 - 0 - 0 - LSX - - - ILZ060 - 130600 - Montgomery - IL - US - 39.26 - -89.42 - 0 - 0 - LSX - - - ILZ084 - 130840 - Jackson - IL - US - 37.76 - -89.42 - 0 - 0 - PAH - - - TNZ089 - 420890 - Fayette - TN - US - 35.20 - -89.42 - 0 - 0 - MEG - - - WIZ063 - 490630 - Dane - WI - US - 43.07 - -89.42 - 0 - 0 - MKX - - - WIZ057 - 490570 - Columbia - WI - US - 43.47 - -89.39 - 0 - 0 - MKX - - - ILZ042 - 130420 - Logan - IL - US - 40.12 - -89.38 - 0 - 0 - ILX - - - WIZ046 - 490460 - Marquette - WI - US - 43.81 - -89.38 - 0 - 0 - MKX - - - MIZ002 - 220020 - Ontonagon - MI - US - 46.68 - -89.37 - 0 - 0 - MQT - - - ILZ080 - 130800 - Perry - IL - US - 38.08 - -89.36 - 0 - 0 - PAH - - - ILZ030 - 130300 - Marshall - IL - US - 41.04 - -89.35 - 0 - 0 - ILX - - - ILZ008 - 130080 - Ogle - IL - US - 42.04 - -89.32 - 0 - 0 - LOT - - - ILZ018 - 130180 - Putnam - IL - US - 41.21 - -89.32 - 0 - 0 - DVN - - - ILZ092 - 130920 - Alexander - IL - US - 37.16 - -89.32 - 0 - 0 - PAH - - - MOZ112 - 251120 - Mississippi - MO - US - 36.83 - -89.32 - 0 - 0 - PAH - - - MSZ022 - 240220 - Calhoun - MS - US - 33.95 - -89.32 - 0 - 0 - MEG - - - ILZ010 - 130100 - Lee - IL - US - 41.75 - -89.29 - 0 - 0 - LOT - - - ILZ052 - 130520 - Christian - IL - US - 39.58 - -89.29 - 0 - 0 - ILX - - - ILZ088 - 130880 - Union - IL - US - 37.47 - -89.29 - 0 - 0 - PAH - - - MSZ074 - 240740 - Forrest - MS - US - 31.18 - -89.29 - 0 - 0 - JAN - - - TNZ050 - 420500 - Haywood - TN - US - 35.61 - -89.29 - 0 - 0 - MEG - - - MSZ032 - 240320 - Choctaw - MS - US - 33.33 - -89.27 - 0 - 0 - JAN - - - MSZ029 - 240290 - Webster - MS - US - 33.60 - -89.26 - 0 - 0 - JAN - - - ILZ031 - 130310 - Woodford - IL - US - 40.76 - -89.25 - 0 - 0 - ILX - - - WIZ045 - 490450 - Waushara - WI - US - 44.11 - -89.24 - 0 - 0 - GRB - - - KYZ001 - 170010 - Fulton - KY - US - 36.58 - -89.20 - 0 - 0 - PAH - - - ILZ003 - 130030 - Winnebago - IL - US - 42.32 - -89.17 - 0 - 0 - LOT - - - MSZ003 - 240030 - Benton - MS - US - 34.80 - -89.17 - 0 - 0 - MEG - - - MSZ066 - 240660 - Jones - MS - US - 31.63 - -89.16 - 0 - 0 - JAN - - - TNZ002 - 420020 - Obion - TN - US - 36.35 - -89.14 - 0 - 0 - MEG - - - TNZ051 - 420510 - Crockett - TN - US - 35.84 - -89.13 - 0 - 0 - MEG - - - MSZ051 - 240510 - Newton - MS - US - 32.41 - -89.12 - 0 - 0 - JAN - - - MSZ045 - 240450 - Neshoba - MS - US - 32.76 - -89.11 - 0 - 0 - JAN - - - MSZ057 - 240570 - Jasper - MS - US - 32.02 - -89.11 - 0 - 0 - JAN - - - ILZ093 - 130930 - Pulaski - IL - US - 37.20 - -89.10 - 0 - 0 - PAH - - - MSZ078 - 240780 - Stone - MS - US - 30.78 - -89.10 - 0 - 0 - MOB - - - WIZ069 - 490690 - Rock - WI - US - 42.67 - -89.07 - 0 - 0 - MKX - - - MSZ038 - 240380 - Winston - MS - US - 33.11 - -89.06 - 0 - 0 - JAN - - - MSZ081 - 240810 - Harrison - MS - US - 30.44 - -89.06 - 0 - 0 - LIX - - - WIZ047 - 490470 - Green_Lake - WI - US - 43.81 - -89.06 - 0 - 0 - MKX - - - MSZ015 - 240150 - Pontotoc - MS - US - 34.23 - -89.03 - 0 - 0 - MEG - - - WIZ019 - 490190 - Langlade - WI - US - 45.25 - -89.03 - 0 - 0 - GRB - - - KYZ002 - 170020 - Hickman - KY - US - 36.65 - -89.01 - 0 - 0 - PAH - - - KYZ003 - 170030 - Carlisle - KY - US - 36.87 - -89.00 - 0 - 0 - PAH - - - KYZ004 - 170040 - Ballard - KY - US - 37.07 - -89.00 - 0 - 0 - PAH - - - ILZ053 - 130530 - Macon - IL - US - 39.86 - -88.99 - 0 - 0 - ILX - - - TNZ090 - 420900 - Hardeman - TN - US - 35.22 - -88.99 - 0 - 0 - MEG - - - ILZ065 - 130650 - Fayette - IL - US - 38.98 - -88.98 - 0 - 0 - LSX - - - MSZ014 - 240140 - Union - MS - US - 34.49 - -88.98 - 0 - 0 - MEG - - - MSZ075 - 240750 - Perry - MS - US - 31.18 - -88.98 - 0 - 0 - MOB - - - MSZ023 - 240230 - Chickasaw - MS - US - 33.91 - -88.95 - 0 - 0 - MEG - - - TNZ020 - 420200 - Gibson - TN - US - 36.01 - -88.95 - 0 - 0 - MEG - - - ILZ081 - 130810 - Franklin - IL - US - 38.00 - -88.94 - 0 - 0 - PAH - - - ILZ075 - 130750 - Jefferson - IL - US - 38.30 - -88.93 - 0 - 0 - PAH - - - ILZ085 - 130850 - Williamson - IL - US - 37.74 - -88.93 - 0 - 0 - PAH - - - ILZ070 - 130700 - Marion - IL - US - 38.65 - -88.92 - 0 - 0 - LSX - - - WIZ037 - 490370 - Waupaca - WI - US - 44.46 - -88.91 - 0 - 0 - GRB - - - MSZ004 - 240040 - Tippah - MS - US - 34.80 - -88.89 - 0 - 0 - MEG - - - ILZ019 - 130190 - La_Salle - IL - US - 41.28 - -88.88 - 0 - 0 - LOT - - - ILZ089 - 130890 - Johnson - IL - US - 37.45 - -88.88 - 0 - 0 - PAH - - - ILZ038 - 130380 - McLean - IL - US - 40.52 - -88.87 - 0 - 0 - ILX - - - ILZ043 - 130430 - De_Witt - IL - US - 40.17 - -88.87 - 0 - 0 - ILX - - - MSZ033 - 240330 - Oktibbeha - MS - US - 33.43 - -88.87 - 0 - 0 - JAN - - - MIZ001 - 220010 - Keweenaw - MI - US - 48.01 - -88.84 - 0 - 0 - MQT - - - TNZ052 - 420520 - Madison - TN - US - 35.62 - -88.84 - 0 - 0 - MEG - - - ILZ004 - 130040 - Boone - IL - US - 42.32 - -88.83 - 0 - 0 - LOT - - - MIZ084 - 220840 - Southern_Houghton - MI - US - 46.64 - -88.83 - 0 - 0 - MQT - - - ILZ061 - 130610 - Shelby - IL - US - 39.43 - -88.81 - 0 - 0 - ILX - - - ILZ011 - 130110 - DeKalb - IL - US - 41.89 - -88.77 - 0 - 0 - LOT - - - WIZ064 - 490640 - Jefferson - WI - US - 43.02 - -88.77 - 0 - 0 - MKX - - - MSZ030 - 240300 - Clay - MS - US - 33.66 - -88.75 - 0 - 0 - JAN - - - TNZ003 - 420030 - Weakley - TN - US - 36.28 - -88.73 - 0 - 0 - MEG - - - WIZ011 - 490110 - Forest - WI - US - 45.72 - -88.73 - 0 - 0 - GRB - - - WIZ020 - 490200 - Menominee - WI - US - 44.99 - -88.73 - 0 - 0 - GRB - - - WIZ031 - 490310 - Shawano - WI - US - 44.81 - -88.73 - 0 - 0 - GRB - - - ILZ094 - 130940 - Massac - IL - US - 37.20 - -88.71 - 0 - 0 - PAH - - - KYZ005 - 170050 - McCracken - KY - US - 37.08 - -88.71 - 0 - 0 - PAH - - - WIZ058 - 490580 - Dodge - WI - US - 43.42 - -88.70 - 0 - 0 - MKX - - - MSZ067 - 240670 - Wayne - MS - US - 31.66 - -88.69 - 0 - 0 - MOB - - - MSZ016 - 240160 - Lee - MS - US - 34.30 - -88.68 - 0 - 0 - MEG - - - MSZ058 - 240580 - Clarke - MS - US - 32.03 - -88.68 - 0 - 0 - JAN - - - KYZ006 - 170060 - Graves - KY - US - 36.73 - -88.66 - 0 - 0 - PAH - - - MSZ052 - 240520 - Lauderdale - MS - US - 32.40 - -88.66 - 0 - 0 - JAN - - - ILZ054 - 130540 - Moultrie - IL - US - 39.62 - -88.64 - 0 - 0 - ILX - - - MSZ079 - 240790 - George - MS - US - 30.87 - -88.64 - 0 - 0 - MOB - - - WIZ048 - 490480 - Winnebago - WI - US - 44.07 - -88.64 - 0 - 0 - GRB - - - MSZ046 - 240460 - Kemper - MS - US - 32.76 - -88.63 - 0 - 0 - JAN - - - MSZ076 - 240760 - Greene - MS - US - 31.22 - -88.63 - 0 - 0 - MOB - - - MSZ082 - 240820 - Jackson - MS - US - 30.47 - -88.63 - 0 - 0 - LIX - - - ILZ044 - 130440 - Piatt - IL - US - 40.04 - -88.61 - 0 - 0 - ILX - - - TNZ053 - 420530 - Chester - TN - US - 35.42 - -88.61 - 0 - 0 - MEG - - - ILZ032 - 130320 - Livingston - IL - US - 40.87 - -88.59 - 0 - 0 - LOT - - - ILZ066 - 130660 - Effingham - IL - US - 39.06 - -88.59 - 0 - 0 - ILX - - - MSZ005 - 240050 - Alcorn - MS - US - 34.88 - -88.58 - 0 - 0 - MEG - - - TNZ091 - 420910 - McNairy - TN - US - 35.20 - -88.58 - 0 - 0 - MEG - - - MIZ003 - 220030 - Northern_Houghton - MI - US - 47.05 - -88.57 - 0 - 0 - MQT - - - ILZ090 - 130900 - Pope - IL - US - 37.34 - -88.56 - 0 - 0 - PAH - - - MSZ039 - 240390 - Noxubee - MS - US - 33.11 - -88.56 - 0 - 0 - JAN - - - MIZ010 - 220100 - Iron - MI - US - 46.18 - -88.55 - 0 - 0 - MQT - - - ILZ082 - 130820 - Hamilton - IL - US - 38.08 - -88.54 - 0 - 0 - PAH - - - ILZ086 - 130860 - Saline - IL - US - 37.76 - -88.54 - 0 - 0 - PAH - - - WIZ070 - 490700 - Walworth - WI - US - 42.67 - -88.53 - 0 - 0 - MKX - - - MSZ009 - 240090 - Prentiss - MS - US - 34.61 - -88.52 - 0 - 0 - MEG - - - WIZ051 - 490510 - Fond_Du_Lac - WI - US - 43.74 - -88.52 - 0 - 0 - MKX - - - ILZ071 - 130710 - Clay - IL - US - 38.76 - -88.48 - 0 - 0 - ILX - - - MSZ024 - 240240 - Monroe - MS - US - 33.87 - -88.46 - 0 - 0 - MEG - - - MSZ031 - 240310 - Lowndes - MS - US - 33.52 - -88.46 - 0 - 0 - JAN - - - WIZ038 - 490380 - Outagamie - WI - US - 44.42 - -88.46 - 0 - 0 - GRB - - - ILZ005 - 130050 - McHenry - IL - US - 42.32 - -88.45 - 0 - 0 - LOT - - - ILZ020 - 130200 - Kendall - IL - US - 41.59 - -88.44 - 0 - 0 - LOT - - - TNZ021 - 420210 - Carroll - TN - US - 35.97 - -88.44 - 0 - 0 - MEG - - - ILZ012 - 130120 - Kane - IL - US - 41.94 - -88.43 - 0 - 0 - LOT - - - ILZ076 - 130760 - Wayne - IL - US - 38.43 - -88.43 - 0 - 0 - PAH - - - ILZ021 - 130210 - Grundy - IL - US - 41.29 - -88.42 - 0 - 0 - LOT - - - TNZ054 - 420540 - Henderson - TN - US - 35.62 - -88.39 - 0 - 0 - MEG - - - WIZ021 - 490210 - Northern_Oconto_County - WI - US - 45.20 - -88.39 - 0 - 0 - GRB - - - KYZ007 - 170070 - Livingston - KY - US - 37.20 - -88.38 - 0 - 0 - PAH - - - WIZ012 - 490120 - Florence - WI - US - 45.87 - -88.36 - 0 - 0 - GRB - - - MSZ017 - 240170 - Itawamba - MS - US - 34.28 - -88.35 - 0 - 0 - MEG - - - MIZ004 - 220040 - Baraga - MI - US - 46.69 - -88.33 - 0 - 0 - MQT - - - KYZ008 - 170080 - Marshall - KY - US - 36.91 - -88.31 - 0 - 0 - PAH - - - WIZ065 - 490650 - Waukesha - WI - US - 43.02 - -88.30 - 0 - 0 - MKX - - - KYZ009 - 170090 - Calloway - KY - US - 36.63 - -88.27 - 0 - 0 - PAH - - - TNZ004 - 420040 - Henry - TN - US - 36.32 - -88.26 - 0 - 0 - MEG - - - ILZ091 - 130910 - Hardin - IL - US - 37.51 - -88.25 - 0 - 0 - PAH - - - ILZ062 - 130620 - Cumberland - IL - US - 39.28 - -88.24 - 0 - 0 - ILX - - - ILZ056 - 130560 - Coles - IL - US - 39.53 - -88.22 - 0 - 0 - ILX - - - MSZ006 - 240060 - Tishomingo - MS - US - 34.73 - -88.22 - 0 - 0 - MEG - - - WIZ049 - 490490 - Calumet - WI - US - 44.07 - -88.22 - 0 - 0 - GRB - - - WIZ059 - 490590 - Washington - WI - US - 43.37 - -88.22 - 0 - 0 - MKX - - - ALZ063 - 10630 - Lower_Mobile - AL - US - 30.44 - -88.21 - 0 - 0 - MOB - - - ILZ055 - 130550 - Douglas - IL - US - 39.77 - -88.21 - 0 - 0 - ILX - - - ILZ087 - 130870 - Gallatin - IL - US - 37.75 - -88.21 - 0 - 0 - PAH - - - ALZ051 - 10510 - Choctaw - AL - US - 32.01 - -88.20 - 0 - 0 - MOB - - - ILZ039 - 130390 - Ford - IL - US - 40.70 - -88.20 - 0 - 0 - LOT - - - ILZ045 - 130450 - Champaign - IL - US - 40.14 - -88.20 - 0 - 0 - ILX - - - ALZ052 - 10520 - Washington - AL - US - 31.41 - -88.18 - 0 - 0 - MOB - - - ALZ061 - 10610 - Upper_Mobile - AL - US - 30.93 - -88.18 - 0 - 0 - MOB - - - TNZ092 - 420920 - Hardin - TN - US - 35.22 - -88.18 - 0 - 0 - MEG - - - ILZ067 - 130670 - Jasper - IL - US - 39.02 - -88.16 - 0 - 0 - ILX - - - ILZ083 - 130830 - White - IL - US - 38.08 - -88.15 - 0 - 0 - PAH - - - ALZ030 - 10300 - Sumter - AL - US - 32.65 - -88.13 - 0 - 0 - BMX - - - WIZ074 - 490740 - Southern_Oconto_County - WI - US - 44.85 - -88.12 - 0 - 0 - GRB - - - ALZ012 - 10120 - Lamar - AL - US - 33.80 - -88.11 - 0 - 0 - BMX - - - ILZ072 - 130720 - Richland - IL - US - 38.72 - -88.11 - 0 - 0 - ILX - - - TNZ055 - 420550 - Decatur - TN - US - 35.62 - -88.10 - 0 - 0 - MEG - - - WIZ013 - 490130 - Northern_Marinette_County - WI - US - 45.57 - -88.10 - 0 - 0 - GRB - - - ALZ022 - 10220 - Pickens - AL - US - 33.26 - -88.09 - 0 - 0 - BMX - - - ILZ013 - 130130 - DuPage - IL - US - 41.85 - -88.09 - 0 - 0 - LOT - - - KYZ010 - 170100 - Crittenden - KY - US - 37.34 - -88.09 - 0 - 0 - PAH - - - KYZ011 - 170110 - Lyon - KY - US - 37.03 - -88.07 - 0 - 0 - PAH - - - TNZ022 - 420220 - Benton - TN - US - 36.09 - -88.07 - 0 - 0 - OHX - - - ILZ077 - 130770 - Edwards - IL - US - 38.42 - -88.05 - 0 - 0 - PAH - - - WIZ072 - 490720 - Kenosha - WI - US - 42.58 - -88.05 - 0 - 0 - MKX - - - WIZ071 - 490710 - Racine - WI - US - 42.73 - -88.03 - 0 - 0 - MKX - - - WIZ039 - 490390 - Brown - WI - US - 44.46 - -87.99 - 0 - 0 - GRB - - - ILZ006 - 130060 - Lake - IL - US - 42.32 - -87.98 - 0 - 0 - LOT - - - ALZ031 - 10310 - Greene - AL - US - 32.84 - -87.96 - 0 - 0 - BMX - - - KYZ014 - 170140 - Union - KY - US - 37.69 - -87.95 - 0 - 0 - PAH - - - WIZ066 - 490660 - Milwaukee - WI - US - 43.02 - -87.94 - 0 - 0 - MKX - - - WIZ073 - 490730 - Southern_Marinette_County - WI - US - 45.18 - -87.94 - 0 - 0 - GRB - - - WIZ052 - 490520 - Sheboygan - WI - US - 43.72 - -87.93 - 0 - 0 - MKX - - - ALZ011 - 10110 - Marion - AL - US - 34.12 - -87.92 - 0 - 0 - BMX - - - KYZ012 - 170120 - Trigg - KY - US - 36.83 - -87.92 - 0 - 0 - PAH - - - WIZ060 - 490600 - Ozaukee - WI - US - 43.37 - -87.92 - 0 - 0 - MKX - - - ILZ014 - 130140 - Cook - IL - US - 41.81 - -87.90 - 0 - 0 - LOT - - - ILZ022 - 130220 - Will - IL - US - 41.47 - -87.90 - 0 - 0 - LOT - - - INZ085 - 140850 - Posey - IN - US - 38.01 - -87.90 - 0 - 0 - PAH - - - ILZ023 - 130230 - Kankakee - IL - US - 41.15 - -87.89 - 0 - 0 - LOT - - - KYZ013 - 170130 - Caldwell - KY - US - 37.17 - -87.89 - 0 - 0 - PAH - - - MIZ011 - 220110 - Dickinson - MI - US - 45.99 - -87.87 - 0 - 0 - MQT - - - ALZ003 - 10030 - Franklin - AL - US - 34.45 - -87.85 - 0 - 0 - HUN - - - TNZ056 - 420560 - Perry - TN - US - 35.64 - -87.85 - 0 - 0 - OHX - - - ALZ053 - 10530 - Clarke - AL - US - 31.60 - -87.84 - 0 - 0 - MOB - - - ILZ033 - 130330 - Iroquois - IL - US - 40.75 - -87.83 - 0 - 0 - LOT - - - TNZ005 - 420050 - Stewart - TN - US - 36.50 - -87.83 - 0 - 0 - OHX - - - ILZ078 - 130780 - Wabash - IL - US - 38.41 - -87.82 - 0 - 0 - PAH - - - TNZ093 - 420930 - Wayne - TN - US - 35.26 - -87.80 - 0 - 0 - OHX - - - ALZ039 - 10390 - Marengo - AL - US - 32.27 - -87.79 - 0 - 0 - BMX - - - ALZ002 - 10020 - Colbert - AL - US - 34.74 - -87.78 - 0 - 0 - HUN - - - ILZ063 - 130630 - Clark - IL - US - 39.33 - -87.78 - 0 - 0 - ILX - - - TNZ024 - 420240 - Humphreys - TN - US - 36.03 - -87.77 - 0 - 0 - OHX - - - WIZ050 - 490500 - Manitowoc - WI - US - 44.11 - -87.77 - 0 - 0 - GRB - - - ILZ057 - 130570 - Edgar - IL - US - 39.68 - -87.75 - 0 - 0 - ILX - - - TNZ023 - 420230 - Houston - TN - US - 36.28 - -87.75 - 0 - 0 - OHX - - - ILZ046 - 130460 - Vermilion - IL - US - 40.19 - -87.74 - 0 - 0 - ILX - - - ILZ068 - 130680 - Crawford - IL - US - 39.02 - -87.74 - 0 - 0 - ILX - - - ALZ062 - 10620 - Upper_Baldwin - AL - US - 31.01 - -87.72 - 0 - 0 - MOB - - - ILZ073 - 130730 - Lawrence - IL - US - 38.72 - -87.71 - 0 - 0 - ILX - - - ALZ001 - 10010 - Lauderdale - AL - US - 34.88 - -87.70 - 0 - 0 - HUN - - - ALZ064 - 10640 - Lower_Baldwin - AL - US - 30.45 - -87.70 - 0 - 0 - MOB - - - ALZ013 - 10130 - Fayette - AL - US - 33.73 - -87.68 - 0 - 0 - BMX - - - KYZ015 - 170150 - Webster - KY - US - 37.50 - -87.66 - 0 - 0 - PAH - - - INZ081 - 140810 - Gibson - IN - US - 38.35 - -87.65 - 0 - 0 - PAH - - - ALZ032 - 10320 - Hale - AL - US - 32.75 - -87.64 - 0 - 0 - BMX - - - KYZ018 - 170180 - Henderson - KY - US - 37.81 - -87.61 - 0 - 0 - PAH - - - MIZ005 - 220050 - Marquette - MI - US - 46.48 - -87.61 - 0 - 0 - MQT - - - INZ086 - 140860 - Vanderburgh - IN - US - 38.00 - -87.58 - 0 - 0 - PAH - - - KYZ016 - 170160 - Hopkins - KY - US - 37.34 - -87.58 - 0 - 0 - PAH - - - MIZ012 - 220120 - Menominee - MI - US - 45.55 - -87.57 - 0 - 0 - MQT - - - WIZ040 - 490400 - Kewaunee - WI - US - 44.50 - -87.57 - 0 - 0 - GRB - - - KYZ017 - 170170 - Christian - KY - US - 36.90 - -87.50 - 0 - 0 - PAH - - - TNZ058 - 420580 - Lewis - TN - US - 35.53 - -87.49 - 0 - 0 - OHX - - - TNZ057 - 420570 - Hickman - TN - US - 35.81 - -87.47 - 0 - 0 - OHX - - - INZ060 - 140600 - Sullivan - IN - US - 39.08 - -87.46 - 0 - 0 - IND - - - ALZ023 - 10230 - Tuscaloosa - AL - US - 33.32 - -87.45 - 0 - 0 - BMX - - - INZ043 - 140430 - Vermillion - IN - US - 39.89 - -87.45 - 0 - 0 - IND - - - INZ067 - 140670 - Knox - IN - US - 38.66 - -87.43 - 0 - 0 - IND - - - INZ051 - 140510 - Vigo - IN - US - 39.43 - -87.42 - 0 - 0 - IND - - - FLZ001 - 90010 - Inland_Escambia - FL - US - 30.86 - -87.40 - 0 - 0 - MOB - - - INZ010 - 140100 - Newton - IN - US - 40.98 - -87.40 - 0 - 0 - LOT - - - TNZ094 - 420940 - Lawrence - TN - US - 35.24 - -87.40 - 0 - 0 - OHX - - - INZ001 - 140010 - Lake - IN - US - 41.44 - -87.38 - 0 - 0 - LOT - - - TNZ006 - 420060 - Montgomery - TN - US - 36.49 - -87.38 - 0 - 0 - OHX - - - ALZ014 - 10140 - Winston - AL - US - 34.15 - -87.37 - 0 - 0 - BMX - - - ALZ055 - 10550 - Monroe - AL - US - 31.54 - -87.35 - 0 - 0 - MOB - - - TNZ025 - 420250 - Dickson - TN - US - 36.15 - -87.35 - 0 - 0 - OHX - - - ALZ004 - 10040 - Lawrence - AL - US - 34.56 - -87.32 - 0 - 0 - HUN - - - INZ019 - 140190 - Benton - IN - US - 40.61 - -87.32 - 0 - 0 - LOT - - - INZ028 - 140280 - Warren - IN - US - 40.31 - -87.32 - 0 - 0 - IND - - - ALZ015 - 10150 - Walker - AL - US - 33.76 - -87.30 - 0 - 0 - BMX - - - INZ082 - 140820 - Pike - IN - US - 38.39 - -87.28 - 0 - 0 - PAH - - - KYZ020 - 170200 - McLean - KY - US - 37.54 - -87.28 - 0 - 0 - PAH - - - ALZ033 - 10330 - Perry - AL - US - 32.59 - -87.27 - 0 - 0 - BMX - - - INZ035 - 140350 - Fountain - IN - US - 40.17 - -87.27 - 0 - 0 - IND - - - WIZ022 - 490220 - Door - WI - US - 45.05 - -87.27 - 0 - 0 - GRB - - - ALZ054 - 10540 - Wilcox - AL - US - 32.05 - -87.26 - 0 - 0 - MOB - - - INZ087 - 140870 - Warrick - IN - US - 38.06 - -87.25 - 0 - 0 - PAH - - - INZ044 - 140440 - Parke - IN - US - 39.79 - -87.23 - 0 - 0 - IND - - - FLZ002 - 90020 - Coastal_Escambia - FL - US - 30.50 - -87.20 - 0 - 0 - MOB - - - KYZ022 - 170220 - Todd - KY - US - 36.86 - -87.20 - 0 - 0 - PAH - - - ALZ059 - 10590 - Escambia - AL - US - 31.13 - -87.16 - 0 - 0 - MOB - - - ALZ034 - 10340 - Bibb - AL - US - 33.04 - -87.15 - 0 - 0 - BMX - - - ALZ040 - 10400 - Dallas - AL - US - 32.38 - -87.14 - 0 - 0 - BMX - - - KYZ021 - 170210 - Muhlenberg - KY - US - 37.23 - -87.14 - 0 - 0 - PAH - - - KYZ019 - 170190 - Daviess - KY - US - 37.75 - -87.12 - 0 - 0 - PAH - - - INZ011 - 140110 - Jasper - IN - US - 41.01 - -87.11 - 0 - 0 - LOT - - - INZ052 - 140520 - Clay - IN - US - 39.39 - -87.10 - 0 - 0 - IND - - - INZ068 - 140680 - Daviess - IN - US - 38.70 - -87.10 - 0 - 0 - IND - - - TNZ026 - 420260 - Cheatham - TN - US - 36.26 - -87.09 - 0 - 0 - OHX - - - INZ002 - 140020 - Porter - IN - US - 41.47 - -87.08 - 0 - 0 - LOT - - - TNZ060 - 420600 - Maury - TN - US - 35.64 - -87.07 - 0 - 0 - OHX - - - ALZ056 - 10560 - Conecuh - AL - US - 31.47 - -87.04 - 0 - 0 - MOB - - - FLZ003 - 90030 - Inland_Santa_Rosa - FL - US - 30.86 - -87.04 - 0 - 0 - MOB - - - ALZ005 - 10050 - Limestone - AL - US - 34.78 - -87.02 - 0 - 0 - HUN - - - INZ088 - 140880 - Spencer - IN - US - 37.99 - -87.02 - 0 - 0 - PAH - - - TNZ095 - 420950 - Giles - TN - US - 35.23 - -87.02 - 0 - 0 - OHX - - - INZ061 - 140610 - Greene - IN - US - 39.03 - -86.98 - 0 - 0 - IND - - - ALZ024 - 10240 - Jefferson - AL - US - 33.55 - -86.93 - 0 - 0 - BMX - - - MIZ013 - 220130 - Delta - MI - US - 45.82 - -86.91 - 0 - 0 - MQT - - - TNZ059 - 420590 - Williamson - TN - US - 35.88 - -86.91 - 0 - 0 - OHX - - - INZ029 - 140290 - Tippecanoe - IN - US - 40.40 - -86.90 - 0 - 0 - IND - - - INZ036 - 140360 - Montgomery - IN - US - 40.05 - -86.90 - 0 - 0 - IND - - - FLZ004 - 90040 - Coastal_Santa_Rosa - FL - US - 30.53 - -86.89 - 0 - 0 - MOB - - - INZ083 - 140830 - Dubois - IN - US - 38.36 - -86.88 - 0 - 0 - LMK - - - KYZ026 - 170260 - Ohio - KY - US - 37.48 - -86.86 - 0 - 0 - LMK - - - INZ053 - 140530 - Owen - IN - US - 39.31 - -86.85 - 0 - 0 - IND - - - KYZ070 - 170700 - Logan - KY - US - 36.86 - -86.85 - 0 - 0 - LMK - - - INZ020 - 140200 - White - IN - US - 40.75 - -86.84 - 0 - 0 - IWX - - - ALZ007 - 10070 - Morgan - AL - US - 34.50 - -86.83 - 0 - 0 - HUN - - - INZ045 - 140450 - Putnam - IN - US - 39.67 - -86.83 - 0 - 0 - IND - - - TNZ007 - 420070 - Robertson - TN - US - 36.50 - -86.82 - 0 - 0 - OHX - - - INZ069 - 140690 - Martin - IN - US - 38.70 - -86.81 - 0 - 0 - IND - - - KYZ023 - 170230 - Hancock - KY - US - 37.83 - -86.81 - 0 - 0 - LMK - - - ALZ016 - 10160 - Cullman - AL - US - 34.09 - -86.78 - 0 - 0 - HUN - - - TNZ027 - 420270 - Davidson - TN - US - 36.19 - -86.78 - 0 - 0 - OHX - - - TNZ061 - 420610 - Marshall - TN - US - 35.49 - -86.77 - 0 - 0 - OHX - - - INZ003 - 140030 - La_Porte - IN - US - 41.50 - -86.71 - 0 - 0 - IWX - - - ALZ035 - 10350 - Chilton - AL - US - 32.87 - -86.70 - 0 - 0 - BMX - - - INZ012 - 140120 - Starke - IN - US - 41.31 - -86.70 - 0 - 0 - IWX - - - INZ013 - 140130 - Pulaski - IN - US - 41.05 - -86.70 - 0 - 0 - IWX - - - ALZ025 - 10250 - Shelby - AL - US - 33.29 - -86.68 - 0 - 0 - BMX - - - ALZ057 - 10570 - Butler - AL - US - 31.75 - -86.68 - 0 - 0 - MOB - - - KYZ061 - 170610 - Butler - KY - US - 37.20 - -86.67 - 0 - 0 - LMK - - - ALZ041 - 10410 - Autauga - AL - US - 32.52 - -86.66 - 0 - 0 - BMX - - - ALZ042 - 10420 - Lowndes - AL - US - 32.19 - -86.66 - 0 - 0 - BMX - - - ALZ017 - 10170 - Blount - AL - US - 34.01 - -86.64 - 0 - 0 - BMX - - - INZ089 - 140890 - Perry - IN - US - 38.05 - -86.63 - 0 - 0 - LMK - - - FLZ006 - 90060 - Coastal_Okaloosa - FL - US - 30.55 - -86.59 - 0 - 0 - MOB - - - KYZ072 - 170720 - Simpson - KY - US - 36.77 - -86.59 - 0 - 0 - LMK - - - FLZ005 - 90050 - Inland_Okaloosa - FL - US - 30.86 - -86.58 - 0 - 0 - MOB - - - INZ021 - 140210 - Carroll - IN - US - 40.59 - -86.57 - 0 - 0 - IND - - - TNZ096 - 420960 - Lincoln - TN - US - 35.19 - -86.57 - 0 - 0 - HUN - - - MIZ077 - 220770 - Berrien - MI - US - 42.01 - -86.53 - 0 - 0 - IWX - - - ALZ006 - 10060 - Madison - AL - US - 34.74 - -86.52 - 0 - 0 - HUN - - - INZ046 - 140460 - Hendricks - IN - US - 39.77 - -86.52 - 0 - 0 - IND - - - INZ062 - 140620 - Monroe - IN - US - 39.16 - -86.52 - 0 - 0 - IND - - - INZ076 - 140760 - Orange - IN - US - 38.54 - -86.50 - 0 - 0 - LMK - - - INZ070 - 140700 - Lawrence - IN - US - 38.84 - -86.49 - 0 - 0 - IND - - - INZ037 - 140370 - Boone - IN - US - 40.06 - -86.48 - 0 - 0 - IND - - - INZ054 - 140540 - Morgan - IN - US - 39.48 - -86.48 - 0 - 0 - IND - - - MIZ006 - 220060 - Alger - MI - US - 46.43 - -86.48 - 0 - 0 - MQT - - - TNZ008 - 420080 - Sumner - TN - US - 36.45 - -86.48 - 0 - 0 - OHX - - - INZ030 - 140300 - Clinton - IN - US - 40.31 - -86.47 - 0 - 0 - IND - - - INZ084 - 140840 - Crawford - IN - US - 38.26 - -86.46 - 0 - 0 - LMK - - - TNZ075 - 420750 - Bedford - TN - US - 35.52 - -86.45 - 0 - 0 - OHX - - - ALZ060 - 10600 - Covington - AL - US - 31.26 - -86.44 - 0 - 0 - MOB - - - KYZ024 - 170240 - Breckinridge - KY - US - 37.81 - -86.42 - 0 - 0 - LMK - - - TNZ062 - 420620 - Rutherford - TN - US - 35.86 - -86.41 - 0 - 0 - OHX - - - KYZ071 - 170710 - Warren - KY - US - 36.99 - -86.40 - 0 - 0 - LMK - - - INZ022 - 140220 - Cass - IN - US - 40.75 - -86.38 - 0 - 0 - IWX - - - TNZ076 - 420760 - Moore - TN - US - 35.28 - -86.38 - 0 - 0 - HUN - - - KYZ027 - 170270 - Grayson - KY - US - 37.47 - -86.35 - 0 - 0 - LMK - - - ALZ008 - 10080 - Marshall - AL - US - 34.36 - -86.32 - 0 - 0 - HUN - - - ALZ058 - 10580 - Crenshaw - AL - US - 31.75 - -86.32 - 0 - 0 - MOB - - - ALZ026 - 10260 - St._Clair - AL - US - 33.69 - -86.31 - 0 - 0 - BMX - - - INZ004 - 140040 - St._Joseph - IN - US - 41.60 - -86.30 - 0 - 0 - IWX - - - MIZ043 - 220430 - Oceana - MI - US - 43.64 - -86.29 - 0 - 0 - GRR - - - TNZ028 - 420280 - Wilson - TN - US - 36.15 - -86.29 - 0 - 0 - OHX - - - MIZ037 - 220370 - Mason - MI - US - 44.00 - -86.28 - 0 - 0 - GRR - - - ALZ036 - 10360 - Coosa - AL - US - 32.93 - -86.27 - 0 - 0 - BMX - - - INZ014 - 140140 - Marshall - IN - US - 41.33 - -86.27 - 0 - 0 - IWX - - - KYZ062 - 170620 - Edmonson - KY - US - 37.20 - -86.27 - 0 - 0 - LMK - - - INZ063 - 140630 - Brown - IN - US - 39.19 - -86.24 - 0 - 0 - IND - - - KYZ025 - 170250 - Meade - KY - US - 38.00 - -86.24 - 0 - 0 - LMK - - - MIZ085 - 220850 - Northern_Schoolcraft - MI - US - 46.33 - -86.23 - 0 - 0 - MQT - - - ALZ044 - 10440 - Montgomery - AL - US - 32.24 - -86.21 - 0 - 0 - BMX - - - FLZ007 - 90070 - Inland_Walton - FL - US - 30.85 - -86.21 - 0 - 0 - TAE - - - INZ015 - 140150 - Fulton - IN - US - 41.05 - -86.21 - 0 - 0 - IWX - - - KYZ073 - 170730 - Allen - KY - US - 36.78 - -86.19 - 0 - 0 - LMK - - - MIZ014 - 220140 - Southern_Schoolcraft - MI - US - 46.00 - -86.17 - 0 - 0 - MQT - - - ALZ027 - 10270 - Talladega - AL - US - 33.40 - -86.15 - 0 - 0 - BMX - - - ALZ043 - 10430 - Elmore - AL - US - 32.59 - -86.14 - 0 - 0 - BMX - - - INZ047 - 140470 - Marion - IN - US - 39.78 - -86.14 - 0 - 0 - IND - - - INZ090 - 140900 - Harrison - IN - US - 38.19 - -86.13 - 0 - 0 - LMK - - - MIZ050 - 220500 - Muskegon - MI - US - 43.30 - -86.13 - 0 - 0 - GRR - - - TNZ029 - 420290 - Trousdale - TN - US - 36.40 - -86.13 - 0 - 0 - OHX - - - FLZ008 - 90080 - Coastal_Walton - FL - US - 30.49 - -86.12 - 0 - 0 - TAE - - - INZ031 - 140310 - Howard - IN - US - 40.48 - -86.12 - 0 - 0 - IND - - - INZ055 - 140550 - Johnson - IN - US - 39.49 - -86.11 - 0 - 0 - IND - - - MIZ031 - 220310 - Manistee - MI - US - 44.35 - -86.10 - 0 - 0 - APX - - - TNZ097 - 420970 - Franklin - TN - US - 35.18 - -86.10 - 0 - 0 - HUN - - - INZ077 - 140770 - Washington - IN - US - 38.60 - -86.09 - 0 - 0 - LMK - - - INZ071 - 140710 - Jackson - IN - US - 38.90 - -86.07 - 0 - 0 - IND - - - MIZ071 - 220710 - Van_Buren - MI - US - 42.25 - -86.07 - 0 - 0 - GRR - - - TNZ077 - 420770 - Coffee - TN - US - 35.50 - -86.07 - 0 - 0 - OHX - - - INZ039 - 140390 - Hamilton - IN - US - 40.08 - -86.06 - 0 - 0 - IND - - - ALZ018 - 10180 - Etowah - AL - US - 34.03 - -86.05 - 0 - 0 - BMX - - - INZ038 - 140380 - Tipton - IN - US - 40.32 - -86.05 - 0 - 0 - IND - - - TNZ063 - 420630 - Cannon - TN - US - 35.81 - -86.05 - 0 - 0 - OHX - - - MIZ025 - 220250 - Benzie - MI - US - 44.65 - -86.04 - 0 - 0 - APX - - - MIZ056 - 220560 - Ottawa - MI - US - 42.99 - -86.03 - 0 - 0 - GRR - - - INZ023 - 140230 - Miami - IN - US - 40.79 - -86.02 - 0 - 0 - IWX - - - MIZ078 - 220780 - Cass - MI - US - 41.92 - -86.00 - 0 - 0 - IWX - - - TNZ009 - 420090 - Macon - TN - US - 36.53 - -86.00 - 0 - 0 - OHX - - - ALZ065 - 10650 - Coffee - AL - US - 31.41 - -85.99 - 0 - 0 - TAE - - - KYZ028 - 170280 - Hardin - KY - US - 37.72 - -85.98 - 0 - 0 - LMK - - - ALZ009 - 10090 - Jackson - AL - US - 34.74 - -85.97 - 0 - 0 - HUN - - - KYZ074 - 170740 - Barren - KY - US - 36.95 - -85.96 - 0 - 0 - LMK - - - TNZ030 - 420300 - Smith - TN - US - 36.26 - -85.96 - 0 - 0 - OHX - - - ALZ049 - 10490 - Pike - AL - US - 31.85 - -85.93 - 0 - 0 - BMX - - - ALZ028 - 10280 - Clay - AL - US - 33.30 - -85.91 - 0 - 0 - BMX - - - KYZ063 - 170630 - Hart - KY - US - 37.30 - -85.91 - 0 - 0 - LMK - - - MIZ064 - 220640 - Allegan - MI - US - 42.60 - -85.91 - 0 - 0 - GRR - - - INZ064 - 140640 - Bartholomew - IN - US - 39.19 - -85.90 - 0 - 0 - IND - - - INZ091 - 140910 - Floyd - IN - US - 38.30 - -85.90 - 0 - 0 - LMK - - - INZ016 - 140160 - Kosciusko - IN - US - 41.25 - -85.87 - 0 - 0 - IWX - - - INZ005 - 140050 - Elkhart - IN - US - 41.60 - -85.86 - 0 - 0 - IWX - - - TNZ064 - 420640 - DeKalb - TN - US - 35.98 - -85.84 - 0 - 0 - OHX - - - ALZ019 - 10190 - Calhoun - AL - US - 33.76 - -85.83 - 0 - 0 - BMX - - - ALZ068 - 10680 - Geneva - AL - US - 31.10 - -85.83 - 0 - 0 - TAE - - - ALZ010 - 10100 - De_Kalb - AL - US - 34.53 - -85.82 - 0 - 0 - HUN - - - ALZ037 - 10370 - Tallapoosa - AL - US - 32.81 - -85.80 - 0 - 0 - BMX - - - INZ024 - 140240 - Wabash - IN - US - 40.85 - -85.80 - 0 - 0 - IWX - - - INZ056 - 140560 - Shelby - IN - US - 39.52 - -85.80 - 0 - 0 - IND - - - MIZ038 - 220380 - Lake - MI - US - 43.99 - -85.80 - 0 - 0 - GRR - - - MIZ044 - 220440 - Newaygo - MI - US - 43.56 - -85.80 - 0 - 0 - GRR - - - FLZ009 - 90090 - Holmes - FL - US - 30.86 - -85.77 - 0 - 0 - TAE - - - INZ048 - 140480 - Hancock - IN - US - 39.83 - -85.77 - 0 - 0 - IND - - - TNZ078 - 420780 - Warren - TN - US - 35.68 - -85.77 - 0 - 0 - OHX - - - INZ078 - 140780 - Scott - IN - US - 38.69 - -85.74 - 0 - 0 - LMK - - - ALZ045 - 10450 - Macon - AL - US - 32.42 - -85.72 - 0 - 0 - BMX - - - INZ040 - 140400 - Madison - IN - US - 40.17 - -85.72 - 0 - 0 - IND - - - ALZ046 - 10460 - Bullock - AL - US - 32.10 - -85.71 - 0 - 0 - BMX - - - FLZ010 - 90100 - Washington - FL - US - 30.62 - -85.71 - 0 - 0 - TAE - - - INZ092 - 140920 - Clark - IN - US - 38.44 - -85.71 - 0 - 0 - LMK - - - KYZ075 - 170750 - Monroe - KY - US - 36.73 - -85.71 - 0 - 0 - LMK - - - MIZ020 - 220200 - Leelanau - MI - US - 44.99 - -85.71 - 0 - 0 - APX - - - KYZ029 - 170290 - Bullitt - KY - US - 37.97 - -85.70 - 0 - 0 - LMK - - - TNZ079 - 420790 - Grundy - TN - US - 35.38 - -85.70 - 0 - 0 - OHX - - - KYZ030 - 170300 - Jefferson - KY - US - 38.19 - -85.69 - 0 - 0 - LMK - - - KYZ053 - 170530 - Larue - KY - US - 37.57 - -85.69 - 0 - 0 - LMK - - - FLZ012 - 90120 - Bay - FL - US - 30.31 - -85.68 - 0 - 0 - TAE - - - TNZ031 - 420310 - Jackson - TN - US - 36.37 - -85.67 - 0 - 0 - OHX - - - INZ032 - 140320 - Grant - IN - US - 40.53 - -85.66 - 0 - 0 - IWX - - - INZ072 - 140720 - Jennings - IN - US - 39.00 - -85.63 - 0 - 0 - IND - - - ALZ020 - 10200 - Cherokee - AL - US - 34.23 - -85.62 - 0 - 0 - BMX - - - KYZ076 - 170760 - Metcalfe - KY - US - 37.01 - -85.62 - 0 - 0 - LMK - - - TNZ098 - 420980 - Marion - TN - US - 35.16 - -85.62 - 0 - 0 - MRX - - - ALZ066 - 10660 - Dale - AL - US - 31.41 - -85.61 - 0 - 0 - TAE - - - ALZ021 - 10210 - Cleburne - AL - US - 33.72 - -85.60 - 0 - 0 - BMX - - - MIZ026 - 220260 - Grand_Traverse - MI - US - 44.75 - -85.58 - 0 - 0 - APX - - - MIZ032 - 220320 - Wexford - MI - US - 44.34 - -85.58 - 0 - 0 - APX - - - MIZ057 - 220570 - Kent - MI - US - 43.03 - -85.56 - 0 - 0 - GRR - - - MIZ079 - 220790 - St._Joseph - MI - US - 41.92 - -85.55 - 0 - 0 - IWX - - - MIZ007 - 220070 - Luce - MI - US - 46.50 - -85.54 - 0 - 0 - MQT - - - TNZ010 - 420100 - Clay - TN - US - 36.52 - -85.54 - 0 - 0 - OHX - - - KYZ064 - 170640 - Green - KY - US - 37.29 - -85.53 - 0 - 0 - LMK - - - MIZ072 - 220720 - Kalamazoo - MI - US - 42.25 - -85.53 - 0 - 0 - GRR - - - INZ017 - 140170 - Whitley - IN - US - 41.15 - -85.50 - 0 - 0 - IWX - - - INZ065 - 140650 - Decatur - IN - US - 39.29 - -85.50 - 0 - 0 - IND - - - INZ025 - 140250 - Huntington - IN - US - 40.84 - -85.49 - 0 - 0 - IWX - - - GAZ001 - 100010 - Dade - GA - US - 34.81 - -85.48 - 0 - 0 - FFC - - - INZ057 - 140570 - Rush - IN - US - 39.62 - -85.48 - 0 - 0 - IND - - - KYZ031 - 170310 - Oldham - KY - US - 38.42 - -85.47 - 0 - 0 - LMK - - - INZ079 - 140790 - Jefferson - IN - US - 38.75 - -85.45 - 0 - 0 - LMK - - - KYZ045 - 170450 - Nelson - KY - US - 37.76 - -85.45 - 0 - 0 - LMK - - - TNZ032 - 420320 - Putnam - TN - US - 36.15 - -85.45 - 0 - 0 - OHX - - - ALZ029 - 10290 - Randolph - AL - US - 33.31 - -85.44 - 0 - 0 - BMX - - - TNZ065 - 420650 - White - TN - US - 35.94 - -85.44 - 0 - 0 - OHX - - - INZ006 - 140060 - Lagrange - IN - US - 41.65 - -85.43 - 0 - 0 - IWX - - - INZ008 - 140080 - Noble - IN - US - 41.41 - -85.43 - 0 - 0 - IWX - - - TNZ080 - 420800 - Van_Buren - TN - US - 35.69 - -85.43 - 0 - 0 - OHX - - - KYZ081 - 170810 - Cumberland - KY - US - 36.78 - -85.42 - 0 - 0 - LMK - - - TNZ081 - 420810 - Sequatchie - TN - US - 35.36 - -85.42 - 0 - 0 - MRX - - - ALZ050 - 10500 - Barbour - AL - US - 31.89 - -85.40 - 0 - 0 - BMX - - - INZ041 - 140410 - Delaware - IN - US - 40.24 - -85.40 - 0 - 0 - IND - - - INZ049 - 140490 - Henry - IN - US - 39.94 - -85.40 - 0 - 0 - IND - - - ALZ038 - 10380 - Chambers - AL - US - 32.93 - -85.36 - 0 - 0 - BMX - - - ALZ069 - 10690 - Houston - AL - US - 31.16 - -85.35 - 0 - 0 - TAE - - - ALZ047 - 10470 - Lee - AL - US - 32.58 - -85.34 - 0 - 0 - BMX - - - KYZ065 - 170650 - Taylor - KY - US - 37.33 - -85.34 - 0 - 0 - LMK - - - MIZ039 - 220390 - Osceola - MI - US - 43.99 - -85.33 - 0 - 0 - GRR - - - MIZ045 - 220450 - Mecosta - MI - US - 43.64 - -85.33 - 0 - 0 - GRR - - - INZ033 - 140330 - Blackford - IN - US - 40.49 - -85.32 - 0 - 0 - IWX - - - GAZ011 - 100110 - Chattooga - GA - US - 34.44 - -85.31 - 0 - 0 - FFC - - - KYZ032 - 170320 - Trimble - KY - US - 38.62 - -85.31 - 0 - 0 - LMK - - - KYZ038 - 170380 - Spencer - KY - US - 38.05 - -85.31 - 0 - 0 - LMK - - - MIZ065 - 220650 - Barry - MI - US - 42.60 - -85.31 - 0 - 0 - GRR - - - GAZ002 - 100020 - Walker - GA - US - 34.79 - -85.29 - 0 - 0 - FFC - - - KYZ077 - 170770 - Adair - KY - US - 37.12 - -85.29 - 0 - 0 - LMK - - - KYZ054 - 170540 - Marion - KY - US - 37.57 - -85.28 - 0 - 0 - LMK - - - TNZ033 - 420330 - Overton - TN - US - 36.35 - -85.28 - 0 - 0 - OHX - - - INZ073 - 140730 - Ripley - IN - US - 39.11 - -85.27 - 0 - 0 - ILN - - - INZ026 - 140260 - Wells - IN - US - 40.76 - -85.26 - 0 - 0 - IWX - - - ALZ067 - 10670 - Henry - AL - US - 31.55 - -85.23 - 0 - 0 - TAE - - - FLZ011 - 90110 - Jackson - FL - US - 30.79 - -85.23 - 0 - 0 - TAE - - - GAZ019 - 100190 - Floyd - GA - US - 34.34 - -85.23 - 0 - 0 - FFC - - - FLZ014 - 90140 - Gulf - FL - US - 29.94 - -85.22 - 0 - 0 - TAE - - - KYZ034 - 170340 - Shelby - KY - US - 38.20 - -85.22 - 0 - 0 - LMK - - - GAZ041 - 100410 - Haralson - GA - US - 33.78 - -85.21 - 0 - 0 - FFC - - - KYZ046 - 170460 - Washington - KY - US - 37.77 - -85.20 - 0 - 0 - LMK - - - MIZ051 - 220510 - Montcalm - MI - US - 43.30 - -85.20 - 0 - 0 - GRR - - - TNZ099 - 420990 - Hamilton - TN - US - 35.23 - -85.20 - 0 - 0 - MRX - - - GAZ030 - 100300 - Polk - GA - US - 34.00 - -85.17 - 0 - 0 - FFC - - - INZ058 - 140580 - Fayette - IN - US - 39.65 - -85.17 - 0 - 0 - ILN - - - ALZ048 - 10480 - Russell - AL - US - 32.29 - -85.16 - 0 - 0 - BMX - - - FLZ013 - 90130 - Calhoun - FL - US - 30.40 - -85.16 - 0 - 0 - TAE - - - TNZ082 - 420820 - Bledsoe - TN - US - 35.57 - -85.16 - 0 - 0 - MRX - - - KYZ082 - 170820 - Clinton - KY - US - 36.75 - -85.15 - 0 - 0 - LMK - - - MIZ021 - 220210 - Antrim - MI - US - 45.01 - -85.15 - 0 - 0 - APX - - - KYZ089 - 170890 - Carroll - KY - US - 38.68 - -85.14 - 0 - 0 - ILN - - - TNZ011 - 420110 - Pickett - TN - US - 36.52 - -85.14 - 0 - 0 - OHX - - - GAZ003 - 100030 - Catoosa - GA - US - 34.88 - -85.12 - 0 - 0 - FFC - - - KYZ033 - 170330 - Henry - KY - US - 38.47 - -85.12 - 0 - 0 - LMK - - - GAZ052 - 100520 - Heard - GA - US - 33.28 - -85.11 - 0 - 0 - FFC - - - MIZ033 - 220330 - Missaukee - MI - US - 44.34 - -85.10 - 0 - 0 - APX - - - MIZ027 - 220270 - Kalkaska - MI - US - 44.69 - -85.09 - 0 - 0 - APX - - - MIZ058 - 220580 - Ionia - MI - US - 42.95 - -85.08 - 0 - 0 - GRR - - - GAZ042 - 100420 - Carroll - GA - US - 33.62 - -85.07 - 0 - 0 - FFC - - - INZ018 - 140180 - Allen - IN - US - 41.11 - -85.07 - 0 - 0 - IWX - - - KYZ078 - 170780 - Russell - KY - US - 37.01 - -85.07 - 0 - 0 - LMK - - - INZ066 - 140660 - Franklin - IN - US - 39.39 - -85.06 - 0 - 0 - ILN - - - MIZ019 - 220190 - Charlevoix - MI - US - 45.25 - -85.06 - 0 - 0 - APX - - - MIZ080 - 220800 - Branch - MI - US - 41.92 - -85.06 - 0 - 0 - IWX - - - GAZ066 - 100660 - Troup - GA - US - 33.04 - -85.04 - 0 - 0 - FFC - - - GAZ120 - 101200 - Quitman - GA - US - 31.88 - -85.02 - 0 - 0 - TAE - - - INZ050 - 140500 - Wayne - IN - US - 39.87 - -85.02 - 0 - 0 - ILN - - - INZ034 - 140340 - Jay - IN - US - 40.45 - -85.01 - 0 - 0 - IWX - - - INZ042 - 140420 - Randolph - IN - US - 40.17 - -85.01 - 0 - 0 - IND - - - MIZ073 - 220730 - Calhoun - MI - US - 42.25 - -85.01 - 0 - 0 - GRR - - - INZ080 - 140800 - Switzerland - IN - US - 38.81 - -85.00 - 0 - 0 - ILN - - - KYZ039 - 170390 - Anderson - KY - US - 38.00 - -85.00 - 0 - 0 - LMK - - - INZ007 - 140070 - Steuben - IN - US - 41.65 - -84.99 - 0 - 0 - IWX - - - INZ009 - 140090 - De_Kalb - IN - US - 41.41 - -84.99 - 0 - 0 - IWX - - - INZ075 - 140750 - Ohio - IN - US - 38.97 - -84.99 - 0 - 0 - ILN - - - MIZ015 - 220150 - Mackinac - MI - US - 46.04 - -84.99 - 0 - 0 - APX - - - GAZ004 - 100040 - Whitfield - GA - US - 34.80 - -84.98 - 0 - 0 - FFC - - - INZ074 - 140740 - Dearborn - IN - US - 39.12 - -84.98 - 0 - 0 - ILN - - - TNZ066 - 420660 - Cumberland - TN - US - 35.96 - -84.98 - 0 - 0 - OHX - - - GAZ121 - 101210 - Clay - GA - US - 31.64 - -84.96 - 0 - 0 - TAE - - - KYZ066 - 170660 - Casey - KY - US - 37.33 - -84.95 - 0 - 0 - LMK - - - MIZ016 - 220160 - Emmet - MI - US - 45.53 - -84.95 - 0 - 0 - APX - - - INZ027 - 140270 - Adams - IN - US - 40.76 - -84.94 - 0 - 0 - IWX - - - INZ059 - 140590 - Union - IN - US - 39.62 - -84.93 - 0 - 0 - ILN - - - GAZ078 - 100780 - Harris - GA - US - 32.73 - -84.92 - 0 - 0 - FFC - - - TNZ083 - 420830 - Rhea - TN - US - 35.62 - -84.92 - 0 - 0 - MRX - - - KYZ035 - 170350 - Franklin - KY - US - 38.23 - -84.89 - 0 - 0 - LMK - - - TNZ034 - 420340 - Fentress - TN - US - 36.36 - -84.89 - 0 - 0 - OHX - - - GAZ031 - 100310 - Paulding - GA - US - 33.93 - -84.88 - 0 - 0 - FFC - - - GAZ012 - 100120 - Gordon - GA - US - 34.51 - -84.87 - 0 - 0 - FFC - - - GAZ089 - 100890 - Muscogee - GA - US - 32.49 - -84.87 - 0 - 0 - FFC - - - GAZ142 - 101420 - Early - GA - US - 31.30 - -84.87 - 0 - 0 - TAE - - - GAZ155 - 101550 - Seminole - GA - US - 30.90 - -84.87 - 0 - 0 - TAE - - - KYZ047 - 170470 - Mercer - KY - US - 37.82 - -84.87 - 0 - 0 - LMK - - - KYZ055 - 170550 - Boyle - KY - US - 37.63 - -84.86 - 0 - 0 - LMK - - - FLZ026 - 90260 - Liberty - FL - US - 30.29 - -84.85 - 0 - 0 - TAE - - - GAZ102 - 101020 - Stewart - GA - US - 32.07 - -84.85 - 0 - 0 - FFC - - - KYZ090 - 170900 - Gallatin - KY - US - 38.77 - -84.85 - 0 - 0 - ILN - - - MIZ040 - 220400 - Clare - MI - US - 43.99 - -84.85 - 0 - 0 - GRR - - - MIZ046 - 220460 - Isabella - MI - US - 43.64 - -84.85 - 0 - 0 - GRR - - - TNZ100 - 421000 - Bradley - TN - US - 35.18 - -84.85 - 0 - 0 - MRX - - - GAZ020 - 100200 - Bartow - GA - US - 34.25 - -84.84 - 0 - 0 - FFC - - - MIZ066 - 220660 - Eaton - MI - US - 42.60 - -84.84 - 0 - 0 - GRR - - - KYZ083 - 170830 - Wayne - KY - US - 36.80 - -84.83 - 0 - 0 - JKL - - - KYZ094 - 170940 - Owen - KY - US - 38.53 - -84.83 - 0 - 0 - ILN - - - GAZ090 - 100900 - Chattahoochee - GA - US - 32.38 - -84.82 - 0 - 0 - FFC - - - TNZ084 - 420840 - Meigs - TN - US - 35.52 - -84.82 - 0 - 0 - MRX - - - FLZ015 - 90150 - Franklin - FL - US - 29.80 - -84.77 - 0 - 0 - TAE - - - GAZ005 - 100050 - Murray - GA - US - 34.79 - -84.76 - 0 - 0 - FFC - - - KYZ040 - 170400 - Woodford - KY - US - 38.02 - -84.76 - 0 - 0 - LMK - - - GAZ053 - 100530 - Coweta - GA - US - 33.35 - -84.75 - 0 - 0 - FFC - - - KYZ091 - 170910 - Boone - KY - US - 38.96 - -84.75 - 0 - 0 - ILN - - - GAZ043 - 100430 - Douglas - GA - US - 33.69 - -84.74 - 0 - 0 - FFC - - - GAZ122 - 101220 - Randolph - GA - US - 31.77 - -84.74 - 0 - 0 - TAE - - - GAZ143 - 101430 - Miller - GA - US - 31.17 - -84.72 - 0 - 0 - TAE - - - GAZ067 - 100670 - Meriwether - GA - US - 33.03 - -84.67 - 0 - 0 - FFC - - - KYZ067 - 170670 - Lincoln - KY - US - 37.44 - -84.66 - 0 - 0 - LMK - - - OHZ060 - 350600 - Preble - OH - US - 39.74 - -84.65 - 0 - 0 - ILN - - - KYZ095 - 170950 - Grant - KY - US - 38.64 - -84.64 - 0 - 0 - ILN - - - TNZ085 - 420850 - McMinn - TN - US - 35.45 - -84.63 - 0 - 0 - MRX - - - GAZ123 - 101230 - Calhoun - GA - US - 31.54 - -84.62 - 0 - 0 - TAE - - - GAZ156 - 101560 - Decatur - GA - US - 30.89 - -84.62 - 0 - 0 - TAE - - - MIZ022 - 220220 - Otsego - MI - US - 45.03 - -84.62 - 0 - 0 - APX - - - OHZ034 - 350340 - Mercer - OH - US - 40.54 - -84.62 - 0 - 0 - ILN - - - OHZ042 - 350420 - Darke - OH - US - 40.14 - -84.62 - 0 - 0 - ILN - - - TNZ035 - 420350 - Morgan - TN - US - 36.14 - -84.62 - 0 - 0 - MRX - - - FLZ016 - 90160 - Gadsden - FL - US - 30.56 - -84.61 - 0 - 0 - TAE - - - KYZ079 - 170790 - Pulaski - KY - US - 37.12 - -84.61 - 0 - 0 - JKL - - - MIZ028 - 220280 - Crawford - MI - US - 44.69 - -84.61 - 0 - 0 - APX - - - MIZ034 - 220340 - Roscommon - MI - US - 44.34 - -84.61 - 0 - 0 - APX - - - MIZ052 - 220520 - Gratiot - MI - US - 43.30 - -84.61 - 0 - 0 - GRR - - - MIZ059 - 220590 - Clinton - MI - US - 42.95 - -84.60 - 0 - 0 - GRR - - - MIZ081 - 220810 - Hillsdale - MI - US - 41.89 - -84.60 - 0 - 0 - IWX - - - GAZ044 - 100440 - South_Fulton - GA - US - 33.62 - -84.59 - 0 - 0 - FFC - - - KYZ036 - 170360 - Scott - KY - US - 38.30 - -84.59 - 0 - 0 - LMK - - - KYZ048 - 170480 - Jessamine - KY - US - 37.87 - -84.59 - 0 - 0 - LMK - - - OHZ070 - 350700 - Butler - OH - US - 39.44 - -84.58 - 0 - 0 - ILN - - - OHZ015 - 350150 - Paulding - OH - US - 41.12 - -84.57 - 0 - 0 - IWX - - - OHZ024 - 350240 - Van_Wert - OH - US - 40.84 - -84.57 - 0 - 0 - IWX - - - TNZ101 - 421010 - West_Polk - TN - US - 35.14 - -84.57 - 0 - 0 - MRX - - - GAZ032 - 100320 - Cobb - GA - US - 33.93 - -84.56 - 0 - 0 - FFC - - - OHZ001 - 350010 - Williams - OH - US - 41.57 - -84.56 - 0 - 0 - IWX - - - KYZ056 - 170560 - Garrard - KY - US - 37.65 - -84.55 - 0 - 0 - LMK - - - GAZ103 - 101030 - Webster - GA - US - 32.07 - -84.54 - 0 - 0 - FFC - - - OHZ077 - 350770 - Hamilton - OH - US - 39.16 - -84.54 - 0 - 0 - ILN - - - GAZ091 - 100910 - Marion - GA - US - 32.35 - -84.52 - 0 - 0 - FFC - - - KYZ084 - 170840 - McCreary - KY - US - 36.78 - -84.52 - 0 - 0 - JKL - - - KYZ092 - 170920 - Kenton - KY - US - 38.94 - -84.52 - 0 - 0 - ILN - - - TNZ067 - 420670 - Roane - TN - US - 35.85 - -84.52 - 0 - 0 - MRX - - - OHZ004 - 350040 - Defiance - OH - US - 41.29 - -84.51 - 0 - 0 - IWX - - - TNZ012 - 420120 - Scott - TN - US - 36.39 - -84.51 - 0 - 0 - MRX - - - GAZ054 - 100540 - Fayette - GA - US - 33.41 - -84.49 - 0 - 0 - FFC - - - GAZ079 - 100790 - Talbot - GA - US - 32.70 - -84.49 - 0 - 0 - FFC - - - KYZ041 - 170410 - Fayette - KY - US - 38.03 - -84.48 - 0 - 0 - LMK - - - MIZ017 - 220170 - Cheboygan - MI - US - 45.49 - -84.47 - 0 - 0 - APX - - - GAZ013 - 100130 - Pickens - GA - US - 34.47 - -84.46 - 0 - 0 - FFC - - - GAZ021 - 100210 - Cherokee - GA - US - 34.25 - -84.46 - 0 - 0 - FFC - - - TNZ102 - 421020 - East_Polk - TN - US - 35.12 - -84.44 - 0 - 0 - MRX - - - MIZ074 - 220740 - Jackson - MI - US - 42.25 - -84.43 - 0 - 0 - GRR - - - GAZ007 - 100070 - Gilmer - GA - US - 34.70 - -84.42 - 0 - 0 - FFC - - - GAZ124 - 101240 - Terrell - GA - US - 31.79 - -84.42 - 0 - 0 - TAE - - - FLZ027 - 90270 - Wakulla - FL - US - 30.14 - -84.40 - 0 - 0 - TAE - - - GAZ068 - 100680 - Pike - GA - US - 33.09 - -84.39 - 0 - 0 - FFC - - - GAZ144 - 101440 - Baker - GA - US - 31.27 - -84.39 - 0 - 0 - TAE - - - MIZ041 - 220410 - Gladwin - MI - US - 43.99 - -84.39 - 0 - 0 - APX - - - MIZ047 - 220470 - Midland - MI - US - 43.65 - -84.39 - 0 - 0 - DTX - - - KYZ093 - 170930 - Campbell - KY - US - 38.96 - -84.37 - 0 - 0 - ILN - - - KYZ096 - 170960 - Pendleton - KY - US - 38.70 - -84.37 - 0 - 0 - ILN - - - MIZ067 - 220670 - Ingham - MI - US - 42.60 - -84.37 - 0 - 0 - GRR - - - GAZ033 - 100330 - North_Fulton - GA - US - 33.92 - -84.35 - 0 - 0 - FFC - - - GAZ055 - 100550 - Clayton - GA - US - 33.50 - -84.35 - 0 - 0 - FFC - - - MIZ008 - 220080 - Chippewa - MI - US - 46.34 - -84.35 - 0 - 0 - APX - - - TNZ068 - 420680 - Loudon - TN - US - 35.76 - -84.35 - 0 - 0 - MRX - - - FLZ017 - 90170 - Leon - FL - US - 30.49 - -84.34 - 0 - 0 - TAE - - - KYZ037 - 170370 - Harrison - KY - US - 38.43 - -84.33 - 0 - 0 - LMK - - - KYZ068 - 170680 - Rockcastle - KY - US - 37.35 - -84.33 - 0 - 0 - JKL - - - GAZ069 - 100690 - Upson - GA - US - 32.85 - -84.32 - 0 - 0 - FFC - - - KYZ057 - 170570 - Madison - KY - US - 37.72 - -84.31 - 0 - 0 - LMK - - - GAZ092 - 100920 - Schley - GA - US - 32.29 - -84.30 - 0 - 0 - FFC - - - GAZ056 - 100560 - Spalding - GA - US - 33.27 - -84.29 - 0 - 0 - FFC - - - TNZ086 - 420860 - Northwest_Monroe - TN - US - 35.46 - -84.28 - 0 - 0 - MRX - - - OHZ061 - 350610 - Montgomery - OH - US - 39.75 - -84.27 - 0 - 0 - ILN - - - GAZ145 - 101450 - Mitchell - GA - US - 31.26 - -84.25 - 0 - 0 - TAE - - - GAZ080 - 100800 - Taylor - GA - US - 32.55 - -84.23 - 0 - 0 - FFC - - - GAZ006 - 100060 - Fannin - GA - US - 34.80 - -84.22 - 0 - 0 - FFC - - - GAZ157 - 101570 - Grady - GA - US - 30.88 - -84.22 - 0 - 0 - TAE - - - OHZ051 - 350510 - Miami - OH - US - 40.04 - -84.22 - 0 - 0 - ILN - - - GAZ125 - 101250 - Dougherty - GA - US - 31.55 - -84.21 - 0 - 0 - TAE - - - KYZ042 - 170420 - Bourbon - KY - US - 38.22 - -84.21 - 0 - 0 - LMK - - - OHZ043 - 350430 - Shelby - OH - US - 40.33 - -84.21 - 0 - 0 - ILN - - - TNZ036 - 420360 - Anderson - TN - US - 36.10 - -84.20 - 0 - 0 - MRX - - - GAZ045 - 100450 - DeKalb - GA - US - 33.79 - -84.19 - 0 - 0 - FFC - - - GAZ104 - 101040 - Sumter - GA - US - 32.05 - -84.18 - 0 - 0 - FFC - - - KYZ049 - 170490 - Clark - KY - US - 37.97 - -84.17 - 0 - 0 - LMK - - - OHZ071 - 350710 - Warren - OH - US - 39.42 - -84.17 - 0 - 0 - ILN - - - OHZ035 - 350350 - Auglaize - OH - US - 40.52 - -84.16 - 0 - 0 - ILN - - - GAZ014 - 100140 - Dawson - GA - US - 34.48 - -84.15 - 0 - 0 - FFC - - - GAZ070 - 100700 - Lamar - GA - US - 33.06 - -84.15 - 0 - 0 - FFC - - - MIZ060 - 220600 - Shiawassee - MI - US - 42.96 - -84.15 - 0 - 0 - DTX - - - OHZ078 - 350780 - Clermont - OH - US - 39.02 - -84.15 - 0 - 0 - ILN - - - TNZ087 - 420870 - Southeast_Monroe - TN - US - 35.38 - -84.15 - 0 - 0 - MRX - - - GAZ057 - 100570 - Henry - GA - US - 33.48 - -84.14 - 0 - 0 - FFC - - - TNZ013 - 420130 - Campbell - TN - US - 36.39 - -84.14 - 0 - 0 - MRX - - - GAZ126 - 101260 - Lee - GA - US - 31.77 - -84.13 - 0 - 0 - TAE - - - MIZ023 - 220230 - Montmorency - MI - US - 45.03 - -84.13 - 0 - 0 - APX - - - MIZ029 - 220290 - Oscoda - MI - US - 44.68 - -84.13 - 0 - 0 - APX - - - MIZ035 - 220350 - Ogemaw - MI - US - 44.34 - -84.13 - 0 - 0 - APX - - - OHZ016 - 350160 - Putnam - OH - US - 41.01 - -84.13 - 0 - 0 - IWX - - - OHZ025 - 350250 - Allen - OH - US - 40.78 - -84.13 - 0 - 0 - IWX - - - KYZ080 - 170800 - Laurel - KY - US - 37.13 - -84.12 - 0 - 0 - JKL - - - KYZ085 - 170850 - Whitley - KY - US - 36.78 - -84.12 - 0 - 0 - JKL - - - OHZ002 - 350020 - Fulton - OH - US - 41.60 - -84.12 - 0 - 0 - IWX - - - OHZ005 - 350050 - Henry - OH - US - 41.32 - -84.10 - 0 - 0 - IWX - - - GAZ022 - 100220 - Forsyth - GA - US - 34.19 - -84.09 - 0 - 0 - FFC - - - KYZ097 - 170970 - Bracken - KY - US - 38.68 - -84.08 - 0 - 0 - ILN - - - KYZ098 - 170980 - Robertson - KY - US - 38.51 - -84.08 - 0 - 0 - ILN - - - MIZ082 - 220820 - Lenawee - MI - US - 41.90 - -84.07 - 0 - 0 - DTX - - - MIZ048 - 220480 - Bay - MI - US - 43.74 - -84.06 - 0 - 0 - DTX - - - GAZ046 - 100460 - Rockdale - GA - US - 33.66 - -84.04 - 0 - 0 - FFC - - - GAZ093 - 100930 - Macon - GA - US - 32.35 - -84.04 - 0 - 0 - FFC - - - GAZ034 - 100340 - Gwinnett - GA - US - 33.96 - -84.03 - 0 - 0 - FFC - - - MIZ053 - 220530 - Saginaw - MI - US - 43.35 - -84.03 - 0 - 0 - DTX - - - KYZ043 - 170430 - Nicholas - KY - US - 38.33 - -84.02 - 0 - 0 - LMK - - - GAZ015 - 100150 - Lumpkin - GA - US - 34.57 - -84.01 - 0 - 0 - FFC - - - NCZ060 - 330600 - Cherokee - NC - US - 35.14 - -84.01 - 0 - 0 - MRX - - - KYZ069 - 170690 - Jackson - KY - US - 37.42 - -84.00 - 0 - 0 - JKL - - - GAZ008 - 100080 - Union - GA - US - 34.81 - -83.98 - 0 - 0 - FFC - - - GAZ058 - 100580 - Butts - GA - US - 33.32 - -83.97 - 0 - 0 - FFC - - - GAZ081 - 100810 - Crawford - GA - US - 32.69 - -83.97 - 0 - 0 - FFC - - - TNZ069 - 420690 - Knox - TN - US - 35.99 - -83.96 - 0 - 0 - MRX - - - KYZ058 - 170580 - Estill - KY - US - 37.70 - -83.93 - 0 - 0 - JKL - - - GAZ071 - 100710 - Monroe - GA - US - 33.02 - -83.92 - 0 - 0 - FFC - - - GAZ158 - 101580 - Thomas - GA - US - 30.87 - -83.92 - 0 - 0 - TAE - - - KYZ050 - 170500 - Montgomery - KY - US - 38.05 - -83.92 - 0 - 0 - JKL - - - TNZ071 - 420710 - NW_Blount - TN - US - 35.71 - -83.92 - 0 - 0 - MRX - - - MIZ068 - 220680 - Livingston - MI - US - 42.61 - -83.91 - 0 - 0 - DTX - - - OHZ062 - 350620 - Greene - OH - US - 39.70 - -83.88 - 0 - 0 - ILN - - - MIZ042 - 220420 - Arenac - MI - US - 44.04 - -83.87 - 0 - 0 - APX - - - GAZ048 - 100480 - Newton - GA - US - 33.56 - -83.86 - 0 - 0 - FFC - - - GAZ094 - 100940 - Peach - GA - US - 32.56 - -83.86 - 0 - 0 - FFC - - - OHZ079 - 350790 - Brown - OH - US - 38.95 - -83.86 - 0 - 0 - ILN - - - FLZ018 - 90180 - Jefferson - FL - US - 30.38 - -83.84 - 0 - 0 - TAE - - - GAZ023 - 100230 - Hall - GA - US - 34.30 - -83.84 - 0 - 0 - FFC - - - GAZ127 - 101270 - Worth - GA - US - 31.59 - -83.84 - 0 - 0 - TAE - - - KYZ059 - 170590 - Powell - KY - US - 37.83 - -83.84 - 0 - 0 - JKL - - - KYZ086 - 170860 - Knox - KY - US - 36.87 - -83.84 - 0 - 0 - JKL - - - MIZ075 - 220750 - Washtenaw - MI - US - 42.26 - -83.84 - 0 - 0 - DTX - - - TNZ037 - 420370 - Union - TN - US - 36.30 - -83.84 - 0 - 0 - MRX - - - TNZ072 - 420720 - Blount_Smoky_Mountains - TN - US - 35.57 - -83.84 - 0 - 0 - MRX - - - GAZ105 - 101050 - Dooly - GA - US - 32.16 - -83.82 - 0 - 0 - FFC - - - KYZ099 - 170990 - Mason - KY - US - 38.62 - -83.82 - 0 - 0 - ILN - - - MIZ018 - 220180 - Presque_Isle - MI - US - 45.42 - -83.82 - 0 - 0 - APX - - - NCZ058 - 330580 - Graham - NC - US - 35.34 - -83.81 - 0 - 0 - GSP - - - OHZ072 - 350720 - Clinton - OH - US - 39.39 - -83.79 - 0 - 0 - ILN - - - GAZ106 - 101060 - Crisp - GA - US - 31.91 - -83.78 - 0 - 0 - FFC - - - OHZ053 - 350530 - Clark - OH - US - 39.90 - -83.78 - 0 - 0 - ILN - - - OHZ044 - 350440 - Logan - OH - US - 40.38 - -83.76 - 0 - 0 - ILN - - - OHZ052 - 350520 - Champaign - OH - US - 40.14 - -83.76 - 0 - 0 - ILN - - - GAZ016 - 100160 - White - GA - US - 34.65 - -83.75 - 0 - 0 - FFC - - - GAZ047 - 100470 - Walton - GA - US - 33.76 - -83.75 - 0 - 0 - FFC - - - GAZ146 - 101460 - Colquitt - GA - US - 31.18 - -83.75 - 0 - 0 - TAE - - - NCZ061 - 330610 - Clay - NC - US - 35.07 - -83.75 - 0 - 0 - MRX - - - GAZ009 - 100090 - Towns - GA - US - 34.89 - -83.74 - 0 - 0 - FFC - - - KYZ116 - 171160 - Clay - KY - US - 37.15 - -83.74 - 0 - 0 - JKL - - - OHZ003 - 350030 - Lucas - OH - US - 41.57 - -83.74 - 0 - 0 - CLE - - - KYZ051 - 170510 - Bath - KY - US - 38.15 - -83.73 - 0 - 0 - JKL - - - KYZ044 - 170440 - Fleming - KY - US - 38.36 - -83.72 - 0 - 0 - JKL - - - KYZ111 - 171110 - Lee - KY - US - 37.60 - -83.72 - 0 - 0 - JKL - - - KYZ087 - 170870 - Bell - KY - US - 36.77 - -83.71 - 0 - 0 - JKL - - - KYZ114 - 171140 - Owsley - KY - US - 37.40 - -83.71 - 0 - 0 - JKL - - - GAZ035 - 100350 - Barrow - GA - US - 34.01 - -83.70 - 0 - 0 - FFC - - - GAZ059 - 100590 - Jasper - GA - US - 33.33 - -83.69 - 0 - 0 - FFC - - - GAZ082 - 100820 - Bibb - GA - US - 32.80 - -83.69 - 0 - 0 - FFC - - - MIZ061 - 220610 - Genesee - MI - US - 43.00 - -83.69 - 0 - 0 - DTX - - - TNZ014 - 420140 - Claiborne - TN - US - 36.47 - -83.69 - 0 - 0 - MRX - - - GAZ095 - 100950 - Houston - GA - US - 32.49 - -83.67 - 0 - 0 - FFC - - - FLZ028 - 90280 - Taylor - FL - US - 29.99 - -83.65 - 0 - 0 - TAE - - - OHZ026 - 350260 - Hardin - OH - US - 40.66 - -83.65 - 0 - 0 - ILN - - - OHZ006 - 350060 - Wood - OH - US - 41.39 - -83.64 - 0 - 0 - CLE - - - OHZ017 - 350170 - Hancock - OH - US - 40.99 - -83.64 - 0 - 0 - CLE - - - GAZ128 - 101280 - Turner - GA - US - 31.71 - -83.63 - 0 - 0 - TAE - - - KYZ060 - 170600 - Menifee - KY - US - 37.94 - -83.61 - 0 - 0 - JKL - - - OHZ080 - 350800 - Highland - OH - US - 39.20 - -83.61 - 0 - 0 - ILN - - - MIZ036 - 220360 - Iosco - MI - US - 44.34 - -83.60 - 0 - 0 - APX - - - GAZ025 - 100250 - Jackson - GA - US - 34.13 - -83.59 - 0 - 0 - FFC - - - MIZ030 - 220300 - Alcona - MI - US - 44.69 - -83.59 - 0 - 0 - APX - - - GAZ072 - 100720 - Jones - GA - US - 33.01 - -83.58 - 0 - 0 - FFC - - - NCZ051 - 330510 - Swain - NC - US - 35.48 - -83.56 - 0 - 0 - GSP - - - GAZ159 - 101590 - Brooks - GA - US - 30.85 - -83.55 - 0 - 0 - TAE - - - MIZ024 - 220240 - Alpena - MI - US - 45.03 - -83.54 - 0 - 0 - APX - - - TNZ073 - 420730 - North_Sevier - TN - US - 35.87 - -83.53 - 0 - 0 - MRX - - - GAZ017 - 100170 - Habersham - GA - US - 34.63 - -83.51 - 0 - 0 - GSP - - - GAZ024 - 100240 - Banks - GA - US - 34.35 - -83.50 - 0 - 0 - FFC - - - GAZ129 - 101290 - Tift - GA - US - 31.46 - -83.50 - 0 - 0 - TAE - - - TNZ038 - 420380 - Grainger - TN - US - 36.25 - -83.50 - 0 - 0 - MRX - - - FLZ019 - 90190 - Madison - FL - US - 30.46 - -83.49 - 0 - 0 - TAE - - - OHZ081 - 350810 - Adams - OH - US - 38.82 - -83.49 - 0 - 0 - ILN - - - GAZ049 - 100490 - Morgan - GA - US - 33.62 - -83.48 - 0 - 0 - FFC - - - KYZ108 - 171080 - Wolfe - KY - US - 37.75 - -83.48 - 0 - 0 - JKL - - - MIZ083 - 220830 - Monroe - MI - US - 41.91 - -83.48 - 0 - 0 - DTX - - - TNZ070 - 420700 - Jefferson - TN - US - 36.04 - -83.47 - 0 - 0 - MRX - - - GAZ037 - 100370 - Oconee - GA - US - 33.83 - -83.46 - 0 - 0 - FFC - - - GAZ107 - 101070 - Pulaski - GA - US - 32.25 - -83.46 - 0 - 0 - FFC - - - OHZ063 - 350630 - Fayette - OH - US - 39.54 - -83.46 - 0 - 0 - ILN - - - TNZ074 - 420740 - Sevier_Smoky_Mountains - TN - US - 35.69 - -83.46 - 0 - 0 - MRX - - - GAZ147 - 101470 - Cook - GA - US - 31.19 - -83.43 - 0 - 0 - TAE - - - OHZ054 - 350540 - Madison - OH - US - 39.90 - -83.43 - 0 - 0 - ILN - - - KYZ052 - 170520 - Rowan - KY - US - 38.21 - -83.42 - 0 - 0 - JKL - - - NCZ062 - 330620 - Macon - NC - US - 35.16 - -83.42 - 0 - 0 - GSP - - - GAZ083 - 100830 - Twiggs - GA - US - 32.67 - -83.41 - 0 - 0 - FFC - - - MIZ054 - 220540 - Tuscola - MI - US - 43.51 - -83.40 - 0 - 0 - DTX - - - GAZ108 - 101080 - Wilcox - GA - US - 31.98 - -83.39 - 0 - 0 - FFC - - - MIZ069 - 220690 - Oakland - MI - US - 42.66 - -83.39 - 0 - 0 - DTX - - - GAZ010 - 100100 - Rabun - GA - US - 34.85 - -83.38 - 0 - 0 - GSP - - - GAZ036 - 100360 - Clarke - GA - US - 33.95 - -83.38 - 0 - 0 - FFC - - - KYZ117 - 171170 - Leslie - KY - US - 37.11 - -83.36 - 0 - 0 - JKL - - - OHZ045 - 350450 - Union - OH - US - 40.30 - -83.36 - 0 - 0 - ILN - - - GAZ060 - 100600 - Putnam - GA - US - 33.32 - -83.34 - 0 - 0 - FFC - - - KYZ100 - 171000 - Lewis - KY - US - 38.52 - -83.34 - 0 - 0 - ILN - - - GAZ096 - 100960 - Bleckley - GA - US - 32.42 - -83.32 - 0 - 0 - FFC - - - OHZ027 - 350270 - Wyandot - OH - US - 40.84 - -83.31 - 0 - 0 - CLE - - - GAZ018 - 100180 - Stephens - GA - US - 34.57 - -83.29 - 0 - 0 - GSP - - - KYZ112 - 171120 - Breathitt - KY - US - 37.52 - -83.28 - 0 - 0 - JKL - - - KYZ115 - 171150 - Perry - KY - US - 37.22 - -83.28 - 0 - 0 - JKL - - - TNZ039 - 420390 - Hamblen - TN - US - 36.23 - -83.28 - 0 - 0 - MRX - - - GAZ131 - 101310 - Irwin - GA - US - 31.62 - -83.25 - 0 - 0 - TAE - - - GAZ160 - 101600 - Lowndes - GA - US - 30.82 - -83.25 - 0 - 0 - TAE - - - GAZ073 - 100730 - Baldwin - GA - US - 33.05 - -83.24 - 0 - 0 - FFC - - - GAZ130 - 101300 - Ben_Hill - GA - US - 31.75 - -83.24 - 0 - 0 - TAE - - - GAZ026 - 100260 - Franklin - GA - US - 34.39 - -83.23 - 0 - 0 - GSP - - - GAZ148 - 101480 - Berrien - GA - US - 31.25 - -83.23 - 0 - 0 - TAE - - - KYZ106 - 171060 - Morgan - KY - US - 37.92 - -83.23 - 0 - 0 - JKL - - - MIZ062 - 220620 - Lapeer - MI - US - 43.11 - -83.22 - 0 - 0 - DTX - - - MIZ076 - 220760 - Wayne - MI - US - 42.25 - -83.21 - 0 - 0 - DTX - - - GAZ027 - 100270 - Madison - GA - US - 34.13 - -83.19 - 0 - 0 - FFC - - - KYZ088 - 170880 - Harlan - KY - US - 36.85 - -83.19 - 0 - 0 - JKL - - - GAZ050 - 100500 - Greene - GA - US - 33.56 - -83.18 - 0 - 0 - FFC - - - GAZ084 - 100840 - Wilkinson - GA - US - 32.79 - -83.18 - 0 - 0 - FFC - - - FLZ034 - 90340 - Dixie - FL - US - 29.56 - -83.16 - 0 - 0 - TAE - - - NCZ059 - 330590 - Northern_Jackson - NC - US - 35.37 - -83.14 - 0 - 0 - GSP - - - OHZ036 - 350360 - Marion - OH - US - 40.57 - -83.14 - 0 - 0 - CLE - - - TNZ015 - 420150 - Hancock - TN - US - 36.50 - -83.14 - 0 - 0 - MRX - - - TNZ040 - 420400 - Northwest_Cocke - TN - US - 36.00 - -83.13 - 0 - 0 - MRX - - - FLZ029 - 90290 - Lafayette - FL - US - 30.04 - -83.12 - 0 - 0 - TAE - - - GAZ109 - 101090 - Dodge - GA - US - 32.17 - -83.12 - 0 - 0 - FFC - - - OHZ008 - 350080 - Sandusky - OH - US - 41.37 - -83.12 - 0 - 0 - CLE - - - OHZ018 - 350180 - Seneca - OH - US - 41.12 - -83.12 - 0 - 0 - CLE - - - SCZ001 - 400010 - Oconee_Mountains - SC - US - 34.83 - -83.12 - 0 - 0 - GSP - - - TNZ041 - 420410 - Cocke_Smoky_Mountains - TN - US - 35.86 - -83.09 - 0 - 0 - MRX - - - GAZ161 - 101610 - Lanier - GA - US - 31.02 - -83.08 - 0 - 0 - TAE - - - KYZ104 - 171040 - Elliott - KY - US - 38.14 - -83.08 - 0 - 0 - JKL - - - KYZ109 - 171090 - Magoffin - KY - US - 37.69 - -83.08 - 0 - 0 - JKL - - - OHZ082 - 350820 - Pike - OH - US - 39.07 - -83.08 - 0 - 0 - ILN - - - NCZ063 - 330630 - Southern_Jackson - NC - US - 35.15 - -83.07 - 0 - 0 - GSP - - - OHZ073 - 350730 - Ross - OH - US - 39.34 - -83.07 - 0 - 0 - ILN - - - KYZ102 - 171020 - Carter - KY - US - 38.34 - -83.06 - 0 - 0 - RLX - - - OHZ007 - 350070 - Ottawa - OH - US - 41.54 - -83.06 - 0 - 0 - CLE - - - GAZ038 - 100380 - Oglethorpe - GA - US - 33.87 - -83.04 - 0 - 0 - FFC - - - MIZ049 - 220490 - Huron - MI - US - 43.87 - -83.04 - 0 - 0 - DTX - - - GAZ061 - 100610 - Hancock - GA - US - 33.27 - -83.02 - 0 - 0 - FFC - - - OHZ055 - 350550 - Franklin - OH - US - 39.96 - -83.01 - 0 - 0 - ILN - - - FLZ021 - 90210 - Suwannee - FL - US - 30.17 - -83.00 - 0 - 0 - JAX - - - NCZ052 - 330520 - Haywood - NC - US - 35.54 - -83.00 - 0 - 0 - GSP - - - OHZ064 - 350640 - Pickaway - OH - US - 39.63 - -83.00 - 0 - 0 - ILN - - - SCZ004 - 400040 - Greater_Oconee - SC - US - 34.64 - -83.00 - 0 - 0 - GSP - - - VAZ001 - 460010 - Lee - VA - US - 36.74 - -83.00 - 0 - 0 - MRX - - - OHZ046 - 350460 - Delaware - OH - US - 40.28 - -82.99 - 0 - 0 - ILN - - - FLZ020 - 90200 - Hamilton - FL - US - 30.48 - -82.96 - 0 - 0 - JAX - - - OHZ088 - 350880 - Scioto - OH - US - 38.79 - -82.96 - 0 - 0 - ILN - - - GAZ028 - 100280 - Hart - GA - US - 34.35 - -82.95 - 0 - 0 - GSP - - - TNZ016 - 420160 - Hawkins - TN - US - 36.42 - -82.94 - 0 - 0 - MRX - - - GAZ097 - 100970 - Laurens - GA - US - 32.43 - -82.93 - 0 - 0 - FFC - - - GAZ110 - 101100 - Telfair - GA - US - 31.96 - -82.93 - 0 - 0 - FFC - - - KYZ101 - 171010 - Greenup - KY - US - 38.56 - -82.92 - 0 - 0 - RLX - - - KYZ113 - 171130 - Knott - KY - US - 37.36 - -82.92 - 0 - 0 - JKL - - - MIZ070 - 220700 - Macomb - MI - US - 42.68 - -82.92 - 0 - 0 - DTX - - - OHZ028 - 350280 - Crawford - OH - US - 40.85 - -82.91 - 0 - 0 - CLE - - - GAZ149 - 101490 - Atkinson - GA - US - 31.30 - -82.88 - 0 - 0 - JAX - - - TNZ042 - 420420 - Northwest_Greene - TN - US - 36.21 - -82.88 - 0 - 0 - MRX - - - GAZ132 - 101320 - Coffee - GA - US - 31.59 - -82.87 - 0 - 0 - JAX - - - GAZ162 - 101620 - Echols - GA - US - 30.73 - -82.86 - 0 - 0 - JAX - - - KYZ118 - 171180 - Letcher - KY - US - 37.12 - -82.86 - 0 - 0 - JKL - - - GAZ051 - 100510 - Taliaferro - GA - US - 33.59 - -82.85 - 0 - 0 - FFC - - - GAZ029 - 100290 - Elbert - GA - US - 34.12 - -82.84 - 0 - 0 - GSP - - - KYZ107 - 171070 - Johnson - KY - US - 37.86 - -82.82 - 0 - 0 - JKL - - - OHZ037 - 350370 - Morrow - OH - US - 40.53 - -82.82 - 0 - 0 - CLE - - - FLZ035 - 90350 - Gilchrist - FL - US - 29.75 - -82.81 - 0 - 0 - JAX - - - MIZ055 - 220550 - Sanilac - MI - US - 43.43 - -82.81 - 0 - 0 - DTX - - - NCZ064 - 330640 - Transylvania - NC - US - 35.22 - -82.81 - 0 - 0 - GSP - - - GAZ074 - 100740 - Washington - GA - US - 32.99 - -82.79 - 0 - 0 - FFC - - - FLZ039 - 90390 - Levy - FL - US - 29.30 - -82.78 - 0 - 0 - TBW - - - TNZ043 - 420430 - Southeast_Greene - TN - US - 36.01 - -82.77 - 0 - 0 - MRX - - - KYZ110 - 171100 - Floyd - KY - US - 37.52 - -82.76 - 0 - 0 - JKL - - - GAZ111 - 101110 - Wheeler - GA - US - 32.11 - -82.75 - 0 - 0 - FFC - - - KYZ105 - 171050 - Lawrence - KY - US - 38.08 - -82.75 - 0 - 0 - RLX - - - GAZ039 - 100390 - Wilkes - GA - US - 33.79 - -82.74 - 0 - 0 - FFC - - - SCZ002 - 400020 - Pickens_Mountains - SC - US - 34.95 - -82.73 - 0 - 0 - GSP - - - FLZ050 - 90500 - Pinellas - FL - US - 27.89 - -82.71 - 0 - 0 - TBW - - - MIZ063 - 220630 - St._Clair - MI - US - 42.85 - -82.71 - 0 - 0 - DTX - - - GAZ085 - 100850 - Johnson - GA - US - 32.67 - -82.70 - 0 - 0 - FFC - - - KYZ103 - 171030 - Boyd - KY - US - 38.37 - -82.70 - 0 - 0 - RLX - - - GAZ163 - 101630 - Clinch - GA - US - 30.88 - -82.69 - 0 - 0 - JAX - - - SCZ005 - 400050 - Greater_Pickens - SC - US - 34.79 - -82.69 - 0 - 0 - GSP - - - NCZ048 - 330480 - Madison - NC - US - 35.87 - -82.68 - 0 - 0 - GSP - - - SCZ010 - 400100 - Anderson - SC - US - 34.51 - -82.65 - 0 - 0 - GSP - - - VAZ005 - 460050 - Scott - VA - US - 36.74 - -82.64 - 0 - 0 - MRX - - - GAZ062 - 100620 - Warren - GA - US - 33.43 - -82.63 - 0 - 0 - FFC - - - GAZ133 - 101330 - Jeff_Davis - GA - US - 31.82 - -82.63 - 0 - 0 - JAX - - - FLZ022 - 90220 - Columbia - FL - US - 30.21 - -82.62 - 0 - 0 - JAX - - - OHZ009 - 350090 - Erie - OH - US - 41.39 - -82.62 - 0 - 0 - CLE - - - OHZ083 - 350830 - Jackson - OH - US - 39.02 - -82.62 - 0 - 0 - RLX - - - OHZ065 - 350650 - Fairfield - OH - US - 39.74 - -82.60 - 0 - 0 - ILN - - - GAZ075 - 100750 - Glascock - GA - US - 33.23 - -82.59 - 0 - 0 - FFC - - - VAZ002 - 460020 - Wise - VA - US - 37.00 - -82.59 - 0 - 0 - MRX - - - OHZ019 - 350190 - Huron - OH - US - 41.14 - -82.58 - 0 - 0 - CLE - - - GAZ098 - 100980 - Treutlen - GA - US - 32.40 - -82.56 - 0 - 0 - FFC - - - OHZ087 - 350870 - Lawrence - OH - US - 38.62 - -82.56 - 0 - 0 - RLX - - - GAZ112 - 101120 - Montgomery - GA - US - 32.15 - -82.53 - 0 - 0 - FFC - - - NCZ053 - 330530 - Buncombe - NC - US - 35.62 - -82.53 - 0 - 0 - GSP - - - OHZ029 - 350290 - Richland - OH - US - 40.77 - -82.53 - 0 - 0 - CLE - - - OHZ084 - 350840 - Vinton - OH - US - 39.21 - -82.51 - 0 - 0 - RLX - - - KYZ119 - 171190 - Martin - KY - US - 37.82 - -82.50 - 0 - 0 - JKL - - - NCZ065 - 330650 - Henderson - NC - US - 35.32 - -82.50 - 0 - 0 - GSP - - - SCZ003 - 400030 - Greenville_Mountains - SC - US - 35.09 - -82.49 - 0 - 0 - GSP - - - SCZ011 - 400110 - Abbeville - SC - US - 34.25 - -82.49 - 0 - 0 - GSP - - - TNZ044 - 420440 - Washington - TN - US - 36.27 - -82.49 - 0 - 0 - MRX - - - OHZ056 - 350560 - Licking - OH - US - 40.09 - -82.48 - 0 - 0 - ILN - - - GAZ063 - 100630 - McDuffie - GA - US - 33.49 - -82.47 - 0 - 0 - CAE - - - FLZ042 - 90420 - Citrus - FL - US - 28.86 - -82.46 - 0 - 0 - TBW - - - OHZ047 - 350470 - Knox - OH - US - 40.40 - -82.46 - 0 - 0 - CLE - - - FLZ049 - 90490 - Pasco - FL - US - 28.32 - -82.45 - 0 - 0 - TBW - - - OHZ074 - 350740 - Hocking - OH - US - 39.50 - -82.45 - 0 - 0 - ILN - - - GAZ040 - 100400 - Lincoln - GA - US - 33.81 - -82.44 - 0 - 0 - CAE - - - GAZ076 - 100760 - Jefferson - GA - US - 33.04 - -82.44 - 0 - 0 - FFC - - - GAZ134 - 101340 - Bacon - GA - US - 31.56 - -82.42 - 0 - 0 - JAX - - - GAZ150 - 101500 - Ware - GA - US - 31.02 - -82.41 - 0 - 0 - JAX - - - TNZ045 - 420450 - Unicoi - TN - US - 36.11 - -82.41 - 0 - 0 - MRX - - - WVZ005 - 480050 - Wayne - WV - US - 38.14 - -82.41 - 0 - 0 - RLX - - - FLZ055 - 90550 - Manatee - FL - US - 27.43 - -82.40 - 0 - 0 - TBW - - - FLZ048 - 90480 - Hernando - FL - US - 28.56 - -82.37 - 0 - 0 - TBW - - - FLZ030 - 90300 - Union - FL - US - 30.03 - -82.35 - 0 - 0 - JAX - - - FLZ036 - 90360 - Alachua - FL - US - 29.68 - -82.35 - 0 - 0 - JAX - - - FLZ051 - 90510 - Hillsborough - FL - US - 27.91 - -82.35 - 0 - 0 - TBW - - - FLZ060 - 90600 - Sarasota - FL - US - 27.17 - -82.35 - 0 - 0 - TBW - - - KYZ120 - 171200 - Pike - KY - US - 37.47 - -82.35 - 0 - 0 - JKL - - - OHZ086 - 350860 - Gallia - OH - US - 38.81 - -82.34 - 0 - 0 - RLX - - - SCZ006 - 400060 - Greater_Greenville - SC - US - 34.77 - -82.34 - 0 - 0 - GSP - - - VAZ003 - 460030 - Dickenson - VA - US - 37.13 - -82.34 - 0 - 0 - RLX - - - GAZ113 - 101130 - Toombs - GA - US - 32.13 - -82.33 - 0 - 0 - FFC - - - GAZ086 - 100860 - Emanuel - GA - US - 32.56 - -82.32 - 0 - 0 - FFC - - - SCZ018 - 400180 - McCormick - SC - US - 33.83 - -82.32 - 0 - 0 - CAE - - - NCZ049 - 330490 - Yancey - NC - US - 35.89 - -82.31 - 0 - 0 - GSP - - - NCZ509 - 335090 - Polk_Mountains - NC - US - 35.29 - -82.31 - 0 - 0 - GSP - - - GAZ135 - 101350 - Appling - GA - US - 31.72 - -82.30 - 0 - 0 - JAX - - - OHZ030 - 350300 - Ashland - OH - US - 40.81 - -82.28 - 0 - 0 - CLE - - - WVZ006 - 480060 - Cabell - WV - US - 38.41 - -82.27 - 0 - 0 - RLX - - - TNZ017 - 420170 - Sullivan - TN - US - 36.51 - -82.26 - 0 - 0 - MRX - - - FLZ023 - 90230 - Baker - FL - US - 30.36 - -82.25 - 0 - 0 - JAX - - - GAZ064 - 100640 - Columbia - GA - US - 33.53 - -82.24 - 0 - 0 - CAE - - - OHZ066 - 350660 - Perry - OH - US - 39.74 - -82.24 - 0 - 0 - RLX - - - FLZ031 - 90310 - Bradford - FL - US - 29.93 - -82.23 - 0 - 0 - JAX - - - GAZ151 - 101510 - Pierce - GA - US - 31.37 - -82.20 - 0 - 0 - JAX - - - NCZ507 - 335070 - Rutherford_Mountains - NC - US - 35.46 - -82.18 - 0 - 0 - GSP - - - GAZ164 - 101640 - Charlton - GA - US - 30.71 - -82.15 - 0 - 0 - JAX - - - TNZ046 - 420460 - Northwest_Carter - TN - US - 36.38 - -82.15 - 0 - 0 - MRX - - - FLZ043 - 90430 - Sumter - FL - US - 28.63 - -82.13 - 0 - 0 - TBW - - - NCZ510 - 335100 - Eastern_Polk - NC - US - 35.29 - -82.13 - 0 - 0 - GSP - - - NCZ050 - 330500 - Mitchell - NC - US - 35.98 - -82.12 - 0 - 0 - GSP - - - OHZ010 - 350100 - Lorain - OH - US - 41.29 - -82.11 - 0 - 0 - CLE - - - TNZ047 - 420470 - Southeast_Carter - TN - US - 36.23 - -82.11 - 0 - 0 - MRX - - - WVZ024 - 480240 - Mingo - WV - US - 37.74 - -82.11 - 0 - 0 - RLX - - - NCZ505 - 335050 - McDowell_Mountains - NC - US - 35.74 - -82.10 - 0 - 0 - GSP - - - SCZ019 - 400190 - Greenwood - SC - US - 34.18 - -82.10 - 0 - 0 - GSP - - - FLZ040 - 90400 - Marion - FL - US - 29.24 - -82.09 - 0 - 0 - JAX - - - GAZ065 - 100650 - Richmond - GA - US - 33.39 - -82.09 - 0 - 0 - CAE - - - VAZ006 - 460060 - Russell - VA - US - 36.93 - -82.09 - 0 - 0 - MRX - - - GAZ099 - 100990 - Candler - GA - US - 32.41 - -82.08 - 0 - 0 - CHS - - - WVZ013 - 480130 - Lincoln - WV - US - 38.16 - -82.04 - 0 - 0 - RLX - - - OHZ085 - 350850 - Meigs - OH - US - 39.04 - -82.03 - 0 - 0 - RLX - - - OHZ075 - 350750 - Athens - OH - US - 39.36 - -82.01 - 0 - 0 - RLX - - - VAZ004 - 460040 - Buchanan - VA - US - 37.29 - -82.01 - 0 - 0 - RLX - - - GAZ114 - 101140 - Tattnall - GA - US - 32.05 - -82.00 - 0 - 0 - CHS - - - GAZ152 - 101520 - Brantley - GA - US - 31.19 - -82.00 - 0 - 0 - JAX - - - WVZ007 - 480070 - Mason - WV - US - 38.75 - -82.00 - 0 - 0 - RLX - - - SCZ012 - 400120 - Laurens - SC - US - 34.49 - -81.98 - 0 - 0 - GSP - - - FLZ062 - 90620 - Charlotte - FL - US - 26.90 - -81.97 - 0 - 0 - TBW - - - VAZ008 - 460080 - Washington - VA - US - 36.76 - -81.97 - 0 - 0 - MRX - - - GAZ087 - 100870 - Jenkins - GA - US - 32.78 - -81.96 - 0 - 0 - CHS - - - OHZ057 - 350570 - Muskingum - OH - US - 39.96 - -81.96 - 0 - 0 - PBZ - - - SCZ007 - 400070 - Spartanburg - SC - US - 34.89 - -81.96 - 0 - 0 - GSP - - - NCZ506 - 335060 - Eastern_McDowell - NC - US - 35.64 - -81.95 - 0 - 0 - GSP - - - GAZ077 - 100770 - Burke - GA - US - 33.05 - -81.94 - 0 - 0 - CAE - - - NCZ508 - 335080 - Greater_Rutherford - NC - US - 35.39 - -81.94 - 0 - 0 - GSP - - - OHZ038 - 350380 - Holmes - OH - US - 40.56 - -81.93 - 0 - 0 - CLE - - - FLZ065 - 90650 - Lee - FL - US - 26.55 - -81.92 - 0 - 0 - TBW - - - OHZ020 - 350200 - Medina - OH - US - 41.13 - -81.92 - 0 - 0 - CLE - - - NCZ033 - 330330 - Avery - NC - US - 36.10 - -81.91 - 0 - 0 - GSP - - - SCZ025 - 400250 - Edgefield - SC - US - 33.76 - -81.91 - 0 - 0 - CAE - - - OHZ048 - 350480 - Coshocton - OH - US - 40.30 - -81.90 - 0 - 0 - PBZ - - - WVZ025 - 480250 - Logan - WV - US - 37.83 - -81.90 - 0 - 0 - RLX - - - GAZ136 - 101360 - Wayne - GA - US - 31.58 - -81.88 - 0 - 0 - JAX - - - OHZ031 - 350310 - Wayne - OH - US - 40.83 - -81.88 - 0 - 0 - CLE - - - WVZ014 - 480140 - Putnam - WV - US - 38.48 - -81.88 - 0 - 0 - RLX - - - GAZ115 - 101150 - Evans - GA - US - 32.16 - -81.87 - 0 - 0 - CHS - - - NCZ503 - 335030 - Burke_Mountains - NC - US - 35.88 - -81.85 - 0 - 0 - GSP - - - TNZ018 - 420180 - Johnson - TN - US - 36.44 - -81.85 - 0 - 0 - MRX - - - OHZ067 - 350670 - Morgan - OH - US - 39.61 - -81.83 - 0 - 0 - RLX - - - FLZ032 - 90320 - Clay - FL - US - 29.96 - -81.82 - 0 - 0 - JAX - - - FLZ056 - 90560 - Hardee - FL - US - 27.49 - -81.81 - 0 - 0 - TBW - - - FLZ061 - 90610 - De_Soto - FL - US - 27.19 - -81.81 - 0 - 0 - TBW - - - FLZ144 - 91440 - Southern_Lake_County - FL - US - 28.56 - -81.80 - 0 - 0 - MLB - - - GAZ165 - 101650 - Inland_Camden - GA - US - 30.95 - -81.76 - 0 - 0 - JAX - - - FLZ037 - 90370 - Putnam - FL - US - 29.58 - -81.75 - 0 - 0 - JAX - - - FLZ024 - 90240 - Nassau - FL - US - 30.54 - -81.74 - 0 - 0 - JAX - - - SCZ026 - 400260 - Saluda - SC - US - 33.99 - -81.74 - 0 - 0 - CAE - - - FLZ069 - 90690 - Coastal_Collier_County - FL - US - 26.07 - -81.73 - 0 - 0 - MFL - - - GAZ100 - 101000 - Bulloch - GA - US - 32.40 - -81.73 - 0 - 0 - CHS - - - GAZ137 - 101370 - Long - GA - US - 31.77 - -81.73 - 0 - 0 - CHS - - - WVZ026 - 480260 - Boone - WV - US - 38.00 - -81.72 - 0 - 0 - RLX - - - FLZ025 - 90250 - Duval - FL - US - 30.34 - -81.71 - 0 - 0 - JAX - - - WVZ008 - 480080 - Jackson - WV - US - 38.83 - -81.71 - 0 - 0 - RLX - - - NCZ018 - 330180 - Watauga - NC - US - 36.25 - -81.68 - 0 - 0 - RNK - - - NCZ504 - 335040 - Greater_Burke - NC - US - 35.72 - -81.66 - 0 - 0 - GSP - - - OHZ011 - 350110 - Cuyahoga - OH - US - 41.45 - -81.66 - 0 - 0 - CLE - - - WVZ033 - 480330 - McDowell - WV - US - 37.38 - -81.65 - 0 - 0 - RLX - - - FLZ044 - 90440 - Northern_Lake_County - FL - US - 29.03 - -81.64 - 0 - 0 - MLB - - - SCZ013 - 400130 - Union - SC - US - 34.68 - -81.64 - 0 - 0 - GSP - - - GAZ088 - 100880 - Screven - GA - US - 32.77 - -81.63 - 0 - 0 - CHS - - - GAZ153 - 101530 - Inland_Glynn - GA - US - 31.28 - -81.63 - 0 - 0 - JAX - - - FLZ052 - 90520 - Polk - FL - US - 28.00 - -81.62 - 0 - 0 - TBW - - - SCZ008 - 400080 - Cherokee - SC - US - 35.01 - -81.62 - 0 - 0 - GSP - - - SCZ020 - 400200 - Newberry - SC - US - 34.29 - -81.62 - 0 - 0 - CAE - - - NCZ501 - 335010 - Caldwell_Mountains - NC - US - 36.01 - -81.61 - 0 - 0 - GSP - - - SCZ030 - 400300 - Aiken - SC - US - 33.54 - -81.60 - 0 - 0 - CAE - - - VAZ007 - 460070 - Tazewell - VA - US - 37.14 - -81.56 - 0 - 0 - RNK - - - WVZ015 - 480150 - Kanawha - WV - US - 38.30 - -81.56 - 0 - 0 - RLX - - - FLZ078 - 90780 - Monroe/Lower_Keys - FL - US - 24.64 - -81.55 - 0 - 0 - KEY - - - GAZ166 - 101660 - Coastal_Camden - GA - US - 30.91 - -81.55 - 0 - 0 - JAX - - - GAZ138 - 101380 - Inland_Liberty - GA - US - 31.87 - -81.54 - 0 - 0 - CHS - - - NCZ068 - 330680 - Cleveland - NC - US - 35.36 - -81.54 - 0 - 0 - GSP - - - VAZ009 - 460090 - Smyth - VA - US - 36.82 - -81.54 - 0 - 0 - RNK - - - WVZ034 - 480340 - Wyoming - WV - US - 37.60 - -81.54 - 0 - 0 - RLX - - - OHZ021 - 350210 - Summit - OH - US - 41.13 - -81.53 - 0 - 0 - CLE - - - NCZ502 - 335020 - Greater_Caldwell - NC - US - 35.91 - -81.52 - 0 - 0 - GSP - - - GAZ116 - 101160 - Inland_Bryan - GA - US - 32.00 - -81.50 - 0 - 0 - CHS - - - WVZ009 - 480090 - Wood - WV - US - 39.22 - -81.50 - 0 - 0 - RLX - - - NCZ001 - 330010 - Ashe - NC - US - 36.41 - -81.49 - 0 - 0 - RNK - - - OHZ039 - 350390 - Tuscarawas - OH - US - 40.43 - -81.49 - 0 - 0 - PBZ - - - GAZ140 - 101400 - Inland_McIntosh - GA - US - 31.52 - -81.48 - 0 - 0 - CHS - - - SCZ035 - 400350 - Barnwell - SC - US - 33.29 - -81.48 - 0 - 0 - CAE - - - OHZ058 - 350580 - Guernsey - OH - US - 40.02 - -81.47 - 0 - 0 - PBZ - - - OHZ068 - 350680 - Noble - OH - US - 39.76 - -81.46 - 0 - 0 - PBZ - - - FLZ033 - 90330 - St._Johns - FL - US - 29.94 - -81.45 - 0 - 0 - JAX - - - OHZ076 - 350760 - Washington - OH - US - 39.43 - -81.45 - 0 - 0 - RLX - - - GAZ154 - 101540 - Coastal_Glynn - GA - US - 31.23 - -81.41 - 0 - 0 - JAX - - - WVZ017 - 480170 - Wirt - WV - US - 39.04 - -81.38 - 0 - 0 - RLX - - - FLZ041 - 90410 - Inland_Volusia_County - FL - US - 29.10 - -81.37 - 0 - 0 - MLB - - - OHZ032 - 350320 - Stark - OH - US - 40.81 - -81.36 - 0 - 0 - CLE - - - SCZ040 - 400400 - Allendale - SC - US - 32.95 - -81.34 - 0 - 0 - CHS - - - GAZ101 - 101010 - Effingham - GA - US - 32.35 - -81.33 - 0 - 0 - CHS - - - GAZ141 - 101410 - Coastal_McIntosh - GA - US - 31.46 - -81.33 - 0 - 0 - CHS - - - WVZ016 - 480160 - Roane - WV - US - 38.74 - -81.32 - 0 - 0 - RLX - - - FLZ038 - 90380 - Flagler - FL - US - 29.47 - -81.31 - 0 - 0 - JAX - - - FLZ070 - 90700 - Inland_Collier_County - FL - US - 26.16 - -81.31 - 0 - 0 - MFL - - - FLZ045 - 90450 - Orange - FL - US - 28.56 - -81.27 - 0 - 0 - MLB - - - FLZ053 - 90530 - Osceola - FL - US - 27.99 - -81.26 - 0 - 0 - MLB - - - FLZ057 - 90570 - Highlands - FL - US - 27.34 - -81.26 - 0 - 0 - TBW - - - VAZ015 - 460150 - Grayson - VA - US - 36.69 - -81.26 - 0 - 0 - RNK - - - GAZ118 - 101180 - Inland_Chatham - GA - US - 32.07 - -81.24 - 0 - 0 - CHS - - - OHZ012 - 350120 - Lake - OH - US - 41.71 - -81.24 - 0 - 0 - CLE - - - SCZ027 - 400270 - Lexington - SC - US - 33.92 - -81.24 - 0 - 0 - CAE - - - NCZ056 - 330560 - Catawba - NC - US - 35.68 - -81.23 - 0 - 0 - GSP - - - NCZ069 - 330690 - Lincoln - NC - US - 35.48 - -81.23 - 0 - 0 - GSP - - - FLZ046 - 90460 - Seminole - FL - US - 28.74 - -81.22 - 0 - 0 - MLB - - - FLZ063 - 90630 - Glades - FL - US - 26.99 - -81.22 - 0 - 0 - MFL - - - FLZ066 - 90660 - Hendry - FL - US - 26.52 - -81.22 - 0 - 0 - MFL - - - WVZ035 - 480350 - Raleigh - WV - US - 37.75 - -81.22 - 0 - 0 - RLX - - - GAZ139 - 101390 - Coastal_Liberty - GA - US - 31.66 - -81.21 - 0 - 0 - CHS - - - NCZ019 - 330190 - Wilkes - NC - US - 36.21 - -81.21 - 0 - 0 - RNK - - - GAZ117 - 101170 - Coastal_Bryan - GA - US - 31.83 - -81.20 - 0 - 0 - CHS - - - OHZ013 - 350130 - Geauga - OH - US - 41.53 - -81.19 - 0 - 0 - CLE - - - OHZ022 - 350220 - Portage - OH - US - 41.17 - -81.19 - 0 - 0 - CLE - - - WVZ010 - 480100 - Pleasants - WV - US - 39.37 - -81.19 - 0 - 0 - RLX - - - NCZ070 - 330700 - Gaston - NC - US - 35.28 - -81.18 - 0 - 0 - GSP - - - SCZ009 - 400090 - York - SC - US - 34.99 - -81.18 - 0 - 0 - GSP - - - SCZ014 - 400140 - Chester - SC - US - 34.68 - -81.18 - 0 - 0 - GSP - - - NCZ035 - 330350 - Alexander - NC - US - 35.90 - -81.17 - 0 - 0 - GSP - - - VAZ010 - 460100 - Bland - VA - US - 37.13 - -81.15 - 0 - 0 - RNK - - - WVZ018 - 480180 - Calhoun - WV - US - 38.83 - -81.13 - 0 - 0 - RLX - - - FLZ075 - 90750 - Mainland_Monroe - FL - US - 25.46 - -81.12 - 0 - 0 - MFL - - - NCZ002 - 330020 - Alleghany - NC - US - 36.47 - -81.12 - 0 - 0 - RNK - - - SCZ042 - 400420 - Hampton - SC - US - 32.79 - -81.12 - 0 - 0 - CHS - - - OHZ049 - 350490 - Harrison - OH - US - 40.29 - -81.10 - 0 - 0 - PBZ - - - SCZ021 - 400210 - Fairfield - SC - US - 34.37 - -81.10 - 0 - 0 - CAE - - - WVZ042 - 480420 - Mercer - WV - US - 37.42 - -81.10 - 0 - 0 - RNK - - - OHZ040 - 350400 - Carroll - OH - US - 40.57 - -81.09 - 0 - 0 - PBZ - - - OHZ069 - 350690 - Monroe - OH - US - 39.70 - -81.07 - 0 - 0 - PBZ - - - WVZ019 - 480190 - Ritchie - WV - US - 39.20 - -81.07 - 0 - 0 - RLX - - - WVZ036 - 480360 - Fayette - WV - US - 38.04 - -81.07 - 0 - 0 - RLX - - - VAZ012 - 460120 - Wythe - VA - US - 36.92 - -81.06 - 0 - 0 - RNK - - - SCZ047 - 400470 - Inland_Jasper - SC - US - 32.42 - -81.05 - 0 - 0 - CHS - - - WVZ027 - 480270 - Clay - WV - US - 38.47 - -81.05 - 0 - 0 - RLX - - - FLZ141 - 91410 - Coastal_Volusia_County - FL - US - 29.02 - -81.03 - 0 - 0 - MLB - - - GAZ119 - 101190 - Coastal_Chatham - GA - US - 31.91 - -81.02 - 0 - 0 - CHS - - - SCZ041 - 400410 - Bamberg - SC - US - 33.23 - -81.01 - 0 - 0 - CAE - - - SCZ051 - 400510 - Coastal_Jasper - SC - US - 32.27 - -81.00 - 0 - 0 - CHS - - - OHZ059 - 350590 - Belmont - OH - US - 40.00 - -80.97 - 0 - 0 - PBZ - - - SCZ028 - 400280 - Richland - SC - US - 34.00 - -80.97 - 0 - 0 - CAE - - - FLZ077 - 90770 - Monroe/Middle_Keys - FL - US - 24.76 - -80.96 - 0 - 0 - KEY - - - FLZ058 - 90580 - Okeechobee - FL - US - 27.38 - -80.94 - 0 - 0 - MLB - - - NCZ036 - 330360 - Iredell - NC - US - 35.78 - -80.90 - 0 - 0 - GSP - - - WVZ011 - 480110 - Tyler - WV - US - 39.45 - -80.87 - 0 - 0 - RLX - - - WVZ043 - 480430 - Summers - WV - US - 37.65 - -80.87 - 0 - 0 - RNK - - - FLZ147 - 91470 - Northern_Brevard_County - FL - US - 28.56 - -80.86 - 0 - 0 - MLB - - - WVZ037 - 480370 - Nicholas - WV - US - 38.32 - -80.84 - 0 - 0 - RLX - - - WVZ029 - 480290 - Gilmer - WV - US - 38.92 - -80.83 - 0 - 0 - RLX - - - NCZ071 - 330710 - Mecklenburg - NC - US - 35.26 - -80.80 - 0 - 0 - GSP - - - OHZ033 - 350330 - Mahoning - OH - US - 41.01 - -80.80 - 0 - 0 - CLE - - - OHZ041 - 350410 - Columbiana - OH - US - 40.76 - -80.80 - 0 - 0 - PBZ - - - SCZ036 - 400360 - Orangeburg - SC - US - 33.44 - -80.79 - 0 - 0 - CAE - - - OHZ050 - 350500 - Jefferson - OH - US - 40.37 - -80.77 - 0 - 0 - PBZ - - - SCZ037 - 400370 - Calhoun - SC - US - 33.67 - -80.77 - 0 - 0 - CAE - - - OHZ014 - 350140 - Ashtabula_Inland - OH - US - 41.71 - -80.76 - 0 - 0 - CLE - - - OHZ023 - 350230 - Trumbull - OH - US - 41.31 - -80.76 - 0 - 0 - CLE - - - OHZ089 - 350890 - Ashtabula_Lakeshore - OH - US - 41.88 - -80.76 - 0 - 0 - CLE - - - VAZ016 - 460160 - Carroll - VA - US - 36.74 - -80.75 - 0 - 0 - RNK - - - WVZ028 - 480280 - Braxton - WV - US - 38.71 - -80.74 - 0 - 0 - RLX - - - SCZ043 - 400430 - Inland_Colleton - SC - US - 32.92 - -80.73 - 0 - 0 - CHS - - - WVZ020 - 480200 - Doddridge - WV - US - 39.27 - -80.73 - 0 - 0 - RLX - - - SCZ048 - 400480 - Beaufort - SC - US - 32.39 - -80.72 - 0 - 0 - CHS - - - VAZ011 - 460110 - Giles - VA - US - 37.31 - -80.72 - 0 - 0 - RNK - - - VAZ013 - 460130 - Pulaski - VA - US - 37.06 - -80.72 - 0 - 0 - RNK - - - NCZ003 - 330030 - Surry - NC - US - 36.40 - -80.70 - 0 - 0 - RNK - - - WVZ004 - 480040 - Marshall - WV - US - 39.88 - -80.70 - 0 - 0 - PBZ - - - WVZ012 - 480120 - Wetzel - WV - US - 39.58 - -80.67 - 0 - 0 - PBZ - - - FLZ047 - 90470 - Southern_Brevard_County - FL - US - 28.08 - -80.66 - 0 - 0 - MLB - - - NCZ020 - 330200 - Yadkin - NC - US - 36.16 - -80.66 - 0 - 0 - RNK - - - SCZ015 - 400150 - Lancaster - SC - US - 34.76 - -80.66 - 0 - 0 - CAE - - - FLZ174 - 91740 - Far_South_Miami-Dade_County - FL - US - 25.30 - -80.63 - 0 - 0 - MFL - - - WVZ003 - 480030 - Ohio - WV - US - 40.11 - -80.63 - 0 - 0 - PBZ - - - FLZ073 - 90730 - Inland_Miami-Dade_County - FL - US - 25.69 - -80.61 - 0 - 0 - MFL - - - FLZ054 - 90540 - Indian_River - FL - US - 27.71 - -80.60 - 0 - 0 - MLB - - - WVZ001 - 480010 - Hancock - WV - US - 40.52 - -80.60 - 0 - 0 - PBZ - - - WVZ002 - 480020 - Brooke - WV - US - 40.28 - -80.60 - 0 - 0 - PBZ - - - FLZ071 - 90710 - Inland_Broward_County - FL - US - 26.15 - -80.59 - 0 - 0 - MFL - - - SCZ022 - 400220 - Kershaw - SC - US - 34.34 - -80.58 - 0 - 0 - CAE - - - NCZ082 - 330820 - Union - NC - US - 35.01 - -80.56 - 0 - 0 - GSP - - - FLZ067 - 90670 - Inland_Palm_Beach_County - FL - US - 26.64 - -80.54 - 0 - 0 - MFL - - - NCZ072 - 330720 - Cabarrus - NC - US - 35.35 - -80.54 - 0 - 0 - GSP - - - WVZ044 - 480440 - Monroe - WV - US - 37.55 - -80.54 - 0 - 0 - RNK - - - NCZ037 - 330370 - Davie - NC - US - 35.90 - -80.53 - 0 - 0 - GSP - - - WVZ030 - 480300 - Lewis - WV - US - 38.94 - -80.52 - 0 - 0 - RLX - - - NCZ057 - 330570 - Rowan - NC - US - 35.67 - -80.47 - 0 - 0 - GSP - - - SCZ049 - 400490 - Coastal_Colleton - SC - US - 32.61 - -80.46 - 0 - 0 - CHS - - - FLZ059 - 90590 - St._Lucie - FL - US - 27.38 - -80.44 - 0 - 0 - MLB - - - SCZ044 - 400440 - Dorchester - SC - US - 33.07 - -80.44 - 0 - 0 - CHS - - - WVZ038 - 480380 - Webster - WV - US - 38.49 - -80.43 - 0 - 0 - RLX - - - WVZ045 - 480450 - Greenbrier - WV - US - 37.98 - -80.43 - 0 - 0 - RNK - - - VAZ014 - 460140 - Montgomery - VA - US - 37.17 - -80.40 - 0 - 0 - RNK - - - WVZ031 - 480310 - Harrison - WV - US - 39.28 - -80.39 - 0 - 0 - RLX - - - FLZ064 - 90640 - Martin - FL - US - 27.11 - -80.38 - 0 - 0 - MLB - - - FLZ076 - 90760 - Monroe/Upper_Keys - FL - US - 25.15 - -80.38 - 0 - 0 - KEY - - - VAZ017 - 460170 - Floyd - VA - US - 36.92 - -80.37 - 0 - 0 - RNK - - - PAZ020 - 380200 - Beaver - PA - US - 40.67 - -80.34 - 0 - 0 - PBZ - - - VAZ032 - 460320 - Patrick - VA - US - 36.71 - -80.33 - 0 - 0 - RNK - - - PAZ013 - 380130 - Lawrence - PA - US - 40.99 - -80.31 - 0 - 0 - PBZ - - - FLZ173 - 91730 - Coastal_Miami_Dade_County - FL - US - 25.64 - -80.30 - 0 - 0 - MFL - - - FLZ072 - 90720 - Metro_Broward_County - FL - US - 26.15 - -80.28 - 0 - 0 - MFL - - - FLZ074 - 90740 - Metropolitan_Miami_Dade - FL - US - 25.78 - -80.28 - 0 - 0 - MFL - - - NCZ073 - 330730 - Stanly - NC - US - 35.33 - -80.28 - 0 - 0 - RAH - - - NCZ021 - 330210 - Forsyth - NC - US - 36.11 - -80.27 - 0 - 0 - RAH - - - SCZ031 - 400310 - Sumter - SC - US - 33.90 - -80.27 - 0 - 0 - CAE - - - NCZ038 - 330380 - Davidson - NC - US - 35.76 - -80.26 - 0 - 0 - RAH - - - PAZ007 - 380070 - Mercer - PA - US - 41.28 - -80.26 - 0 - 0 - PBZ - - - NCZ004 - 330040 - Stokes - NC - US - 36.40 - -80.24 - 0 - 0 - RNK - - - SCZ029 - 400290 - Lee - SC - US - 34.16 - -80.23 - 0 - 0 - CAE - - - WVZ039 - 480390 - Upshur - WV - US - 38.90 - -80.23 - 0 - 0 - RLX - - - PAZ031 - 380310 - Greene - PA - US - 39.87 - -80.22 - 0 - 0 - PBZ - - - VAZ018 - 460180 - Craig - VA - US - 37.49 - -80.22 - 0 - 0 - RNK - - - WVZ021 - 480210 - Marion - WV - US - 39.51 - -80.22 - 0 - 0 - PBZ - - - SCZ038 - 400380 - Clarendon - SC - US - 33.69 - -80.21 - 0 - 0 - CAE - - - PAZ029 - 380290 - Washington - PA - US - 40.22 - -80.19 - 0 - 0 - PBZ - - - SCZ016 - 400160 - Chesterfield - SC - US - 34.59 - -80.17 - 0 - 0 - CAE - - - FLZ068 - 90680 - Metro_Palm_Beach_County - FL - US - 26.64 - -80.14 - 0 - 0 - MFL - - - PAZ001 - 380010 - Northern_Erie - PA - US - 42.10 - -80.14 - 0 - 0 - CLE - - - FLZ172 - 91720 - Coastal_Broward_County - FL - US - 26.15 - -80.12 - 0 - 0 - MFL - - - WVZ022 - 480220 - Monongalia - WV - US - 39.58 - -80.10 - 0 - 0 - PBZ - - - NCZ083 - 330830 - Anson - NC - US - 35.01 - -80.09 - 0 - 0 - RAH - - - PAZ002 - 380020 - Southern_Erie - PA - US - 42.03 - -80.07 - 0 - 0 - CLE - - - PAZ003 - 380030 - Crawford - PA - US - 41.67 - -80.07 - 0 - 0 - CLE - - - FLZ168 - 91680 - Coastal_Palm_Beach_County - FL - US - 26.65 - -80.06 - 0 - 0 - MFL - - - WVZ032 - 480320 - Taylor - WV - US - 39.34 - -80.06 - 0 - 0 - RLX - - - VAZ022 - 460220 - Roanoke - VA - US - 37.26 - -80.05 - 0 - 0 - RNK - - - PAZ021 - 380210 - Allegheny - PA - US - 40.44 - -80.03 - 0 - 0 - PBZ - - - WVZ040 - 480400 - Barbour - WV - US - 39.12 - -80.02 - 0 - 0 - RLX - - - WVZ046 - 480460 - Pocahontas - WV - US - 38.39 - -80.00 - 0 - 0 - RLX - - - SCZ023 - 400230 - Darlington - SC - US - 34.31 - -79.98 - 0 - 0 - ILM - - - VAZ019 - 460190 - Alleghany - VA - US - 37.78 - -79.95 - 0 - 0 - RNK - - - PAZ014 - 380140 - Butler - PA - US - 40.92 - -79.93 - 0 - 0 - PBZ - - - VAZ033 - 460330 - Franklin - VA - US - 37.01 - -79.92 - 0 - 0 - RNK - - - SCZ045 - 400450 - Berkeley - SC - US - 33.17 - -79.90 - 0 - 0 - CHS - - - NCZ074 - 330740 - Montgomery - NC - US - 35.32 - -79.89 - 0 - 0 - RAH - - - VAZ043 - 460430 - Henry - VA - US - 36.70 - -79.87 - 0 - 0 - RNK - - - SCZ050 - 400500 - Charleston - SC - US - 32.85 - -79.86 - 0 - 0 - CHS - - - WVZ047 - 480470 - Randolph - WV - US - 38.75 - -79.81 - 0 - 0 - RLX - - - NCZ039 - 330390 - Randolph - NC - US - 35.71 - -79.80 - 0 - 0 - RAH - - - NCZ022 - 330220 - Guilford - NC - US - 36.07 - -79.79 - 0 - 0 - RAH - - - VAZ023 - 460230 - Botetourt - VA - US - 37.55 - -79.79 - 0 - 0 - RNK - - - NCZ005 - 330050 - Rockingham - NC - US - 36.39 - -79.77 - 0 - 0 - RNK - - - NCZ084 - 330840 - Richmond - NC - US - 34.99 - -79.76 - 0 - 0 - RAH - - - VAZ020 - 460200 - Bath - VA - US - 38.06 - -79.75 - 0 - 0 - RNK - - - PAZ008 - 380080 - Venango - PA - US - 41.40 - -79.74 - 0 - 0 - PBZ - - - SCZ039 - 400390 - Williamsburg - SC - US - 33.59 - -79.71 - 0 - 0 - ILM - - - WVZ023 - 480230 - Preston - WV - US - 39.46 - -79.70 - 0 - 0 - PBZ - - - SCZ017 - 400170 - Marlboro - SC - US - 34.55 - -79.69 - 0 - 0 - ILM - - - SCZ032 - 400320 - Florence - SC - US - 34.04 - -79.69 - 0 - 0 - ILM - - - PAZ032 - 380320 - Fayette - PA - US - 39.93 - -79.66 - 0 - 0 - PBZ - - - WVZ041 - 480410 - Tucker - WV - US - 39.11 - -79.57 - 0 - 0 - PBZ - - - VAZ021 - 460210 - Highland - VA - US - 38.39 - -79.56 - 0 - 0 - LWX - - - VAZ034 - 460340 - Bedford - VA - US - 37.31 - -79.52 - 0 - 0 - RNK - - - NCZ085 - 330850 - Scotland - NC - US - 34.84 - -79.51 - 0 - 0 - RAH - - - PAZ015 - 380150 - Clarion - PA - US - 41.20 - -79.46 - 0 - 0 - PBZ - - - PAZ022 - 380220 - Armstrong - PA - US - 40.85 - -79.46 - 0 - 0 - PBZ - - - PAZ030 - 380300 - Westmoreland - PA - US - 40.36 - -79.44 - 0 - 0 - PBZ - - - WVZ501 - 485010 - Western_Grant - WV - US - 39.20 - -79.44 - 0 - 0 - LWX - - - NCZ075 - 330750 - Moore - NC - US - 35.28 - -79.43 - 0 - 0 - RAH - - - NYZ019 - 320190 - Chautauqua - NY - US - 42.29 - -79.41 - 0 - 0 - BUF - - - VAZ024 - 460240 - Rockbridge - VA - US - 37.81 - -79.41 - 0 - 0 - RNK - - - VAZ044 - 460440 - Pittsylvania - VA - US - 36.84 - -79.41 - 0 - 0 - RNK - - - NCZ023 - 330230 - Alamance - NC - US - 36.04 - -79.39 - 0 - 0 - RAH - - - SCZ024 - 400240 - Dillon - SC - US - 34.42 - -79.36 - 0 - 0 - ILM - - - SCZ033 - 400330 - Marion - SC - US - 34.00 - -79.35 - 0 - 0 - ILM - - - WVZ054 - 480540 - Pendleton - WV - US - 38.68 - -79.35 - 0 - 0 - LWX - - - NCZ006 - 330060 - Caswell - NC - US - 36.39 - -79.34 - 0 - 0 - RNK - - - SCZ046 - 400460 - Georgetown - SC - US - 33.45 - -79.34 - 0 - 0 - ILM - - - PAZ004 - 380040 - Warren - PA - US - 41.81 - -79.27 - 0 - 0 - CTP - - - NCZ086 - 330860 - Hoke - NC - US - 35.02 - -79.24 - 0 - 0 - RAH - - - PAZ009 - 380090 - Forest - PA - US - 41.47 - -79.24 - 0 - 0 - PBZ - - - NCZ040 - 330400 - Chatham - NC - US - 35.69 - -79.23 - 0 - 0 - RAH - - - MDZ001 - 200010 - Garrett - MD - US - 39.46 - -79.21 - 0 - 0 - PBZ - - - NCZ076 - 330760 - Lee - NC - US - 35.46 - -79.17 - 0 - 0 - RAH - - - WVZ502 - 485020 - Eastern_Grant - WV - US - 39.06 - -79.17 - 0 - 0 - LWX - - - VAZ035 - 460350 - Amherst - VA - US - 37.59 - -79.16 - 0 - 0 - RNK - - - PAZ023 - 380230 - Indiana - PA - US - 40.64 - -79.14 - 0 - 0 - PBZ - - - NCZ087 - 330870 - Robeson - NC - US - 34.63 - -79.13 - 0 - 0 - ILM - - - VAZ025 - 460250 - Augusta - VA - US - 38.18 - -79.13 - 0 - 0 - LWX - - - VAZ045 - 460450 - Campbell - VA - US - 37.25 - -79.13 - 0 - 0 - RNK - - - WVZ503 - 485030 - Western_Mineral - WV - US - 39.40 - -79.13 - 0 - 0 - LWX - - - NCZ024 - 330240 - Orange - NC - US - 36.04 - -79.11 - 0 - 0 - RAH - - - PAZ033 - 380330 - Somerset - PA - US - 40.00 - -79.04 - 0 - 0 - CTP - - - NCZ007 - 330070 - Person - NC - US - 36.39 - -78.98 - 0 - 0 - RAH - - - PAZ016 - 380160 - Jefferson - PA - US - 41.14 - -78.96 - 0 - 0 - PBZ - - - SCZ034 - 400340 - Horry - SC - US - 33.94 - -78.94 - 0 - 0 - ILM - - - MDZ501 - 205010 - Extreme_Western_Allegany - MD - US - 39.58 - -78.92 - 0 - 0 - LWX - - - VAZ036 - 460360 - Nelson - VA - US - 37.79 - -78.92 - 0 - 0 - LWX - - - WVZ504 - 485040 - Eastern_Mineral - WV - US - 39.44 - -78.89 - 0 - 0 - LWX - - - NCZ077 - 330770 - Harnett - NC - US - 35.38 - -78.88 - 0 - 0 - RAH - - - VAZ058 - 460580 - Halifax - VA - US - 36.80 - -78.88 - 0 - 0 - RNK - - - NCZ025 - 330250 - Durham - NC - US - 36.05 - -78.86 - 0 - 0 - RAH - - - VAZ026 - 460260 - Rockingham - VA - US - 38.53 - -78.86 - 0 - 0 - LWX - - - VAZ046 - 460460 - Appomattox - VA - US - 37.38 - -78.81 - 0 - 0 - RNK - - - WVZ055 - 480550 - Hardy - WV - US - 39.00 - -78.81 - 0 - 0 - LWX - - - NCZ088 - 330880 - Cumberland - NC - US - 35.04 - -78.80 - 0 - 0 - RAH - - - NYZ085 - 320850 - Southern_Erie - NY - US - 42.62 - -78.80 - 0 - 0 - BUF - - - NYZ001 - 320010 - Niagara - NY - US - 43.20 - -78.77 - 0 - 0 - BUF - - - NYZ010 - 320100 - Northern_Erie - NY - US - 42.94 - -78.74 - 0 - 0 - BUF - - - PAZ024 - 380240 - Cambria - PA - US - 40.48 - -78.71 - 0 - 0 - CTP - - - NYZ020 - 320200 - Cattaraugus - NY - US - 42.27 - -78.68 - 0 - 0 - BUF - - - VAZ059 - 460590 - Charlotte - VA - US - 36.98 - -78.68 - 0 - 0 - RNK - - - PAZ010 - 380100 - Elk - PA - US - 41.42 - -78.67 - 0 - 0 - CTP - - - WVZ050 - 480500 - Hampshire - WV - US - 39.32 - -78.66 - 0 - 0 - LWX - - - MDZ502 - 205020 - Central_and_Eastern_Allegany - MD - US - 39.58 - -78.65 - 0 - 0 - LWX - - - NCZ008 - 330080 - Granville - NC - US - 36.28 - -78.63 - 0 - 0 - RAH - - - NCZ041 - 330410 - Wake - NC - US - 35.79 - -78.63 - 0 - 0 - RAH - - - NCZ099 - 330990 - Columbus - NC - US - 34.21 - -78.61 - 0 - 0 - ILM - - - PAZ005 - 380050 - McKean - PA - US - 41.80 - -78.58 - 0 - 0 - CTP - - - VAZ027 - 460270 - Shenandoah - VA - US - 38.86 - -78.58 - 0 - 0 - LWX - - - VAZ047 - 460470 - Buckingham - VA - US - 37.56 - -78.55 - 0 - 0 - RNK - - - NCZ096 - 330960 - Bladen - NC - US - 34.61 - -78.53 - 0 - 0 - ILM - - - VAZ037 - 460370 - Albemarle - VA - US - 38.00 - -78.52 - 0 - 0 - LWX - - - PAZ034 - 380340 - Bedford - PA - US - 40.02 - -78.48 - 0 - 0 - CTP - - - VAZ029 - 460290 - Page - VA - US - 38.62 - -78.48 - 0 - 0 - LWX - - - VAZ038 - 460380 - Greene - VA - US - 38.33 - -78.47 - 0 - 0 - LWX - - - VAZ060 - 460600 - Prince_Edward - VA - US - 37.24 - -78.46 - 0 - 0 - AKQ - - - PAZ017 - 380170 - Clearfield - PA - US - 40.99 - -78.43 - 0 - 0 - CTP - - - NCZ009 - 330090 - Vance - NC - US - 36.35 - -78.40 - 0 - 0 - RAH - - - NCZ042 - 330420 - Johnston - NC - US - 35.53 - -78.39 - 0 - 0 - RAH - - - NCZ089 - 330890 - Sampson - NC - US - 34.93 - -78.39 - 0 - 0 - RAH - - - VAZ065 - 460650 - Mecklenburg - VA - US - 36.72 - -78.39 - 0 - 0 - AKQ - - - PAZ025 - 380250 - Blair - PA - US - 40.50 - -78.37 - 0 - 0 - CTP - - - NCZ100 - 331000 - Brunswick - NC - US - 34.10 - -78.30 - 0 - 0 - ILM - - - VAZ028 - 460280 - Frederick - VA - US - 39.23 - -78.29 - 0 - 0 - LWX - - - NCZ026 - 330260 - Franklin - NC - US - 36.04 - -78.28 - 0 - 0 - RAH - - - VAZ048 - 460480 - Fluvanna - VA - US - 37.85 - -78.28 - 0 - 0 - AKQ - - - VAZ061 - 460610 - Cumberland - VA - US - 37.52 - -78.28 - 0 - 0 - AKQ - - - VAZ039 - 460390 - Madison - VA - US - 38.43 - -78.27 - 0 - 0 - LWX - - - VAZ066 - 460660 - Lunenburg - VA - US - 36.95 - -78.25 - 0 - 0 - AKQ - - - WVZ051 - 480510 - Morgan - WV - US - 39.54 - -78.25 - 0 - 0 - LWX - - - NYZ002 - 320020 - Orleans - NY - US - 43.25 - -78.23 - 0 - 0 - BUF - - - NYZ012 - 320120 - Wyoming - NY - US - 42.70 - -78.22 - 0 - 0 - BUF - - - PAZ011 - 380110 - Cameron - PA - US - 41.42 - -78.21 - 0 - 0 - CTP - - - VAZ030 - 460300 - Warren - VA - US - 38.90 - -78.20 - 0 - 0 - LWX - - - NYZ011 - 320110 - Genesee - NY - US - 43.00 - -78.18 - 0 - 0 - BUF - - - VAZ040 - 460400 - Rappahannock - VA - US - 38.69 - -78.14 - 0 - 0 - LWX - - - PAZ035 - 380350 - Fulton - PA - US - 39.94 - -78.13 - 0 - 0 - CTP - - - NCZ010 - 330100 - Warren - NC - US - 36.37 - -78.11 - 0 - 0 - RAH - - - NCZ078 - 330780 - Wayne - NC - US - 35.37 - -78.06 - 0 - 0 - RAH - - - VAZ050 - 460500 - Orange - VA - US - 38.26 - -78.04 - 0 - 0 - LWX - - - VAZ067 - 460670 - Nottoway - VA - US - 37.14 - -78.03 - 0 - 0 - AKQ - - - WVZ052 - 480520 - Berkeley - WV - US - 39.44 - -78.03 - 0 - 0 - LWX - - - NYZ021 - 320210 - Allegany - NY - US - 42.26 - -78.01 - 0 - 0 - BUF - - - PAZ018 - 380180 - Northern_Centre - PA - US - 41.00 - -78.01 - 0 - 0 - CTP - - - VAZ049 - 460490 - Louisa - VA - US - 37.94 - -78.00 - 0 - 0 - AKQ - - - VAZ031 - 460310 - Clarke - VA - US - 39.12 - -77.99 - 0 - 0 - LWX - - - NCZ027 - 330270 - Nash - NC - US - 35.96 - -77.98 - 0 - 0 - RAH - - - PAZ026 - 380260 - Huntingdon - PA - US - 40.40 - -77.97 - 0 - 0 - CTP - - - VAZ068 - 460680 - Amelia - VA - US - 37.34 - -77.95 - 0 - 0 - AKQ - - - NCZ043 - 330430 - Wilson - NC - US - 35.71 - -77.93 - 0 - 0 - RAH - - - NCZ090 - 330900 - Duplin - NC - US - 34.95 - -77.93 - 0 - 0 - MHX - - - VAZ051 - 460510 - Culpeper - VA - US - 38.51 - -77.93 - 0 - 0 - LWX - - - PAZ006 - 380060 - Potter - PA - US - 41.74 - -77.91 - 0 - 0 - CTP - - - VAZ062 - 460620 - Goochland - VA - US - 37.73 - -77.90 - 0 - 0 - AKQ - - - VAZ069 - 460690 - Powhatan - VA - US - 37.55 - -77.90 - 0 - 0 - AKQ - - - NCZ097 - 330970 - Pender - NC - US - 34.51 - -77.89 - 0 - 0 - ILM - - - NCZ101 - 331010 - New_Hanover - NC - US - 34.16 - -77.88 - 0 - 0 - ILM - - - WVZ053 - 480530 - Jefferson - WV - US - 39.32 - -77.88 - 0 - 0 - LWX - - - VAZ079 - 460790 - Brunswick - VA - US - 36.79 - -77.86 - 0 - 0 - AKQ - - - VAZ041 - 460410 - Fauquier - VA - US - 38.71 - -77.84 - 0 - 0 - LWX - - - PAZ036 - 380360 - Franklin - PA - US - 40.01 - -77.78 - 0 - 0 - CTP - - - NYZ013 - 320130 - Livingston - NY - US - 42.73 - -77.77 - 0 - 0 - BUF - - - MDZ003 - 200030 - Washington - MD - US - 39.52 - -77.72 - 0 - 0 - LWX - - - PAZ012 - 380120 - Northern_Clinton - PA - US - 41.28 - -77.71 - 0 - 0 - CTP - - - PAZ019 - 380190 - Southern_Centre - PA - US - 40.89 - -77.69 - 0 - 0 - CTP - - - NYZ003 - 320030 - Monroe - NY - US - 43.16 - -77.68 - 0 - 0 - BUF - - - VAZ056 - 460560 - Spotsylvania - VA - US - 38.19 - -77.66 - 0 - 0 - LWX - - - NCZ079 - 330790 - Greene - NC - US - 35.50 - -77.65 - 0 - 0 - MHX - - - VAZ080 - 460800 - Dinwiddie - VA - US - 37.07 - -77.65 - 0 - 0 - AKQ - - - VAZ042 - 460420 - Loudoun - VA - US - 39.09 - -77.64 - 0 - 0 - LWX - - - NCZ011 - 330110 - Halifax - NC - US - 36.25 - -77.62 - 0 - 0 - RAH - - - NCZ091 - 330910 - Lenoir - NC - US - 35.21 - -77.61 - 0 - 0 - MHX - - - PAZ027 - 380270 - Mifflin - PA - US - 40.61 - -77.60 - 0 - 0 - CTP - - - NCZ028 - 330280 - Edgecombe - NC - US - 35.91 - -77.59 - 0 - 0 - RAH - - - VAZ070 - 460700 - Chesterfield - VA - US - 37.39 - -77.56 - 0 - 0 - AKQ - - - VAZ087 - 460870 - Greensville - VA - US - 36.72 - -77.56 - 0 - 0 - AKQ - - - PAZ028 - 380280 - Juniata - PA - US - 40.48 - -77.50 - 0 - 0 - CTP - - - NCZ012 - 330120 - Northampton - NC - US - 36.36 - -77.49 - 0 - 0 - AKQ - - - VAZ052 - 460520 - Pr_William/Manassas/Manassas_Pk - VA - US - 38.72 - -77.47 - 0 - 0 - LWX - - - VAZ055 - 460550 - Stafford - VA - US - 38.42 - -77.46 - 0 - 0 - LWX - - - VAZ063 - 460630 - Hanover - VA - US - 37.78 - -77.46 - 0 - 0 - AKQ - - - VAZ071 - 460710 - Henrico - VA - US - 37.53 - -77.42 - 0 - 0 - AKQ - - - MDZ004 - 200040 - Frederick - MD - US - 39.47 - -77.40 - 0 - 0 - LWX - - - NCZ044 - 330440 - Pitt - NC - US - 35.58 - -77.40 - 0 - 0 - MHX - - - NCZ092 - 330920 - Jones - NC - US - 35.01 - -77.39 - 0 - 0 - MHX - - - PAZ045 - 380450 - Southern_Clinton - PA - US - 41.09 - -77.39 - 0 - 0 - CTP - - - NYZ022 - 320220 - Steuben - NY - US - 42.29 - -77.36 - 0 - 0 - BGM - - - VAZ064 - 460640 - Caroline - VA - US - 38.01 - -77.36 - 0 - 0 - AKQ - - - NYZ014 - 320140 - Ontario - NY - US - 42.81 - -77.29 - 0 - 0 - BUF - - - PAZ056 - 380560 - Perry - PA - US - 40.41 - -77.29 - 0 - 0 - CTP - - - VAZ053 - 460530 - Fairfax - VA - US - 38.84 - -77.29 - 0 - 0 - LWX - - - VAZ088 - 460880 - Sussex - VA - US - 36.91 - -77.29 - 0 - 0 - AKQ - - - NCZ098 - 330980 - Onslow - NC - US - 34.72 - -77.26 - 0 - 0 - MHX - - - PAZ037 - 380370 - Tioga - PA - US - 41.77 - -77.25 - 0 - 0 - CTP - - - PAZ063 - 380630 - Cumberland - PA - US - 40.14 - -77.24 - 0 - 0 - CTP - - - PAZ064 - 380640 - Adams - PA - US - 39.90 - -77.22 - 0 - 0 - CTP - - - VAZ081 - 460810 - Prince_George - VA - US - 37.16 - -77.22 - 0 - 0 - AKQ - - - MDZ009 - 200090 - Montgomery - MD - US - 39.14 - -77.20 - 0 - 0 - LWX - - - VAZ057 - 460570 - King_George - VA - US - 38.28 - -77.18 - 0 - 0 - LWX - - - VAZ092 - 460920 - Southampton - VA - US - 36.78 - -77.16 - 0 - 0 - AKQ - - - NYZ015 - 320150 - Yates - NY - US - 42.61 - -77.13 - 0 - 0 - BGM - - - VAZ054 - 460540 - Arlington/Falls_Ch/Alexandria - VA - US - 38.86 - -77.12 - 0 - 0 - LWX - - - PAZ041 - 380410 - Northern_Lycoming - PA - US - 41.41 - -77.11 - 0 - 0 - CTP - - - PAZ049 - 380490 - Union - PA - US - 40.98 - -77.10 - 0 - 0 - CTP - - - NCZ029 - 330290 - Martin - NC - US - 35.86 - -77.09 - 0 - 0 - MHX - - - PAZ050 - 380500 - Snyder - PA - US - 40.76 - -77.09 - 0 - 0 - CTP - - - VAZ082 - 460820 - Charles_City - VA - US - 37.36 - -77.08 - 0 - 0 - AKQ - - - VAZ072 - 460720 - King_William - VA - US - 37.71 - -77.06 - 0 - 0 - AKQ - - - MDZ005 - 200050 - Carroll - MD - US - 39.53 - -77.05 - 0 - 0 - LWX - - - NCZ093 - 330930 - Craven - NC - US - 35.13 - -77.05 - 0 - 0 - MHX - - - NYZ004 - 320040 - Wayne - NY - US - 43.18 - -77.04 - 0 - 0 - BUF - - - DCZ001 - 510010 - District_of_Columbia - DC - US - 38.89 - -77.02 - 0 - 0 - LWX - - - NCZ030 - 330300 - Bertie - NC - US - 36.03 - -77.01 - 0 - 0 - AKQ - - - VAZ083 - 460830 - New_Kent - VA - US - 37.50 - -76.99 - 0 - 0 - AKQ - - - MDZ016 - 200160 - Charles - MD - US - 38.48 - -76.98 - 0 - 0 - LWX - - - NCZ013 - 330130 - Hertford - NC - US - 36.39 - -76.96 - 0 - 0 - AKQ - - - MDZ010 - 200100 - Howard - MD - US - 39.23 - -76.94 - 0 - 0 - LWX - - - VAZ074 - 460740 - Essex - VA - US - 37.95 - -76.93 - 0 - 0 - AKQ - - - VAZ073 - 460730 - King_and_Queen - VA - US - 37.70 - -76.92 - 0 - 0 - AKQ - - - VAZ089 - 460890 - Surry - VA - US - 37.10 - -76.91 - 0 - 0 - AKQ - - - MDZ013 - 200130 - Prince_Georges - MD - US - 38.83 - -76.88 - 0 - 0 - LWX - - - PAZ046 - 380460 - Southern_Lycoming - PA - US - 41.22 - -76.88 - 0 - 0 - CTP - - - NYZ023 - 320230 - Schuyler - NY - US - 42.40 - -76.86 - 0 - 0 - BGM - - - NCZ080 - 330800 - Beaufort - NC - US - 35.48 - -76.84 - 0 - 0 - MHX - - - VAZ075 - 460750 - Westmoreland - VA - US - 38.12 - -76.80 - 0 - 0 - AKQ - - - PAZ057 - 380570 - Dauphin - PA - US - 40.40 - -76.79 - 0 - 0 - CTP - - - NYZ016 - 320160 - Seneca - NY - US - 42.79 - -76.78 - 0 - 0 - BGM - - - NYZ024 - 320240 - Chemung - NY - US - 42.15 - -76.75 - 0 - 0 - BGM - - - VAZ090 - 460900 - James_City - VA - US - 37.32 - -76.75 - 0 - 0 - AKQ - - - VAZ076 - 460760 - Richmond - VA - US - 37.95 - -76.73 - 0 - 0 - AKQ - - - NCZ014 - 330140 - Gates - NC - US - 36.42 - -76.71 - 0 - 0 - AKQ - - - NCZ094 - 330940 - Pamlico - NC - US - 35.15 - -76.71 - 0 - 0 - MHX - - - VAZ093 - 460930 - Isle_of_Wight - VA - US - 36.89 - -76.71 - 0 - 0 - AKQ - - - PAZ065 - 380650 - York - PA - US - 39.97 - -76.69 - 0 - 0 - CTP - - - PAZ052 - 380520 - Northumberland - PA - US - 40.89 - -76.67 - 0 - 0 - CTP - - - VAZ096 - 460960 - Suffolk - VA - US - 36.74 - -76.67 - 0 - 0 - AKQ - - - NCZ031 - 330310 - Chowan - NC - US - 36.17 - -76.66 - 0 - 0 - AKQ - - - PAZ051 - 380510 - Montour - PA - US - 41.02 - -76.66 - 0 - 0 - CTP - - - MDZ006 - 200060 - Northern_Baltimore - MD - US - 39.57 - -76.64 - 0 - 0 - LWX - - - VAZ085 - 460850 - Middlesex - VA - US - 37.65 - -76.64 - 0 - 0 - AKQ - - - MDZ011 - 200110 - Southern_Baltimore - MD - US - 39.31 - -76.61 - 0 - 0 - LWX - - - MDZ014 - 200140 - Anne_Arundel - MD - US - 38.97 - -76.61 - 0 - 0 - LWX - - - NCZ045 - 330450 - Washington - NC - US - 35.84 - -76.60 - 0 - 0 - MHX - - - NCZ095 - 330950 - Carteret - NC - US - 34.85 - -76.60 - 0 - 0 - MHX - - - NYZ005 - 320050 - Northern_Cayuga - NY - US - 43.22 - -76.60 - 0 - 0 - BUF - - - MDZ017 - 200170 - St._Marys - MD - US - 38.28 - -76.59 - 0 - 0 - LWX - - - VAZ084 - 460840 - Gloucester - VA - US - 37.43 - -76.55 - 0 - 0 - AKQ - - - MDZ018 - 200180 - Calvert - MD - US - 38.54 - -76.54 - 0 - 0 - LWX - - - PAZ038 - 380380 - Bradford - PA - US - 41.77 - -76.53 - 0 - 0 - BGM - - - PAZ042 - 380420 - Sullivan - PA - US - 41.44 - -76.52 - 0 - 0 - CTP - - - VAZ091 - 460910 - York - VA - US - 37.23 - -76.51 - 0 - 0 - AKQ - - - NYZ017 - 320170 - Southern_Cayuga - NY - US - 42.82 - -76.50 - 0 - 0 - BGM - - - VAZ094 - 460940 - Newport_News/Hampton - VA - US - 37.10 - -76.50 - 0 - 0 - AKQ - - - NYZ025 - 320250 - Tompkins - NY - US - 42.45 - -76.47 - 0 - 0 - BGM - - - VAZ078 - 460780 - Lancaster - VA - US - 37.73 - -76.45 - 0 - 0 - AKQ - - - VAZ077 - 460770 - Northumberland - VA - US - 37.86 - -76.44 - 0 - 0 - AKQ - - - PAZ053 - 380530 - Columbia - PA - US - 41.04 - -76.43 - 0 - 0 - CTP - - - PAZ059 - 380590 - Lebanon - PA - US - 40.38 - -76.42 - 0 - 0 - CTP - - - NCZ032 - 330320 - Perquimans - NC - US - 36.22 - -76.40 - 0 - 0 - AKQ - - - MDZ007 - 200070 - Harford - MD - US - 39.50 - -76.32 - 0 - 0 - LWX - - - NYZ055 - 320550 - Tioga - NY - US - 42.20 - -76.32 - 0 - 0 - BGM - - - PAZ066 - 380660 - Lancaster - PA - US - 40.02 - -76.31 - 0 - 0 - CTP - - - VAZ095 - 460950 - Norfolk/Portsmouth - VA - US - 36.87 - -76.30 - 0 - 0 - AKQ - - - VAZ086 - 460860 - Mathews - VA - US - 37.42 - -76.29 - 0 - 0 - AKQ - - - NCZ015 - 330150 - Pasquotank - NC - US - 36.31 - -76.28 - 0 - 0 - AKQ - - - VAZ097 - 460970 - Chesapeake - VA - US - 36.71 - -76.28 - 0 - 0 - AKQ - - - NCZ081 - 330810 - Western_Hyde - NC - US - 35.51 - -76.26 - 0 - 0 - MHX - - - PAZ058 - 380580 - Schuylkill - PA - US - 40.72 - -76.23 - 0 - 0 - CTP - - - NCZ046 - 330460 - Tyrrell - NC - US - 35.79 - -76.21 - 0 - 0 - MHX - - - NYZ006 - 320060 - Oswego - NY - US - 43.43 - -76.19 - 0 - 0 - BUF - - - NYZ018 - 320180 - Onondaga - NY - US - 43.02 - -76.19 - 0 - 0 - BGM - - - NCZ016 - 330160 - Camden - NC - US - 36.36 - -76.17 - 0 - 0 - AKQ - - - MDZ012 - 200120 - Kent - MD - US - 39.20 - -76.15 - 0 - 0 - PHI - - - MDZ019 - 200190 - Talbot - MD - US - 38.76 - -76.15 - 0 - 0 - PHI - - - NYZ044 - 320440 - Cortland - NY - US - 42.60 - -76.07 - 0 - 0 - BGM - - - MDZ015 - 200150 - Queen_Anne's - MD - US - 39.06 - -76.06 - 0 - 0 - PHI - - - VAZ098 - 460980 - Virginia_Beach - VA - US - 36.74 - -76.05 - 0 - 0 - AKQ - - - MDZ021 - 200210 - Dorchester - MD - US - 38.41 - -76.03 - 0 - 0 - AKQ - - - PAZ043 - 380430 - Wyoming - PA - US - 41.52 - -76.01 - 0 - 0 - BGM - - - PAZ060 - 380600 - Berks - PA - US - 40.41 - -75.99 - 0 - 0 - PHI - - - PAZ047 - 380470 - Luzerne - PA - US - 41.16 - -75.96 - 0 - 0 - BGM - - - NYZ007 - 320070 - Jefferson - NY - US - 44.03 - -75.95 - 0 - 0 - BUF - - - VAZ100 - 461000 - Northampton - VA - US - 37.34 - -75.95 - 0 - 0 - AKQ - - - NCZ017 - 330170 - Western_Currituck - NC - US - 36.31 - -75.94 - 0 - 0 - AKQ - - - MDZ008 - 200080 - Cecil - MD - US - 39.55 - -75.93 - 0 - 0 - PHI - - - NCZ104 - 331040 - Eastern_Hyde - NC - US - 35.13 - -75.92 - 0 - 0 - MHX - - - NCZ047 - 330470 - Western_Dare - NC - US - 35.77 - -75.87 - 0 - 0 - MHX - - - MDZ020 - 200200 - Caroline - MD - US - 38.90 - -75.86 - 0 - 0 - PHI - - - NCZ102 - 331020 - Eastern_Currituck - NC - US - 36.37 - -75.84 - 0 - 0 - AKQ - - - PAZ039 - 380390 - Susquehanna - PA - US - 41.82 - -75.81 - 0 - 0 - BGM - - - MDZ023 - 200230 - Somerset - MD - US - 38.10 - -75.80 - 0 - 0 - AKQ - - - NYZ056 - 320560 - Broome - NY - US - 42.21 - -75.76 - 0 - 0 - BGM - - - PAZ067 - 380670 - Chester - PA - US - 39.99 - -75.76 - 0 - 0 - PHI - - - PAZ054 - 380540 - Carbon - PA - US - 40.94 - -75.74 - 0 - 0 - PHI - - - PAZ044 - 380440 - Lackawanna - PA - US - 41.40 - -75.64 - 0 - 0 - BGM - - - VAZ099 - 460990 - Accomack - VA - US - 37.74 - -75.64 - 0 - 0 - AKQ - - - MDZ022 - 200220 - Wicomico - MD - US - 38.39 - -75.62 - 0 - 0 - AKQ - - - NYZ036 - 320360 - Madison - NY - US - 42.96 - -75.62 - 0 - 0 - BGM - - - PAZ061 - 380610 - Lehigh - PA - US - 40.60 - -75.62 - 0 - 0 - PHI - - - DEZ001 - 80010 - New_Castle - DE - US - 39.57 - -75.60 - 0 - 0 - PHI - - - NYZ045 - 320450 - Chenango - NY - US - 42.47 - -75.59 - 0 - 0 - BGM - - - DEZ002 - 80020 - Kent - DE - US - 39.10 - -75.53 - 0 - 0 - PHI - - - NCZ103 - 331030 - Eastern_Dare - NC - US - 35.48 - -75.48 - 0 - 0 - MHX - - - NYZ008 - 320080 - Lewis - NY - US - 43.82 - -75.48 - 0 - 0 - BUF - - - NYZ009 - 320090 - Northern_Oneida - NY - US - 43.38 - -75.48 - 0 - 0 - BGM - - - PAZ070 - 380700 - Delaware - PA - US - 39.93 - -75.43 - 0 - 0 - PHI - - - DEZ003 - 80030 - Inland_Sussex - DE - US - 38.70 - -75.42 - 0 - 0 - PHI - - - NYZ037 - 320370 - Southern_Oneida - NY - US - 43.08 - -75.41 - 0 - 0 - BGM - - - MDZ024 - 200240 - Inland_Worcester - MD - US - 38.23 - -75.39 - 0 - 0 - AKQ - - - PAZ068 - 380680 - Montgomery - PA - US - 40.21 - -75.36 - 0 - 0 - PHI - - - PAZ062 - 380620 - Northampton - PA - US - 40.75 - -75.34 - 0 - 0 - PHI - - - NJZ016 - 300160 - Salem - NJ - US - 39.58 - -75.32 - 0 - 0 - PHI - - - PAZ055 - 380550 - Monroe - PA - US - 41.03 - -75.31 - 0 - 0 - PHI - - - PAZ072 - 380720 - Southern_Wayne - PA - US - 41.44 - -75.28 - 0 - 0 - BGM - - - PAZ040 - 380400 - Northern_Wayne - PA - US - 41.80 - -75.27 - 0 - 0 - BGM - - - NYZ087 - 320870 - Southwestern_St._Lawrence - NY - US - 44.46 - -75.23 - 0 - 0 - BTV - - - MDZ025 - 200250 - Maryland_Beaches - MD - US - 38.17 - -75.18 - 0 - 0 - AKQ - - - NJZ017 - 300170 - Gloucester - NJ - US - 39.70 - -75.16 - 0 - 0 - PHI - - - NJZ021 - 300210 - Cumberland - NJ - US - 39.37 - -75.14 - 0 - 0 - PHI - - - PAZ071 - 380710 - Philadelphia - PA - US - 39.99 - -75.13 - 0 - 0 - PHI - - - PAZ069 - 380690 - Bucks - PA - US - 40.32 - -75.11 - 0 - 0 - PHI - - - DEZ004 - 80040 - Delaware_Beaches - DE - US - 38.63 - -75.09 - 0 - 0 - PHI - - - PAZ048 - 380480 - Pike - PA - US - 41.34 - -75.03 - 0 - 0 - BGM - - - NYZ046 - 320460 - Otsego - NY - US - 42.61 - -75.02 - 0 - 0 - BGM - - - NJZ007 - 300070 - Warren - NJ - US - 40.83 - -74.99 - 0 - 0 - PHI - - - NYZ026 - 320260 - Northern_St._Lawrence - NY - US - 44.86 - -74.99 - 0 - 0 - BTV - - - NYZ032 - 320320 - Northern_Herkimer - NY - US - 43.71 - -74.97 - 0 - 0 - ALY - - - NJZ009 - 300090 - Hunterdon - NJ - US - 40.56 - -74.96 - 0 - 0 - PHI - - - NJZ018 - 300180 - Camden - NJ - US - 39.79 - -74.95 - 0 - 0 - PHI - - - NYZ038 - 320380 - Southern_Herkimer - NY - US - 43.08 - -74.95 - 0 - 0 - ALY - - - NYZ029 - 320290 - Southeastern_St._Lawrence - NY - US - 44.39 - -74.93 - 0 - 0 - BTV - - - NYZ057 - 320570 - Delaware - NY - US - 42.19 - -74.93 - 0 - 0 - BGM - - - NJZ023 - 300230 - Cape_May - NJ - US - 39.15 - -74.81 - 0 - 0 - PHI - - - NJZ019 - 300190 - Northwestern_Burlington - NJ - US - 39.97 - -74.77 - 0 - 0 - PHI - - - NJZ024 - 300240 - Atlantic_Coastal_Cape_May - NJ - US - 39.11 - -74.76 - 0 - 0 - PHI - - - NYZ062 - 320620 - Sullivan - NY - US - 41.72 - -74.76 - 0 - 0 - BGM - - - NJZ015 - 300150 - Mercer - NJ - US - 40.27 - -74.71 - 0 - 0 - PHI - - - NJZ022 - 300220 - Atlantic - NJ - US - 39.50 - -74.69 - 0 - 0 - PHI - - - NJZ001 - 300010 - Sussex - NJ - US - 41.13 - -74.68 - 0 - 0 - PHI - - - NJZ010 - 300100 - Somerset - NJ - US - 40.56 - -74.60 - 0 - 0 - PHI - - - NJZ027 - 300270 - Southeastern_Burlington - NJ - US - 39.73 - -74.60 - 0 - 0 - PHI - - - NJZ008 - 300080 - Morris - NJ - US - 40.86 - -74.58 - 0 - 0 - PHI - - - NJZ025 - 300250 - Coastal_Atlantic - NJ - US - 39.40 - -74.46 - 0 - 0 - PHI - - - NYZ033 - 320330 - Hamilton - NY - US - 43.66 - -74.46 - 0 - 0 - ALY - - - NYZ039 - 320390 - Southern_Fulton - NY - US - 43.05 - -74.44 - 0 - 0 - ALY - - - NYZ047 - 320470 - Schoharie - NY - US - 42.59 - -74.44 - 0 - 0 - ALY - - - NYZ082 - 320820 - Northern_Fulton - NY - US - 43.17 - -74.44 - 0 - 0 - ALY - - - NJZ012 - 300120 - Middlesex - NJ - US - 40.42 - -74.43 - 0 - 0 - PHI - - - NYZ040 - 320400 - Montgomery - NY - US - 42.91 - -74.43 - 0 - 0 - ALY - - - NYZ063 - 320630 - Western_Ulster - NY - US - 41.88 - -74.43 - 0 - 0 - ALY - - - NYZ027 - 320270 - Northern_Franklin - NY - US - 44.86 - -74.39 - 0 - 0 - BTV - - - NJZ002 - 300020 - Western_Passaic - NJ - US - 41.09 - -74.36 - 0 - 0 - OKX - - - NYZ067 - 320670 - Orange - NY - US - 41.39 - -74.36 - 0 - 0 - OKX - - - NJZ013 - 300130 - Western_Monmouth - NJ - US - 40.26 - -74.32 - 0 - 0 - PHI - - - NJZ020 - 300200 - Ocean - NJ - US - 39.85 - -74.32 - 0 - 0 - PHI - - - NJZ011 - 300110 - Union - NJ - US - 40.66 - -74.31 - 0 - 0 - OKX - - - NYZ058 - 320580 - Western_Greene - NY - US - 42.26 - -74.28 - 0 - 0 - ALY - - - NJZ026 - 300260 - Coastal_Ocean - NJ - US - 39.64 - -74.26 - 0 - 0 - PHI - - - NYZ030 - 320300 - Southern_Franklin - NY - US - 44.54 - -74.26 - 0 - 0 - BTV - - - NJZ005 - 300050 - Essex - NJ - US - 40.79 - -74.25 - 0 - 0 - OKX - - - NJZ004 - 300040 - Eastern_Passaic - NJ - US - 40.91 - -74.20 - 0 - 0 - OKX - - - NYZ048 - 320480 - Western_Schenectady - NY - US - 42.80 - -74.17 - 0 - 0 - ALY - - - NYZ074 - 320740 - Richmond_(Staten_Is.) - NY - US - 40.58 - -74.15 - 0 - 0 - OKX - - - NYZ051 - 320510 - Western_Albany - NY - US - 42.58 - -74.14 - 0 - 0 - ALY - - - NYZ064 - 320640 - Eastern_Ulster - NY - US - 41.88 - -74.09 - 0 - 0 - ALY - - - NJZ003 - 300030 - Bergen - NJ - US - 40.94 - -74.08 - 0 - 0 - OKX - - - NJZ006 - 300060 - Hudson - NJ - US - 40.74 - -74.07 - 0 - 0 - OKX - - - NYZ069 - 320690 - Rockland - NY - US - 41.16 - -74.07 - 0 - 0 - OKX - - - NJZ014 - 300140 - Eastern_Monmouth - NJ - US - 40.28 - -74.03 - 0 - 0 - PHI - - - NYZ049 - 320490 - Eastern_Schenectady - NY - US - 42.85 - -73.96 - 0 - 0 - ALY - - - NYZ072 - 320720 - New_York_(Manhattan) - NY - US - 40.79 - -73.96 - 0 - 0 - OKX - - - NYZ075 - 320750 - Kings_(Brooklyn) - NY - US - 40.66 - -73.94 - 0 - 0 - OKX - - - NYZ059 - 320590 - Eastern_Greene - NY - US - 42.30 - -73.91 - 0 - 0 - ALY - - - NYZ034 - 320340 - Western_Essex - NY - US - 44.10 - -73.90 - 0 - 0 - BTV - - - NYZ050 - 320500 - Southern_Saratoga - NY - US - 42.94 - -73.88 - 0 - 0 - ALY - - - NYZ041 - 320410 - Northern_Saratoga - NY - US - 43.17 - -73.87 - 0 - 0 - ALY - - - NYZ052 - 320520 - Eastern_Albany - NY - US - 42.62 - -73.86 - 0 - 0 - ALY - - - NYZ065 - 320650 - Western_Dutchess - NY - US - 41.76 - -73.85 - 0 - 0 - ALY - - - NYZ073 - 320730 - Bronx - NY - US - 40.86 - -73.85 - 0 - 0 - OKX - - - NYZ042 - 320420 - Northern_Warren - NY - US - 43.58 - -73.84 - 0 - 0 - ALY - - - NYZ076 - 320760 - Queens - NY - US - 40.68 - -73.83 - 0 - 0 - OKX - - - NYZ031 - 320310 - Western_Clinton - NY - US - 44.71 - -73.79 - 0 - 0 - BTV - - - NYZ071 - 320710 - Southern_Westchester - NY - US - 40.99 - -73.78 - 0 - 0 - OKX - - - NYZ068 - 320680 - Putnam - NY - US - 41.43 - -73.76 - 0 - 0 - OKX - - - NYZ060 - 320600 - Western_Columbia - NY - US - 42.24 - -73.75 - 0 - 0 - ALY - - - NYZ083 - 320830 - Southeast_Warren - NY - US - 43.34 - -73.74 - 0 - 0 - ALY - - - NYZ070 - 320700 - Northern_Westchester - NY - US - 41.18 - -73.73 - 0 - 0 - OKX - - - NYZ053 - 320530 - Western_Rensselaer - NY - US - 42.70 - -73.62 - 0 - 0 - ALY - - - NYZ066 - 320660 - Eastern_Dutchess - NY - US - 41.78 - -73.62 - 0 - 0 - ALY - - - NYZ077 - 320770 - Nassau - NY - US - 40.75 - -73.59 - 0 - 0 - OKX - - - NYZ028 - 320280 - Eastern_Clinton - NY - US - 44.74 - -73.57 - 0 - 0 - BTV - - - NYZ061 - 320610 - Eastern_Columbia - NY - US - 42.24 - -73.52 - 0 - 0 - ALY - - - NYZ043 - 320430 - Northern_Washington - NY - US - 43.56 - -73.44 - 0 - 0 - ALY - - - NYZ084 - 320840 - Southern_Washington - NY - US - 43.18 - -73.44 - 0 - 0 - ALY - - - NYZ035 - 320350 - Eastern_Essex - NY - US - 44.17 - -73.43 - 0 - 0 - BTV - - - NYZ054 - 320540 - Eastern_Rensselaer - NY - US - 42.72 - -73.42 - 0 - 0 - ALY - - - CTZ009 - 70090 - Southern_Fairfield - CT - US - 41.13 - -73.41 - 0 - 0 - OKX - - - CTZ005 - 70050 - Northern_Fairfield - CT - US - 41.41 - -73.31 - 0 - 0 - OKX - - - VTZ001 - 450010 - Grand_Isle - VT - US - 44.78 - -73.29 - 0 - 0 - BTV - - - MAZ025 - 210250 - Southern_Berkshire - MA - US - 42.23 - -73.25 - 0 - 0 - ALY - - - CTZ013 - 70130 - Southern_Litchfield - CT - US - 41.64 - -73.24 - 0 - 0 - ALY - - - VTZ009 - 450090 - Western_Addison - VT - US - 44.02 - -73.23 - 0 - 0 - BTV - - - CTZ001 - 70010 - Northern_Litchfield - CT - US - 41.86 - -73.20 - 0 - 0 - ALY - - - NYZ078 - 320780 - Northwest_Suffolk - NY - US - 40.88 - -73.18 - 0 - 0 - OKX - - - VTZ011 - 450110 - Western_Rutland - VT - US - 43.57 - -73.18 - 0 - 0 - BTV - - - MAZ001 - 210010 - Northern_Berkshire - MA - US - 42.56 - -73.16 - 0 - 0 - ALY - - - NYZ080 - 320800 - Southwest_Suffolk - NY - US - 40.73 - -73.15 - 0 - 0 - OKX - - - VTZ005 - 450050 - Western_Chittenden - VT - US - 44.49 - -73.13 - 0 - 0 - BTV - - - VTZ013 - 450130 - Bennington - VT - US - 43.02 - -73.06 - 0 - 0 - ALY - - - CTZ006 - 70060 - Northern_New_Haven - CT - US - 41.47 - -73.03 - 0 - 0 - OKX - - - VTZ002 - 450020 - Western_Franklin - VT - US - 44.82 - -73.03 - 0 - 0 - BTV - - - VTZ017 - 450170 - Eastern_Chittenden - VT - US - 44.40 - -72.94 - 0 - 0 - BTV - - - VTZ018 - 450180 - Eastern_Addison - VT - US - 44.05 - -72.94 - 0 - 0 - BTV - - - MAZ009 - 210090 - Western_Hampden - MA - US - 42.19 - -72.93 - 0 - 0 - BOX - - - MAZ008 - 210080 - Western_Hampshire - MA - US - 42.39 - -72.87 - 0 - 0 - BOX - - - VTZ019 - 450190 - Eastern_Rutland - VT - US - 43.57 - -72.86 - 0 - 0 - BTV - - - CTZ010 - 70100 - Southern_New_Haven - CT - US - 41.30 - -72.82 - 0 - 0 - OKX - - - MAZ002 - 210020 - Western_Franklin - MA - US - 42.59 - -72.80 - 0 - 0 - BOX - - - VTZ014 - 450140 - Western_Windham - VT - US - 43.00 - -72.78 - 0 - 0 - ALY - - - VTZ016 - 450160 - Eastern_Franklin - VT - US - 44.83 - -72.77 - 0 - 0 - BTV - - - CTZ002 - 70020 - Hartford - CT - US - 41.79 - -72.72 - 0 - 0 - BOX - - - VTZ006 - 450060 - Lamoille - VT - US - 44.60 - -72.65 - 0 - 0 - BTV - - - VTZ012 - 450120 - Windsor - VT - US - 43.59 - -72.59 - 0 - 0 - BTV - - - VTZ008 - 450080 - Washington - VT - US - 44.26 - -72.58 - 0 - 0 - BTV - - - VTZ015 - 450150 - Eastern_Windham - VT - US - 42.98 - -72.57 - 0 - 0 - ALY - - - CTZ007 - 70070 - Northern_Middlesex - CT - US - 41.48 - -72.53 - 0 - 0 - OKX - - - MAZ010 - 210100 - Eastern_Hampshire - MA - US - 42.31 - -72.51 - 0 - 0 - BOX - - - MAZ011 - 210110 - Eastern_Hampden - MA - US - 42.14 - -72.50 - 0 - 0 - BOX - - - CTZ011 - 70110 - Southern_Middlesex - CT - US - 41.33 - -72.46 - 0 - 0 - OKX - - - MAZ003 - 210030 - Eastern_Franklin - MA - US - 42.52 - -72.46 - 0 - 0 - BOX - - - NYZ079 - 320790 - Northeast_Suffolk - NY - US - 41.07 - -72.41 - 0 - 0 - OKX - - - VTZ010 - 450100 - Orange - VT - US - 43.99 - -72.41 - 0 - 0 - BTV - - - NYZ081 - 320810 - Southeast_Suffolk - NY - US - 40.90 - -72.37 - 0 - 0 - OKX - - - CTZ003 - 70030 - Tolland - CT - US - 41.81 - -72.31 - 0 - 0 - BOX - - - NHZ011 - 290110 - Cheshire - NH - US - 42.94 - -72.24 - 0 - 0 - BOX - - - VTZ003 - 450030 - Orleans - VT - US - 44.77 - -72.23 - 0 - 0 - BTV - - - NHZ007 - 290070 - Sullivan - NH - US - 43.36 - -72.20 - 0 - 0 - GYX - - - CTZ008 - 70080 - Northern_New_London - CT - US - 41.53 - -72.13 - 0 - 0 - OKX - - - VTZ007 - 450070 - Caledonia - VT - US - 44.46 - -72.13 - 0 - 0 - BTV - - - CTZ004 - 70040 - Windham - CT - US - 41.83 - -72.02 - 0 - 0 - BOX - - - CTZ012 - 70120 - Southern_New_London - CT - US - 41.36 - -71.96 - 0 - 0 - OKX - - - NHZ005 - 290050 - Southern_Grafton - NH - US - 43.71 - -71.93 - 0 - 0 - GYX - - - MAZ004 - 210040 - Northern_Worcester - MA - US - 42.43 - -71.92 - 0 - 0 - BOX - - - MAZ012 - 210120 - Southern_Worcester - MA - US - 42.18 - -71.81 - 0 - 0 - BOX - - - NHZ015 - 290150 - Wrn_And_Central_Hillsborough - NH - US - 42.95 - -71.78 - 0 - 0 - BOX - - - NHZ003 - 290030 - Northern_Grafton - NH - US - 44.13 - -71.76 - 0 - 0 - GYX - - - VTZ004 - 450040 - Essex - VT - US - 44.68 - -71.74 - 0 - 0 - BTV - - - NHZ008 - 290080 - Merrimack - NH - US - 43.31 - -71.67 - 0 - 0 - GYX - - - RIZ003 - 390030 - Western_Kent - RI - US - 41.66 - -71.66 - 0 - 0 - BOX - - - RIZ006 - 390060 - Washington - RI - US - 41.48 - -71.66 - 0 - 0 - BOX - - - MAZ026 - 210260 - Northwest_Middlesex_County - MA - US - 42.61 - -71.59 - 0 - 0 - BOX - - - RIZ001 - 390010 - Northwest_Providence - RI - US - 41.87 - -71.59 - 0 - 0 - BOX - - - RIZ008 - 390080 - Block_Island - RI - US - 41.19 - -71.57 - 0 - 0 - BOX - - - NHZ012 - 290120 - Eastern_Hillsborough - NH - US - 42.88 - -71.50 - 0 - 0 - BOX - - - RIZ004 - 390040 - Eastern_Kent - RI - US - 41.68 - -71.46 - 0 - 0 - BOX - - - NHZ009 - 290090 - Belknap - NH - US - 43.52 - -71.45 - 0 - 0 - GYX - - - RIZ002 - 390020 - Southeast_Providence - RI - US - 41.81 - -71.45 - 0 - 0 - BOX - - - NHZ002 - 290020 - Southern_Coos - NH - US - 44.41 - -71.39 - 0 - 0 - GYX - - - MAZ005 - 210050 - Central_Middlesex_County - MA - US - 42.44 - -71.33 - 0 - 0 - BOX - - - NHZ001 - 290010 - Northern_Coos - NH - US - 45.02 - -71.33 - 0 - 0 - GYX - - - RIZ005 - 390050 - Bristol - RI - US - 41.71 - -71.27 - 0 - 0 - BOX - - - NHZ006 - 290060 - Southern_Carroll - NH - US - 43.71 - -71.26 - 0 - 0 - GYX - - - RIZ007 - 390070 - Newport - RI - US - 41.56 - -71.26 - 0 - 0 - BOX - - - MAZ013 - 210130 - Western_Norfolk - MA - US - 42.15 - -71.24 - 0 - 0 - BOX - - - NHZ004 - 290040 - Northern_Carroll - NH - US - 44.10 - -71.22 - 0 - 0 - GYX - - - MAZ017 - 210170 - Northern_Bristol - MA - US - 41.93 - -71.18 - 0 - 0 - BOX - - - NHZ013 - 290130 - Interior_Rockingham - NH - US - 43.01 - -71.17 - 0 - 0 - GYX - - - MAZ014 - 210140 - Southeast_Middlesex - MA - US - 42.41 - -71.16 - 0 - 0 - BOX - - - MAZ006 - 210060 - Western_Essex - MA - US - 42.72 - -71.08 - 0 - 0 - BOX - - - MAZ015 - 210150 - Suffolk - MA - US - 42.34 - -71.07 - 0 - 0 - BOX - - - MAZ020 - 210200 - Southern_Bristol - MA - US - 41.65 - -71.07 - 0 - 0 - BOX - - - NHZ010 - 290100 - Strafford - NH - US - 43.33 - -71.03 - 0 - 0 - GYX - - - MAZ016 - 210160 - Eastern_Norfolk - MA - US - 42.22 - -71.02 - 0 - 0 - BOX - - - MAZ018 - 210180 - Western_Plymouth - MA - US - 42.00 - -70.88 - 0 - 0 - BOX - - - MAZ007 - 210070 - Eastern_Essex - MA - US - 42.65 - -70.83 - 0 - 0 - BOX - - - NHZ014 - 290140 - Coastal_Rockingham - NH - US - 42.99 - -70.82 - 0 - 0 - GYX - - - MEZ007 - 190070 - Northern_Oxford - ME - US - 44.88 - -70.80 - 0 - 0 - GYX - - - MAZ021 - 210210 - Southern_Plymouth - MA - US - 41.72 - -70.77 - 0 - 0 - BOX - - - MAZ019 - 210190 - Eastern_Plymouth - MA - US - 42.03 - -70.73 - 0 - 0 - BOX - - - MEZ018 - 190180 - Interior_York - ME - US - 43.52 - -70.73 - 0 - 0 - GYX - - - MAZ023 - 210230 - Dukes - MA - US - 41.38 - -70.70 - 0 - 0 - BOX - - - MEZ012 - 190120 - Southern_Oxford - ME - US - 44.20 - -70.63 - 0 - 0 - GYX - - - MEZ023 - 190230 - Coastal_York - ME - US - 43.34 - -70.58 - 0 - 0 - GYX - - - MEZ019 - 190190 - Interior_Cumberland - ME - US - 43.91 - -70.49 - 0 - 0 - GYX - - - MEZ008 - 190080 - Northern_Franklin - ME - US - 45.14 - -70.48 - 0 - 0 - GYX - - - MEZ024 - 190240 - Coastal_Cumberland - ME - US - 43.75 - -70.26 - 0 - 0 - GYX - - - MEZ020 - 190200 - Androscoggin - ME - US - 44.20 - -70.24 - 0 - 0 - GYX - - - MEZ013 - 190130 - Southern_Franklin - ME - US - 44.67 - -70.23 - 0 - 0 - GYX - - - MEZ009 - 190090 - Central_Somerset - ME - US - 45.42 - -70.10 - 0 - 0 - GYX - - - MEZ003 - 190030 - Northern_Somerset - ME - US - 46.27 - -70.01 - 0 - 0 - CAR - - - MAZ024 - 210240 - Nantucket - MA - US - 41.31 - -70.00 - 0 - 0 - BOX - - - MAZ022 - 210220 - Barnstable - MA - US - 41.80 - -69.99 - 0 - 0 - BOX - - - MEZ025 - 190250 - Sagadahoc - ME - US - 43.94 - -69.89 - 0 - 0 - GYX - - - MEZ021 - 190210 - Kennebec - ME - US - 44.42 - -69.75 - 0 - 0 - GYX - - - MEZ014 - 190140 - Southern_Somerset - ME - US - 44.85 - -69.67 - 0 - 0 - GYX - - - MEZ026 - 190260 - Lincoln - ME - US - 44.05 - -69.54 - 0 - 0 - GYX - - - MEZ010 - 190100 - Central_Piscataquis - ME - US - 45.55 - -69.38 - 0 - 0 - CAR - - - MEZ004 - 190040 - Northern_Piscataquis - ME - US - 46.12 - -69.27 - 0 - 0 - CAR - - - MEZ027 - 190270 - Knox - ME - US - 44.14 - -69.23 - 0 - 0 - GYX - - - MEZ031 - 190310 - Southern_Piscataquis - ME - US - 45.27 - -69.22 - 0 - 0 - CAR - - - MEZ022 - 190220 - Interior_Waldo - ME - US - 44.53 - -69.16 - 0 - 0 - GYX - - - MEZ001 - 190010 - Northwest_Aroostook - ME - US - 47.01 - -69.06 - 0 - 0 - CAR - - - MEZ028 - 190280 - Coastal_Waldo - ME - US - 44.36 - -69.04 - 0 - 0 - GYX - - - MEZ015 - 190150 - Southern_Penobscot - ME - US - 44.93 - -68.81 - 0 - 0 - CAR - - - MEZ005 - 190050 - Northern_Penobscot - ME - US - 45.95 - -68.69 - 0 - 0 - CAR - - - MEZ011 - 190110 - Central_Penobscot - ME - US - 45.39 - -68.41 - 0 - 0 - CAR - - - MEZ016 - 190160 - Interior_Hancock - ME - US - 44.88 - -68.41 - 0 - 0 - CAR - - - MEZ029 - 190290 - Coastal_Hancock - ME - US - 44.45 - -68.39 - 0 - 0 - CAR - - - MEZ002 - 190020 - Northeast_Aroostook - ME - US - 46.83 - -68.30 - 0 - 0 - CAR - - - MEZ006 - 190060 - Southeast_Aroostook - ME - US - 45.97 - -68.09 - 0 - 0 - CAR - - - MEZ032 - 190320 - Northern_Washington - ME - US - 45.48 - -67.73 - 0 - 0 - CAR - - - MEZ017 - 190170 - Central_Washington - ME - US - 45.00 - -67.57 - 0 - 0 - CAR - - - MEZ030 - 190300 - Coastal_Washington - ME - US - 44.67 - -67.49 - 0 - 0 - CAR - - - PRZ010 - 530100 - Mayaguez_and_Vicinity - PR - US - 18.26 - -67.12 - 0 - 0 - SJU - - - PRZ011 - 530110 - Southwest - PR - US - 18.05 - -67.04 - 0 - 0 - SJU - - - PRZ008 - 530080 - Northwest - PR - US - 18.42 - -66.97 - 0 - 0 - SJU - - - PRZ009 - 530090 - Western_Interior - PR - US - 18.21 - -66.82 - 0 - 0 - SJU - - - PRZ007 - 530070 - Ponce_and_Vicinity - PR - US - 18.03 - -66.63 - 0 - 0 - SJU - - - PRZ005 - 530050 - North_Central - PR - US - 18.40 - -66.48 - 0 - 0 - SJU - - - PRZ006 - 530060 - Central_Interior - PR - US - 18.20 - -66.43 - 0 - 0 - SJU - - - PRZ001 - 530010 - San_Juan_and_Vicinity - PR - US - 18.37 - -66.11 - 0 - 0 - SJU - - - PRZ003 - 530030 - Southeast - PR - US - 18.02 - -66.07 - 0 - 0 - SJU - - - PRZ004 - 530040 - Eastern_Interior - PR - US - 18.17 - -66.04 - 0 - 0 - SJU - - - PRZ002 - 530020 - Northeast - PR - US - 18.26 - -65.76 - 0 - 0 - SJU - - - PRZ013 - 530130 - Vieques - PR - US - 18.13 - -65.42 - 0 - 0 - SJU - - - PRZ012 - 530120 - Culebra - PR - US - 18.32 - -65.31 - 0 - 0 - SJU - - - VIZ001 - 520010 - St._Thomas...St._John..._and_Adj - VI - US - 18.34 - -64.87 - 0 - 0 - SJU - - - VIZ002 - 520020 - St_Croix - VI - US - 17.73 - -64.73 - 0 - 0 - SJU - - - CAZ000 - 50000 - No_name - CA - US - 32.92 - -118.48 - 0 - 0 - - - - GUZ012 - 540120 - Sonsorol - GU - US - 5.30 - 132.22 - 0 - 0 - GUM - - - GUZ011 - 540110 - Koror - GU - US - 7.53 - 134.56 - 0 - 0 - GUM - - - GUZ013 - 540130 - Kayangel - GU - US - 8.08 - 134.72 - 0 - 0 - GUM - - - GUZ022 - 540220 - Ngulu - GU - US - 8.30 - 137.51 - 0 - 0 - GUM - - - GUZ021 - 540210 - Yap - GU - US - 9.54 - 138.12 - 0 - 0 - GUM - - - GUZ023 - 540230 - Ulithi - GU - US - 10.02 - 139.79 - 0 - 0 - GUM - - - GUZ024 - 540240 - Sorol - GU - US - 8.21 - 140.70 - 0 - 0 - GUM - - - GUZ025 - 540250 - Woleai - GU - US - 7.38 - 143.92 - 0 - 0 - GUM - - - GUZ001 - 540010 - Guam - GU - US - 13.44 - 144.79 - 0 - 0 - GUM - - - GUZ002 - 540020 - Rota - GU - US - 14.15 - 145.20 - 0 - 0 - GUM - - - GUZ003 - 540030 - Tinian - GU - US - 15.01 - 145.63 - 0 - 0 - GUM - - - GUZ005 - 540050 - Agrihan - GU - US - 18.76 - 145.66 - 0 - 0 - GUM - - - GUZ004 - 540040 - Saipan - GU - US - 15.19 - 145.76 - 0 - 0 - GUM - - - GUZ026 - 540260 - Satawal - GU - US - 7.36 - 147.04 - 0 - 0 - GUM - - - GUZ032 - 540320 - Puluwat - GU - US - 7.38 - 149.18 - 0 - 0 - GUM - - - GUZ031 - 540310 - Chuuk - GU - US - 7.35 - 151.83 - 0 - 0 - GUM - - - GUZ033 - 540330 - Lukunor - GU - US - 5.50 - 153.82 - 0 - 0 - GUM - - - GUZ041 - 540410 - Pohnpei - GU - US - 6.88 - 158.22 - 0 - 0 - GUM - - - GUZ042 - 540420 - Mokil - GU - US - 6.68 - 159.79 - 0 - 0 - GUM - - - GUZ043 - 540430 - Pingelap - GU - US - 6.21 - 160.71 - 0 - 0 - GUM - - - GUZ062 - 540620 - Ujelang - GU - US - 9.76 - 160.97 - 0 - 0 - GUM - - - GUZ063 - 540630 - Enewetak - GU - US - 11.34 - 162.33 - 0 - 0 - GUM - - - GUZ051 - 540510 - Kosrae - GU - US - 5.32 - 162.97 - 0 - 0 - GUM - - - GUZ081 - 540810 - Wake_Island - GU - US - 19.30 - 166.63 - 0 - 0 - GUM - - - GUZ064 - 540640 - Ailinglaplap - GU - US - 7.29 - 168.75 - 0 - 0 - GUM - - - GUZ065 - 540650 - Jaluit - GU - US - 5.85 - 169.53 - 0 - 0 - GUM - - - GUZ066 - 540660 - Utirik - GU - US - 11.24 - 169.86 - 0 - 0 - GUM - - - GUZ067 - 540670 - Wotje - GU - US - 9.55 - 170.24 - 0 - 0 - GUM - - - GUZ061 - 540610 - Majuro - GU - US - 7.11 - 171.08 - 0 - 0 - GUM - - - GUZ068 - 540680 - Mili - GU - US - 6.04 - 171.95 - 0 - 0 - GUM - - - AKZ191 - 21910 - Western_Aleutians - AK - US - 51.51 - 179.05 - 0 - 0 - AFC - - - PKZ175 - 691750 - Adak_to_Kiska - - US - 51.71 - -178.59 - 0 - 0 - AFC - - - PKZ185 - 691850 - St_Matthew_Island_Waters - - US - 60.43 - -174.18 - 0 - 0 - AFC - - - PKZ172 - 691720 - Nikolski_to_Adak - - US - 52.26 - -173.19 - 0 - 0 - AFC - - - PSZ152 - 721520 - Coastal_waters_of_Swain's_I - - US - -11.08 - -171.03 - 0 - 0 - STU - - - PSZ150 - 721500 - Cstal_wtrs_of_Tututila_and_Aunuu - - US - -14.31 - -170.77 - 0 - 0 - STU - - - PKZ179 - 691790 - Pribilof_Is_Nearshore_Waters - - US - 56.90 - -169.97 - 0 - 0 - AFC - - - PKZ210 - 692100 - Dall_Point_to_Wales - - US - 63.31 - -169.57 - 0 - 0 - AFG - - - PSZ151 - 721510 - Coastal_waters_of_Manua - - US - -14.21 - -169.45 - 0 - 0 - STU - - - PKZ225 - 692250 - Cape_Thompson_to_Cape_Beaufort - - US - 69.01 - -167.45 - 0 - 0 - AFG - - - PKZ170 - 691700 - Cape_Sarichef_to_Nikoski - - US - 53.72 - -166.78 - 0 - 0 - AFC - - - PKZ220 - 692200 - Wales_to_Cape_Thompson - - US - 66.97 - -166.69 - 0 - 0 - AFG - - - PKZ171 - 691710 - Unalaska_Bay - - US - 53.92 - -166.59 - 0 - 0 - AFC - - - PKZ180 - 691800 - Cape_Newenham_to_Dall_Point - - US - 59.92 - -165.98 - 0 - 0 - AFC - - - PKZ200 - 692000 - Norton_Sound - - US - 63.99 - -163.30 - 0 - 0 - AFG - - - PKZ230 - 692300 - Cape_Beaufort_to_Point_Franklin - - US - 70.53 - -163.03 - 0 - 0 - AFG - - - PKZ165 - 691650 - Port_Heiden_to_Cape_Sarichef - - US - 56.01 - -162.88 - 0 - 0 - AFC - - - PKZ215 - 692150 - Kotzebue_Sound - - US - 66.65 - -162.83 - 0 - 0 - AFG - - - PKZ155 - 691550 - Castle_Cape_to_Cape_Sarichef - - US - 54.50 - -160.72 - 0 - 0 - AFC - - - PKZ160 - 691600 - Cape_Newenham_to_Port_Heiden - - US - 57.98 - -160.52 - 0 - 0 - AFC - - - PHZ110 - 701100 - Kauai_Northwest_Waters - - US - 22.44 - -159.99 - 0 - 0 - HFO - - - PHZ112 - 701120 - Kauai_Leeward_Waters - - US - 21.64 - -159.99 - 0 - 0 - HFO - - - PHZ111 - 701110 - Kauai_Windward_Waters - - US - 22.41 - -159.03 - 0 - 0 - HFO - - - PHZ113 - 701130 - Kauai_Channel - - US - 21.62 - -159.00 - 0 - 0 - HFO - - - PHZ115 - 701150 - Oahu_Leeward_Waters - - US - 21.04 - -158.18 - 0 - 0 - HFO - - - PHZ114 - 701140 - Oahu_Windward_Waters - - US - 21.88 - -157.59 - 0 - 0 - HFO - - - PHZ116 - 701160 - Kaiwi_Channel - - US - 21.22 - -157.49 - 0 - 0 - HFO - - - PHZ118 - 701180 - Maui_County_Leeward_Waters - - US - 20.70 - -157.49 - 0 - 0 - HFO - - - PHZ120 - 701200 - Pailolo_Channel - - US - 21.03 - -156.91 - 0 - 0 - HFO - - - PHZ119 - 701190 - Maalaea_Bay - - US - 20.75 - -156.53 - 0 - 0 - HFO - - - PHZ121 - 701210 - Alenuihaha_Channel - - US - 20.30 - -156.44 - 0 - 0 - HFO - - - PHZ123 - 701230 - Big_Island_Leeward_Waters - - US - 19.34 - -156.40 - 0 - 0 - HFO - - - PHZ117 - 701170 - Maui_County_Windward_Waters - - US - 21.32 - -156.39 - 0 - 0 - HFO - - - PKZ235 - 692350 - Point_Franklin_to_Cape_Halkett - - US - 71.66 - -156.01 - 0 - 0 - AFG - - - PKZ150 - 691500 - Sitkinak_to_Castle_Cape - - US - 55.91 - -155.76 - 0 - 0 - AFC - - - PHZ124 - 701240 - Big_Island_Southeast_Waters - - US - 18.71 - -155.37 - 0 - 0 - HFO - - - PHZ122 - 701220 - Big_Island_Windward_Waters - - US - 19.92 - -154.97 - 0 - 0 - HFO - - - PKZ138 - 691380 - _Shelikof_Strait - - US - 57.83 - -153.52 - 0 - 0 - AFC - - - PKZ137 - 691370 - _Marmot_Bay - - US - 58.00 - -152.62 - 0 - 0 - AFC - - - PKZ136 - 691360 - _Chiniak_Bay - - US - 57.70 - -152.37 - 0 - 0 - AFC - - - PKZ132 - 691320 - Shuyak_Island_To_Sitkinak - - US - 56.92 - -152.20 - 0 - 0 - AFC - - - PKZ140 - 691400 - Cook_Inlt_N_of_Kamishak_Bay_and_ - - US - 60.34 - -151.89 - 0 - 0 - AFC - - - PKZ141 - 691410 - Kachemak_Bay - - US - 59.56 - -151.45 - 0 - 0 - AFC - - - PKZ130 - 691300 - Barren_Is_And_Kamishak_Bay_Wtrs - - US - 58.64 - -151.33 - 0 - 0 - AFC - - - PKZ121 - 691210 - _Resurrection_Bay - - US - 60.06 - -149.39 - 0 - 0 - AFC - - - PKZ240 - 692400 - Cape_Halkett_to_Flaxman_Island - - US - 71.09 - -149.19 - 0 - 0 - AFG - - - PKZ129 - 691290 - Passage_Canal - - US - 60.81 - -148.58 - 0 - 0 - AFC - - - PKZ125 - 691250 - Prince_William_Sound - - US - 60.48 - -147.34 - 0 - 0 - AFC - - - PKZ120 - 691200 - Cape_Suckling_to_Gore_Point - - US - 59.42 - -147.01 - 0 - 0 - AFC - - - PKZ128 - 691280 - _Valdez_Arm - - US - 60.94 - -146.86 - 0 - 0 - AFC - - - PKZ127 - 691270 - _Valdez_Narrows - - US - 61.05 - -146.67 - 0 - 0 - AFC - - - PKZ126 - 691260 - _Port_of_Valdez - - US - 61.11 - -146.44 - 0 - 0 - AFC - - - PKZ245 - 692450 - Flaxman_I_to_Demarcation_Point - - US - 70.60 - -143.39 - 0 - 0 - AFG - - - PKZ052 - 690520 - Icy_Cape_to_Cape_Suckling - - US - 59.40 - -142.97 - 0 - 0 - AJK - - - PKZ051 - 690510 - Cape_Fairweather_to_Icy_Cape - - US - 58.95 - -140.30 - 0 - 0 - AJK - - - PKZ053 - 690530 - Yakutat_Bay - - US - 59.80 - -139.76 - 0 - 0 - AJK - - - PKZ043 - 690430 - SE_AK_Outside_Wtrs_From_C_Edgecu - - US - 57.59 - -137.69 - 0 - 0 - AJK - - - PKZ022 - 690220 - Cross_Sound - - US - 58.14 - -136.36 - 0 - 0 - AJK - - - PKZ011 - 690110 - _Glacier_Bay - - US - 58.72 - -136.23 - 0 - 0 - AJK - - - PKZ042 - 690420 - Cape_Decision_to_Cape_Edgecumbe - - US - 56.23 - -136.12 - 0 - 0 - AJK - - - PKZ021 - 690210 - Icy_Strait - - US - 58.27 - -135.73 - 0 - 0 - AJK - - - PKZ012 - 690120 - Northern_Lynn_Canal - - US - 59.10 - -135.30 - 0 - 0 - AJK - - - PKZ013 - 690130 - Southern_Lynn_Canal - - US - 58.59 - -135.07 - 0 - 0 - AJK - - - PKZ032 - 690320 - Northern_Chatham_Strait - - US - 57.61 - -134.77 - 0 - 0 - AJK - - - PKZ033 - 690330 - Southern_Chatham_Strait - - US - 56.54 - -134.55 - 0 - 0 - AJK - - - PKZ041 - 690410 - Dixon_Entrance_to_Cape_Decision - - US - 55.04 - -134.31 - 0 - 0 - AJK - - - PKZ031 - 690310 - Stephens_Passage - - US - 57.94 - -134.29 - 0 - 0 - AJK - - - PKZ034 - 690340 - Frederick_Sound - - US - 56.99 - -134.28 - 0 - 0 - AJK - - - PKZ035 - 690350 - Sumner_Strait - - US - 56.40 - -133.28 - 0 - 0 - AJK - - - PKZ036 - 690360 - Clarence_Strait - - US - 55.40 - -131.52 - 0 - 0 - AJK - - - PZZ170 - 611700 - Cstal_Wtrs_From_C_Flattery_To_Ja - - US - 48.22 - -125.73 - 0 - 0 - SEW - - - PZZ173 - 611730 - Wtrs_From_James_I_To_Pt_Grenvl_2 - - US - 47.57 - -125.40 - 0 - 0 - SEW - - - PZZ376 - 613760 - Wtrs_fr_C_Blanco_OR_to_Pt._St._G - - US - 42.33 - -125.39 - 0 - 0 - MFR - - - PZZ370 - 613700 - Wtrs_fr_Florence_to_C_Blanco_OR_ - - US - 43.40 - -125.19 - 0 - 0 - MFR - - - PZZ275 - 612750 - Wtrs_fr_Cascade_Hd_to_Florence_O - - US - 44.59 - -125.15 - 0 - 0 - PQR - - - PZZ470 - 614700 - Wtrs_fr_Pt._St._Geo_to_C_Mendoci - - US - 41.14 - -125.08 - 0 - 0 - EKA - - - PZZ176 - 611760 - Cstal_Wtrs_From_Pt_Grenvl_To_C_S - - US - 46.97 - -125.06 - 0 - 0 - SEW - - - PZZ153 - 611530 - Cstal_Wtrs_From_James_I_To_Pt_Gr - - US - 47.74 - -124.99 - 0 - 0 - SEW - - - PZZ270 - 612700 - Wtrs_fr_C_Shoalwtr_WA_to_Cascade - - US - 45.92 - -124.99 - 0 - 0 - PQR - - - PZZ150 - 611500 - Cstal_Wtrs_From_C_Flattery_To_Ja - - US - 48.17 - -124.89 - 0 - 0 - SEW - - - PZZ475 - 614750 - Wtrs_fr_C_Mendocino_to_Pt._Arena - - US - 39.69 - -124.74 - 0 - 0 - EKA - - - PZZ350 - 613500 - Cstal_wtrs_fr_Florence_to_C_Blan - - US - 43.47 - -124.68 - 0 - 0 - MFR - - - PZZ330 - 613300 - Chetco_River_Bar - - US - 42.31 - -124.60 - 0 - 0 - MFR - - - PZZ130 - 611300 - W_Entr_U.S._Wtrs_St_Of_Juan_De_F - - US - 48.37 - -124.48 - 0 - 0 - SEW - - - PZZ310 - 613100 - Coos_Bay_Bar - - US - 43.43 - -124.47 - 0 - 0 - MFR - - - PZZ156 - 611560 - Cstal_Wtrs_From_Pt_Grenvl_To_C_S - - US - 47.02 - -124.44 - 0 - 0 - SEW - - - PZZ356 - 613560 - Cstal_wtrs_fr_C_Blanco_OR_to_Pt. - - US - 42.24 - -124.43 - 0 - 0 - MFR - - - PZZ450 - 614500 - Cstal_wtrs_fr_Pt._St._Geo_to_C_M - - US - 41.11 - -124.33 - 0 - 0 - EKA - - - PZZ250 - 612500 - Cstal_wtrs_fr_C_Shoalwtr_WA_to_C - - US - 45.93 - -124.20 - 0 - 0 - PQR - - - PZZ410 - 614100 - Humboldt_Bay_Bar - - US - 40.77 - -124.19 - 0 - 0 - EKA - - - PZZ255 - 612550 - Cstal_wtrs_fr_Cascade_Hd_to_Flor - - US - 44.47 - -124.10 - 0 - 0 - PQR - - - PZZ110 - 611100 - Grays_Harbor_Bar - - US - 46.93 - -123.99 - 0 - 0 - SEW - - - PZZ570 - 615700 - Wtrs_fr_Pt._Arena_to_Pigeon_Pt._ - - US - 38.08 - -123.99 - 0 - 0 - MTR - - - PZZ455 - 614550 - Cstal_wtrs_fr_C_Mendocino_to_Pt. - - US - 39.69 - -123.91 - 0 - 0 - EKA - - - PZZ131 - 611310 - Ctrl_U.S._Wtrs_St_Of_Juan_De_Fuc - - US - 48.27 - -123.68 - 0 - 0 - SEW - - - PZZ210 - 612100 - Columbia_River_Bar - - US - 46.21 - -123.68 - 0 - 0 - PQR - - - PZZ540 - 615400 - Cstal_Wtrs_fr_Pt_Arena_to_Pt_Rey - - US - 38.48 - -123.53 - 0 - 0 - MTR - - - PZZ132 - 611320 - E_Entr_U.S._Wtrs_St_Of_Juan_De_F - - US - 48.21 - -122.96 - 0 - 0 - SEW - - - PZZ133 - 611330 - Nrn_Inlnd_Wtrs_Incl_The_Sn_Juan_ - - US - 48.58 - -122.78 - 0 - 0 - SEW - - - PZZ575 - 615750 - Wtrs_fr_Pigeon_Pt._to_Pt._Piedra - - US - 36.41 - -122.76 - 0 - 0 - MTR - - - PZZ545 - 615450 - Cstal_Wtrs_fr_Pt_Reyes_to_Pigeon - - US - 37.58 - -122.72 - 0 - 0 - MTR - - - PZZ134 - 611340 - Admiralty_Inlet - - US - 48.06 - -122.68 - 0 - 0 - SEW - - - PZZ560 - 615600 - Cstal_Wtrs_fr_Pigeon_Pt_to_Pt_Pi - - US - 36.99 - -122.59 - 0 - 0 - MTR - - - PZZ135 - 611350 - Puget_Sound_and_Hood_Canal - - US - 47.56 - -122.47 - 0 - 0 - SEW - - - PZZ530 - 615300 - Sn_Francisco/Sn_Pablo/Suisun_Bay - - US - 37.83 - -122.39 - 0 - 0 - MTR - - - PZZ535 - 615350 - Monterey_Bay - - US - 36.79 - -121.89 - 0 - 0 - MTR - - - PZZ565 - 615650 - Cstal_Wtrs_fr_Pt_Pinos_to_Pt_Pie - - US - 36.11 - -121.84 - 0 - 0 - MTR - - - PZZ670 - 616700 - The_Wtrs_fr_Pt._Piedras_Blancas_ - - US - 35.14 - -121.55 - 0 - 0 - LOX - - - PZZ673 - 616730 - Wtrs_fr_Pt._Arguello_to_Sta_Cruz - - US - 34.18 - -120.98 - 0 - 0 - LOX - - - PZZ650 - 616500 - E_Sta_Barbara_Chnl_fr_Pt._Concep - - US - 34.28 - -119.87 - 0 - 0 - LOX - - - PZZ676 - 616760 - Out_wtrs_fr_Sta_Cruz_I_to_Sn_Cle - - US - 33.54 - -119.79 - 0 - 0 - LOX - - - PZZ655 - 616550 - Inr_wtrs_fr_Pt_Mugu_to_Sn_Mateo_ - - US - 33.59 - -118.55 - 0 - 0 - LOX - - - PZZ775 - 617750 - Wtrs_fr_Sn_Mateo_point_to_the_Me - - US - 32.83 - -118.20 - 0 - 0 - SGX - - - PZZ750 - 617500 - Cstal_Wtrs_fr_Sn_Mateo_Pt_to_the - - US - 32.92 - -117.55 - 0 - 0 - SGX - - - GMZ135 - 681350 - Laguna_Madre_From_5_nm_N_Of_Port - - US - 26.93 - -97.44 - 0 - 0 - BRO - - - GMZ132 - 681320 - Laguna_Madre_From_The_Arroyo_Col - - US - 26.49 - -97.37 - 0 - 0 - BRO - - - GMZ230 - 682300 - Bays_and_Wtrways_fr_Baffin_Bay_t - - US - 27.54 - -97.31 - 0 - 0 - CRP - - - GMZ130 - 681300 - Laguna_Madre_From_the_Port_Of_Br - - US - 26.19 - -97.30 - 0 - 0 - BRO - - - GMZ155 - 681550 - Cstal_wtrs_fr_Baffin_Bay_to_Port - - US - 26.92 - -97.23 - 0 - 0 - BRO - - - GMZ250 - 682500 - Cstal_wtrs_fr_Baffin_Bay_to_Port - - US - 27.52 - -97.10 - 0 - 0 - CRP - - - GMZ150 - 681500 - Cstal_wtrs_fr_Port_Mansfield_TX_ - - US - 26.28 - -97.04 - 0 - 0 - BRO - - - GMZ235 - 682350 - Bays_and_Wtrways_fr_Port_Aransas - - US - 28.16 - -96.82 - 0 - 0 - CRP - - - GMZ175 - 681750 - Wtrs_fr_Baffin_Bay_to_Port_Mansf - - US - 26.87 - -96.68 - 0 - 0 - BRO - - - GMZ255 - 682550 - Cstal_wtrs_fr_Port_Aransas_to_Ma - - US - 28.06 - -96.66 - 0 - 0 - CRP - - - GMZ270 - 682700 - Wtrs_fr_Baffin_Bay_to_Port_Arans - - US - 27.35 - -96.51 - 0 - 0 - CRP - - - GMZ170 - 681700 - Wtrs_fr_Port_Mansfield_TX_to_the - - US - 26.26 - -96.50 - 0 - 0 - BRO - - - GMZ330 - 683300 - Matagorda_Bay - - US - 28.60 - -96.32 - 0 - 0 - HGX - - - GMZ275 - 682750 - Wtrs_fr_Port_Aransas_to_Matagord - - US - 27.74 - -96.12 - 0 - 0 - CRP - - - GMZ350 - 683500 - Cstal_wtrs_fr_Freeport_to_Matago - - US - 28.52 - -95.70 - 0 - 0 - HGX - - - GMZ370 - 683700 - Wtrs_fr_Freeport_to_Matagorda_Sh - - US - 28.13 - -95.38 - 0 - 0 - HGX - - - GMZ335 - 683350 - Galveston_Bay - - US - 29.41 - -94.87 - 0 - 0 - HGX - - - GMZ355 - 683550 - Cstal_wtrs_fr_Hi_I_to_Freeport_T - - US - 29.10 - -94.78 - 0 - 0 - HGX - - - GMZ375 - 683750 - Wtrs_fr_Hi_I_to_Freeport_TX_fr_2 - - US - 28.66 - -94.60 - 0 - 0 - HGX - - - GMZ450 - 684500 - Cstal_wtrs_fr_Cameron_LA_to_Hi_I - - US - 29.58 - -93.95 - 0 - 0 - LCH - - - GMZ430 - 684300 - Sabine_Lake - - US - 29.62 - -93.85 - 0 - 0 - LCH - - - GMZ470 - 684700 - Wtrs_fr_Cameron_LA_to_Hi_I_TX_fr - - US - 29.07 - -93.82 - 0 - 0 - LCH - - - GMZ432 - 684320 - Calcasieu_Lake - - US - 29.92 - -93.31 - 0 - 0 - LCH - - - GMZ452 - 684520 - Cstal_wtrs_fr_Intracoastal_Cty_t - - US - 29.48 - -92.72 - 0 - 0 - LCH - - - GMZ472 - 684720 - Wtrs_fr__Intracoastal_Cty_to_Cam - - US - 28.95 - -92.68 - 0 - 0 - LCH - - - LSZ145 - 651450 - Duluth_MN_to_Port_Wing_WI - - US - 46.76 - -91.84 - 0 - 0 - DLH - - - LSZ144 - 651440 - Two_Harbors_to_Duluth_MN - - US - 46.89 - -91.82 - 0 - 0 - DLH - - - GMZ475 - 684750 - Wtrs_fr_Lwr_Atchafalaya_Riv_to_I - - US - 28.70 - -91.72 - 0 - 0 - LCH - - - GMZ435 - 684350 - Vermillion_Bay - - US - 29.38 - -91.70 - 0 - 0 - LCH - - - GMZ455 - 684550 - Cstal_wtrs_fr_Lwr_Atchafalaya_Ri - - US - 29.32 - -91.69 - 0 - 0 - LCH - - - LSZ143 - 651430 - Silver_Bay_Hbr_to_2_Hbrs_MN - - US - 47.13 - -91.40 - 0 - 0 - DLH - - - LSZ146 - 651460 - Port_Wing_to_Sand_Island_WI - - US - 46.91 - -91.19 - 0 - 0 - DLH - - - LSZ142 - 651420 - Taconite_Hbr_to_Silver_Bay_Hbr_M - - US - 47.38 - -91.05 - 0 - 0 - DLH - - - LSZ121 - 651210 - Chequamegon_Bay-Bayfield_to_Oak_ - - US - 46.69 - -90.81 - 0 - 0 - DLH - - - LSZ147 - 651470 - Sand_Island_to_Bayfield_WI - - US - 46.91 - -90.71 - 0 - 0 - DLH - - - LSZ148 - 651480 - Oak_Point_to_Saxon_Harbor_WI - - US - 46.67 - -90.59 - 0 - 0 - DLH - - - LSZ141 - 651410 - Grand_Marais_to_Taconite_Hbr_MN - - US - 47.58 - -90.57 - 0 - 0 - DLH - - - LSZ162 - 651620 - L_Sup_W_of_a_line_fr_Saxon_Hbr_W - - US - 47.28 - -90.56 - 0 - 0 - DLH - - - LSZ240 - 652400 - Saxon_Harbor_WI_to_Black_Riv_MI - - US - 46.66 - -90.24 - 0 - 0 - MQT - - - GMZ550 - 685500 - Cstal_wtrs_fr_the_SW_pass_of_the - - US - 29.00 - -90.19 - 0 - 0 - LIX - - - GMZ570 - 685700 - Wtrs_fr_the_SW_Pass_of_the_MS_Ri - - US - 28.39 - -90.18 - 0 - 0 - LIX - - - GMZ530 - 685300 - L_Pontchartrain_and_L_Maurepas - - US - 30.17 - -90.10 - 0 - 0 - LIX - - - LSZ241 - 652410 - Black_River_To_Ontonagon_MI - - US - 46.81 - -89.91 - 0 - 0 - MQT - - - LSZ140 - 651400 - Gnd_Portage_to_Gnd_Marais_MN - - US - 47.84 - -89.85 - 0 - 0 - DLH - - - LSZ263 - 652630 - L_Sup_fr_Saxon_Hbr_WI_to_Upr_Ent - - US - 47.45 - -89.29 - 0 - 0 - MQT - - - GMZ555 - 685550 - Cstal_wtrs_fr_Pascagoula_MS_to_t - - US - 29.72 - -89.09 - 0 - 0 - LIX - - - LSZ242 - 652420 - Ontonagon_to_Upr_Entr_of_Portage - - US - 47.10 - -88.96 - 0 - 0 - MQT - - - GMZ575 - 685750 - Wtrs_fr_Pascagoula_MS_to_the_SW_ - - US - 28.86 - -88.56 - 0 - 0 - LIX - - - LSZ243 - 652430 - Upr_Entr_of_Portage_Canal_to_Eag - - US - 47.37 - -88.47 - 0 - 0 - MQT - - - LSZ247 - 652470 - Portage_L_to_Huron_I_MI_to_Lwr_E - - US - 46.90 - -88.37 - 0 - 0 - MQT - - - LSZ246 - 652460 - Pt_Isabelle_to_Lwr_Entr_of_Porta - - US - 47.15 - -88.22 - 0 - 0 - MQT - - - LSZ264 - 652640 - L_Sup_fr_Upr_Entr_to_Portage_Can - - US - 47.83 - -88.08 - 0 - 0 - MQT - - - GMZ650 - 686500 - Cstal_wtrs_fr_Pensacola_FL_to_Pa - - US - 30.19 - -88.01 - 0 - 0 - MOB - - - LSZ244 - 652440 - Eagle_River_to_Manitou_I_MI - - US - 47.49 - -87.95 - 0 - 0 - MQT - - - GMZ630 - 686300 - Mobile_Bay - - US - 30.53 - -87.93 - 0 - 0 - MOB - - - LMZ644 - 646440 - Port_Washington_to_N_Pt_Lt_WI - - US - 43.24 - -87.87 - 0 - 0 - MKX - - - LMZ522 - 645220 - Grn_Bay_S_of_line_fr__Oconto_WI_ - - US - 44.71 - -87.79 - 0 - 0 - GRB - - - LMZ645 - 646450 - N_Point_Light_to_Wind_Point_WI - - US - 42.93 - -87.77 - 0 - 0 - MKX - - - LMZ740 - 647400 - Winthrop_Hbr_to_Wilmette_Hbr_IL - - US - 42.28 - -87.77 - 0 - 0 - LOT - - - LSZ265 - 652650 - L_Sup_W_of_Line_fr_Manitou_I_to_ - - US - 47.00 - -87.73 - 0 - 0 - MQT - - - LMZ643 - 646430 - Sheboygan_to_Port_Washington_WI - - US - 43.55 - -87.72 - 0 - 0 - MKX - - - LMZ646 - 646460 - Wind_Pt_WI_to_Winthrop_Hbr_IL - - US - 42.64 - -87.72 - 0 - 0 - MKX - - - LSZ245 - 652450 - Manitou_I_to_Point_Isabelle_MI - - US - 47.32 - -87.71 - 0 - 0 - MQT - - - GMZ670 - 686700 - Wtrs_fr_Pensacola_FL_to_Pascagou - - US - 29.60 - -87.65 - 0 - 0 - MOB - - - LMZ543 - 645430 - Two_Rivers_to_Sheboygan_WI - - US - 43.95 - -87.64 - 0 - 0 - GRB - - - LMZ742 - 647420 - Nerly_I_to_Calumet_Harbor_IL - - US - 41.84 - -87.60 - 0 - 0 - LOT - - - LMZ741 - 647410 - Wilmette_Harbor_to_Nerly_I_IL - - US - 41.98 - -87.58 - 0 - 0 - LOT - - - LSZ248 - 652480 - Huron_Islands_to_Marquette_MI - - US - 46.77 - -87.52 - 0 - 0 - MQT - - - LMZ669 - 646690 - L_MI_fr_Sheboygan_to_Port_Washin - - US - 43.63 - -87.44 - 0 - 0 - MKX - - - LMZ743 - 647430 - Calumet_Harbor_IL_to_Gary_IN - - US - 41.70 - -87.42 - 0 - 0 - LOT - - - LMZ671 - 646710 - L_MI_fr_Port_Washington_to_N_Pt_ - - US - 43.20 - -87.41 - 0 - 0 - MKX - - - LMZ673 - 646730 - L_MI_fr_N_Pt_Lt_to_Wind_Pt_WI_5N - - US - 42.93 - -87.40 - 0 - 0 - MKX - - - LMZ521 - 645210 - Grn_Bay_S_of_line_fr__Cedar_Riv_ - - US - 45.11 - -87.39 - 0 - 0 - GRB - - - LMZ542 - 645420 - Sturgeon_Bay_to_Two_Rivers_WI - - US - 44.49 - -87.37 - 0 - 0 - GRB - - - LMZ777 - 647770 - L_MI_fr_Winthrop_Hbr_to_Wilmette - - US - 42.31 - -87.37 - 0 - 0 - LOT - - - LMZ567 - 645670 - L_MI_fr_2_Rivs_to_Sheboygan_WI_5 - - US - 44.05 - -87.33 - 0 - 0 - GRB - - - LMZ675 - 646750 - L_MI_fr_Wind_Pt_WI_to_Winthrop_H - - US - 42.61 - -87.32 - 0 - 0 - MKX - - - LMZ779 - 647790 - L_MI_fr_Wilmette_Hbr_to_MI_Cty_i - - US - 41.95 - -87.26 - 0 - 0 - LOT - - - LMZ744 - 647440 - Gary_to_Burns_Harbor_IN - - US - 41.67 - -87.25 - 0 - 0 - LOT - - - LMZ565 - 645650 - L_MI_fr_Sturgeon_Bay_to_2_Rivs_W - - US - 44.47 - -87.11 - 0 - 0 - GRB - - - LSZ249 - 652490 - Marquette_to_Munising_MI - - US - 46.60 - -87.05 - 0 - 0 - MQT - - - LMZ745 - 647450 - Burns_Harbor_to_MI_City_IN - - US - 41.72 - -87.04 - 0 - 0 - LOT - - - LMZ541 - 645410 - Rock_I_Passage_to_Sturgeon_Bay_W - - US - 45.07 - -86.96 - 0 - 0 - GRB - - - LMZ870 - 648700 - L_MI_fr_Whthall_to_Pentwtr_MI_5N - - US - 43.63 - -86.96 - 0 - 0 - GRR - - - LMZ221 - 642210 - Grn_Bay_N_of_line_fr_Cedar_Riv_M - - US - 45.66 - -86.94 - 0 - 0 - MQT - - - LMZ046 - 640460 - MI_City_IN_to_New_Buffalo_MI - - US - 41.80 - -86.86 - 0 - 0 - IWX - - - LSZ266 - 652660 - L_Sup_E_of_a_line_fr_Manitou_I_t - - US - 47.21 - -86.85 - 0 - 0 - MQT - - - LMZ878 - 648780 - L_MI_fr_St_Joseph_to_S_Haven_MI_ - - US - 42.36 - -86.84 - 0 - 0 - GRR - - - GMZ675 - 686750 - Wtrs_fr_Destin_to_Pensacola_FL_f - - US - 29.72 - -86.83 - 0 - 0 - MOB - - - LMZ080 - 640800 - L_MI_MI_Cty_IN_to_St._Joseph_MI_ - - US - 41.97 - -86.79 - 0 - 0 - IWX - - - LMZ872 - 648720 - L_MI_fr_Gnd_Haven_to_Whthall_MI_ - - US - 43.22 - -86.78 - 0 - 0 - GRR - - - LMZ874 - 648740 - L_MI_fr_Holland_to_Gnd_Haven_MI_ - - US - 42.95 - -86.78 - 0 - 0 - GRR - - - LMZ366 - 643660 - L_MI_fr_Pt_Betsie_to_Manistee_MI - - US - 44.53 - -86.75 - 0 - 0 - APX - - - GMZ655 - 686550 - Cstal_wtrs_fr_Destin_to_Pensacol - - US - 30.24 - -86.72 - 0 - 0 - MOB - - - LMZ043 - 640430 - New_Buffalo_MI_to_St_Joseph_MI - - US - 41.97 - -86.67 - 0 - 0 - IWX - - - LMZ563 - 645630 - L_MI_fr_Rock_I_Passage_to_Sturge - - US - 45.02 - -86.67 - 0 - 0 - GRB - - - LMZ250 - 642500 - 5NM_E_of_a_line_fr_Fairport_MI_t - - US - 45.49 - -86.66 - 0 - 0 - MQT - - - LMZ868 - 648680 - L_MI_fr_Pentwtr_to_Manistee_MI_5 - - US - 43.95 - -86.65 - 0 - 0 - GRR - - - LMZ876 - 648760 - L_MI_fr_S_Haven_to_Holland_MI_5N - - US - 42.60 - -86.65 - 0 - 0 - GRR - - - LMZ849 - 648490 - Pentwater_to_Manistee_MI - - US - 44.03 - -86.57 - 0 - 0 - GRR - - - LMZ848 - 648480 - Whitehall_to_Pentwater_MI - - US - 43.59 - -86.53 - 0 - 0 - GRR - - - LSZ250 - 652500 - Munising_to_Grand_Marais_MI - - US - 46.59 - -86.49 - 0 - 0 - MQT - - - LMZ844 - 648440 - St_Joseph_to_South_Haven_MI - - US - 42.28 - -86.46 - 0 - 0 - GRR - - - LMZ847 - 648470 - Grand_Haven_to_Whitehall_MI - - US - 43.22 - -86.36 - 0 - 0 - GRR - - - LMZ346 - 643460 - Manistee_to_Point_Betsie_MI - - US - 44.48 - -86.33 - 0 - 0 - APX - - - LMZ261 - 642610 - L_MI_fr_Seul_Choix_Pt_to_Rock_I_ - - US - 45.60 - -86.32 - 0 - 0 - MQT - - - LMZ846 - 648460 - Holland_to_Grand_Haven_MI - - US - 42.91 - -86.30 - 0 - 0 - GRR - - - LMZ845 - 648450 - South_Haven_to_Holland_MI - - US - 42.59 - -86.28 - 0 - 0 - GRR - - - LMZ248 - 642480 - Seul_Choix_Pt_to_Pt_Detour_MI - - US - 45.79 - -86.27 - 0 - 0 - MQT - - - LMZ364 - 643640 - L_MI_fr_Charlevoix_to_Pt_Betsie_ - - US - 45.02 - -86.19 - 0 - 0 - APX - - - LMZ345 - 643450 - Pt_Betsie_to_Sleeping_Bear_Pt_MI - - US - 44.82 - -86.18 - 0 - 0 - APX - - - LMZ344 - 643440 - Sleeping_Bear_Pt_to_Gnd_Traverse - - US - 45.09 - -85.79 - 0 - 0 - APX - - - GMZ770 - 687700 - Wtrs_fr_Apalachicola_to_Destin_F - - US - 29.27 - -85.76 - 0 - 0 - TAE - - - LMZ341 - 643410 - Seul_Choix_Pt_to_5NM_W_of_Mackin - - US - 45.96 - -85.71 - 0 - 0 - APX - - - GMZ750 - 687500 - Cstal_wtrs_fr_Apalachicola_to_De - - US - 29.84 - -85.65 - 0 - 0 - TAE - - - LSZ267 - 652670 - L_Sup_fr_Gnd_Marais_MI_to_Whtfis - - US - 47.00 - -85.61 - 0 - 0 - MQT - - - LMZ362 - 643620 - L_MI_S_of_a_line_fr_Seul_Choix_P - - US - 45.60 - -85.57 - 0 - 0 - APX - - - LMZ323 - 643230 - Gnd_Traverse_Bay_S_of_a_line_Gnd - - US - 44.98 - -85.56 - 0 - 0 - APX - - - LSZ251 - 652510 - Grand_Marais_to_Whitefish_Pt_MI - - US - 46.75 - -85.41 - 0 - 0 - MQT - - - LMZ342 - 643420 - Norwood_MI_to_5NM_W_of_Mackinac_ - - US - 45.53 - -85.20 - 0 - 0 - APX - - - LSZ321 - 653210 - Whtfish_Bay_(U.S._Portion)/Whtfi - - US - 46.54 - -84.77 - 0 - 0 - APX - - - LHZ345 - 743450 - Sts_of_Mackinac_within_5NM_of_Ma - - US - 45.81 - -84.71 - 0 - 0 - APX - - - GMZ755 - 687550 - Cstal_Wtrs_From__Ochlockonee_Riv - - US - 29.61 - -84.54 - 0 - 0 - TAE - - - GMZ775 - 687750 - Wtrs_fr__Suwannee_Riv_to_Apalach - - US - 29.15 - -84.35 - 0 - 0 - TAE - - - LHZ347 - 743470 - 5NM_E_of_Mackinac_Br_to_Presque_ - - US - 45.73 - -84.31 - 0 - 0 - APX - - - LHZ346 - 743460 - St_Ignace_to_False_Detour_Chnl - - US - 45.94 - -84.13 - 0 - 0 - APX - - - LSZ322 - 653220 - St._Marys_Riv_Pt_Iroquois_to_E._ - - US - 46.26 - -84.11 - 0 - 0 - APX - - - GMZ730 - 687300 - Apalachee_Bay_or_Cstal_Wtrs_From - - US - 29.90 - -83.95 - 0 - 0 - TAE - - - LHZ361 - 743610 - L_Huron_fr_5NM_E_of_Mackinac_Br_ - - US - 45.63 - -83.69 - 0 - 0 - APX - - - LHZ422 - 744220 - Inr_Saginaw_Bay_SW_of_Pt_Au_Gres - - US - 43.80 - -83.67 - 0 - 0 - DTX - - - GMZ870 - 688700 - Wtrs_fr_Tarpon_Spgs_to_Suwannee_ - - US - 28.60 - -83.54 - 0 - 0 - TBW - - - GMZ765 - 687650 - Cstal_wtrs_fr__Suwannee_Riv_to_K - - US - 29.50 - -83.53 - 0 - 0 - TAE - - - LHZ421 - 744210 - Out_Saginaw_Bay_SW_of_Alabaster_ - - US - 44.07 - -83.38 - 0 - 0 - DTX - - - GMZ873 - 688730 - Wtrs_fr_Englewood_to_Tarpon_Spgs - - US - 27.42 - -83.36 - 0 - 0 - TBW - - - LEZ142 - 631420 - Maumee_Bay_to_Reno_Beach_OH - - US - 41.74 - -83.35 - 0 - 0 - CLE - - - LHZ348 - 743480 - Presque_I_Lt_to_Sturgeon_Pt_MI_I - - US - 45.06 - -83.32 - 0 - 0 - APX - - - LEZ444 - 634440 - MI_Wtrs_of_L_Erie_fr_Detroit_Riv - - US - 41.89 - -83.29 - 0 - 0 - DTX - - - LHZ349 - 743490 - Sturgeon_Point_to_Alabaster_MI - - US - 44.45 - -83.26 - 0 - 0 - APX - - - LEZ162 - 631620 - Detroit_Riv_Lt._to_Maumee_Bay_OH - - US - 41.86 - -83.20 - 0 - 0 - CLE - - - LCZ423 - 604230 - Detroit_River - - US - 42.18 - -83.16 - 0 - 0 - DTX - - - GMZ850 - 688500 - Cstal_wtrs_fr_Tarpon_Spgs_to_Suw - - US - 28.74 - -82.94 - 0 - 0 - TBW - - - LEZ143 - 631430 - Reno_Beach_to_The_Islands_OH - - US - 41.63 - -82.94 - 0 - 0 - CLE - - - LEZ163 - 631630 - Reno_Beach_to_The_Is_OH_beyond_5 - - US - 41.73 - -82.92 - 0 - 0 - CLE - - - GMZ853 - 688530 - Cstal_wtrs_fr_Englewood_to_Tarpo - - US - 27.53 - -82.87 - 0 - 0 - TBW - - - GMZ876 - 688760 - Wtrs_fr_Bonita_Beach_to_Englewoo - - US - 26.39 - -82.86 - 0 - 0 - TBW - - - LHZ362 - 743620 - L_Huron_fr_Presque_I_Lt_to_Sturg - - US - 45.10 - -82.84 - 0 - 0 - APX - - - LCZ460 - 604600 - L_St._Clair_Open_L_(U.S._Portion - - US - 42.52 - -82.76 - 0 - 0 - DTX - - - LHZ363 - 743630 - L_Huron_fr_Sturgeon_Pt_to_Alabas - - US - 44.42 - -82.75 - 0 - 0 - APX - - - LEZ144 - 631440 - The_Islands_to_Vermilion_OH - - US - 41.48 - -82.71 - 0 - 0 - CLE - - - GMZ830 - 688300 - Tampa_Bay_waters - - US - 27.76 - -82.60 - 0 - 0 - TBW - - - LHZ441 - 744410 - Port_Austin_to_Harbor_Beach_MI - - US - 43.93 - -82.59 - 0 - 0 - DTX - - - LHZ442 - 744420 - Harbor_Beach_to_Port_Sanilac_MI - - US - 43.64 - -82.53 - 0 - 0 - DTX - - - GMZ075 - 680750 - Wtrs_fr_Key_W_to_20_NM_W_of_Dry_ - - US - 24.26 - -82.51 - 0 - 0 - KEY - - - LHZ462 - 744620 - L_Huron_fr_Port_Austin_to_Hbr_Be - - US - 44.05 - -82.51 - 0 - 0 - DTX - - - LEZ164 - 631640 - The_Is_to_Vermilion_OH_beyond_5n - - US - 41.59 - -82.48 - 0 - 0 - CLE - - - LCZ422 - 604220 - St._Clair_River - - US - 42.77 - -82.47 - 0 - 0 - DTX - - - LHZ443 - 744430 - Port_Sanilac_to_Port_Huron_MI - - US - 43.21 - -82.43 - 0 - 0 - DTX - - - GMZ676 - 686760 - Wtrs_fr_Chokoloskee_to_Bonita_Be - - US - 25.80 - -82.42 - 0 - 0 - MFL - - - LHZ463 - 744630 - L_Huron_fr_Hbr_Beach_to_Port_Sni - - US - 43.70 - -82.41 - 0 - 0 - DTX - - - LHZ464 - 744640 - L_Huron_fr_Port_Snilac_to_Port_H - - US - 43.33 - -82.40 - 0 - 0 - DTX - - - GMZ856 - 688560 - Cstal_wtrs_fr_Bonita_Beach_to_En - - US - 26.56 - -82.28 - 0 - 0 - TBW - - - LEZ145 - 631450 - Vermilion_to_Avon_Point_OH - - US - 41.51 - -82.17 - 0 - 0 - CLE - - - LEZ165 - 631650 - Vermilion_to_Avon_Pt_OH_beyond_5 - - US - 41.61 - -82.04 - 0 - 0 - CLE - - - GMZ033 - 680330 - Wtrs_fr_E_C_Sable_to_Chokoloskee - - US - 25.27 - -82.00 - 0 - 0 - KEY - - - GMZ656 - 686560 - Cstal_wtrs_fr_Chokoloskee_to_Bon - - US - 25.96 - -81.92 - 0 - 0 - MFL - - - LEZ166 - 631660 - Avon_Pt_to_Willowick_OH_beyond_5 - - US - 41.82 - -81.81 - 0 - 0 - CLE - - - LEZ146 - 631460 - Avon_Point_to_Willowick_OH - - US - 41.54 - -81.66 - 0 - 0 - CLE - - - GMZ054 - 680540 - Cstal_wtrs_fr_the_W_end_of_the_S - - US - 24.48 - -81.61 - 0 - 0 - KEY - - - GMZ032 - 680320 - Gulf_Side_of_the_Lwr_Keys_out_20 - - US - 24.86 - -81.48 - 0 - 0 - KEY - - - GMZ074 - 680740 - Wtrs_fr_the_W_end_of_the_Seven_M - - US - 23.93 - -81.44 - 0 - 0 - KEY - - - GMZ657 - 686570 - Cstal_wtrs_fr_E_C_Sable_to_Choko - - US - 25.47 - -81.41 - 0 - 0 - MFL - - - AMZ450 - 664500 - Cstal_wtrs_fr_Altamaha_Snd_to_Fe - - US - 30.99 - -81.28 - 0 - 0 - JAX - - - LEZ147 - 631470 - Willowick_to_Geneva-on-the_L_OH - - US - 41.80 - -81.22 - 0 - 0 - CLE - - - AMZ452 - 664520 - Cstal_wtrs_fr_Fernandina_Beach_t - - US - 30.28 - -81.18 - 0 - 0 - JAX - - - LEZ167 - 631670 - Willowick_to_Geneva-on-the-L_OH_ - - US - 42.00 - -81.16 - 0 - 0 - CLE - - - AMZ354 - 663540 - Cstal_wtrs_fr_Savannah_GA_to_Alt - - US - 31.67 - -81.05 - 0 - 0 - CHS - - - AMZ550 - 665500 - Flagler_Beach_to_Volusia-Brevard - - US - 29.22 - -80.97 - 0 - 0 - MLB - - - AMZ454 - 664540 - Cstal_wtrs_fr_St._Augustine_to_F - - US - 29.66 - -80.94 - 0 - 0 - JAX - - - GMZ053 - 680530 - Cstal_wtrs_fr_Craig_Key_to_the_W - - US - 24.57 - -80.90 - 0 - 0 - KEY - - - GMZ031 - 680310 - Florida_Bay - - US - 24.99 - -80.86 - 0 - 0 - KEY - - - AMZ610 - 666100 - Lake_Okeechobee - - US - 26.94 - -80.82 - 0 - 0 - MFL - - - GMZ073 - 680730 - Wtrs_fr_Craig_Key_to_the_W_end_o - - US - 24.10 - -80.79 - 0 - 0 - KEY - - - LEZ148 - 631480 - Geneva-on-the-L_to_Conneaut_OH - - US - 41.96 - -80.75 - 0 - 0 - CLE - - - AMZ472 - 664720 - Wtrs_fr_Fernandina_Beach_to_St._ - - US - 30.27 - -80.73 - 0 - 0 - JAX - - - AMZ470 - 664700 - Wtrs_fr_Altamaha_Snd_GA_to_Ferna - - US - 30.90 - -80.71 - 0 - 0 - JAX - - - LEZ168 - 631680 - Geneva-on-the-L_to_Conneaut_OH_b - - US - 42.11 - -80.69 - 0 - 0 - CLE - - - AMZ474 - 664740 - Wtrs_fr_St._Augustine_to_Flagler - - US - 29.71 - -80.54 - 0 - 0 - JAX - - - AMZ552 - 665520 - Volusia-Brevard_Cnty_Line_to_Seb - - US - 28.39 - -80.48 - 0 - 0 - MLB - - - AMZ352 - 663520 - Cstal_wtrs_fr_Edisto_Beach_SC_to - - US - 32.18 - -80.47 - 0 - 0 - CHS - - - AMZ374 - 663740 - Wtrs_fr_Savannah_GA_to_Altamaha_ - - US - 31.48 - -80.45 - 0 - 0 - CHS - - - LEZ169 - 631690 - Conneaut_OH_to_Ripley_NY_beyond_ - - US - 42.33 - -80.35 - 0 - 0 - CLE - - - GMZ052 - 680520 - Cstal_wtrs_fr_O_Reef_to_Craig_Ke - - US - 24.94 - -80.34 - 0 - 0 - KEY - - - AMZ630 - 666300 - Biscayne_Bay - - US - 25.58 - -80.28 - 0 - 0 - MFL - - - AMZ570 - 665700 - Flagler_Beach_to_Volusia-Brevard - - US - 29.20 - -80.22 - 0 - 0 - MLB - - - LEZ149 - 631490 - Conneaut_OH_to_Ripley_NY - - US - 42.15 - -80.15 - 0 - 0 - CLE - - - GMZ072 - 680720 - Wtrs_fr_O_Reef_to_Craig_Key_fr_2 - - US - 24.53 - -80.05 - 0 - 0 - KEY - - - AMZ555 - 665550 - Sebastian_Inlt_to_Jupiter_Inlt_0 - - US - 27.40 - -80.03 - 0 - 0 - MLB - - - AMZ651 - 666510 - Cstal_wtrs_fr_Deerfield_Beach_to - - US - 25.77 - -80.01 - 0 - 0 - MFL - - - AMZ330 - 663300 - Charleston_Harbor - - US - 32.78 - -79.89 - 0 - 0 - CHS - - - AMZ572 - 665720 - Volusia-Brevard_Cnty_Line_to_Seb - - US - 28.42 - -79.87 - 0 - 0 - MLB - - - AMZ650 - 666500 - Cstal_wtrs_fr_Jupiter_Inlt_to_De - - US - 26.59 - -79.74 - 0 - 0 - MFL - - - AMZ370 - 663700 - Wtrs_fr_S_Sntee_Riv_SC_to_Savann - - US - 32.35 - -79.63 - 0 - 0 - CHS - - - LEZ040 - 630400 - Ripley_to_Dunkirk_NY - - US - 42.43 - -79.56 - 0 - 0 - BUF - - - AMZ575 - 665750 - Sebastian_Inlt_to_Jupiter_Inlt_2 - - US - 27.46 - -79.52 - 0 - 0 - MLB - - - AMZ350 - 663500 - Cstal_wtrs_fr_S_Sntee_Riv_to_Edi - - US - 32.65 - -79.51 - 0 - 0 - CHS - - - AMZ671 - 666710 - Wtrs_fr_Deerfield_Beach_to_O_Ree - - US - 25.50 - -79.50 - 0 - 0 - MFL - - - LEZ061 - 630610 - Ripley_to_Buffalo_NY_extending_f - - US - 42.55 - -79.49 - 0 - 0 - BUF - - - AMZ670 - 666700 - Wtrs_fr_Jupiter_Inlt_to_Deerfiel - - US - 26.58 - -79.34 - 0 - 0 - MFL - - - LEZ041 - 630410 - Dunkirk_to_Buffalo_NY - - US - 42.69 - -79.11 - 0 - 0 - BUF - - - LEZ020 - 630200 - Buffalo_Hbr_and_the_Upr_Niagara_ - - US - 43.11 - -79.06 - 0 - 0 - BUF - - - AMZ256 - 662560 - Cstal_wtrs_fr_Murrells_Inlt_to_S - - US - 33.21 - -78.86 - 0 - 0 - ILM - - - LOZ042 - 620420 - Niagara_Riv_to_Hamlin_Beach_NY - - US - 43.36 - -78.79 - 0 - 0 - BUF - - - LOZ062 - 620620 - Niagara_Riv_to_Hamlin_Beach_NY_b - - US - 43.55 - -78.63 - 0 - 0 - BUF - - - AMZ254 - 662540 - Cstal_wtrs_fr_Ltl_Riv_Inlt_to_Mu - - US - 33.62 - -78.59 - 0 - 0 - ILM - - - AMZ252 - 662520 - Cstal_wtrs_fr_C_Fear_NC_to_Ltl_R - - US - 33.69 - -78.01 - 0 - 0 - ILM - - - AMZ270 - 662700 - Wtrs_fr_Surf_Cty_NC_to_S_Sntee_R - - US - 33.49 - -77.96 - 0 - 0 - ILM - - - AMZ250 - 662500 - Cstal_wtrs_fr_Surf_Cty_to_C_Fear - - US - 34.07 - -77.60 - 0 - 0 - ILM - - - LOZ043 - 620430 - Hamlin_Beach_to_Sodus_Bay_NY - - US - 43.33 - -77.46 - 0 - 0 - BUF - - - LOZ063 - 620630 - Hamlin_Beach_to_Sodus_Bay_NY_bey - - US - 43.47 - -77.38 - 0 - 0 - BUF - - - ANZ536 - 675360 - Tidal_Potomac_fr_Ind_Hd_to_Cobb_ - - US - 38.42 - -77.12 - 0 - 0 - LWX - - - ANZ535 - 675350 - Tidal_Potomac_fr_Key_Br_to_Ind_H - - US - 38.75 - -77.04 - 0 - 0 - LWX - - - AMZ158 - 661580 - Cstal_wtrs_fr_C_Lookout_to_Surf_ - - US - 34.52 - -76.95 - 0 - 0 - MHX - - - LOZ064 - 620640 - Sodus_Bay_to_Mex_Bay_NY_beyond_5 - - US - 43.62 - -76.75 - 0 - 0 - BUF - - - LOZ044 - 620440 - Sodus_Bay_to_Mexico_Bay_NY - - US - 43.44 - -76.62 - 0 - 0 - BUF - - - ANZ537 - 675370 - Tidal_Potomac_fr_Cobb_I_MD_to_Sm - - US - 38.15 - -76.58 - 0 - 0 - LWX - - - ANZ533 - 675330 - Chsapke_Bay_fr_N_Beach_to_Drum_P - - US - 38.56 - -76.41 - 0 - 0 - LWX - - - LOZ065 - 620650 - Mex_Bay_NY_to_the_St._Lawrence_R - - US - 43.78 - -76.39 - 0 - 0 - BUF - - - LOZ045 - 620450 - Mex_Bay_NY_to_the_St._Lawrence_R - - US - 43.86 - -76.36 - 0 - 0 - BUF - - - ANZ531 - 675310 - Chsapke_Bay_fr_Pooles_I_to_Sndy_ - - US - 39.18 - -76.35 - 0 - 0 - LWX - - - AMZ156 - 661560 - Cstal_wtrs_fr_Ocracoke_Inlt_to_C - - US - 34.80 - -76.27 - 0 - 0 - MHX - - - ANZ532 - 675320 - Chsapke_Bay_fr_Sndy_Pt_to_N_Beac - - US - 38.90 - -76.27 - 0 - 0 - LWX - - - AMZ135 - 661350 - Pamlico_Sound - - US - 35.30 - -76.13 - 0 - 0 - MHX - - - ANZ632 - 676320 - Chsapke_Bay_fr_New_Pt_Comfort_to - - US - 37.10 - -76.13 - 0 - 0 - AKQ - - - ANZ534 - 675340 - Chsapke_Bay_fr_Drum_Pt_MD_to_Smi - - US - 38.13 - -76.11 - 0 - 0 - LWX - - - AMZ130 - 661300 - Albemarle_Sound - - US - 36.00 - -76.09 - 0 - 0 - MHX - - - ANZ631 - 676310 - Chsapke_Bay_fr_Windmill_Pt_to_Ne - - US - 37.46 - -76.09 - 0 - 0 - AKQ - - - ANZ530 - 675300 - Chesapeake_Bay_N_of_Pooles_I_MD - - US - 39.46 - -76.06 - 0 - 0 - LWX - - - ANZ630 - 676300 - Chsapke_Bay_fr_Smith_Pt_to_Windm - - US - 37.80 - -76.04 - 0 - 0 - AKQ - - - ANZ633 - 676330 - Currituck_Sound - - US - 36.40 - -75.92 - 0 - 0 - AKQ - - - SLZ022 - 730220 - St._Lawrence_Riv_above_Ogdensbg_ - - US - 44.45 - -75.79 - 0 - 0 - BUF - - - ANZ656 - 676560 - Cstal_wtrs_fr_C_Charles_Lt_VA_to - - US - 36.78 - -75.68 - 0 - 0 - AKQ - - - AMZ170 - 661700 - Wtrs_fr_Currituck_Beach_Lt_to_Su - - US - 34.83 - -75.64 - 0 - 0 - MHX - - - ANZ654 - 676540 - Cstal_wtrs_fr_Parramore_I_to_C_C - - US - 37.31 - -75.62 - 0 - 0 - AKQ - - - ANZ658 - 676580 - Cstal_wtrs_fr_NC_VA_border_to_Cu - - US - 36.36 - -75.60 - 0 - 0 - AKQ - - - AMZ154 - 661540 - Cstal_wtrs_fr_C_Hatteras_to_Ocra - - US - 35.05 - -75.58 - 0 - 0 - MHX - - - AMZ150 - 661500 - Cstal_wtrs_fr_Currituck_Beach_Lt - - US - 36.02 - -75.50 - 0 - 0 - MHX - - - ANZ652 - 676520 - Cstal_wtrs_fr_Chincoteague_to_Pa - - US - 37.81 - -75.39 - 0 - 0 - AKQ - - - AMZ152 - 661520 - Cstal_wtrs_fr_Oregon_Inlt_to_C_H - - US - 35.50 - -75.38 - 0 - 0 - MHX - - - ANZ430 - 674300 - DE_Bay_wtrs_N_of_E_Pt_NJ_to_Slau - - US - 39.32 - -75.34 - 0 - 0 - PHI - - - SLZ024 - 730240 - St._Lawrence_Riv_fr_Ogdensbg_to_ - - US - 44.86 - -75.23 - 0 - 0 - BUF - - - ANZ431 - 674310 - DE_Bay_wtrs_S_of_E_Pt_NJ_to_Slau - - US - 39.00 - -75.10 - 0 - 0 - PHI - - - ANZ670 - 676700 - Wtrs_fr_Fenwick_I_DE_to_Currituc - - US - 37.28 - -75.10 - 0 - 0 - AKQ - - - ANZ650 - 676500 - Cstal_wtrs_fr_Fenwick_I_DE_to_Ch - - US - 38.23 - -75.07 - 0 - 0 - AKQ - - - ANZ454 - 674540 - Cstal_wtrs_fr_C_May_NJ_to_C_Henl - - US - 38.80 - -74.89 - 0 - 0 - PHI - - - ANZ455 - 674550 - Cstal_wtrs_fr_C_Henlopen_to_Fenw - - US - 38.48 - -74.74 - 0 - 0 - PHI - - - ANZ453 - 674530 - Cstal_wtrs_fr_Gt_Egg_Inlt_to_C_M - - US - 38.97 - -74.57 - 0 - 0 - PHI - - - ANZ452 - 674520 - Cstal_wtrs_fr_Ltl_Egg_Inlt_to_Gt - - US - 39.26 - -74.36 - 0 - 0 - PHI - - - ANZ338 - 673380 - New_York_Harbor - - US - 40.55 - -74.09 - 0 - 0 - OKX - - - ANZ470 - 674700 - Wtrs_fr_Sndy_Hook_NJ_to_Fenwick_ - - US - 39.18 - -74.02 - 0 - 0 - PHI - - - ANZ451 - 674510 - Cstal_wtrs_fr_Manasquan_Inlt_to_ - - US - 39.65 - -73.95 - 0 - 0 - PHI - - - ANZ450 - 674500 - Cstal_wtrs_fr_Sndy_Hook_to_Manas - - US - 40.16 - -73.78 - 0 - 0 - PHI - - - ANZ355 - 673550 - Sndy_Hook_NJ_to_Fire_I_Inlt_NY_o - - US - 40.41 - -73.51 - 0 - 0 - OKX - - - ANZ335 - 673350 - Long_I_Snd_W_of_New_Haven_CT/Por - - US - 41.04 - -73.36 - 0 - 0 - OKX - - - ANZ353 - 673530 - Fire_I_Inlt_NY_to_Moriches_Inlt_ - - US - 40.55 - -73.04 - 0 - 0 - OKX - - - ANZ345 - 673450 - S_Shore_Bays_fr_Jones_Inlt_throu - - US - 40.74 - -73.00 - 0 - 0 - OKX - - - ANZ370 - 673700 - Wtrs_fr_Montauk_Pt_NY_to_Sndy_Ho - - US - 40.31 - -72.48 - 0 - 0 - OKX - - - ANZ330 - 673300 - Long_I_Snd_E_of_New_Haven_CT/Por - - US - 41.15 - -72.44 - 0 - 0 - OKX - - - ANZ340 - 673400 - Peconic_and_Gardiners_Bays - - US - 41.02 - -72.33 - 0 - 0 - OKX - - - ANZ350 - 673500 - Moriches_Inlt_NY_to_Montauk_Pt_N - - US - 40.75 - -72.21 - 0 - 0 - OKX - - - ANZ237 - 672370 - Block_Island_Sound - - US - 41.21 - -71.61 - 0 - 0 - BOX - - - ANZ236 - 672360 - Narragansett_Bay - - US - 41.62 - -71.29 - 0 - 0 - BOX - - - ANZ235 - 672350 - Rhode_Island_Sound - - US - 41.32 - -71.13 - 0 - 0 - BOX - - - ANZ230 - 672300 - Boston_Harbor - - US - 42.34 - -70.94 - 0 - 0 - BOX - - - ANZ233 - 672330 - Vineyard_Sound - - US - 41.43 - -70.78 - 0 - 0 - BOX - - - ANZ234 - 672340 - Buzzards_Bay - - US - 41.52 - -70.74 - 0 - 0 - BOX - - - ANZ255 - 672550 - Cstal_wtrs_fr_Nantucket_MA_to_Ma - - US - 41.07 - -70.74 - 0 - 0 - BOX - - - ANZ250 - 672500 - Cstal_wtrs_fr_Merrimack_Riv_MA_o - - US - 42.44 - -70.37 - 0 - 0 - BOX - - - ANZ231 - 672310 - Cape_Cod_Bay - - US - 41.92 - -70.34 - 0 - 0 - BOX - - - ANZ154 - 671540 - Cstal_Wtrs_fr_C_Elizabeth,_ME_to - - US - 43.11 - -70.26 - 0 - 0 - GYX - - - ANZ232 - 672320 - Nantucket_Sound - - US - 41.48 - -70.26 - 0 - 0 - BOX - - - ANZ153 - 671530 - Casco_Bay - - US - 43.72 - -70.06 - 0 - 0 - GYX - - - ANZ254 - 672540 - Cstal_wtrs_fr_Provincetown_MA_to - - US - 41.66 - -69.75 - 0 - 0 - BOX - - - ANZ152 - 671520 - Cstal_Wtrs_fr_Port_Clyde,_ME_to_ - - US - 43.57 - -69.47 - 0 - 0 - GYX - - - ANZ170 - 671700 - Wtrs_fr_Stonington_ME_to_Merrima - - US - 43.32 - -69.31 - 0 - 0 - GYX - - - ANZ270 - 672700 - Wtrs_fr_Merrimack_Riv_MA_to_Watc - - US - 41.69 - -69.29 - 0 - 0 - BOX - - - ANZ150 - 671500 - Cstal_Wtrs_fr_Stonington,_ME_to_ - - US - 43.84 - -68.91 - 0 - 0 - GYX - - - ANZ151 - 671510 - Penobscot_Bay - - US - 44.18 - -68.77 - 0 - 0 - GYX - - - ANZ051 - 670510 - Cstal_Wtrs_fr_Schoodic_Pt,_ME_to - - US - 44.00 - -68.25 - 0 - 0 - CAR - - - ANZ052 - 670520 - Intra_Cstal_Wtrs_fr_Schoodic_Pt, - - US - 44.19 - -68.25 - 0 - 0 - CAR - - - ANZ070 - 670700 - Wtrs_fr_Eport_ME_to_Stonington_( - - US - 43.84 - -67.86 - 0 - 0 - CAR - - - AMZ741 - 667410 - Mona_Passage_Southward_to_17N - - US - 17.74 - -67.69 - 0 - 0 - SJU - - - ANZ050 - 670500 - Cstal_Wtrs_fr_Eport,_ME_to_Schoo - - US - 44.30 - -67.48 - 0 - 0 - CAR - - - AMZ742 - 667420 - Cstal_Wtrs_OF_NWrn_Puerto_Rico_o - - US - 18.34 - -67.30 - 0 - 0 - SJU - - - AMZ745 - 667450 - Cstal_Wtrs_OF_SWrn_Puerto_Rico_o - - US - 18.06 - -67.28 - 0 - 0 - SJU - - - AMZ712 - 667120 - Cstal_Wtrs_of_Nrn_Puerto_Rico_ou - - US - 18.60 - -66.63 - 0 - 0 - SJU - - - AMZ735 - 667350 - Cstal_Wtrs_of_Srn_Puerto_Rico_ou - - US - 17.84 - -66.43 - 0 - 0 - SJU - - - AMZ710 - 667100 - Atl_Wtrs_of_Puerto_Rico_AND_USVI - - US - 19.04 - -66.01 - 0 - 0 - SJU - - - AMZ732 - 667320 - Carib_Wtrs_of_Puerto_Rico_fr_10_ - - US - 17.49 - -65.58 - 0 - 0 - SJU - - - AMZ725 - 667250 - Cstal_Wtrs_of_Srn_USVI,_Vieques, - - US - 18.24 - -65.16 - 0 - 0 - SJU - - - AMZ715 - 667150 - Cstal_Wtrs_of_Nrn_USVI_and_Culeb - - US - 18.47 - -64.85 - 0 - 0 - SJU - - - AMZ722 - 667220 - Anegada_Passage_Sward_to_17N - - US - 17.75 - -64.08 - 0 - 0 - SJU - - - PMZ161 - 711610 - Koror_Palau_Coastal_Waters - - US - 7.34 - 134.48 - 0 - 0 - GUM - - - PMZ171 - 711710 - Yap_Coastal_Waters - - US - 9.48 - 138.08 - 0 - 0 - GUM - - - PMZ151 - 711510 - Guam_Coastal_Waters - - US - 13.32 - 144.66 - 0 - 0 - GUM - - - PMZ152 - 711520 - Rota_Coastal_Waters - - US - 14.18 - 145.24 - 0 - 0 - GUM - - - PMZ153 - 711530 - Tinian_Coastal_Waters - - US - 14.83 - 145.45 - 0 - 0 - GUM - - - PMZ154 - 711540 - Saipan_Coastal_Waters - - US - 15.40 - 145.81 - 0 - 0 - GUM - - - PMZ172 - 711720 - Chuuk_Coastal_Waters - - US - 7.45 - 151.83 - 0 - 0 - GUM - - - PMZ173 - 711730 - Pohnpei_Coastal_Waters - - US - 6.97 - 158.23 - 0 - 0 - GUM - - - PMZ174 - 711740 - Kosrae_Coastal_Waters - - US - 5.35 - 162.95 - 0 - 0 - GUM - - - PMZ191 - 711910 - Waters_out_to_40_Nautical_Miles - - US - 19.30 - 166.64 - 0 - 0 - GUM - - - PMZ181 - 711810 - Majuro_Coastal_Waters - - US - 7.08 - 171.38 - 0 - 0 - GUM - - - PKZ176 - 691760 - Kiska_to_Attu - - US - 52.48 - 174.46 - 0 - 0 - AFC - - + + + + + AKZ187 + 21870 + Central_Aleutians + AK + US + 52.22 + -174.23 + 0 + 0 + AFC + + + AKZ213 + 22130 + St_Lawrence_I_and_Bering_St_Cst + AK + US + 63.36 + -170.27 + 0 + 0 + AFG + + + AKZ195 + 21950 + Pribilof_Islands + AK + US + 57.18 + -170.26 + 0 + 0 + AFC + + + AKZ185 + 21850 + Eastern_Aleutians + AK + US + 53.63 + -166.66 + 0 + 0 + AFC + + + AKZ207 + 22070 + Chukchi_Sea_Coast + AK + US + 67.98 + -165.11 + 0 + 0 + AFG + + + AKZ211 + 22110 + Southern_Seward_Peninsula_Coast + AK + US + 64.58 + -164.56 + 0 + 0 + AFG + + + AKZ214 + 22140 + Yukon_Delta + AK + US + 62.24 + -164.37 + 0 + 0 + AFG + + + AKZ155 + 21550 + Kuskokwim_Delta + AK + US + 60.18 + -163.61 + 0 + 0 + AFC + + + AKZ208 + 22080 + Lower_Kobuk_and_Noatak_Valleys + AK + US + 67.77 + -162.75 + 0 + 0 + AFG + + + AKZ210 + 22100 + Nrn_and_Interior_Seward_Penin + AK + US + 65.40 + -162.41 + 0 + 0 + AFG + + + AKZ201 + 22010 + Western_Arctic_Coast + AK + US + 69.84 + -161.53 + 0 + 0 + AFG + + + AKZ181 + 21810 + Alaska_Peninsula + AK + US + 55.82 + -161.44 + 0 + 0 + AFC + + + AKZ209 + 22090 + Baldwin_Penin_and_Selawik_Vly + AK + US + 66.69 + -161.06 + 0 + 0 + AFG + + + AKZ212 + 22120 + Ern_Norton_Snd_and_Nulato_Hills + AK + US + 63.74 + -160.39 + 0 + 0 + AFG + + + HIZ001 + 110010 + Niihau + HI + US + 21.89 + -160.15 + 0 + 0 + HFO + + + AKZ215 + 22150 + Lower_Yukon_Valley + AK + US + 62.56 + -159.94 + 0 + 0 + AFG + + + HIZ003 + 110030 + Kauai_Leeward + HI + US + 22.02 + -159.67 + 0 + 0 + HFO + + + HIZ004 + 110040 + Kauai_Mountains + HI + US + 22.07 + -159.54 + 0 + 0 + HFO + + + HIZ002 + 110020 + Kauai_Windward + HI + US + 22.05 + -159.40 + 0 + 0 + HFO + + + AKZ205 + 22050 + Northwestern_Brooks_Range + AK + US + 69.06 + -158.44 + 0 + 0 + AFG + + + HIZ006 + 110060 + Waianae_Coast + HI + US + 21.48 + -158.21 + 0 + 0 + HFO + + + HIZ011 + 110110 + Waianae_Mountains + HI + US + 21.46 + -158.10 + 0 + 0 + HFO + + + HIZ007 + 110070 + Oahu_North_Shore + HI + US + 21.59 + -158.08 + 0 + 0 + HFO + + + HIZ005 + 110050 + Oahu_South_Shore + HI + US + 21.33 + -158.05 + 0 + 0 + HFO + + + HIZ010 + 110100 + Central_Oahu + HI + US + 21.50 + -158.01 + 0 + 0 + HFO + + + HIZ008 + 110080 + Oahu_Koolau + HI + US + 21.50 + -157.89 + 0 + 0 + HFO + + + HIZ009 + 110090 + Olomana + HI + US + 21.39 + -157.73 + 0 + 0 + HFO + + + HIZ013 + 110130 + Molokai_Leeward + HI + US + 21.14 + -157.09 + 0 + 0 + HFO + + + AKZ217 + 22170 + Upper_Kobuk_and_Noatak_Valleys + AK + US + 67.41 + -156.95 + 0 + 0 + AFG + + + HIZ015 + 110150 + Lanai_Mauka + HI + US + 20.82 + -156.92 + 0 + 0 + HFO + + + HIZ012 + 110120 + Molokai_Windward + HI + US + 21.14 + -156.85 + 0 + 0 + HFO + + + HIZ014 + 110140 + Lanai_Makai + HI + US + 20.83 + -156.84 + 0 + 0 + HFO + + + HIZ018 + 110180 + Maui_Leeward_West + HI + US + 20.89 + -156.67 + 0 + 0 + HFO + + + HIZ016 + 110160 + Kahoolawe + HI + US + 20.56 + -156.62 + 0 + 0 + HFO + + + AKZ216 + 22160 + Lwr_Koyukuk_and_Middle_Yukon_Vly + AK + US + 64.44 + -156.58 + 0 + 0 + AFG + + + HIZ017 + 110170 + Maui_Windward_West + HI + US + 20.92 + -156.58 + 0 + 0 + HFO + + + HIZ019 + 110190 + Maui_Central_Valley + HI + US + 20.85 + -156.45 + 0 + 0 + HFO + + + HIZ021 + 110210 + Leeward_Haleakala + HI + US + 20.72 + -156.31 + 0 + 0 + HFO + + + HIZ022 + 110220 + Haleakala_Summit + HI + US + 20.72 + -156.23 + 0 + 0 + HFO + + + HIZ020 + 110200 + Windward_Haleakala + HI + US + 20.80 + -156.18 + 0 + 0 + HFO + + + AKZ151 + 21510 + Kuskokwim_Valley + AK + US + 62.26 + -156.04 + 0 + 0 + AFC + + + HIZ023 + 110230 + Kona + HI + US + 19.45 + -155.86 + 0 + 0 + HFO + + + HIZ026 + 110260 + Kohala + HI + US + 20.02 + -155.74 + 0 + 0 + HFO + + + AKZ161 + 21610 + Bristol_Bay + AK + US + 58.67 + -155.70 + 0 + 0 + AFC + + + HIZ027 + 110270 + Big_Island_Interior + HI + US + 19.56 + -155.61 + 0 + 0 + HFO + + + HIZ028 + 110280 + Big_Island_Summit + HI + US + 19.44 + -155.58 + 0 + 0 + HFO + + + HIZ024 + 110240 + South_Big_Island + HI + US + 19.19 + -155.42 + 0 + 0 + HFO + + + AKZ202 + 22020 + Northern_Arctic_Coast + AK + US + 70.78 + -155.25 + 0 + 0 + AFG + + + HIZ025 + 110250 + Big_Island_North_and_East + HI + US + 19.81 + -155.19 + 0 + 0 + HFO + + + AKZ171 + 21710 + Kodiak_Island + AK + US + 58.65 + -154.17 + 0 + 0 + AFC + + + AKZ219 + 22190 + Upper_Koyukuk_Valley + AK + US + 66.28 + -152.42 + 0 + 0 + AFG + + + AKZ221 + 22210 + Central_Interior + AK + US + 64.61 + -151.55 + 0 + 0 + AFG + + + AKZ145 + 21450 + Susitna_Valley + AK + US + 61.95 + -150.71 + 0 + 0 + AFC + + + AKZ121 + 21210 + Western_Kenai_Peninsula + AK + US + 60.12 + -150.69 + 0 + 0 + AFC + + + AKZ225 + 22250 + Denali + AK + US + 63.51 + -150.21 + 0 + 0 + AFG + + + AKZ101 + 21010 + Anchorage + AK + US + 61.20 + -149.71 + 0 + 0 + AFC + + + AKZ203 + 22030 + Central_Beaufort_Sea_Coast + AK + US + 70.34 + -149.66 + 0 + 0 + AFG + + + AKZ111 + 21110 + Matanuska_Valley + AK + US + 61.60 + -149.43 + 0 + 0 + AFC + + + AKZ125 + 21250 + Western_Prince_William_Sound + AK + US + 60.28 + -149.43 + 0 + 0 + AFC + + + AKZ218 + 22180 + Southeastern_Brooks_Range + AK + US + 67.94 + -147.78 + 0 + 0 + AFG + + + AKZ206 + 22060 + Northeastern_Brooks_Range + AK + US + 68.97 + -147.55 + 0 + 0 + AFG + + + AKZ222 + 22220 + Middle_Tanana_Valley + AK + US + 64.97 + -147.45 + 0 + 0 + AFG + + + AKZ223 + 22230 + Deltana_and_Tanana_Flats + AK + US + 64.13 + -146.62 + 0 + 0 + AFG + + + AKZ131 + 21310 + Northeast_Prince_William_Sound + AK + US + 61.14 + -146.39 + 0 + 0 + AFC + + + AKZ220 + 22200 + Yukon_Flats_and_Surrounding_Upla + AK + US + 66.46 + -146.25 + 0 + 0 + AFG + + + AKZ135 + 21350 + Southeast_Prince_William_Sound + AK + US + 60.65 + -145.32 + 0 + 0 + AFC + + + AKZ141 + 21410 + Copper_River_Basin + AK + US + 61.88 + -144.85 + 0 + 0 + AFC + + + AKZ204 + 22040 + Eastern_Beaufort_Sea_Coast + AK + US + 69.85 + -143.75 + 0 + 0 + AFG + + + AKZ224 + 22240 + Upr_Tanana_Vly_and_the_Ftymile_C + AK + US + 64.21 + -143.50 + 0 + 0 + AFG + + + AKZ226 + 22260 + Eastern_Alaska_Range + AK + US + 62.77 + -142.76 + 0 + 0 + AFG + + + AKZ017 + 20170 + C_Fairweather_to_C_Suckling_Csta + AK + US + 59.74 + -140.70 + 0 + 0 + AJK + + + AKZ022 + 20220 + Salisbury_Snd_to_C_Fairweather_C + AK + US + 58.68 + -137.66 + 0 + 0 + AJK + + + AKZ020 + 20200 + Glacier_Bay + AK + US + 58.79 + -136.99 + 0 + 0 + AJK + + + AKZ021 + 20210 + Eastern_Chichagof_Island + AK + US + 57.88 + -135.51 + 0 + 0 + AJK + + + AKZ019 + 20190 + Haines_Borough_and_Lynn_Canal + AK + US + 58.95 + -135.41 + 0 + 0 + AJK + + + AKZ018 + 20180 + Taiya_Inlet_and_Klondike_Hiway + AK + US + 59.57 + -135.35 + 0 + 0 + AJK + + + AKZ023 + 20230 + C_Decision_to_Salisbury_Snd_Csta + AK + US + 56.85 + -135.25 + 0 + 0 + AJK + + + AKZ024 + 20240 + Ern_Baranof_I_and_Srn_Admty_I + AK + US + 57.31 + -134.27 + 0 + 0 + AJK + + + AKZ025 + 20250 + Juneau_Borough_and_Nrn_Admty_I + AK + US + 58.08 + -133.64 + 0 + 0 + AJK + + + AKZ027 + 20270 + Dixon_Entr_to_C_Decision_Cstal_A + AK + US + 55.36 + -133.19 + 0 + 0 + AJK + + + AKZ026 + 20260 + Inr_Chnls_fr_Kupreanof_I_to_Etol + AK + US + 56.53 + -133.00 + 0 + 0 + AJK + + + AKZ028 + 20280 + Southern_Inner_Channels + AK + US + 55.71 + -132.71 + 0 + 0 + AJK + + + AKZ029 + 20290 + Misty_Fjords + AK + US + 55.67 + -130.98 + 0 + 0 + AJK + + + WAZ516 + 475160 + North_Coast + WA + US + 47.95 + -124.39 + 0 + 0 + SEW + + + ORZ022 + 370220 + Curry_County_Coast + OR + US + 42.35 + -124.27 + 0 + 0 + MFR + + + WAZ515 + 475150 + Western_Strait_of_Juan_De_Fuca + WA + US + 48.19 + -124.25 + 0 + 0 + SEW + + + ORZ021 + 370210 + South_Central_Oregon_Coast + OR + US + 43.28 + -124.24 + 0 + 0 + MFR + + + WAZ517 + 475170 + Central_Coast + WA + US + 47.16 + -124.06 + 0 + 0 + SEW + + + CAZ001 + 50010 + Redwood_Coast + CA + US + 41.02 + -124.03 + 0 + 0 + EKA + + + ORZ002 + 370020 + Central_Oregon_Coast + OR + US + 44.44 + -124.01 + 0 + 0 + PQR + + + ORZ001 + 370010 + North_Oregon_Coast + OR + US + 45.64 + -123.92 + 0 + 0 + PQR + + + ORZ024 + 370240 + Ern_Curry_Cnty_and_Josephine_Cnt + OR + US + 42.39 + -123.75 + 0 + 0 + MFR + + + CAZ003 + 50030 + North_Coast_Interior + CA + US + 40.99 + -123.72 + 0 + 0 + EKA + + + WAZ021 + 470210 + South_Washington_Coast + WA + US + 46.47 + -123.71 + 0 + 0 + PQR + + + CAZ002 + 50020 + Mendocino_Coast + CA + US + 39.40 + -123.64 + 0 + 0 + EKA + + + ORZ004 + 370040 + Ctrl_Coast_Range_of_Wrn_Oregon + OR + US + 44.42 + -123.62 + 0 + 0 + PQR + + + WAZ513 + 475130 + Olympics + WA + US + 47.71 + -123.61 + 0 + 0 + SEW + + + WAZ512 + 475120 + Lower_Chehalis_Valley_Area + WA + US + 47.09 + -123.52 + 0 + 0 + SEW + + + WAZ020 + 470200 + Willapa_Hills + WA + US + 46.52 + -123.51 + 0 + 0 + PQR + + + ORZ003 + 370030 + Coast_Range_of_Northwest_Oregon + OR + US + 45.59 + -123.40 + 0 + 0 + PQR + + + CAZ076 + 50760 + Mendocino_Interior + CA + US + 39.40 + -123.39 + 0 + 0 + EKA + + + ORZ023 + 370230 + Central_Douglas_County + OR + US + 43.32 + -123.35 + 0 + 0 + MFR + + + WAZ514 + 475140 + Eastern_Strait_of_Juan_de_Fuca + WA + US + 48.07 + -123.28 + 0 + 0 + SEW + + + CAZ080 + 50800 + Western_Siskiyou_County + CA + US + 41.49 + -123.13 + 0 + 0 + MFR + + + ORZ008 + 370080 + South__Willamette_Valley + OR + US + 44.32 + -123.11 + 0 + 0 + PQR + + + CAZ004 + 50040 + Upper_Trinity_River + CA + US + 40.44 + -123.07 + 0 + 0 + EKA + + + CAZ505 + 55050 + Cstal_N_Bay_Incl_Pt_Reyes_Natl_S + CA + US + 38.30 + -122.99 + 0 + 0 + MTR + + + WAZ001 + 470010 + San_Juan_County + WA + US + 48.60 + -122.99 + 0 + 0 + SEW + + + ORZ007 + 370070 + Central_Willamette_Valley + OR + US + 45.05 + -122.94 + 0 + 0 + PQR + + + WAZ511 + 475110 + Hood_Canal_Area + WA + US + 47.52 + -122.94 + 0 + 0 + SEW + + + WAZ022 + 470220 + Lwr_Columbia_and_I_-_5_Corridor_ + WA + US + 46.11 + -122.88 + 0 + 0 + PQR + + + ORZ005 + 370050 + Lower_Columbia + OR + US + 45.97 + -122.87 + 0 + 0 + PQR + + + WAZ504 + 475040 + Southwest_Interior + WA + US + 46.78 + -122.87 + 0 + 0 + SEW + + + ORZ026 + 370260 + Jackson_County + OR + US + 42.48 + -122.86 + 0 + 0 + MFR + + + ORZ006 + 370060 + Greater_Portland_Metro_Area + OR + US + 45.52 + -122.83 + 0 + 0 + PQR + + + CAZ506 + 55060 + North_Bay_Interior_Valleys + CA + US + 38.34 + -122.78 + 0 + 0 + MTR + + + ORZ012 + 370120 + Cascade_Foothills_in_Lane_Cnty + OR + US + 43.91 + -122.77 + 0 + 0 + PQR + + + ORZ025 + 370250 + Ern_Douglas_County_Foothills + OR + US + 43.18 + -122.75 + 0 + 0 + MFR + + + CAZ063 + 50630 + Mtns_SWrn_Shasta_Cnty_to_Nrn_L_C + CA + US + 39.91 + -122.73 + 0 + 0 + STO + + + CAZ064 + 50640 + Clear_Lake/Southern_Lake_County + CA + US + 38.96 + -122.67 + 0 + 0 + STO + + + CAZ081 + 50810 + Central_Siskiyou_County + CA + US + 41.68 + -122.60 + 0 + 0 + MFR + + + WAZ503 + 475030 + Western_Whatcom_County + WA + US + 48.82 + -122.59 + 0 + 0 + SEW + + + WAZ039 + 470390 + Greater_Vancouver_Area + WA + US + 45.73 + -122.54 + 0 + 0 + PQR + + + ORZ010 + 370100 + Nrn_Oregon_Cascade_Foothills + OR + US + 44.86 + -122.52 + 0 + 0 + PQR + + + WAZ509 + 475090 + Tacoma_Area + WA + US + 47.17 + -122.52 + 0 + 0 + SEW + + + WAZ510 + 475100 + Admiralty_Inlet_Area + WA + US + 48.15 + -122.50 + 0 + 0 + SEW + + + WAZ040 + 470400 + S_Washington_Cascade_Foothills + WA + US + 46.00 + -122.48 + 0 + 0 + PQR + + + CAZ006 + 50060 + San_Francisco + CA + US + 37.75 + -122.42 + 0 + 0 + MTR + + + WAZ506 + 475060 + Western_Skagit_County + WA + US + 48.47 + -122.42 + 0 + 0 + SEW + + + CAZ509 + 55090 + San_Francisco_Peninsula_Coast + CA + US + 37.36 + -122.38 + 0 + 0 + MTR + + + WAZ508 + 475080 + Seattle/Bremerton_Area + WA + US + 47.51 + -122.29 + 0 + 0 + SEW + + + CAZ507 + 55070 + North_Bay_Mountains + CA + US + 38.54 + -122.27 + 0 + 0 + MTR + + + CAZ015 + 50150 + Northern_Sacramento_Valley + CA + US + 40.26 + -122.25 + 0 + 0 + STO + + + ORZ013 + 370130 + Cascades_in_Lane_County + OR + US + 43.84 + -122.25 + 0 + 0 + PQR + + + ORZ028 + 370280 + Siskiyou_Mtns_and_Srn_Oregon_Cas + OR + US + 42.41 + -122.24 + 0 + 0 + MFR + + + CAZ013 + 50130 + Shasta_L_Area_/_Nrn_Shasta_Cnty + CA + US + 40.87 + -122.21 + 0 + 0 + STO + + + ORZ027 + 370270 + South_Central_Oregon_Cascades + OR + US + 43.21 + -122.21 + 0 + 0 + MFR + + + CAZ082 + 50820 + South_Central_Siskiyou_County + CA + US + 41.30 + -122.14 + 0 + 0 + MFR + + + WAZ507 + 475070 + Everett_and_Vicinity + WA + US + 48.03 + -122.14 + 0 + 0 + SEW + + + CAZ508 + 55080 + San_Francisco_Bay_Shoreline + CA + US + 37.64 + -122.08 + 0 + 0 + MTR + + + WAZ505 + 475050 + East_Puget_Sound_Lowlands + WA + US + 47.53 + -122.05 + 0 + 0 + SEW + + + WAZ019 + 470190 + South_Washington_Cascades + WA + US + 46.00 + -122.04 + 0 + 0 + PQR + + + CAZ512 + 55120 + Santa_Cruz_Mountains + CA + US + 37.20 + -121.98 + 0 + 0 + MTR + + + CAZ510 + 55100 + East_Bay_Interior_Valleys + CA + US + 37.82 + -121.97 + 0 + 0 + MTR + + + ORZ009 + 370090 + Western_Columbia_River_Gorge + OR + US + 45.61 + -121.96 + 0 + 0 + PQR + + + ORZ011 + 370110 + Northern_Oregon_Cascades + OR + US + 44.93 + -121.94 + 0 + 0 + PQR + + + WAZ023 + 470230 + Western_Columbia_River_Gorge + WA + US + 45.66 + -121.92 + 0 + 0 + PQR + + + CAZ016 + 50160 + Central_Sacramento_Valley + CA + US + 39.40 + -121.90 + 0 + 0 + STO + + + CAZ083 + 50830 + N_Ctrl_and_SE_Siskiyou_County + CA + US + 41.59 + -121.90 + 0 + 0 + MFR + + + CAZ530 + 55300 + Srn_Monterey_Bay_and_Big_Sur_Cst + CA + US + 36.35 + -121.90 + 0 + 0 + MTR + + + WAZ519 + 475190 + W_Slopes_Ctrl_Cascades_and_Passe + WA + US + 47.08 + -121.89 + 0 + 0 + SEW + + + CAZ018 + 50180 + Carquinez_Strait_and_Delta + CA + US + 38.07 + -121.80 + 0 + 0 + STO + + + CAZ529 + 55290 + Northern_Monterey_Bay + CA + US + 36.96 + -121.79 + 0 + 0 + MTR + + + CAZ511 + 55110 + E_Bay_Hills_and_the_Diablo_Rng + CA + US + 37.48 + -121.73 + 0 + 0 + MTR + + + CAZ513 + 55130 + Santa_Clara_Vly_Incl_San_Jose + CA + US + 37.17 + -121.69 + 0 + 0 + MTR + + + CAZ066 + 50660 + NE_Foothills/Sacramento_Valley + CA + US + 40.13 + -121.65 + 0 + 0 + STO + + + CAZ017 + 50170 + Southern_Sacramento_Valley + CA + US + 38.64 + -121.63 + 0 + 0 + STO + + + CAZ084 + 50840 + NE_Siskiyou_and_NW_Modoc_Cnties + CA + US + 41.86 + -121.63 + 0 + 0 + MFR + + + ORZ029 + 370290 + Klamath_Basin + OR + US + 42.47 + -121.63 + 0 + 0 + MFR + + + ORZ014 + 370140 + Upper_Hood_River_Valley + OR + US + 45.56 + -121.58 + 0 + 0 + PQR + + + CAZ528 + 55280 + Nrn_Salinas_Vly/Hollister_Vly_an + CA + US + 36.67 + -121.56 + 0 + 0 + MTR + + + CAZ014 + 50140 + Burney_Basin_/_Ern_Shasta_Cnty + CA + US + 40.88 + -121.52 + 0 + 0 + STO + + + WAZ518 + 475180 + W_Slopes_Nrn_Cascades_and_Passes + WA + US + 48.39 + -121.49 + 0 + 0 + SEW + + + CAZ517 + 55170 + Sta_Lucia_Mtns_and_Los_Padres_Na + CA + US + 36.19 + -121.39 + 0 + 0 + MTR + + + CAZ068 + 50680 + Wrn_Plumas_County/Lassen_Park + CA + US + 40.22 + -121.32 + 0 + 0 + STO + + + ORZ030 + 370300 + Nrn_and_Ern_Klamath_Cnty_and_Wrn + OR + US + 42.80 + -121.24 + 0 + 0 + MFR + + + ORZ042 + 370420 + North_Central_Oregon + OR + US + 45.04 + -121.10 + 0 + 0 + PDT + + + CAZ516 + 55160 + Srn_Salinas_Vly/Arroyo_Seco_and_ + CA + US + 36.09 + -121.09 + 0 + 0 + MTR + + + WAZ024 + 470240 + East_Columbia_River_Gorge + WA + US + 45.70 + -121.06 + 0 + 0 + PDT + + + ORZ041 + 370410 + East_Columbia_River_Gorge + OR + US + 45.64 + -121.02 + 0 + 0 + PDT + + + WAZ501 + 475010 + E_Slopes_of_the_Ctrl_Cascades + WA + US + 47.05 + -120.96 + 0 + 0 + PDT + + + ORZ043 + 370430 + Central_Oregon + OR + US + 44.00 + -120.95 + 0 + 0 + PDT + + + CAZ019 + 50190 + Northern_San_Joaquin_Valley + CA + US + 37.76 + -120.93 + 0 + 0 + STO + + + CAZ518 + 55180 + Mtns_Of_Sn_Benito_Cnty_And_Int_M + CA + US + 36.39 + -120.89 + 0 + 0 + MTR + + + CAZ034 + 50340 + San_Luis_Obispo_Cnty_Ctrl_Coast + CA + US + 35.35 + -120.78 + 0 + 0 + LOX + + + WAZ502 + 475020 + East_Slopes_of_the_Srn_Cascades + WA + US + 46.10 + -120.78 + 0 + 0 + PDT + + + CAZ085 + 50850 + Modoc_County + CA + US + 41.58 + -120.74 + 0 + 0 + MFR + + + CAZ067 + 50670 + Motherlode + CA + US + 38.63 + -120.71 + 0 + 0 + STO + + + CAZ071 + 50710 + Lassen-Ern_Plumas-Ern_Sierra_Cnt + CA + US + 40.31 + -120.66 + 0 + 0 + REV + + + WAZ027 + 470270 + Yakima_Valley + WA + US + 46.43 + -120.45 + 0 + 0 + PDT + + + CAZ035 + 50350 + Santa_Barbara_County_Ctrl_Coast + CA + US + 34.72 + -120.41 + 0 + 0 + LOX + + + CAZ089 + 50890 + West-Central_San_Joaquin_Valley + CA + US + 36.62 + -120.39 + 0 + 0 + HNX + + + WAZ026 + 470260 + Kittitas_Valley + WA + US + 47.00 + -120.39 + 0 + 0 + PDT + + + WAZ042 + 470420 + East_Slopes_Northern_Cascades + WA + US + 48.13 + -120.38 + 0 + 0 + OTX + + + CAZ069 + 50690 + West_Slope_Nrn_Sierra_Nevada + CA + US + 38.76 + -120.37 + 0 + 0 + STO + + + CAZ037 + 50370 + San_Luis_Obispo_Cnty_Int_Vlys + CA + US + 35.41 + -120.31 + 0 + 0 + LOX + + + ORZ031 + 370310 + Central_and_Eastern_Lake_County + OR + US + 42.80 + -120.24 + 0 + 0 + MFR + + + ORZ506 + 375060 + Ochoco-John_Day_Highlands + OR + US + 44.34 + -120.20 + 0 + 0 + PDT + + + WAZ041 + 470410 + Wenatchee_Area + WA + US + 47.61 + -120.18 + 0 + 0 + OTX + + + CAZ051 + 50510 + San_Luis_Obispo_County_Mtns + CA + US + 35.16 + -120.17 + 0 + 0 + LOX + + + CAZ036 + 50360 + Santa_Ynez_Valley + CA + US + 34.72 + -120.14 + 0 + 0 + LOX + + + CAZ070 + 50700 + Surprise_Valley_California + CA + US + 41.58 + -120.11 + 0 + 0 + REV + + + CAZ090 + 50900 + East-Central_San_Joaquin_Valley + CA + US + 37.11 + -120.11 + 0 + 0 + HNX + + + ORZ504 + 375040 + Nrn_Wheeler_and_Srn_Gilliam_Cnti + OR + US + 45.01 + -120.10 + 0 + 0 + PDT + + + CAZ072 + 50720 + Greater_Lake_Tahoe_Area + CA + US + 38.89 + -119.96 + 0 + 0 + REV + + + CAZ039 + 50390 + Santa_Barbara_County_S_Coast + CA + US + 34.45 + -119.95 + 0 + 0 + LOX + + + NVZ002 + 280020 + Greater_Lake_Tahoe_Area + NV + US + 39.19 + -119.90 + 0 + 0 + REV + + + CAZ052 + 50520 + Santa_Barbara_County_Mountains + CA + US + 34.77 + -119.88 + 0 + 0 + LOX + + + CAZ091 + 50910 + Southwestern_San_Joaquin_Valley + CA + US + 35.75 + -119.78 + 0 + 0 + HNX + + + CAZ038 + 50380 + Cuyama_Valley + CA + US + 34.96 + -119.77 + 0 + 0 + LOX + + + NVZ005 + 280050 + Northern_Washoe_County + NV + US + 41.01 + -119.65 + 0 + 0 + REV + + + ORZ044 + 370440 + Lower_Columbia_Basin + OR + US + 45.60 + -119.65 + 0 + 0 + PDT + + + WAZ044 + 470440 + Waterville_Plateau + WA + US + 47.68 + -119.65 + 0 + 0 + OTX + + + CAZ093 + 50930 + Mariposa_Madera_and_Fresno_Cnty_ + CA + US + 37.24 + -119.64 + 0 + 0 + HNX + + + NVZ003 + 280030 + Gter_Reno-Carson_Cty-Minden_Area + NV + US + 39.36 + -119.63 + 0 + 0 + REV + + + ORZ505 + 375050 + John_Day_Basin + OR + US + 44.63 + -119.49 + 0 + 0 + PDT + + + WAZ034 + 470340 + Moses_Lake_Area + WA + US + 47.03 + -119.48 + 0 + 0 + OTX + + + WAZ043 + 470430 + Okanogan_Valley + WA + US + 48.47 + -119.47 + 0 + 0 + OTX + + + WAZ028 + 470280 + Lower_Columbia_Basin + WA + US + 46.21 + -119.43 + 0 + 0 + PDT + + + CAZ044 + 50440 + Ventura_County_Interior_Valleys + CA + US + 34.44 + -119.25 + 0 + 0 + LOX + + + CAZ040 + 50400 + Ventura_County_Coast + CA + US + 34.22 + -119.19 + 0 + 0 + LOX + + + CAZ092 + 50920 + Southeastern_San_Joaquin_Valley + CA + US + 35.82 + -119.14 + 0 + 0 + HNX + + + CAZ096 + 50960 + Sierra_NV_fr_Yosemite_to_Kings_C + CA + US + 37.43 + -119.12 + 0 + 0 + HNX + + + CAZ053 + 50530 + Ventura_County_Mountains + CA + US + 34.65 + -119.10 + 0 + 0 + LOX + + + ORZ501 + 375010 + Foothills_of_the_Blue_Mountains + OR + US + 45.53 + -119.07 + 0 + 0 + PDT + + + ORZ061 + 370610 + Harney_County + OR + US + 43.01 + -119.06 + 0 + 0 + BOI + + + CAZ094 + 50940 + Tulare_County_Foothills + CA + US + 36.23 + -118.96 + 0 + 0 + HNX + + + WAZ035 + 470350 + Upper_Columbia_Basin + WA + US + 47.41 + -118.91 + 0 + 0 + OTX + + + ORZ503 + 375030 + Southern_Blue_Mtns_of_Oregon + OR + US + 45.23 + -118.88 + 0 + 0 + PDT + + + CAZ045 + 50450 + Ventura_County_Coastal_Valleys + CA + US + 34.23 + -118.87 + 0 + 0 + LOX + + + WAZ038 + 470380 + Okanogan_Highlands + WA + US + 48.42 + -118.75 + 0 + 0 + OTX + + + CAZ073 + 50730 + Mono + CA + US + 38.08 + -118.74 + 0 + 0 + REV + + + CAZ095 + 50950 + Kern_County_Mountains + CA + US + 35.30 + -118.71 + 0 + 0 + HNX + + + CAZ046 + 50460 + Santa_Monica_Mtns_Recnl_Area + CA + US + 34.09 + -118.58 + 0 + 0 + LOX + + + CAZ088 + 50880 + Santa_Clarita_Valley + CA + US + 34.46 + -118.55 + 0 + 0 + LOX + + + NVZ001 + 280010 + Mineral_and_Srn_Lyon_Counties + NV + US + 38.56 + -118.55 + 0 + 0 + REV + + + NVZ004 + 280040 + Wrn_NV_Bsn_and_Rng_including_Pyr + NV + US + 40.01 + -118.53 + 0 + 0 + REV + + + CAZ547 + 55470 + Los_Angeles_Cnty_Sn_Fernando_Vly + CA + US + 34.21 + -118.51 + 0 + 0 + LOX + + + CAZ097 + 50970 + Tulare_County_Mountains + CA + US + 36.27 + -118.48 + 0 + 0 + HNX + + + CAZ087 + 50870 + Catalina_Island + CA + US + 33.39 + -118.45 + 0 + 0 + LOX + + + CAZ054 + 50540 + Los_Angeles_Cnty_Mtns_excluding_ + CA + US + 34.48 + -118.26 + 0 + 0 + LOX + + + CAZ519 + 55190 + Ern_Sierra_Slopes_of_Inyo_Cnty + CA + US + 36.63 + -118.26 + 0 + 0 + VEF + + + CAZ041 + 50410 + Los_Angeles_Cnty_Cst_including_D + CA + US + 33.92 + -118.24 + 0 + 0 + LOX + + + CAZ059 + 50590 + Antelope_Valley + CA + US + 34.62 + -118.22 + 0 + 0 + LOX + + + ORZ502 + 375020 + Northern_Blue_Mtns_of_Oregon + OR + US + 45.65 + -118.19 + 0 + 0 + PDT + + + NVZ030 + 280300 + Humboldt_County + NV + US + 41.26 + -118.16 + 0 + 0 + LKN + + + WAZ029 + 470290 + Foothills_of_the_Blue_Mountains + WA + US + 46.31 + -118.16 + 0 + 0 + PDT + + + CAZ520 + 55200 + Owens_Valley + CA + US + 36.63 + -118.08 + 0 + 0 + VEF + + + CAZ521 + 55210 + White_Mountains_of_Inyo_County + CA + US + 36.92 + -118.00 + 0 + 0 + VEF + + + CAZ548 + 55480 + Los_Angeles_Cnty_Sn_Gabriel_Vly + CA + US + 34.05 + -117.96 + 0 + 0 + LOX + + + CAZ099 + 50990 + Southeastern_Kern_County_Desert + CA + US + 35.15 + -117.93 + 0 + 0 + HNX + + + WAZ030 + 470300 + Northwest_Blue_Mountains + WA + US + 46.17 + -117.87 + 0 + 0 + PDT + + + CAZ098 + 50980 + Indian_Wells_Valley + CA + US + 35.62 + -117.82 + 0 + 0 + HNX + + + CAZ042 + 50420 + Orange_County_Coastal_Areas + CA + US + 33.67 + -117.79 + 0 + 0 + SGX + + + WAZ037 + 470370 + Northeast_Mountains + WA + US + 48.36 + -117.71 + 0 + 0 + OTX + + + WAZ036 + 470360 + Spokane_Area + WA + US + 47.60 + -117.70 + 0 + 0 + OTX + + + ORZ049 + 370490 + Grande_Ronde_Valley + OR + US + 45.39 + -117.69 + 0 + 0 + PDT + + + ORZ062 + 370620 + Baker_County + OR + US + 44.66 + -117.65 + 0 + 0 + BOI + + + WAZ033 + 470330 + Washington_Palouse + WA + US + 46.89 + -117.64 + 0 + 0 + OTX + + + ORZ063 + 370630 + Malheur_County + OR + US + 43.21 + -117.62 + 0 + 0 + BOI + + + CAZ057 + 50570 + Santa_Ana_Mtns_and_Foothills + CA + US + 33.63 + -117.45 + 0 + 0 + SGX + + + WAZ031 + 470310 + Northeast_Blue_Mountains + WA + US + 46.21 + -117.37 + 0 + 0 + OTX + + + CAZ043 + 50430 + San_Diego_County_Coastal_Areas + CA + US + 33.00 + -117.28 + 0 + 0 + SGX + + + CAZ048 + 50480 + Sn_Bernardino_and_Rivside_Cnty_V + CA + US + 33.85 + -117.28 + 0 + 0 + SGX + + + ORZ050 + 370500 + Wallowa_County + OR + US + 45.54 + -117.17 + 0 + 0 + PDT + + + WAZ032 + 470320 + Lwr_Garfield_and_Asotin_Cnties + WA + US + 46.35 + -117.16 + 0 + 0 + OTX + + + NVZ014 + 280140 + Esmeralda_and_Ctrl_Nye_County + NV + US + 37.65 + -117.15 + 0 + 0 + VEF + + + CAZ055 + 50550 + San_Bernardino_County_Mountains + CA + US + 34.23 + -117.13 + 0 + 0 + SGX + + + ORZ064 + 370640 + Oregon_Lower_Treasure_Valley + OR + US + 44.02 + -117.11 + 0 + 0 + BOI + + + CAZ050 + 50500 + San_Diego_County_Valleys + CA + US + 33.03 + -117.06 + 0 + 0 + SGX + + + CAZ060 + 50600 + Apple_and_Lucerne_Valleys + CA + US + 34.43 + -117.03 + 0 + 0 + SGX + + + CAZ523 + 55230 + Western_Mojave_Desert + CA + US + 35.27 + -116.98 + 0 + 0 + VEF + + + IDZ003 + 120030 + Idaho_Palouse + ID + US + 46.96 + -116.96 + 0 + 0 + OTX + + + CAZ522 + 55220 + Death_Valley_National_Park + CA + US + 36.63 + -116.85 + 0 + 0 + VEF + + + IDZ002 + 120020 + Coeur_d'Alene_Area + ID + US + 47.62 + -116.83 + 0 + 0 + OTX + + + NVZ037 + 280370 + Srn_Lander_Cnty_and_Srn_Eureka_C + NV + US + 39.62 + -116.78 + 0 + 0 + LKN + + + NVZ036 + 280360 + Nrn_Lander_Cnty_and_Nrn_Eureka_C + NV + US + 40.51 + -116.76 + 0 + 0 + LKN + + + IDZ012 + 120120 + Lower_Treasure_Valley + ID + US + 43.82 + -116.75 + 0 + 0 + BOI + + + IDZ026 + 120260 + Lewiston_Area + ID + US + 46.47 + -116.71 + 0 + 0 + OTX + + + IDZ029 + 120290 + Owyhee_Mountains + ID + US + 43.07 + -116.70 + 0 + 0 + BOI + + + CAZ056 + 50560 + Riverside_County_Mountains + CA + US + 33.73 + -116.60 + 0 + 0 + SGX + + + NVZ013 + 280130 + Northern_Nye_County + NV + US + 38.60 + -116.59 + 0 + 0 + LKN + + + CAZ058 + 50580 + San_Diego_County_Mountains + CA + US + 33.00 + -116.57 + 0 + 0 + SGX + + + IDZ001 + 120010 + Northern_Panhandle + ID + US + 48.36 + -116.55 + 0 + 0 + OTX + + + IDZ027 + 120270 + Lewis_and_Srn_Nez_Perce_Cnties + ID + US + 46.16 + -116.51 + 0 + 0 + OTX + + + IDZ008 + 120080 + Lwr_Hells_Canyon/Salmon_Riv_Rgn + ID + US + 45.65 + -116.49 + 0 + 0 + MSO + + + CAZ061 + 50610 + Coachella_Valley + CA + US + 33.73 + -116.36 + 0 + 0 + SGX + + + CAZ062 + 50620 + San_Diego_County_Deserts + CA + US + 33.02 + -116.31 + 0 + 0 + SGX + + + CAZ525 + 55250 + Morongo_Basin + CA + US + 34.39 + -116.15 + 0 + 0 + VEF + + + NVZ017 + 280170 + Wrn_Clark_and_Srn_Nye_County + NV + US + 36.28 + -116.11 + 0 + 0 + VEF + + + IDZ015 + 120150 + Southwest_Highlands + ID + US + 42.51 + -116.02 + 0 + 0 + BOI + + + IDZ011 + 120110 + West_Central_Mountains + ID + US + 44.70 + -115.94 + 0 + 0 + BOI + + + IDZ004 + 120040 + Central_Panhandle_Mountains + ID + US + 47.34 + -115.93 + 0 + 0 + OTX + + + CAZ030 + 50300 + Joshua_Tree_National_Park + CA + US + 33.93 + -115.89 + 0 + 0 + PSR + + + IDZ007 + 120070 + Orofino/Grangeville_Region + ID + US + 46.24 + -115.85 + 0 + 0 + MSO + + + IDZ014 + 120140 + Upper_Treasure_Valley + ID + US + 43.16 + -115.77 + 0 + 0 + BOI + + + CAZ524 + 55240 + Ern_Mojave_Dsrt,_Incl_the_Mojave + CA + US + 35.17 + -115.61 + 0 + 0 + VEF + + + NVZ019 + 280190 + Spring_Mtns-Red_Rock_Canyon + NV + US + 36.13 + -115.57 + 0 + 0 + VEF + + + NVZ031 + 280310 + Northern_Elko_County + NV + US + 41.49 + -115.52 + 0 + 0 + LKN + + + IDZ005 + 120050 + Northern_Clearwater_Mountains + ID + US + 46.65 + -115.47 + 0 + 0 + MSO + + + CAZ033 + 50330 + Imperial_County + CA + US + 33.02 + -115.41 + 0 + 0 + PSR + + + IDZ013 + 120130 + Boise_Mountains + ID + US + 43.79 + -115.39 + 0 + 0 + BOI + + + CAZ032 + 50320 + Riverside_County/Ern_Deserts + CA + US + 33.75 + -115.33 + 0 + 0 + PSR + + + IDZ006 + 120060 + Southern_Clearwater_Mountains + ID + US + 45.88 + -115.33 + 0 + 0 + MSO + + + NVZ034 + 280340 + Ruby_Mtns/East_Humboldt_Range + NV + US + 40.56 + -115.33 + 0 + 0 + LKN + + + MTZ001 + 260010 + Kootenai/Cabinet_Region + MT + US + 48.18 + -115.15 + 0 + 0 + MSO + + + NVZ018 + 280180 + Sheep_Range + NV + US + 36.84 + -115.15 + 0 + 0 + VEF + + + NVZ020 + 280200 + Las_Vegas_Valley + NV + US + 36.11 + -115.12 + 0 + 0 + VEF + + + NVZ022 + 280220 + Southern_Clark_County + NV + US + 35.50 + -115.09 + 0 + 0 + VEF + + + CAZ526 + 55260 + Cadiz_Basin + CA + US + 34.45 + -115.08 + 0 + 0 + VEF + + + MTZ004 + 260040 + Lower_Clark_Fork_Region + MT + US + 47.38 + -115.02 + 0 + 0 + MSO + + + NVZ035 + 280350 + White_Pine_County + NV + US + 39.40 + -114.97 + 0 + 0 + LKN + + + NVZ015 + 280150 + Lincoln_County + NV + US + 37.76 + -114.96 + 0 + 0 + VEF + + + IDZ028 + 120280 + Camas_Prairie + ID + US + 43.34 + -114.86 + 0 + 0 + BOI + + + NVZ032 + 280320 + SW_and_South_Ctrl_Elko_County + NV + US + 40.64 + -114.83 + 0 + 0 + LKN + + + CAZ031 + 50310 + Lower_Colorado_River_Valley_CA + CA + US + 33.39 + -114.79 + 0 + 0 + PSR + + + NVZ021 + 280210 + L_Mead_National_Recreation_Area + NV + US + 35.79 + -114.78 + 0 + 0 + VEF + + + IDZ030 + 120300 + Southern_Twin__Falls_County + ID + US + 42.26 + -114.65 + 0 + 0 + BOI + + + AZZ036 + 30360 + L_Mead_National_Recreation_Area + AZ + US + 35.67 + -114.61 + 0 + 0 + VEF + + + AZZ025 + 30250 + Yuma/Martinez_Lake_and_Vicinity + AZ + US + 32.69 + -114.58 + 0 + 0 + PSR + + + NVZ016 + 280160 + Northeast_Clark_County + NV + US + 36.55 + -114.53 + 0 + 0 + VEF + + + IDZ016 + 120160 + Western_Magic_Valley + ID + US + 42.80 + -114.50 + 0 + 0 + BOI + + + IDZ018 + 120180 + Sawtooth_Mountains + ID + US + 44.18 + -114.49 + 0 + 0 + PIH + + + CAZ527 + 55270 + Sn_Bernardino_Cnty-Upr_CO_Riv_Vl + CA + US + 34.58 + -114.44 + 0 + 0 + VEF + + + AZZ020 + 30200 + Lower_Colorado_River_Valley_AZ + AZ + US + 33.65 + -114.43 + 0 + 0 + PSR + + + IDZ009 + 120090 + Western_Lemhi_County + ID + US + 45.10 + -114.39 + 0 + 0 + MSO + + + AZZ002 + 30020 + Lake_Havasu_and_Fort_Mohave + AZ + US + 34.63 + -114.37 + 0 + 0 + VEF + + + MTZ003 + 260030 + Flathead/Mission_Valleys + MT + US + 47.82 + -114.31 + 0 + 0 + MSO + + + IDZ031 + 120310 + Big_and_Little_Wood_River_Rgn + ID + US + 43.59 + -114.29 + 0 + 0 + PIH + + + NVZ033 + 280330 + Extreme_Eastern_Elko_County + NV + US + 40.64 + -114.23 + 0 + 0 + LKN + + + MTZ005 + 260050 + Missoula/Bitterroot_Valleys + MT + US + 46.44 + -114.10 + 0 + 0 + MSO + + + MTZ006 + 260060 + Bitterroot/Sapphire_Mountains + MT + US + 46.16 + -113.95 + 0 + 0 + MSO + + + MTZ002 + 260020 + West_Glacier_Region + MT + US + 48.30 + -113.94 + 0 + 0 + MSO + + + AZZ003 + 30030 + Northwest_Deserts + AZ + US + 35.14 + -113.92 + 0 + 0 + VEF + + + AZZ021 + 30210 + West_Central_Deserts + AZ + US + 33.86 + -113.90 + 0 + 0 + PSR + + + AZZ026 + 30260 + Southwest_Deserts + AZ + US + 32.75 + -113.90 + 0 + 0 + PSR + + + IDZ017 + 120170 + Eastern_Magic_Valley + ID + US + 42.94 + -113.79 + 0 + 0 + PIH + + + MTZ043 + 260430 + Potomac/Seeley_Lake_Region + MT + US + 47.12 + -113.60 + 0 + 0 + MSO + + + IDZ032 + 120320 + Lost_River/Pashimeroi + ID + US + 44.17 + -113.54 + 0 + 0 + PIH + + + IDZ010 + 120100 + Eastern_Lemhi_County + ID + US + 44.96 + -113.48 + 0 + 0 + MSO + + + UTZ019 + 440190 + Utah's_Dixie_and_Zion_Natl_Pk + UT + US + 37.20 + -113.47 + 0 + 0 + SLC + + + UTZ016 + 440160 + Southwest_Utah + UT + US + 37.98 + -113.33 + 0 + 0 + SLC + + + AZZ001 + 30010 + Northwest_Plateau + AZ + US + 36.49 + -113.28 + 0 + 0 + VEF + + + IDZ022 + 120220 + South_Central_Highlands + ID + US + 42.39 + -113.17 + 0 + 0 + PIH + + + MTZ009 + 260090 + Northern_Rocky_Mountain_Front + MT + US + 48.56 + -113.12 + 0 + 0 + TFX + + + AZZ037 + 30370 + Yavapai_County_Vlys_and_Basins + AZ + US + 34.56 + -113.07 + 0 + 0 + FGZ + + + UTZ005 + 440050 + Great_Salt_Lake_Desert_and_Mtns + UT + US + 40.95 + -113.00 + 0 + 0 + SLC + + + UTZ015 + 440150 + West_Central_Utah + UT + US + 39.29 + -112.99 + 0 + 0 + SLC + + + AZZ008 + 30080 + Yavapai_County__Mountains + AZ + US + 34.82 + -112.97 + 0 + 0 + FGZ + + + AZZ031 + 30310 + Western_Pima_County + AZ + US + 32.14 + -112.87 + 0 + 0 + TWC + + + MTZ007 + 260070 + Butte/Blackfoot_Region + MT + US + 46.40 + -112.84 + 0 + 0 + MSO + + + AZZ027 + 30270 + Southwest_Maricopa_County + AZ + US + 32.94 + -112.77 + 0 + 0 + PSR + + + AZZ022 + 30220 + Northwest_Maricopa_County + AZ + US + 33.67 + -112.70 + 0 + 0 + PSR + + + MTZ008 + 260080 + Beaverhead + MT + US + 45.15 + -112.69 + 0 + 0 + TFX + + + MTZ010 + 260100 + Eastern_Glacier + MT + US + 48.65 + -112.67 + 0 + 0 + TFX + + + IDZ020 + 120200 + Upper_Snake_River_Plain + ID + US + 43.66 + -112.62 + 0 + 0 + PIH + + + MTZ048 + 260480 + Southern_Rocky_Mountain_Front + MT + US + 47.73 + -112.60 + 0 + 0 + TFX + + + IDZ021 + 120210 + Lower_Snake_River_Plain + ID + US + 42.94 + -112.55 + 0 + 0 + PIH + + + AZZ007 + 30070 + Coconino_Plateau + AZ + US + 35.71 + -112.43 + 0 + 0 + FGZ + + + UTZ003 + 440030 + Salt_Lake_and_Tooele_Valleys + UT + US + 40.45 + -112.42 + 0 + 0 + SLC + + + UTZ518 + 445180 + Southern_Utah_Mountains + UT + US + 37.79 + -112.33 + 0 + 0 + SLC + + + AZZ006 + 30060 + Grand_Canyon_Country + AZ + US + 36.22 + -112.32 + 0 + 0 + FGZ + + + MTZ014 + 260140 + Central_and_Srn_Lewis_and_Clark + MT + US + 46.87 + -112.28 + 0 + 0 + TFX + + + UTZ002 + 440020 + Northern_Wasatch_Front + UT + US + 41.39 + -112.16 + 0 + 0 + SLC + + + AZZ004 + 30040 + Kaibab_Plateau + AZ + US + 36.56 + -112.14 + 0 + 0 + FGZ + + + MTZ052 + 260520 + Jefferson + MT + US + 46.15 + -112.13 + 0 + 0 + TFX + + + AZZ023 + 30230 + Greater_Phoenix_Area + AZ + US + 33.57 + -112.09 + 0 + 0 + PSR + + + UTZ020 + 440200 + South_Central_Utah + UT + US + 37.50 + -112.04 + 0 + 0 + SLC + + + MTZ015 + 260150 + Madison + MT + US + 45.28 + -112.02 + 0 + 0 + TFX + + + IDZ019 + 120190 + Upper_Snake_Highlands + ID + US + 44.13 + -112.01 + 0 + 0 + PIH + + + MTZ046 + 260460 + Eastern_Pondera + MT + US + 48.23 + -112.00 + 0 + 0 + TFX + + + IDZ024 + 120240 + Cache_Valley/Idaho_Portion + ID + US + 42.14 + -111.94 + 0 + 0 + PIH + + + UTZ001 + 440010 + Cache_Valley/Utah_Portion + UT + US + 41.73 + -111.93 + 0 + 0 + SLC + + + AZZ038 + 30380 + Oak_Creek_and_Sycamore_Canyons + AZ + US + 34.93 + -111.89 + 0 + 0 + FGZ + + + AZZ005 + 30050 + Marble_and_Glen_Canyons + AZ + US + 36.63 + -111.87 + 0 + 0 + FGZ + + + UTZ004 + 440040 + Southern_Wasatch_Front + UT + US + 40.01 + -111.87 + 0 + 0 + SLC + + + UTZ014 + 440140 + Sanpete/Sevier_Valleys + UT + US + 39.17 + -111.84 + 0 + 0 + SLC + + + AZZ032 + 30320 + Tohono_Oodham_Nation + AZ + US + 31.98 + -111.83 + 0 + 0 + TWC + + + AZZ015 + 30150 + Western_Mogollon_Rim + AZ + US + 35.20 + -111.80 + 0 + 0 + FGZ + + + MTZ049 + 260490 + Eastern_Teton + MT + US + 47.80 + -111.80 + 0 + 0 + TFX + + + IDZ023 + 120230 + Caribou_Highlands + ID + US + 42.94 + -111.78 + 0 + 0 + PIH + + + MTZ044 + 260440 + Toole + MT + US + 48.60 + -111.74 + 0 + 0 + TFX + + + AZZ028 + 30280 + NW_and_North_Ctrl_Pinal_County + AZ + US + 33.08 + -111.67 + 0 + 0 + PSR + + + UTZ007 + 440070 + Wasatch_Mountains_I-80_North + UT + US + 41.36 + -111.61 + 0 + 0 + SLC + + + IDZ025 + 120250 + Wasatch_Mountains/Idaho_Portion + ID + US + 42.30 + -111.47 + 0 + 0 + PIH + + + UTZ008 + 440080 + Wasatch_Mountains_South_of_I-80 + UT + US + 40.17 + -111.45 + 0 + 0 + SLC + + + UTZ517 + 445170 + Central_Utah_Mountains + UT + US + 39.02 + -111.44 + 0 + 0 + SLC + + + MTZ053 + 260530 + Broadwater + MT + US + 46.31 + -111.42 + 0 + 0 + TFX + + + UTZ006 + 440060 + Wasatch_Mountain_Valleys + UT + US + 40.86 + -111.39 + 0 + 0 + SLC + + + MTZ012 + 260120 + Cascade + MT + US + 47.26 + -111.34 + 0 + 0 + TFX + + + AZZ029 + 30290 + Southeast_Pinal_County + AZ + US + 32.88 + -111.33 + 0 + 0 + TWC + + + MTZ055 + 260550 + Gallatin + MT + US + 45.34 + -111.29 + 0 + 0 + TFX + + + AZZ012 + 30120 + Ltl_CO_Riv_Vly_in_Coconino_Cnty + AZ + US + 35.44 + -111.25 + 0 + 0 + FGZ + + + MTZ045 + 260450 + Liberty + MT + US + 48.56 + -111.08 + 0 + 0 + TFX + + + AZZ024 + 30240 + Srn_Gila/Tonto_NF_Foothills + AZ + US + 33.51 + -111.03 + 0 + 0 + PSR + + + MTZ054 + 260540 + Meagher + MT + US + 46.63 + -110.97 + 0 + 0 + TFX + + + WYZ023 + 500230 + Star_Valley + WY + US + 42.89 + -110.96 + 0 + 0 + RIW + + + AZZ009 + 30090 + NE_Plateaus_and_Mesas_Hwy_264_Nw + AZ + US + 36.39 + -110.92 + 0 + 0 + FGZ + + + AZZ033 + 30330 + Tucson_Metro/Marana/Grn_Valley + AZ + US + 32.13 + -110.92 + 0 + 0 + TWC + + + AZZ034 + 30340 + Santa_Cruz_County + AZ + US + 31.54 + -110.91 + 0 + 0 + TWC + + + AZZ018 + 30180 + Northern_Gila_County + AZ + US + 34.06 + -110.85 + 0 + 0 + FGZ + + + UTZ012 + 440120 + Castle_Country + UT + US + 39.29 + -110.85 + 0 + 0 + SLC + + + AZZ016 + 30160 + Eastern_Mogollon_Rim + AZ + US + 34.49 + -110.77 + 0 + 0 + FGZ + + + MTZ064 + 260640 + Paradise_Valley + MT + US + 45.33 + -110.73 + 0 + 0 + BYZ + + + UTZ010 + 440100 + Wasatch_Plateau/Book_Cliffs + UT + US + 39.76 + -110.73 + 0 + 0 + SLC + + + UTZ009 + 440090 + Western_Uinta_Mountains + UT + US + 40.70 + -110.70 + 0 + 0 + SLC + + + UTZ021 + 440210 + Glen_Canyon_Rec_Area/L_Powell + UT + US + 37.54 + -110.70 + 0 + 0 + SLC + + + WYZ024 + 500240 + Salt_River_and_Wyoming_Ranges + WY + US + 42.55 + -110.65 + 0 + 0 + RIW + + + UTZ013 + 440130 + San_Rafael_Swell + UT + US + 38.54 + -110.64 + 0 + 0 + SLC + + + WYZ013 + 500130 + Jackson_Hole + WY + US + 43.63 + -110.62 + 0 + 0 + RIW + + + MTZ040 + 260400 + Northern_Park + MT + US + 45.98 + -110.55 + 0 + 0 + BYZ + + + WYZ012 + 500120 + Teton_and_Gros_Ventre_Mountains + WY + US + 43.64 + -110.55 + 0 + 0 + RIW + + + WYZ021 + 500210 + Southwest_Wyoming + WY + US + 41.29 + -110.55 + 0 + 0 + SLC + + + WYZ027 + 500270 + South_Lincoln_County + WY + US + 41.93 + -110.55 + 0 + 0 + RIW + + + MTZ065 + 260650 + Livingston_Area + MT + US + 45.65 + -110.51 + 0 + 0 + BYZ + + + WYZ001 + 500010 + Yellowstone_National_Park + WY + US + 44.62 + -110.49 + 0 + 0 + RIW + + + MTZ013 + 260130 + Chouteau + MT + US + 47.86 + -110.48 + 0 + 0 + TFX + + + UTZ011 + 440110 + Western_Uinta_Basin + UT + US + 40.22 + -110.46 + 0 + 0 + SLC + + + MTZ068 + 260680 + Crazy_Mountains + MT + US + 46.10 + -110.32 + 0 + 0 + BYZ + + + AZZ040 + 30400 + NE_Plateaus_and_Mesas_S_of_Hwy_2 + AZ + US + 35.52 + -110.30 + 0 + 0 + FGZ + + + AZZ013 + 30130 + Ltl_CO_Riv_Vly_in_Navajo_Cnty + AZ + US + 34.88 + -110.29 + 0 + 0 + FGZ + + + MTZ050 + 260500 + Judith_Basin + MT + US + 47.05 + -110.27 + 0 + 0 + TFX + + + AZZ039 + 30390 + Black_Mesa_Area + AZ + US + 36.37 + -110.25 + 0 + 0 + FGZ + + + MTZ067 + 260670 + Absaroka/Beartooth_Mountains + MT + US + 45.33 + -110.13 + 0 + 0 + BYZ + + + MTZ011 + 260110 + Hill + MT + US + 48.57 + -110.11 + 0 + 0 + TFX + + + UTZ029 + 440290 + Canyonlands/Natural_Bridges + UT + US + 37.87 + -110.03 + 0 + 0 + GJT + + + WYZ025 + 500250 + Upper_Grn_River_Basin_Foothills + WY + US + 42.98 + -110.03 + 0 + 0 + RIW + + + MTZ041 + 260410 + Northern_Sweet_Grass + MT + US + 45.93 + -109.86 + 0 + 0 + BYZ + + + MTZ028 + 260280 + Southern_Wheatland + MT + US + 46.38 + -109.84 + 0 + 0 + BYZ + + + MTZ066 + 260660 + Beartooth_Foothills + MT + US + 45.54 + -109.81 + 0 + 0 + BYZ + + + AZZ010 + 30100 + Chinle_Valley + AZ + US + 36.36 + -109.76 + 0 + 0 + FGZ + + + AZZ030 + 30300 + Upper_Gila_River_Valley + AZ + US + 33.05 + -109.75 + 0 + 0 + TWC + + + AZZ035 + 30350 + Cochise_County + AZ + US + 31.89 + -109.75 + 0 + 0 + TWC + + + WYZ014 + 500140 + Wind_River_Mountains_West + WY + US + 43.00 + -109.70 + 0 + 0 + RIW + + + WYZ026 + 500260 + Upper_Green_River_Basin + WY + US + 42.42 + -109.68 + 0 + 0 + RIW + + + AZZ017 + 30170 + White_Mountains + AZ + US + 33.89 + -109.65 + 0 + 0 + FGZ + + + MTZ063 + 260630 + Judith_Gap + MT + US + 46.65 + -109.65 + 0 + 0 + BYZ + + + UTZ027 + 440270 + Arches/Grand_Flat + UT + US + 38.95 + -109.61 + 0 + 0 + GJT + + + WYZ028 + 500280 + Rock_Springs_and_Green_River + WY + US + 41.51 + -109.60 + 0 + 0 + RIW + + + UTZ025 + 440250 + Tavaputs_Plateau + UT + US + 39.50 + -109.58 + 0 + 0 + GJT + + + UTZ028 + 440280 + La_Sal_and_Abajo_Mountains + UT + US + 38.15 + -109.53 + 0 + 0 + GJT + + + UTZ023 + 440230 + Eastern_Uinta_Mountains + UT + US + 40.68 + -109.52 + 0 + 0 + GJT + + + UTZ024 + 440240 + Eastern_Uinta_Basin + UT + US + 40.21 + -109.51 + 0 + 0 + GJT + + + WYZ002 + 500020 + Absaroka_Mountains + WY + US + 44.24 + -109.49 + 0 + 0 + RIW + + + AZZ014 + 30140 + Ltl_CO_Riv_Vly_in_Apache_Cnty + AZ + US + 34.58 + -109.45 + 0 + 0 + FGZ + + + UTZ022 + 440220 + Southeast_Utah + UT + US + 37.40 + -109.45 + 0 + 0 + GJT + + + WYZ029 + 500290 + Flaming_Gorge + WY + US + 41.25 + -109.42 + 0 + 0 + RIW + + + WYZ016 + 500160 + Upper_Wind_River_Basin + WY + US + 43.44 + -109.41 + 0 + 0 + RIW + + + MTZ056 + 260560 + Red_Lodge_Foothills + MT + US + 45.23 + -109.32 + 0 + 0 + BYZ + + + AZZ011 + 30110 + Chuska_Mtns_and_Defiance_Plateay + AZ + US + 35.98 + -109.31 + 0 + 0 + FGZ + + + WYZ015 + 500150 + Wind_River_Mountains_East + WY + US + 43.09 + -109.31 + 0 + 0 + RIW + + + AZZ019 + 30190 + Northern_Greenlee + AZ + US + 33.42 + -109.27 + 0 + 0 + TWC + + + MTZ051 + 260510 + Fergus + MT + US + 47.25 + -109.26 + 0 + 0 + TFX + + + MTZ042 + 260420 + Golden_Valley + MT + US + 46.36 + -109.22 + 0 + 0 + BYZ + + + MTZ034 + 260340 + Northern_Stillwater + MT + US + 45.78 + -109.21 + 0 + 0 + BYZ + + + WYZ003 + 500030 + Cody_Foothills + WY + US + 44.46 + -109.04 + 0 + 0 + RIW + + + MTZ047 + 260470 + Blaine + MT + US + 48.37 + -108.90 + 0 + 0 + TFX + + + MTZ039 + 260390 + Eastern_Carbon + MT + US + 45.32 + -108.71 + 0 + 0 + BYZ + + + COZ006 + 60060 + Grand_Valley + CO + US + 39.16 + -108.65 + 0 + 0 + GJT + + + COZ021 + 60210 + Four_Corners/Upper_Dolores_Riv + CO + US + 37.49 + -108.64 + 0 + 0 + GJT + + + NMZ030 + 310300 + Southwest_Desert/Bootheel + NM + US + 31.93 + -108.63 + 0 + 0 + EPZ + + + COZ020 + 60200 + Paradox_Vly/Little_Dolores_Riv + CO + US + 38.28 + -108.61 + 0 + 0 + GJT + + + WYZ007 + 500070 + Owl_Creek_and_Bridger_Mountains + WY + US + 43.62 + -108.61 + 0 + 0 + RIW + + + WYZ018 + 500180 + Lander_Foothills + WY + US + 42.81 + -108.61 + 0 + 0 + RIW + + + MTZ060 + 260600 + Southwest_Phillips + MT + US + 47.83 + -108.55 + 0 + 0 + GGW + + + COZ001 + 60010 + Lower_Yampa_River_Basin + CO + US + 40.30 + -108.49 + 0 + 0 + GJT + + + COZ003 + 60030 + Roan_and_Tavaputs_Plateaus + CO + US + 39.63 + -108.44 + 0 + 0 + GJT + + + MTZ029 + 260290 + Musselshell + MT + US + 46.44 + -108.40 + 0 + 0 + BYZ + + + WYZ030 + 500300 + East_Sweetwater_County + WY + US + 41.61 + -108.37 + 0 + 0 + RIW + + + COZ017 + 60170 + Uncompahgre_Plateau/Dallas_Divid + CO + US + 38.58 + -108.35 + 0 + 0 + GJT + + + WYZ017 + 500170 + Wind_River_Basin + WY + US + 43.13 + -108.34 + 0 + 0 + RIW + + + MTZ021 + 260210 + Petroleum + MT + US + 47.18 + -108.28 + 0 + 0 + GGW + + + WYZ005 + 500050 + Southwest_Big_Horn_Basin + WY + US + 43.81 + -108.25 + 0 + 0 + RIW + + + NMZ001 + 310010 + Northwest_Plateau + NM + US + 36.35 + -108.23 + 0 + 0 + ABQ + + + MTZ035 + 260350 + Yellowstone + MT + US + 45.98 + -108.20 + 0 + 0 + BYZ + + + WYZ004 + 500040 + North_Big_Horn_Basin + WY + US + 44.57 + -108.19 + 0 + 0 + RIW + + + NMZ022 + 310220 + SW_Mtns/Lower_Gila_Region + NM + US + 33.00 + -108.17 + 0 + 0 + EPZ + + + NMZ014 + 310140 + SW_Mtns/Upper_Gila_Region + NM + US + 33.77 + -108.13 + 0 + 0 + ABQ + + + NMZ008 + 310080 + West_Central_Mountains + NM + US + 35.06 + -108.09 + 0 + 0 + ABQ + + + COZ007 + 60070 + Debeque_to_Silt_Corridor + CO + US + 39.43 + -108.05 + 0 + 0 + GJT + + + WYZ019 + 500190 + Grn_Mtns_and_Rattlesnake_Range + WY + US + 42.40 + -107.96 + 0 + 0 + RIW + + + COZ011 + 60110 + Ctrl_Gunnison_and_Uncompahgre_Ri + CO + US + 38.64 + -107.94 + 0 + 0 + GJT + + + COZ022 + 60220 + Animas_River_Basin + CO + US + 37.25 + -107.92 + 0 + 0 + GJT + + + WYZ006 + 500060 + Southeast_Big_Horn_Basin + WY + US + 43.87 + -107.90 + 0 + 0 + RIW + + + COZ002 + 60020 + Central_Yampa_River_Basin + CO + US + 40.34 + -107.85 + 0 + 0 + GJT + + + COZ009 + 60090 + Grand_and_Battlement_Mesas + CO + US + 39.17 + -107.85 + 0 + 0 + GJT + + + MTZ016 + 260160 + Central_and_Southeast_Phillips + MT + US + 48.02 + -107.82 + 0 + 0 + GGW + + + MTZ059 + 260590 + Northern_Phillips + MT + US + 48.79 + -107.75 + 0 + 0 + GGW + + + NMZ031 + 310310 + Southwest_Desert/Mimbres_Basin + NM + US + 32.20 + -107.75 + 0 + 0 + EPZ + + + COZ018 + 60180 + Northwestern_San_Juan_Mountains + CO + US + 38.08 + -107.64 + 0 + 0 + GJT + + + COZ019 + 60190 + Southwest_San_Juan_Mountains + CO + US + 37.48 + -107.64 + 0 + 0 + GJT + + + COZ013 + 60130 + Flattops + CO + US + 39.98 + -107.53 + 0 + 0 + GJT + + + MTZ038 + 260380 + Southern_Big_Horn + MT + US + 45.26 + -107.48 + 0 + 0 + BYZ + + + WYZ098 + 500980 + Northeast_Big_Horn_Mountains + WY + US + 44.78 + -107.43 + 0 + 0 + BYZ + + + MTZ057 + 260570 + Northern_Big_Horn + MT + US + 45.78 + -107.40 + 0 + 0 + BYZ + + + MTZ030 + 260300 + Treasure + MT + US + 46.18 + -107.34 + 0 + 0 + BYZ + + + COZ023 + 60230 + San_Juan_River_Basin + CO + US + 37.20 + -107.30 + 0 + 0 + GJT + + + WYZ008 + 500080 + Bighorn_Mountains_West + WY + US + 44.21 + -107.28 + 0 + 0 + RIW + + + WYZ061 + 500610 + Southwest_Carbon + WY + US + 41.53 + -107.28 + 0 + 0 + CYS + + + COZ014 + 60140 + Upper_Gunnison_River_Valley + CO + US + 38.51 + -107.17 + 0 + 0 + GJT + + + NMZ002 + 310020 + Northwest_Mtns_including_Jemez + NM + US + 36.16 + -107.10 + 0 + 0 + ABQ + + + WYZ009 + 500090 + Bighorn_Mountains_Southeast + WY + US + 43.88 + -107.07 + 0 + 0 + RIW + + + MTZ022 + 260220 + Garfield + MT + US + 47.41 + -107.03 + 0 + 0 + GGW + + + COZ008 + 60080 + Central_Colorado_River_Basin + CO + US + 39.60 + -106.99 + 0 + 0 + GJT + + + MTZ031 + 260310 + Northern_Rosebud + MT + US + 46.27 + -106.99 + 0 + 0 + BYZ + + + NMZ023 + 310230 + Sierra_County_Lakes_Region + NM + US + 33.04 + -106.97 + 0 + 0 + EPZ + + + COZ005 + 60050 + Upper_Yampa_River_Basin + CO + US + 40.41 + -106.96 + 0 + 0 + GJT + + + COZ012 + 60120 + West_Elk_and_Sawatch_Mountains + CO + US + 38.84 + -106.93 + 0 + 0 + GJT + + + COZ010 + 60100 + Gore_and_Elk_Mtns/Ctrl_Mtn_Vlys + CO + US + 39.45 + -106.92 + 0 + 0 + GJT + + + NMZ032 + 310320 + Southern_Desert + NM + US + 32.37 + -106.87 + 0 + 0 + EPZ + + + NMZ015 + 310150 + Lower_Rio_Grande_Valley + NM + US + 34.03 + -106.86 + 0 + 0 + ABQ + + + NMZ009 + 310090 + Middle_Rio_Gnde_Vly/Albuquerque_ + NM + US + 34.90 + -106.85 + 0 + 0 + ABQ + + + WYZ062 + 500620 + North_Carbon + WY + US + 42.03 + -106.80 + 0 + 0 + CYS + + + WYZ020 + 500200 + Natrona_County_Lower_Elevations + WY + US + 42.97 + -106.79 + 0 + 0 + RIW + + + WYZ099 + 500990 + Sheridan_Foothills + WY + US + 44.78 + -106.77 + 0 + 0 + BYZ + + + COZ004 + 60040 + Elkhead_and_Park_Mountains + CO + US + 40.46 + -106.73 + 0 + 0 + GJT + + + COZ066 + 60660 + La_Garita_Mtns_Above_10000_Ft + CO + US + 38.05 + -106.72 + 0 + 0 + PUB + + + COZ064 + 60640 + Saguache_Cnty_W_of_Continental_D + CO + US + 38.24 + -106.64 + 0 + 0 + PUB + + + COZ031 + 60310 + W_Jackson_and_W_Gnd_Cnties_Above + CO + US + 40.48 + -106.62 + 0 + 0 + BOU + + + MTZ017 + 260170 + Central_and_Southern_Valley + MT + US + 48.12 + -106.62 + 0 + 0 + GGW + + + MTZ061 + 260610 + Northern_Valley + MT + US + 48.79 + -106.62 + 0 + 0 + GGW + + + COZ068 + 60680 + Ern_Sn_Juan_Mtns_Above_10000_Ft + CO + US + 37.40 + -106.61 + 0 + 0 + PUB + + + MTZ058 + 260580 + Southern_Rosebud + MT + US + 45.43 + -106.50 + 0 + 0 + BYZ + + + WYZ011 + 500110 + Southeast_Johnson_County + WY + US + 43.83 + -106.48 + 0 + 0 + RIW + + + WYZ010 + 500100 + Northeast_Johnson_County + WY + US + 44.36 + -106.46 + 0 + 0 + RIW + + + NMZ010 + 310100 + Sandia/Manzano_Mountains + NM + US + 34.76 + -106.40 + 0 + 0 + ABQ + + + COZ060 + 60600 + Ern_Sawatch_Mtns_Above_11000_Ft + CO + US + 38.81 + -106.39 + 0 + 0 + PUB + + + COZ059 + 60590 + Leadvl_Vic/L_Cnty_Below_11000_Ft + CO + US + 39.20 + -106.38 + 0 + 0 + PUB + + + WYZ063 + 500630 + Snowy_Range + WY + US + 41.39 + -106.37 + 0 + 0 + CYS + + + COZ065 + 60650 + Saguache_Cnty_E_of_Continental_D + CO + US + 38.07 + -106.36 + 0 + 0 + PUB + + + TXZ055 + 430550 + El_Paso + TX + US + 31.70 + -106.30 + 0 + 0 + EPZ + + + COZ030 + 60300 + Jackson_County_Below_9000_Feet + CO + US + 40.69 + -106.28 + 0 + 0 + BOU + + + WYZ022 + 500220 + Casper_Mountain + WY + US + 42.61 + -106.24 + 0 + 0 + RIW + + + COZ067 + 60670 + Upr_Rio_Gnde_Vly/Ern_Sn_Juan_Mtn + CO + US + 37.45 + -106.23 + 0 + 0 + PUB + + + COZ058 + 60580 + Wrn_Mosquito_Rng/E_L_Cnty_Above_ + CO + US + 39.21 + -106.21 + 0 + 0 + PUB + + + COZ061 + 60610 + Wrn_Chaffee_Cnty_Between_9000_an + CO + US + 38.74 + -106.20 + 0 + 0 + PUB + + + NMZ024 + 310240 + Tularosa_Basin/Southern_Desert + NM + US + 32.70 + -106.18 + 0 + 0 + EPZ + + + COZ032 + 60320 + Gnd_and_Summit_Cnties_Below_9000 + CO + US + 40.00 + -106.17 + 0 + 0 + BOU + + + COZ062 + 60620 + Ctrl_Chaffee_Cnty_Below_9000_Ft + CO + US + 38.74 + -106.12 + 0 + 0 + PUB + + + NMZ003 + 310030 + Upper_Rio_Grande_Valley + NM + US + 35.80 + -106.07 + 0 + 0 + ABQ + + + COZ069 + 60690 + Del_Norte_Vic/Nrn_Sn_Luis_Vly_Be + CO + US + 37.97 + -106.04 + 0 + 0 + PUB + + + COZ063 + 60630 + Wrn_Mosquito_Rng/E_Chaffee_Cnty_ + CO + US + 38.79 + -105.96 + 0 + 0 + PUB + + + COZ033 + 60330 + S_and_E_Jackson/Larimer/N_and_NE + CO + US + 40.55 + -105.94 + 0 + 0 + BOU + + + COZ034 + 60340 + S_and_SE_Gnd/W_Ctrl_and_SW_Bould + CO + US + 39.55 + -105.91 + 0 + 0 + BOU + + + COZ070 + 60700 + Alamosa_Vic/Ctrl_Sn_Luis_Vly_Bel + CO + US + 37.54 + -105.91 + 0 + 0 + PUB + + + NMZ011 + 310110 + Ctrl_Hi_Plains/Estancia_Valley + NM + US + 34.77 + -105.83 + 0 + 0 + ABQ + + + MTZ023 + 260230 + McCone + MT + US + 47.59 + -105.82 + 0 + 0 + GGW + + + WYZ065 + 500650 + Laramie_Valley + WY + US + 41.59 + -105.81 + 0 + 0 + CYS + + + COZ071 + 60710 + Southern_San_Luis_Valley + CO + US + 37.27 + -105.78 + 0 + 0 + PUB + + + WYZ064 + 500640 + North_Laramie_Range + WY + US + 42.32 + -105.68 + 0 + 0 + CYS + + + COZ037 + 60370 + Central_and_SE_Park_County + CO + US + 39.05 + -105.66 + 0 + 0 + BOU + + + COZ077 + 60770 + Wrn/Ctrl_Fremt_Cnty_Below_8500_F + CO + US + 38.46 + -105.63 + 0 + 0 + PUB + + + MTZ036 + 260360 + Powder_River + MT + US + 45.40 + -105.63 + 0 + 0 + BYZ + + + NMZ025 + 310250 + Southern_Sacramento_Mountains + NM + US + 32.91 + -105.63 + 0 + 0 + EPZ + + + COZ076 + 60760 + NWrn_Fremt_County_above_8500_Ft + CO + US + 38.55 + -105.61 + 0 + 0 + PUB + + + COZ073 + 60730 + Nrn_Sngre_De_Cristo_Mtns_Above_1 + CO + US + 38.00 + -105.59 + 0 + 0 + PUB + + + NMZ017 + 310170 + Capitan/Nrn_Sacramento_Mtns + NM + US + 33.71 + -105.58 + 0 + 0 + ABQ + + + MTZ018 + 260180 + Daniels + MT + US + 48.79 + -105.57 + 0 + 0 + GGW + + + NMZ004 + 310040 + Sangre_de_Cristo_Mountains + NM + US + 36.25 + -105.57 + 0 + 0 + ABQ + + + WYZ054 + 500540 + Northern_Campbell + WY + US + 44.60 + -105.55 + 0 + 0 + UNR + + + WYZ055 + 500550 + Southern_Campbell + WY + US + 43.84 + -105.55 + 0 + 0 + UNR + + + COZ072 + 60720 + Nrn_Sngre_De_Cristo_Mtns_Between + CO + US + 37.98 + -105.49 + 0 + 0 + PUB + + + WYZ059 + 500590 + Converse + WY + US + 43.02 + -105.49 + 0 + 0 + CYS + + + MTZ032 + 260320 + Custer + MT + US + 46.33 + -105.47 + 0 + 0 + BYZ + + + COZ078 + 60780 + Wet_Mtn_Valley_Below_8500_Feet + CO + US + 38.08 + -105.45 + 0 + 0 + PUB + + + TXZ056 + 430560 + Hudspeth + TX + US + 31.32 + -105.45 + 0 + 0 + EPZ + + + MTZ020 + 260200 + Western_Roosevelt + MT + US + 48.29 + -105.41 + 0 + 0 + GGW + + + COZ035 + 60350 + Larimer_and_Boulder_Cnties_Betwe + CO + US + 40.46 + -105.39 + 0 + 0 + BOU + + + MTZ026 + 260260 + Prairie + MT + US + 46.86 + -105.34 + 0 + 0 + GGW + + + COZ036 + 60360 + Jefferson_and_W_Douglas_Cnties_A + CO + US + 39.53 + -105.32 + 0 + 0 + BOU + + + WYZ066 + 500660 + Laramie_Range + WY + US + 41.45 + -105.31 + 0 + 0 + CYS + + + COZ081 + 60810 + Teller_Cnty/Rampart_Rng_above_75 + CO + US + 38.82 + -105.22 + 0 + 0 + PUB + + + COZ039 + 60390 + Boulder_And_Jefferson_Cnties_Bel + CO + US + 39.87 + -105.19 + 0 + 0 + BOU + + + COZ075 + 60750 + Srn_Sngre_De_Cristo_Mtns_Above_1 + CO + US + 37.20 + -105.17 + 0 + 0 + PUB + + + COZ079 + 60790 + Wet_Mtns_Between_6300_and_10000_ + CO + US + 38.08 + -105.14 + 0 + 0 + PUB + + + COZ080 + 60800 + Wet_Mountains_Above_10000_Ft + CO + US + 37.98 + -105.14 + 0 + 0 + PUB + + + COZ083 + 60830 + Canon_City_Vic/Ern_Fremt_County + CO + US + 38.44 + -105.14 + 0 + 0 + PUB + + + NMZ026 + 310260 + Guadalupe_Mtns_of_Chaves_County + NM + US + 32.83 + -105.08 + 0 + 0 + ABQ + + + NMZ016 + 310160 + Lincoln_Cnty_Hi_Plns/Hondo_Vly + NM + US + 33.74 + -105.07 + 0 + 0 + ABQ + + + COZ082 + 60820 + PIkes_Peak_above_11000_Ft + CO + US + 38.82 + -105.04 + 0 + 0 + PUB + + + WYZ067 + 500670 + Platte + WY + US + 42.13 + -104.97 + 0 + 0 + CYS + + + COZ087 + 60870 + Walsenbg_Vic/Upr_Huerfano_Riv_Bs + CO + US + 37.67 + -104.87 + 0 + 0 + PUB + + + MTZ025 + 260250 + Dawson + MT + US + 47.32 + -104.86 + 0 + 0 + GGW + + + COZ074 + 60740 + Srn_Sngre_De_Cristo_Mtns_Between + CO + US + 37.26 + -104.83 + 0 + 0 + PUB + + + COZ040 + 60400 + N_Douglas_Cnty_Below_6000_Feet/D + CO + US + 39.73 + -104.81 + 0 + 0 + BOU + + + COZ038 + 60380 + Larimer_Cnty_Below_6000_Feet/NW_ + CO + US + 40.63 + -104.80 + 0 + 0 + BOU + + + WYZ069 + 500690 + Cheyenne_Foothills + WY + US + 41.33 + -104.75 + 0 + 0 + CYS + + + WYZ056 + 500560 + Western_Crook + WY + US + 44.59 + -104.72 + 0 + 0 + UNR + + + TXZ258 + 432580 + Guadalupe_Mountains + TX + US + 31.90 + -104.71 + 0 + 0 + MAF + + + NMZ027 + 310270 + Guadalupe_Mtns_of_Eddy_County + NM + US + 32.30 + -104.67 + 0 + 0 + MAF + + + MTZ024 + 260240 + Richland + MT + US + 47.75 + -104.64 + 0 + 0 + GGW + + + TXZ079 + 430790 + Presidio_Valley + TX + US + 29.95 + -104.61 + 0 + 0 + MAF + + + COZ043 + 60430 + Central_and_South_Weld_County + CO + US + 40.29 + -104.59 + 0 + 0 + BOU + + + WYZ058 + 500580 + Weston + WY + US + 43.84 + -104.57 + 0 + 0 + UNR + + + MTZ019 + 260190 + Sheridan + MT + US + 48.70 + -104.55 + 0 + 0 + GGW + + + TXZ057 + 430570 + Van_Horn_and_Hiway_54_Corridor + TX + US + 31.24 + -104.55 + 0 + 0 + MAF + + + COZ086 + 60860 + Pueblo_and_Vic/Pueblo_Cnty_Below + CO + US + 38.12 + -104.54 + 0 + 0 + PUB + + + MTZ037 + 260370 + Carter + MT + US + 45.57 + -104.54 + 0 + 0 + BYZ + + + NMZ005 + 310050 + Northeast_Highlands + NM + US + 36.10 + -104.54 + 0 + 0 + ABQ + + + COZ085 + 60850 + CO_Spgs_Vic/Srn_El_Paso_Cnty/Ram + CO + US + 38.74 + -104.51 + 0 + 0 + PUB + + + MTZ062 + 260620 + Eastern_Roosevelt + MT + US + 48.28 + -104.51 + 0 + 0 + GGW + + + COZ088 + 60880 + Trinidad_Vic/Wrn_Las_Animas_Cnty + CO + US + 37.40 + -104.50 + 0 + 0 + PUB + + + COZ084 + 60840 + Nrn_El_Paso_Cnty/Monument_Ridge/ + CO + US + 38.99 + -104.49 + 0 + 0 + PUB + + + WYZ060 + 500600 + Niobrara + WY + US + 43.06 + -104.49 + 0 + 0 + CYS + + + MTZ033 + 260330 + Fallon + MT + US + 46.29 + -104.48 + 0 + 0 + BYZ + + + NMZ012 + 310120 + Conchas_Lake/Guadalupe_County + NM + US + 35.08 + -104.46 + 0 + 0 + ABQ + + + COZ041 + 60410 + Elbert/Ctrl_and_E_Douglas_Cnties + CO + US + 39.28 + -104.43 + 0 + 0 + BOU + + + NMZ018 + 310180 + De_Baca_County + NM + US + 34.39 + -104.41 + 0 + 0 + ABQ + + + TXZ080 + 430800 + Marfa_Plateau + TX + US + 30.16 + -104.39 + 0 + 0 + MAF + + + WYZ057 + 500570 + Wyoming_Black_Hills + WY + US + 44.38 + -104.37 + 0 + 0 + UNR + + + WYZ068 + 500680 + Goshen + WY + US + 42.09 + -104.35 + 0 + 0 + CYS + + + MTZ027 + 260270 + Wibaux + MT + US + 47.02 + -104.33 + 0 + 0 + GGW + + + WYZ070 + 500700 + Pine_Bluffs + WY + US + 41.28 + -104.28 + 0 + 0 + CYS + + + NMZ028 + 310280 + Eddy_County_Plains + NM + US + 32.49 + -104.27 + 0 + 0 + MAF + + + WYZ071 + 500710 + Northeastern_Crook + WY + US + 44.79 + -104.21 + 0 + 0 + UNR + + + NMZ019 + 310190 + Chaves_County_Plains + NM + US + 33.53 + -104.19 + 0 + 0 + ABQ + + + COZ042 + 60420 + Northeast_Weld_County + CO + US + 40.75 + -104.10 + 0 + 0 + BOU + + + COZ045 + 60450 + Ctrl_and_E_Adams_and_Arapahoe_Cn + CO + US + 39.78 + -104.10 + 0 + 0 + BOU + + + NMZ006 + 310060 + Harding_County + NM + US + 35.81 + -103.89 + 0 + 0 + ABQ + + + NDZ031 + 340310 + Golden_Valley + ND + US + 46.94 + -103.83 + 0 + 0 + BIS + + + COZ046 + 60460 + N_and_NE_Elbert_Cnty_Below_6000_ + CO + US + 39.33 + -103.81 + 0 + 0 + BOU + + + COZ044 + 60440 + Morgan_County + CO + US + 40.25 + -103.80 + 0 + 0 + BOU + + + TXZ074 + 430740 + Davis/Apache_Mountains_Area + TX + US + 30.71 + -103.80 + 0 + 0 + MAF + + + TXZ058 + 430580 + Reeves_Cnty_and_Upr_Trans_Pecos + TX + US + 31.39 + -103.78 + 0 + 0 + MAF + + + COZ089 + 60890 + Crowley_County + CO + US + 38.31 + -103.77 + 0 + 0 + PUB + + + NEZ001 + 270010 + Sioux + NE + US + 42.50 + -103.73 + 0 + 0 + CYS + + + COZ093 + 60930 + La_Junta_Vicinity/Otero_County + CO + US + 37.95 + -103.72 + 0 + 0 + PUB + + + SDZ024 + 410240 + Northern_Black_Hills + SD + US + 44.31 + -103.72 + 0 + 0 + UNR + + + NEZ019 + 270190 + Scotts_Bluff + NE + US + 41.85 + -103.71 + 0 + 0 + CYS + + + NEZ020 + 270200 + Banner + NE + US + 41.54 + -103.71 + 0 + 0 + CYS + + + NEZ054 + 270540 + Kimball + NE + US + 41.20 + -103.71 + 0 + 0 + CYS + + + SDZ028 + 410280 + Central_Black_Hills + SD + US + 44.00 + -103.69 + 0 + 0 + UNR + + + SDZ029 + 410290 + Southern_Black_Hills + SD + US + 43.67 + -103.69 + 0 + 0 + UNR + + + NMZ007 + 310070 + Far_Northeast_Plains + NM + US + 36.37 + -103.67 + 0 + 0 + ABQ + + + TXZ059 + 430590 + Loving + TX + US + 31.83 + -103.66 + 0 + 0 + MAF + + + SDZ025 + 410250 + Northern_Foot_Hills + SD + US + 44.44 + -103.64 + 0 + 0 + UNR + + + SDZ027 + 410270 + Southern_Foot_Hills + SD + US + 43.36 + -103.64 + 0 + 0 + UNR + + + COZ047 + 60470 + SE_Elbert_Cnty_Below_6000_Feet/S + CO + US + 38.80 + -103.60 + 0 + 0 + BOU + + + NMZ013 + 310130 + Quay_County + NM + US + 35.17 + -103.57 + 0 + 0 + ABQ + + + COZ094 + 60940 + Eastern_Las_Animas_County + CO + US + 37.32 + -103.56 + 0 + 0 + PUB + + + SDZ041 + 410410 + Fall_River + SD + US + 43.24 + -103.53 + 0 + 0 + UNR + + + NDZ043 + 340430 + Bowman + ND + US + 46.11 + -103.52 + 0 + 0 + BIS + + + SDZ012 + 410120 + Butte + SD + US + 44.89 + -103.51 + 0 + 0 + UNR + + + SDZ001 + 410010 + Harding + SD + US + 45.58 + -103.50 + 0 + 0 + UNR + + + NDZ040 + 340400 + Slope + ND + US + 46.45 + -103.49 + 0 + 0 + BIS + + + NMZ020 + 310200 + Roosevelt_County + NM + US + 34.08 + -103.49 + 0 + 0 + ABQ + + + NDZ001 + 340010 + Divide + ND + US + 48.82 + -103.47 + 0 + 0 + BIS + + + NDZ009 + 340090 + Williams + ND + US + 48.30 + -103.44 + 0 + 0 + BIS + + + NMZ033 + 310330 + Central_Lea_County + NM + US + 32.75 + -103.43 + 0 + 0 + MAF + + + NMZ029 + 310290 + Northern_Lea_County + NM + US + 33.28 + -103.40 + 0 + 0 + MAF + + + NMZ034 + 310340 + Southern_Lea_County + NM + US + 32.25 + -103.39 + 0 + 0 + MAF + + + NMZ021 + 310210 + Curry_County + NM + US + 34.64 + -103.38 + 0 + 0 + ABQ + + + NDZ032 + 340320 + Billings + ND + US + 46.98 + -103.35 + 0 + 0 + BIS + + + SDZ072 + 410720 + Sturgis/Piedmont_Foot_Hills + SD + US + 44.38 + -103.35 + 0 + 0 + UNR + + + NDZ017 + 340170 + McKenzie + ND + US + 47.74 + -103.31 + 0 + 0 + BIS + + + SDZ074 + 410740 + Hermosa_Foot_Hills + SD + US + 43.67 + -103.27 + 0 + 0 + UNR + + + COZ049 + 60490 + Washington_County + CO + US + 40.00 + -103.24 + 0 + 0 + BOU + + + SDZ026 + 410260 + Rapid_City + SD + US + 44.00 + -103.23 + 0 + 0 + UNR + + + TXZ067 + 430670 + Ward + TX + US + 31.46 + -103.18 + 0 + 0 + MAF + + + NEZ002 + 270020 + Dawes + NE + US + 42.72 + -103.14 + 0 + 0 + CYS + + + COZ048 + 60480 + Logan_County + CO + US + 40.72 + -103.11 + 0 + 0 + BOU + + + COZ095 + 60950 + Western_Kiowa_County + CO + US + 38.43 + -103.11 + 0 + 0 + PUB + + + NEZ003 + 270030 + Box_Butte + NE + US + 42.22 + -103.07 + 0 + 0 + CYS + + + TXZ060 + 430600 + Winkler + TX + US + 31.87 + -103.07 + 0 + 0 + MAF + + + TXZ081 + 430810 + Big_Bend_Area + TX + US + 29.69 + -103.06 + 0 + 0 + MAF + + + COZ097 + 60970 + Las_Animas_Vicinity/Bent_County + CO + US + 37.95 + -103.05 + 0 + 0 + PUB + + + NEZ021 + 270210 + Morrill + NE + US + 41.72 + -103.00 + 0 + 0 + CYS + + + NEZ055 + 270550 + Cheyenne + NE + US + 41.22 + -102.99 + 0 + 0 + CYS + + + SDZ030 + 410300 + Custer_Co_Plains + SD + US + 43.67 + -102.96 + 0 + 0 + UNR + + + TXZ027 + 430270 + Bailey + TX + US + 34.07 + -102.82 + 0 + 0 + LUB + + + TXZ033 + 430330 + Cochran + TX + US + 33.61 + -102.82 + 0 + 0 + LUB + + + TXZ039 + 430390 + Yoakum + TX + US + 33.17 + -102.82 + 0 + 0 + LUB + + + SDZ073 + 410730 + Southern_Meade_Co_Plains + SD + US + 44.38 + -102.78 + 0 + 0 + UNR + + + TXZ021 + 430210 + Parmer + TX + US + 34.53 + -102.78 + 0 + 0 + LUB + + + TXZ075 + 430750 + Pecos + TX + US + 30.72 + -102.67 + 0 + 0 + MAF + + + NDZ033 + 340330 + Stark + ND + US + 46.82 + -102.66 + 0 + 0 + BIS + + + NDZ018 + 340180 + Dunn + ND + US + 47.40 + -102.63 + 0 + 0 + BIS + + + TXZ050 + 430500 + Andrews + TX + US + 32.30 + -102.63 + 0 + 0 + MAF + + + TXZ045 + 430450 + Gaines + TX + US + 32.74 + -102.62 + 0 + 0 + MAF + + + COZ092 + 60920 + Cheyenne_County + CO + US + 38.82 + -102.61 + 0 + 0 + GLD + + + COZ091 + 60910 + Kit_Carson_County + CO + US + 39.30 + -102.60 + 0 + 0 + GLD + + + TXZ001 + 430010 + Dallam + TX + US + 36.27 + -102.60 + 0 + 0 + AMA + + + TXZ006 + 430060 + Hartley + TX + US + 35.84 + -102.59 + 0 + 0 + AMA + + + TXZ011 + 430110 + Oldham + TX + US + 35.40 + -102.59 + 0 + 0 + AMA + + + TXZ016 + 430160 + Deaf_Smith + TX + US + 34.97 + -102.59 + 0 + 0 + AMA + + + COZ099 + 60990 + Springfield_Vic/Baca_County + CO + US + 37.32 + -102.56 + 0 + 0 + PUB + + + SDZ031 + 410310 + Pennington_Co_Plains + SD + US + 44.10 + -102.56 + 0 + 0 + UNR + + + SDZ042 + 410420 + Shannon + SD + US + 43.35 + -102.54 + 0 + 0 + UNR + + + TXZ061 + 430610 + Ector + TX + US + 31.87 + -102.54 + 0 + 0 + MAF + + + TXZ068 + 430680 + Crane + TX + US + 31.37 + -102.54 + 0 + 0 + MAF + + + OKZ001 + 360010 + Cimarron + OK + US + 36.74 + -102.51 + 0 + 0 + AMA + + + NDZ044 + 340440 + Adams + ND + US + 46.11 + -102.50 + 0 + 0 + BIS + + + NDZ002 + 340020 + Burke + ND + US + 48.78 + -102.48 + 0 + 0 + BIS + + + SDZ002 + 410020 + Perkins + SD + US + 45.49 + -102.48 + 0 + 0 + UNR + + + SDZ013 + 410130 + Northern_Meade_Co_Plains + SD + US + 44.82 + -102.48 + 0 + 0 + UNR + + + NDZ041 + 340410 + Hettinger + ND + US + 46.42 + -102.46 + 0 + 0 + BIS + + + COZ090 + 60900 + Yuma_County + CO + US + 40.00 + -102.42 + 0 + 0 + GLD + + + NEZ004 + 270040 + Sheridan + NE + US + 42.50 + -102.40 + 0 + 0 + LBF + + + COZ096 + 60960 + Eastern_Kiowa_County + CO + US + 38.44 + -102.39 + 0 + 0 + PUB + + + COZ098 + 60980 + Lamar_Vicinity/Prowers_County + CO + US + 37.95 + -102.39 + 0 + 0 + PUB + + + NDZ010 + 340100 + Mountrail + ND + US + 48.16 + -102.38 + 0 + 0 + BIS + + + COZ050 + 60500 + Sedgwick_County + CO + US + 40.87 + -102.35 + 0 + 0 + BOU + + + COZ051 + 60510 + Phillips_County + CO + US + 40.59 + -102.35 + 0 + 0 + BOU + + + TXZ028 + 430280 + Lamb + TX + US + 34.07 + -102.35 + 0 + 0 + LUB + + + TXZ034 + 430340 + Hockley + TX + US + 33.61 + -102.34 + 0 + 0 + LUB + + + NEZ022 + 270220 + Garden + NE + US + 41.61 + -102.33 + 0 + 0 + LBF + + + NEZ056 + 270560 + Deuel + NE + US + 41.11 + -102.33 + 0 + 0 + LBF + + + TXZ040 + 430400 + Terry + TX + US + 33.17 + -102.33 + 0 + 0 + LUB + + + TXZ022 + 430220 + Castro + TX + US + 34.53 + -102.26 + 0 + 0 + LUB + + + TXZ082 + 430820 + Terrell + TX + US + 30.22 + -102.11 + 0 + 0 + MAF + + + TXZ069 + 430690 + Upton + TX + US + 31.37 + -102.04 + 0 + 0 + MAF + + + TXZ062 + 430620 + Midland + TX + US + 31.87 + -102.03 + 0 + 0 + MAF + + + TXZ051 + 430510 + Martin + TX + US + 32.30 + -101.95 + 0 + 0 + MAF + + + TXZ046 + 430460 + Dawson + TX + US + 32.74 + -101.94 + 0 + 0 + MAF + + + TXZ017 + 430170 + Randall + TX + US + 34.97 + -101.90 + 0 + 0 + AMA + + + TXZ002 + 430020 + Sherman + TX + US + 36.27 + -101.89 + 0 + 0 + AMA + + + TXZ007 + 430070 + Moore + TX + US + 35.84 + -101.89 + 0 + 0 + AMA + + + TXZ012 + 430120 + Potter + TX + US + 35.40 + -101.89 + 0 + 0 + AMA + + + TXZ029 + 430290 + Hale + TX + US + 34.07 + -101.82 + 0 + 0 + LUB + + + TXZ035 + 430350 + Lubbock + TX + US + 33.61 + -101.82 + 0 + 0 + LUB + + + TXZ041 + 430410 + Lynn + TX + US + 33.17 + -101.82 + 0 + 0 + LUB + + + KSZ041 + 160410 + Greeley + KS + US + 38.47 + -101.80 + 0 + 0 + GLD + + + KSZ084 + 160840 + Morton + KS + US + 37.19 + -101.80 + 0 + 0 + DDC + + + KSZ061 + 160610 + Hamilton + KS + US + 37.99 + -101.78 + 0 + 0 + DDC + + + KSZ074 + 160740 + Stanton + KS + US + 37.56 + -101.78 + 0 + 0 + DDC + + + KSZ027 + 160270 + Wallace + KS + US + 38.91 + -101.76 + 0 + 0 + GLD + + + NEZ023 + 270230 + Grant + NE + US + 41.91 + -101.75 + 0 + 0 + LBF + + + KSZ001 + 160010 + Cheyenne + KS + US + 39.78 + -101.73 + 0 + 0 + GLD + + + NDZ019 + 340190 + Mercer + ND + US + 47.28 + -101.73 + 0 + 0 + BIS + + + TXZ023 + 430230 + Swisher + TX + US + 34.53 + -101.73 + 0 + 0 + LUB + + + KSZ013 + 160130 + Sherman + KS + US + 39.35 + -101.72 + 0 + 0 + GLD + + + NEZ035 + 270350 + Arthur + NE + US + 41.56 + -101.70 + 0 + 0 + LBF + + + NEZ069 + 270690 + Chase + NE + US + 40.52 + -101.69 + 0 + 0 + LBF + + + NEZ079 + 270790 + Dundy + NE + US + 40.17 + -101.69 + 0 + 0 + GLD + + + SDZ044 + 410440 + Bennett + SD + US + 43.19 + -101.67 + 0 + 0 + UNR + + + TXZ076 + 430760 + Crockett + TX + US + 30.69 + -101.67 + 0 + 0 + SJT + + + NEZ057 + 270570 + Keith + NE + US + 41.19 + -101.65 + 0 + 0 + LBF + + + NEZ058 + 270580 + Perkins + NE + US + 40.85 + -101.65 + 0 + 0 + LBF + + + SDZ043 + 410430 + Jackson + SD + US + 43.69 + -101.61 + 0 + 0 + UNR + + + NDZ011 + 340110 + Ward + ND + US + 48.33 + -101.60 + 0 + 0 + BIS + + + NDZ042 + 340420 + Grant + ND + US + 46.37 + -101.58 + 0 + 0 + BIS + + + SDZ014 + 410140 + Ziebach + SD + US + 45.00 + -101.57 + 0 + 0 + UNR + + + NDZ003 + 340030 + Renville + ND + US + 48.73 + -101.54 + 0 + 0 + BIS + + + SDZ032 + 410320 + Haakon + SD + US + 44.37 + -101.53 + 0 + 0 + UNR + + + TXZ063 + 430630 + Glasscock + TX + US + 31.87 + -101.52 + 0 + 0 + MAF + + + TXZ070 + 430700 + Reagan + TX + US + 31.37 + -101.52 + 0 + 0 + MAF + + + OKZ002 + 360020 + Texas + OK + US + 36.74 + -101.49 + 0 + 0 + AMA + + + TXZ047 + 430470 + Borden + TX + US + 32.74 + -101.43 + 0 + 0 + MAF + + + TXZ052 + 430520 + Howard + TX + US + 32.30 + -101.43 + 0 + 0 + MAF + + + NEZ094 + 270940 + Western_Cherry + NE + US + 42.54 + -101.42 + 0 + 0 + LBF + + + TXZ013 + 430130 + Carson + TX + US + 35.40 + -101.36 + 0 + 0 + AMA + + + TXZ018 + 430180 + Armstrong + TX + US + 34.97 + -101.36 + 0 + 0 + AMA + + + TXZ003 + 430030 + Hansford + TX + US + 36.27 + -101.35 + 0 + 0 + AMA + + + TXZ008 + 430080 + Hutchinson + TX + US + 35.84 + -101.35 + 0 + 0 + AMA + + + KSZ042 + 160420 + Wichita + KS + US + 38.48 + -101.34 + 0 + 0 + GLD + + + NDZ034 + 340340 + Morton + ND + US + 46.63 + -101.33 + 0 + 0 + BIS + + + NDZ020 + 340200 + Oliver + ND + US + 47.14 + -101.32 + 0 + 0 + BIS + + + KSZ062 + 160620 + Kearny + KS + US + 37.99 + -101.31 + 0 + 0 + DDC + + + KSZ085 + 160850 + Stevens + KS + US + 37.19 + -101.31 + 0 + 0 + DDC + + + KSZ075 + 160750 + Grant + KS + US + 37.56 + -101.30 + 0 + 0 + DDC + + + TXZ030 + 430300 + Floyd + TX + US + 34.07 + -101.30 + 0 + 0 + LUB + + + TXZ036 + 430360 + Crosby + TX + US + 33.61 + -101.30 + 0 + 0 + LUB + + + TXZ042 + 430420 + Garza + TX + US + 33.17 + -101.30 + 0 + 0 + LUB + + + TXZ183 + 431830 + Val_Verde + TX + US + 29.76 + -101.22 + 0 + 0 + EWX + + + TXZ024 + 430240 + Briscoe + TX + US + 34.53 + -101.21 + 0 + 0 + LUB + + + SDZ003 + 410030 + Corson + SD + US + 45.71 + -101.15 + 0 + 0 + ABR + + + KSZ028 + 160280 + Logan + KS + US + 38.91 + -101.14 + 0 + 0 + GLD + + + NEZ024 + 270240 + Hooker + NE + US + 41.91 + -101.13 + 0 + 0 + LBF + + + KSZ002 + 160020 + Rawlins + KS + US + 39.78 + -101.07 + 0 + 0 + GLD + + + NEZ036 + 270360 + McPherson + NE + US + 41.56 + -101.06 + 0 + 0 + LBF + + + NEZ070 + 270700 + Hayes + NE + US + 40.52 + -101.06 + 0 + 0 + LBF + + + KSZ014 + 160140 + Thomas + KS + US + 39.35 + -101.05 + 0 + 0 + GLD + + + NDZ021 + 340210 + McLean + ND + US + 47.51 + -101.04 + 0 + 0 + BIS + + + NEZ080 + 270800 + Hitchcock + NE + US + 40.17 + -101.04 + 0 + 0 + GLD + + + TXZ064 + 430640 + Sterling + TX + US + 31.83 + -101.04 + 0 + 0 + SJT + + + TXZ071 + 430710 + Irion + TX + US + 31.31 + -100.98 + 0 + 0 + SJT + + + TXZ048 + 430480 + Scurry + TX + US + 32.74 + -100.92 + 0 + 0 + MAF + + + TXZ053 + 430530 + Mitchell + TX + US + 32.30 + -100.92 + 0 + 0 + MAF + + + KSZ043 + 160430 + Scott + KS + US + 38.48 + -100.90 + 0 + 0 + DDC + + + NDZ045 + 340450 + Sioux + ND + US + 46.19 + -100.90 + 0 + 0 + BIS + + + SDZ015 + 410150 + Dewey + SD + US + 45.10 + -100.89 + 0 + 0 + ABR + + + SDZ033 + 410330 + Stanley + SD + US + 44.48 + -100.88 + 0 + 0 + ABR + + + KSZ076 + 160760 + Haskell + KS + US + 37.56 + -100.86 + 0 + 0 + DDC + + + KSZ086 + 160860 + Seward + KS + US + 37.19 + -100.85 + 0 + 0 + DDC + + + NDZ004 + 340040 + Bottineau + ND + US + 48.77 + -100.82 + 0 + 0 + BIS + + + TXZ004 + 430040 + Ochiltree + TX + US + 36.27 + -100.82 + 0 + 0 + AMA + + + TXZ009 + 430090 + Roberts + TX + US + 35.84 + -100.82 + 0 + 0 + AMA + + + TXZ014 + 430140 + Gray + TX + US + 35.40 + -100.81 + 0 + 0 + AMA + + + TXZ019 + 430190 + Donley + TX + US + 34.96 + -100.81 + 0 + 0 + AMA + + + TXZ031 + 430310 + Motley + TX + US + 34.08 + -100.78 + 0 + 0 + LUB + + + TXZ037 + 430370 + Dickens + TX + US + 33.62 + -100.78 + 0 + 0 + LUB + + + TXZ043 + 430430 + Kent + TX + US + 33.18 + -100.78 + 0 + 0 + LUB + + + NEZ059 + 270590 + Lincoln + NE + US + 41.04 + -100.74 + 0 + 0 + LBF + + + SDZ046 + 410460 + Mellette + SD + US + 43.63 + -100.72 + 0 + 0 + UNR + + + SDZ047 + 410470 + Todd + SD + US + 43.19 + -100.72 + 0 + 0 + UNR + + + SDZ045 + 410450 + Jones + SD + US + 43.95 + -100.71 + 0 + 0 + ABR + + + TXZ025 + 430250 + Hall + TX + US + 34.53 + -100.68 + 0 + 0 + LUB + + + KSZ063 + 160630 + Finney + KS + US + 37.99 + -100.66 + 0 + 0 + DDC + + + NDZ012 + 340120 + McHenry + ND + US + 48.24 + -100.63 + 0 + 0 + BIS + + + NEZ025 + 270250 + Thomas + NE + US + 41.91 + -100.55 + 0 + 0 + LBF + + + TXZ077 + 430770 + Schleicher + TX + US + 30.89 + -100.54 + 0 + 0 + SJT + + + TXZ078 + 430780 + Sutton + TX + US + 30.49 + -100.54 + 0 + 0 + SJT + + + NEZ005 + 270050 + Eastern_Cherry + NE + US + 42.53 + -100.53 + 0 + 0 + LBF + + + TXZ065 + 430650 + Coke + TX + US + 31.89 + -100.53 + 0 + 0 + SJT + + + NDZ035 + 340350 + Burleigh + ND + US + 46.98 + -100.52 + 0 + 0 + BIS + + + KSZ029 + 160290 + Gove + KS + US + 38.91 + -100.48 + 0 + 0 + GLD + + + NEZ037 + 270370 + Logan + NE + US + 41.57 + -100.48 + 0 + 0 + LBF + + + OKZ003 + 360030 + Beaver + OK + US + 36.74 + -100.48 + 0 + 0 + AMA + + + NEZ081 + 270810 + Red_Willow + NE + US + 40.17 + -100.47 + 0 + 0 + GLD + + + KSZ003 + 160030 + Decatur + KS + US + 39.78 + -100.46 + 0 + 0 + GLD + + + KSZ044 + 160440 + Lane + KS + US + 38.47 + -100.46 + 0 + 0 + DDC + + + TXZ202 + 432020 + Kinney + TX + US + 29.35 + -100.45 + 0 + 0 + EWX + + + KSZ015 + 160150 + Sheridan + KS + US + 39.35 + -100.44 + 0 + 0 + GLD + + + KSZ077 + 160770 + Gray + KS + US + 37.73 + -100.43 + 0 + 0 + DDC + + + TXZ049 + 430490 + Fisher + TX + US + 32.74 + -100.41 + 0 + 0 + SJT + + + TXZ054 + 430540 + Nolan + TX + US + 32.30 + -100.41 + 0 + 0 + SJT + + + TXZ072 + 430720 + Tom_Green + TX + US + 31.39 + -100.40 + 0 + 0 + SJT + + + TXZ217 + 432170 + Maverick + TX + US + 28.65 + -100.39 + 0 + 0 + EWX + + + KSZ087 + 160870 + Meade + KS + US + 37.23 + -100.37 + 0 + 0 + DDC + + + NEZ071 + 270710 + Frontier + NE + US + 40.52 + -100.37 + 0 + 0 + LBF + + + NDZ022 + 340220 + Sheridan + ND + US + 47.59 + -100.36 + 0 + 0 + BIS + + + TXZ005 + 430050 + Lipscomb + TX + US + 36.28 + -100.27 + 0 + 0 + AMA + + + TXZ010 + 430100 + Hemphill + TX + US + 35.84 + -100.27 + 0 + 0 + AMA + + + TXZ015 + 430150 + Wheeler + TX + US + 35.40 + -100.27 + 0 + 0 + AMA + + + TXZ020 + 430200 + Collingsworth + TX + US + 34.96 + -100.27 + 0 + 0 + AMA + + + NDZ046 + 340460 + Emmons + ND + US + 46.29 + -100.26 + 0 + 0 + BIS + + + TXZ032 + 430320 + Cottle + TX + US + 34.08 + -100.26 + 0 + 0 + LUB + + + TXZ038 + 430380 + King + TX + US + 33.62 + -100.26 + 0 + 0 + LUB + + + TXZ044 + 430440 + Stonewall + TX + US + 33.18 + -100.26 + 0 + 0 + LUB + + + TXZ184 + 431840 + Edwards + TX + US + 29.96 + -100.22 + 0 + 0 + EWX + + + TXZ026 + 430260 + Childress + TX + US + 34.53 + -100.21 + 0 + 0 + LUB + + + SDZ034 + 410340 + Sully + SD + US + 44.72 + -100.20 + 0 + 0 + ABR + + + SDZ004 + 410040 + Campbell + SD + US + 45.77 + -100.12 + 0 + 0 + ABR + + + SDZ009 + 410090 + Walworth + SD + US + 45.43 + -100.10 + 0 + 0 + ABR + + + SDZ035 + 410350 + Hughes + SD + US + 44.33 + -100.10 + 0 + 0 + ABR + + + SDZ016 + 410160 + Potter + SD + US + 45.07 + -100.00 + 0 + 0 + ABR + + + NEZ026 + 270260 + Blaine + NE + US + 41.91 + -99.97 + 0 + 0 + LBF + + + TXZ066 + 430660 + Runnels + TX + US + 31.83 + -99.97 + 0 + 0 + SJT + + + NEZ008 + 270080 + Brown + NE + US + 42.46 + -99.93 + 0 + 0 + LBF + + + KSZ045 + 160450 + Ness + KS + US + 38.47 + -99.91 + 0 + 0 + DDC + + + NEZ082 + 270820 + Furnas + NE + US + 40.17 + -99.91 + 0 + 0 + GID + + + KSZ004 + 160040 + Norton + KS + US + 39.78 + -99.90 + 0 + 0 + GLD + + + KSZ064 + 160640 + Hodgeman + KS + US + 38.08 + -99.89 + 0 + 0 + DDC + + + KSZ078 + 160780 + Ford + KS + US + 37.69 + -99.89 + 0 + 0 + DDC + + + NDZ013 + 340130 + Pierce + ND + US + 48.20 + -99.89 + 0 + 0 + BIS + + + TXZ127 + 431270 + Taylor + TX + US + 32.30 + -99.89 + 0 + 0 + SJT + + + KSZ016 + 160160 + Graham + KS + US + 39.34 + -99.88 + 0 + 0 + GLD + + + SDZ049 + 410490 + Tripp + SD + US + 43.38 + -99.88 + 0 + 0 + UNR + + + TXZ113 + 431130 + Jones + TX + US + 32.74 + -99.88 + 0 + 0 + SJT + + + KSZ030 + 160300 + Trego + KS + US + 38.91 + -99.87 + 0 + 0 + DDC + + + NEZ072 + 270720 + Gosper + NE + US + 40.52 + -99.86 + 0 + 0 + GID + + + TXZ073 + 430730 + Concho + TX + US + 31.34 + -99.86 + 0 + 0 + SJT + + + NDZ005 + 340050 + Rolette + ND + US + 48.77 + -99.84 + 0 + 0 + BIS + + + OKZ033 + 360330 + Harmon + OK + US + 34.77 + -99.83 + 0 + 0 + OUN + + + SDZ048 + 410480 + Lyman + SD + US + 43.86 + -99.83 + 0 + 0 + ABR + + + TXZ185 + 431850 + Real + TX + US + 29.86 + -99.83 + 0 + 0 + EWX + + + KSZ088 + 160880 + Clark + KS + US + 37.23 + -99.82 + 0 + 0 + DDC + + + NEZ060 + 270600 + Dawson + NE + US + 40.86 + -99.81 + 0 + 0 + GID + + + TXZ168 + 431680 + Menard + TX + US + 30.90 + -99.80 + 0 + 0 + SJT + + + NDZ036 + 340360 + Kidder + ND + US + 46.98 + -99.79 + 0 + 0 + BIS + + + TXZ203 + 432030 + Uvalde + TX + US + 29.36 + -99.77 + 0 + 0 + EWX + + + TXZ084 + 430840 + Foard + TX + US + 33.99 + -99.76 + 0 + 0 + OUN + + + TXZ218 + 432180 + Zavala + TX + US + 28.87 + -99.76 + 0 + 0 + EWX + + + TXZ228 + 432280 + Dimmit + TX + US + 28.42 + -99.75 + 0 + 0 + EWX + + + TXZ083 + 430830 + Hardeman + TX + US + 34.32 + -99.74 + 0 + 0 + OUN + + + NEZ006 + 270060 + Keya_Paha + NE + US + 42.85 + -99.73 + 0 + 0 + LBF + + + TXZ087 + 430870 + Knox + TX + US + 33.61 + -99.73 + 0 + 0 + OUN + + + TXZ098 + 430980 + Haskell + TX + US + 33.18 + -99.73 + 0 + 0 + SJT + + + NEZ038 + 270380 + Custer + NE + US + 41.39 + -99.72 + 0 + 0 + LBF + + + TXZ169 + 431690 + Kimble + TX + US + 30.50 + -99.71 + 0 + 0 + SJT + + + OKZ009 + 360090 + Ellis + OK + US + 36.22 + -99.69 + 0 + 0 + OUN + + + OKZ014 + 360140 + Roger_Mills + OK + US + 35.72 + -99.68 + 0 + 0 + OUN + + + OKZ021 + 360210 + Beckham + OK + US + 35.27 + -99.68 + 0 + 0 + OUN + + + NDZ023 + 340230 + Wells + ND + US + 47.59 + -99.67 + 0 + 0 + BIS + + + OKZ004 + 360040 + Harper + OK + US + 36.79 + -99.65 + 0 + 0 + OUN + + + OKZ034 + 360340 + Greer + OK + US + 34.92 + -99.56 + 0 + 0 + OUN + + + TXZ239 + 432390 + Webb + TX + US + 27.73 + -99.51 + 0 + 0 + CRP + + + SDZ036 + 410360 + Hyde + SD + US + 44.55 + -99.49 + 0 + 0 + ABR + + + NDZ047 + 340470 + Logan + ND + US + 46.46 + -99.48 + 0 + 0 + BIS + + + TXZ139 + 431390 + Coleman + TX + US + 31.75 + -99.46 + 0 + 0 + SJT + + + NEZ009 + 270090 + Rock + NE + US + 42.44 + -99.45 + 0 + 0 + LBF + + + NEZ027 + 270270 + Loup + NE + US + 41.91 + -99.45 + 0 + 0 + LBF + + + NDZ050 + 340500 + McIntosh + ND + US + 46.11 + -99.44 + 0 + 0 + BIS + + + OKZ036 + 360360 + Jackson + OK + US + 34.59 + -99.44 + 0 + 0 + OUN + + + NEZ073 + 270730 + Phelps + NE + US + 40.51 + -99.41 + 0 + 0 + GID + + + NEZ083 + 270830 + Harlan + NE + US + 40.17 + -99.40 + 0 + 0 + GID + + + TXZ128 + 431280 + Callahan + TX + US + 32.30 + -99.37 + 0 + 0 + SJT + + + TXZ114 + 431140 + Shackelford + TX + US + 32.74 + -99.36 + 0 + 0 + SJT + + + TXZ154 + 431540 + McCulloch + TX + US + 31.22 + -99.35 + 0 + 0 + SJT + + + KSZ005 + 160050 + Phillips + KS + US + 39.78 + -99.34 + 0 + 0 + GID + + + TXZ186 + 431860 + Kerr + TX + US + 30.04 + -99.34 + 0 + 0 + EWX + + + KSZ017 + 160170 + Rooks + KS + US + 39.35 + -99.32 + 0 + 0 + GID + + + KSZ031 + 160310 + Ellis + KS + US + 38.91 + -99.31 + 0 + 0 + DDC + + + KSZ046 + 160460 + Rush + KS + US + 38.52 + -99.30 + 0 + 0 + DDC + + + KSZ079 + 160790 + Edwards + KS + US + 37.90 + -99.29 + 0 + 0 + DDC + + + KSZ080 + 160800 + Kiowa + KS + US + 37.55 + -99.28 + 0 + 0 + DDC + + + OKZ010 + 360100 + Woodward + OK + US + 36.48 + -99.28 + 0 + 0 + OUN + + + KSZ089 + 160890 + Comanche + KS + US + 37.19 + -99.27 + 0 + 0 + DDC + + + NDZ006 + 340060 + Towner + ND + US + 48.69 + -99.25 + 0 + 0 + FGF + + + SDZ051 + 410510 + Buffalo + SD + US + 44.06 + -99.25 + 0 + 0 + ABR + + + KSZ065 + 160650 + Pawnee + KS + US + 38.17 + -99.24 + 0 + 0 + DDC + + + SDZ005 + 410050 + McPherson + SD + US + 45.77 + -99.23 + 0 + 0 + ABR + + + SDZ010 + 410100 + Edmunds + SD + US + 45.42 + -99.22 + 0 + 0 + ABR + + + TXZ085 + 430850 + Wilbarger + TX + US + 34.14 + -99.22 + 0 + 0 + OUN + + + TXZ170 + 431700 + Mason + TX + US + 30.72 + -99.22 + 0 + 0 + SJT + + + TXZ088 + 430880 + Baylor + TX + US + 33.62 + -99.21 + 0 + 0 + OUN + + + TXZ099 + 430990 + Throckmorton + TX + US + 33.18 + -99.21 + 0 + 0 + SJT + + + TXZ187 + 431870 + Bandera + TX + US + 29.74 + -99.21 + 0 + 0 + EWX + + + TXZ248 + 432480 + Zapata + TX + US + 26.94 + -99.21 + 0 + 0 + BRO + + + NDZ014 + 340140 + Benson + ND + US + 48.11 + -99.19 + 0 + 0 + FGF + + + SDZ017 + 410170 + Faulk + SD + US + 45.07 + -99.15 + 0 + 0 + ABR + + + SDZ057 + 410570 + Brule + SD + US + 43.72 + -99.13 + 0 + 0 + FSD + + + TXZ204 + 432040 + Medina + TX + US + 29.39 + -99.11 + 0 + 0 + EWX + + + TXZ219 + 432190 + Frio + TX + US + 28.87 + -99.11 + 0 + 0 + EWX + + + TXZ229 + 432290 + La_Salle + TX + US + 28.34 + -99.10 + 0 + 0 + CRP + + + NEZ061 + 270610 + Buffalo + NE + US + 40.85 + -99.07 + 0 + 0 + GID + + + SDZ050 + 410500 + Gregory + SD + US + 43.25 + -99.02 + 0 + 0 + FSD + + + OKZ015 + 360150 + Dewey + OK + US + 35.99 + -99.01 + 0 + 0 + OUN + + + OKZ035 + 360350 + Kiowa + OK + US + 34.86 + -99.01 + 0 + 0 + OUN + + + SDZ037 + 410370 + Hand + SD + US + 44.55 + -99.01 + 0 + 0 + ABR + + + OKZ016 + 360160 + Custer + OK + US + 35.64 + -99.00 + 0 + 0 + OUN + + + NEZ028 + 270280 + Garfield + NE + US + 41.91 + -98.99 + 0 + 0 + LBF + + + NEZ039 + 270390 + Valley + NE + US + 41.56 + -98.98 + 0 + 0 + GID + + + OKZ005 + 360050 + Woods + OK + US + 36.69 + -98.98 + 0 + 0 + OUN + + + OKZ022 + 360220 + Washita + OK + US + 35.29 + -98.98 + 0 + 0 + OUN + + + NEZ046 + 270460 + Sherman + NE + US + 41.22 + -98.97 + 0 + 0 + GID + + + NDZ037 + 340370 + Stutsman + ND + US + 46.98 + -98.96 + 0 + 0 + BIS + + + NEZ074 + 270740 + Kearney + NE + US + 40.51 + -98.95 + 0 + 0 + GID + + + NEZ084 + 270840 + Franklin + NE + US + 40.17 + -98.95 + 0 + 0 + GID + + + TXZ188 + 431880 + Gillespie + TX + US + 30.32 + -98.95 + 0 + 0 + EWX + + + TXZ140 + 431400 + Brown + TX + US + 31.77 + -98.94 + 0 + 0 + SJT + + + OKZ037 + 360370 + Tillman + OK + US + 34.38 + -98.92 + 0 + 0 + OUN + + + NDZ024 + 340240 + Eddy + ND + US + 47.72 + -98.90 + 0 + 0 + FGF + + + NDZ025 + 340250 + Foster + ND + US + 47.46 + -98.89 + 0 + 0 + BIS + + + TXZ115 + 431150 + Stephens + TX + US + 32.74 + -98.83 + 0 + 0 + FWD + + + TXZ129 + 431290 + Eastland + TX + US + 32.30 + -98.80 + 0 + 0 + FWD + + + KSZ006 + 160060 + Smith + KS + US + 39.78 + -98.78 + 0 + 0 + GID + + + NEZ007 + 270070 + Boyd + NE + US + 42.88 + -98.77 + 0 + 0 + LBF + + + NEZ010 + 270100 + Holt + NE + US + 42.49 + -98.77 + 0 + 0 + LBF + + + KSZ018 + 160180 + Osborne + KS + US + 39.34 + -98.76 + 0 + 0 + GID + + + KSZ032 + 160320 + Russell + KS + US + 38.91 + -98.76 + 0 + 0 + ICT + + + TXZ252 + 432520 + Starr + TX + US + 26.52 + -98.76 + 0 + 0 + BRO + + + KSZ047 + 160470 + Barton + KS + US + 38.47 + -98.75 + 0 + 0 + ICT + + + NDZ015 + 340150 + Ramsey + ND + US + 48.23 + -98.75 + 0 + 0 + FGF + + + TXZ155 + 431550 + San_Saba + TX + US + 31.21 + -98.75 + 0 + 0 + SJT + + + KSZ066 + 160660 + Stafford + KS + US + 38.03 + -98.74 + 0 + 0 + DDC + + + KSZ081 + 160810 + Pratt + KS + US + 37.64 + -98.73 + 0 + 0 + DDC + + + TXZ249 + 432490 + Jim_Hogg + TX + US + 27.08 + -98.70 + 0 + 0 + BRO + + + SDZ063 + 410630 + Charles_Mix + SD + US + 43.17 + -98.69 + 0 + 0 + FSD + + + TXZ086 + 430860 + Wichita + TX + US + 34.01 + -98.69 + 0 + 0 + OUN + + + KSZ090 + 160900 + Barber + KS + US + 37.23 + -98.68 + 0 + 0 + DDC + + + TXZ089 + 430890 + Archer + TX + US + 33.62 + -98.68 + 0 + 0 + OUN + + + TXZ100 + 431000 + Young + TX + US + 33.18 + -98.68 + 0 + 0 + FWD + + + TXZ189 + 431890 + Kendall + TX + US + 29.93 + -98.67 + 0 + 0 + EWX + + + TXZ171 + 431710 + Llano + TX + US + 30.71 + -98.65 + 0 + 0 + EWX + + + SDZ052 + 410520 + Jerauld + SD + US + 44.07 + -98.63 + 0 + 0 + FSD + + + TXZ142 + 431420 + Mills + TX + US + 31.48 + -98.63 + 0 + 0 + FWD + + + SDZ058 + 410580 + Aurora + SD + US + 43.72 + -98.57 + 0 + 0 + FSD + + + TXZ230 + 432300 + McMullen + TX + US + 28.35 + -98.57 + 0 + 0 + CRP + + + NDZ048 + 340480 + La_Moure + ND + US + 46.46 + -98.54 + 0 + 0 + BIS + + + TXZ141 + 431410 + Comanche + TX + US + 31.98 + -98.54 + 0 + 0 + FWD + + + OKZ011 + 360110 + Major + OK + US + 36.33 + -98.53 + 0 + 0 + OUN + + + NEZ029 + 270290 + Wheeler + NE + US + 41.91 + -98.52 + 0 + 0 + LBF + + + NEZ040 + 270400 + Greeley + NE + US + 41.57 + -98.52 + 0 + 0 + GID + + + TXZ240 + 432400 + Duval + TX + US + 27.66 + -98.52 + 0 + 0 + CRP + + + NDZ051 + 340510 + Dickey + ND + US + 46.11 + -98.51 + 0 + 0 + BIS + + + NEZ047 + 270470 + Howard + NE + US + 41.22 + -98.51 + 0 + 0 + GID + + + NEZ062 + 270620 + Hall + NE + US + 40.87 + -98.50 + 0 + 0 + GID + + + NEZ075 + 270750 + Adams + NE + US + 40.52 + -98.50 + 0 + 0 + GID + + + NEZ085 + 270850 + Webster + NE + US + 40.17 + -98.49 + 0 + 0 + GID + + + TXZ205 + 432050 + Bexar + TX + US + 29.44 + -98.47 + 0 + 0 + EWX + + + NDZ007 + 340070 + Cavalier + ND + US + 48.77 + -98.46 + 0 + 0 + FGF + + + OKZ038 + 360380 + Comanche + OK + US + 34.63 + -98.46 + 0 + 0 + OUN + + + TXZ220 + 432200 + Atascosa + TX + US + 28.93 + -98.45 + 0 + 0 + EWX + + + OKZ017 + 360170 + Blaine + OK + US + 35.86 + -98.42 + 0 + 0 + OUN + + + SDZ064 + 410640 + Douglas + SD + US + 43.35 + -98.41 + 0 + 0 + FSD + + + OKZ044 + 360440 + Cotton + OK + US + 34.28 + -98.40 + 0 + 0 + OUN + + + SDZ006 + 410060 + Brown + SD + US + 45.59 + -98.36 + 0 + 0 + ABR + + + TXZ190 + 431900 + Blanco + TX + US + 30.23 + -98.36 + 0 + 0 + EWX + + + OKZ023 + 360230 + Caddo + OK + US + 35.21 + -98.35 + 0 + 0 + OUN + + + SDZ018 + 410180 + Spink + SD + US + 44.94 + -98.35 + 0 + 0 + ABR + + + TXZ206 + 432060 + Comal + TX + US + 29.82 + -98.33 + 0 + 0 + EWX + + + OKZ006 + 360060 + Alfalfa + OK + US + 36.73 + -98.32 + 0 + 0 + OUN + + + TXZ116 + 431160 + Palo_Pinto + TX + US + 32.76 + -98.31 + 0 + 0 + FWD + + + SDZ038 + 410380 + Beadle + SD + US + 44.41 + -98.28 + 0 + 0 + FSD + + + TXZ250 + 432500 + Brooks + TX + US + 27.03 + -98.26 + 0 + 0 + BRO + + + TXZ156 + 431560 + Lampasas + TX + US + 31.25 + -98.24 + 0 + 0 + FWD + + + NDZ028 + 340280 + Griggs + ND + US + 47.46 + -98.23 + 0 + 0 + FGF + + + TXZ253 + 432530 + Hidalgo + TX + US + 26.41 + -98.23 + 0 + 0 + BRO + + + KSZ007 + 160070 + Jewell + KS + US + 39.78 + -98.22 + 0 + 0 + GID + + + KSZ033 + 160330 + Lincoln + KS + US + 39.04 + -98.21 + 0 + 0 + ICT + + + TXZ130 + 431300 + Erath + TX + US + 32.22 + -98.21 + 0 + 0 + FWD + + + KSZ019 + 160190 + Mitchell + KS + US + 39.39 + -98.20 + 0 + 0 + GID + + + KSZ048 + 160480 + Ellsworth + KS + US + 38.69 + -98.20 + 0 + 0 + ICT + + + KSZ050 + 160500 + Rice + KS + US + 38.33 + -98.20 + 0 + 0 + ICT + + + NDZ026 + 340260 + Nelson + ND + US + 47.94 + -98.20 + 0 + 0 + FGF + + + TXZ090 + 430900 + Clay + TX + US + 33.81 + -98.18 + 0 + 0 + OUN + + + TXZ101 + 431010 + Jack + TX + US + 33.24 + -98.17 + 0 + 0 + FWD + + + SDZ059 + 410590 + Davison + SD + US + 43.67 + -98.15 + 0 + 0 + FSD + + + TXZ172 + 431720 + Burnet + TX + US + 30.74 + -98.15 + 0 + 0 + EWX + + + KSZ082 + 160820 + Kingman + KS + US + 37.55 + -98.13 + 0 + 0 + ICT + + + TXZ143 + 431430 + Hamilton + TX + US + 31.72 + -98.11 + 0 + 0 + FWD + + + SDZ053 + 410530 + Sanborn + SD + US + 44.02 + -98.10 + 0 + 0 + FSD + + + NDZ054 + 340540 + Western_Walsh_County + ND + US + 48.37 + -98.09 + 0 + 0 + FGF + + + KSZ067 + 160670 + Reno + KS + US + 37.95 + -98.08 + 0 + 0 + ICT + + + NDZ038 + 340380 + Barnes + ND + US + 46.94 + -98.08 + 0 + 0 + FGF + + + TXZ221 + 432210 + Wilson + TX + US + 29.16 + -98.08 + 0 + 0 + EWX + + + TXZ231 + 432310 + Live_Oak + TX + US + 28.42 + -98.08 + 0 + 0 + CRP + + + KSZ091 + 160910 + Harper + KS + US + 37.19 + -98.07 + 0 + 0 + ICT + + + NEZ016 + 270160 + Antelope + NE + US + 42.17 + -98.07 + 0 + 0 + OAX + + + NEZ030 + 270300 + Boone + NE + US + 41.70 + -98.06 + 0 + 0 + OAX + + + NEZ063 + 270630 + Hamilton + NE + US + 40.93 + -98.05 + 0 + 0 + GID + + + NEZ076 + 270760 + Clay + NE + US + 40.52 + -98.05 + 0 + 0 + GID + + + NEZ086 + 270860 + Nuckolls + NE + US + 40.17 + -98.04 + 0 + 0 + GID + + + TXZ191 + 431910 + Hays + TX + US + 30.05 + -98.02 + 0 + 0 + EWX + + + TXZ241 + 432410 + Jim_Wells + TX + US + 27.66 + -98.02 + 0 + 0 + CRP + + + NEZ041 + 270410 + Nance + NE + US + 41.39 + -97.99 + 0 + 0 + GID + + + OKZ024 + 360240 + Canadian + OK + US + 35.53 + -97.99 + 0 + 0 + OUN + + + TXZ207 + 432070 + Guadalupe + TX + US + 29.62 + -97.98 + 0 + 0 + EWX + + + NEZ048 + 270480 + Merrick + NE + US + 41.13 + -97.94 + 0 + 0 + GID + + + OKZ018 + 360180 + Kingfisher + OK + US + 35.95 + -97.94 + 0 + 0 + OUN + + + NEZ011 + 270110 + Knox + NE + US + 42.66 + -97.90 + 0 + 0 + OAX + + + SDZ068 + 410680 + Bon_Homme + SD + US + 42.97 + -97.90 + 0 + 0 + FSD + + + OKZ027 + 360270 + Grady + OK + US + 35.03 + -97.88 + 0 + 0 + OUN + + + TXZ222 + 432220 + Karnes + TX + US + 28.95 + -97.88 + 0 + 0 + EWX + + + OKZ039 + 360390 + Stephens + OK + US + 34.49 + -97.85 + 0 + 0 + OUN + + + TXZ131 + 431310 + Hood + TX + US + 32.40 + -97.84 + 0 + 0 + FWD + + + OKZ045 + 360450 + Jefferson + OK + US + 34.07 + -97.83 + 0 + 0 + OUN + + + TXZ117 + 431170 + Parker + TX + US + 32.78 + -97.80 + 0 + 0 + FWD + + + TXZ157 + 431570 + Coryell + TX + US + 31.39 + -97.80 + 0 + 0 + FWD + + + SDZ060 + 410600 + Hanson + SD + US + 43.67 + -97.79 + 0 + 0 + FSD + + + OKZ007 + 360070 + Grant + OK + US + 36.79 + -97.78 + 0 + 0 + OUN + + + OKZ012 + 360120 + Garfield + OK + US + 36.38 + -97.78 + 0 + 0 + OUN + + + TXZ132 + 431320 + Somervell + TX + US + 32.21 + -97.78 + 0 + 0 + FWD + + + TXZ192 + 431920 + Travis + TX + US + 30.33 + -97.77 + 0 + 0 + EWX + + + SDZ065 + 410650 + Hutchinson + SD + US + 43.33 + -97.76 + 0 + 0 + FSD + + + SDZ019 + 410190 + Clark + SD + US + 44.85 + -97.74 + 0 + 0 + ABR + + + TXZ091 + 430910 + Montague + TX + US + 33.71 + -97.73 + 0 + 0 + FWD + + + TXZ232 + 432320 + Bee + TX + US + 28.42 + -97.73 + 0 + 0 + CRP + + + TXZ254 + 432540 + Inland_Willacy + TX + US + 26.46 + -97.73 + 0 + 0 + BRO + + + NDZ029 + 340290 + Steele + ND + US + 47.46 + -97.72 + 0 + 0 + FGF + + + NDZ049 + 340490 + Ransom + ND + US + 46.46 + -97.66 + 0 + 0 + FGF + + + TXZ102 + 431020 + Wise + TX + US + 33.22 + -97.65 + 0 + 0 + FWD + + + KSZ008 + 160080 + Republic + KS + US + 39.82 + -97.64 + 0 + 0 + TOP + + + KSZ020 + 160200 + Cloud + KS + US + 39.48 + -97.64 + 0 + 0 + TOP + + + KSZ034 + 160340 + Ottawa + KS + US + 39.13 + -97.64 + 0 + 0 + TOP + + + KSZ049 + 160490 + Saline + KS + US + 38.78 + -97.64 + 0 + 0 + ICT + + + KSZ051 + 160510 + McPherson + KS + US + 38.38 + -97.64 + 0 + 0 + ICT + + + TXZ144 + 431440 + Bosque + TX + US + 31.90 + -97.64 + 0 + 0 + FWD + + + TXZ242 + 432420 + Kleberg + TX + US + 27.43 + -97.64 + 0 + 0 + CRP + + + TXZ251 + 432510 + Kenedy + TX + US + 26.94 + -97.64 + 0 + 0 + BRO + + + NDZ052 + 340520 + Sargent + ND + US + 46.11 + -97.62 + 0 + 0 + FGF + + + TXZ208 + 432080 + Caldwell + TX + US + 29.86 + -97.62 + 0 + 0 + EWX + + + SDZ011 + 410110 + Day + SD + US + 45.37 + -97.61 + 0 + 0 + ABR + + + SDZ054 + 410540 + Miner + SD + US + 44.02 + -97.61 + 0 + 0 + FSD + + + NEZ017 + 270170 + Pierce + NE + US + 42.26 + -97.60 + 0 + 0 + OAX + + + NEZ031 + 270310 + Madison + NE + US + 41.91 + -97.60 + 0 + 0 + OAX + + + SDZ007 + 410070 + Marshall + SD + US + 45.75 + -97.60 + 0 + 0 + ABR + + + TXZ173 + 431730 + Williamson + TX + US + 30.66 + -97.60 + 0 + 0 + EWX + + + NEZ049 + 270490 + Polk + NE + US + 41.22 + -97.59 + 0 + 0 + GID + + + NEZ064 + 270640 + York + NE + US + 40.87 + -97.59 + 0 + 0 + GID + + + NEZ077 + 270770 + Fillmore + NE + US + 40.52 + -97.59 + 0 + 0 + GID + + + NEZ087 + 270870 + Thayer + NE + US + 40.17 + -97.59 + 0 + 0 + GID + + + TXZ255 + 432550 + Inland_Cameron + TX + US + 26.10 + -97.56 + 0 + 0 + BRO + + + NEZ042 + 270420 + Platte + NE + US + 41.54 + -97.54 + 0 + 0 + OAX + + + OKZ028 + 360280 + McClain + OK + US + 35.10 + -97.54 + 0 + 0 + OUN + + + NDZ008 + 340080 + Pembina + ND + US + 48.77 + -97.52 + 0 + 0 + FGF + + + TXZ244 + 432440 + San_Patricio + TX + US + 27.99 + -97.52 + 0 + 0 + CRP + + + TXZ158 + 431580 + Bell + TX + US + 31.05 + -97.50 + 0 + 0 + FWD + + + TXZ223 + 432230 + Gonzales + TX + US + 29.45 + -97.50 + 0 + 0 + EWX + + + TXZ243 + 432430 + Nueces + TX + US + 27.78 + -97.50 + 0 + 0 + CRP + + + NDZ016 + 340160 + Eastern_Walsh_County + ND + US + 48.37 + -97.49 + 0 + 0 + FGF + + + SDZ039 + 410390 + Kingsbury + SD + US + 44.37 + -97.49 + 0 + 0 + FSD + + + TXZ256 + 432560 + Coastal_Willacy + TX + US + 26.47 + -97.49 + 0 + 0 + BRO + + + KSZ083 + 160830 + Sedgwick + KS + US + 37.69 + -97.47 + 0 + 0 + ICT + + + KSZ092 + 160920 + Sumner + KS + US + 37.23 + -97.47 + 0 + 0 + ICT + + + TXZ233 + 432330 + Goliad + TX + US + 28.65 + -97.47 + 0 + 0 + CRP + + + KSZ068 + 160680 + Harvey + KS + US + 38.04 + -97.42 + 0 + 0 + ICT + + + OKZ019 + 360190 + Logan + OK + US + 35.95 + -97.41 + 0 + 0 + OUN + + + NDZ027 + 340270 + Grand_Forks + ND + US + 47.93 + -97.40 + 0 + 0 + FGF + + + OKZ025 + 360250 + Oklahoma + OK + US + 35.55 + -97.40 + 0 + 0 + OUN + + + OKZ029 + 360290 + Cleveland + OK + US + 35.16 + -97.40 + 0 + 0 + OUN + + + SDZ069 + 410690 + Yankton + SD + US + 42.99 + -97.40 + 0 + 0 + FSD + + + SDZ061 + 410610 + McCook + SD + US + 43.67 + -97.37 + 0 + 0 + FSD + + + TXZ224 + 432240 + DeWitt + TX + US + 29.10 + -97.37 + 0 + 0 + EWX + + + TXZ133 + 431330 + Johnson + TX + US + 32.35 + -97.35 + 0 + 0 + FWD + + + TXZ193 + 431930 + Bastrop + TX + US + 30.10 + -97.35 + 0 + 0 + EWX + + + TXZ257 + 432570 + Coastal_Cameron + TX + US + 26.20 + -97.34 + 0 + 0 + BRO + + + OKZ040 + 360400 + Garvin + OK + US + 34.69 + -97.30 + 0 + 0 + OUN + + + TXZ118 + 431180 + Tarrant + TX + US + 32.78 + -97.29 + 0 + 0 + FWD + + + NEZ012 + 270120 + Cedar + NE + US + 42.61 + -97.25 + 0 + 0 + OAX + + + OKZ046 + 360460 + Carter + OK + US + 34.29 + -97.24 + 0 + 0 + OUN + + + OKZ050 + 360500 + Love + OK + US + 33.90 + -97.24 + 0 + 0 + OUN + + + NDZ039 + 340390 + Cass + ND + US + 46.94 + -97.23 + 0 + 0 + FGF + + + TXZ092 + 430920 + Cooke + TX + US + 33.69 + -97.21 + 0 + 0 + FWD + + + TXZ159 + 431590 + McLennan + TX + US + 31.56 + -97.20 + 0 + 0 + FWD + + + NEZ032 + 270320 + Stanton + NE + US + 41.92 + -97.19 + 0 + 0 + OAX + + + SDZ020 + 410200 + Codington + SD + US + 44.98 + -97.19 + 0 + 0 + ABR + + + SDZ022 + 410220 + Hamlin + SD + US + 44.67 + -97.19 + 0 + 0 + ABR + + + OKZ013 + 360130 + Noble + OK + US + 36.39 + -97.17 + 0 + 0 + OUN + + + KSZ021 + 160210 + Clay + KS + US + 39.35 + -97.16 + 0 + 0 + TOP + + + NDZ030 + 340300 + Traill + ND + US + 47.46 + -97.16 + 0 + 0 + FGF + + + SDZ066 + 410660 + Turner + SD + US + 43.29 + -97.16 + 0 + 0 + FSD + + + TXZ246 + 432460 + Refugio + TX + US + 28.30 + -97.15 + 0 + 0 + CRP + + + KSZ035 + 160350 + Dickinson + KS + US + 38.86 + -97.14 + 0 + 0 + TOP + + + NEZ088 + 270880 + Jefferson + NE + US + 40.17 + -97.14 + 0 + 0 + OAX + + + NEZ050 + 270500 + Butler + NE + US + 41.25 + -97.13 + 0 + 0 + OAX + + + NEZ065 + 270650 + Seward + NE + US + 40.87 + -97.13 + 0 + 0 + OAX + + + NEZ078 + 270780 + Saline + NE + US + 40.52 + -97.13 + 0 + 0 + OAX + + + SDZ055 + 410550 + Lake + SD + US + 44.02 + -97.13 + 0 + 0 + FSD + + + OKZ008 + 360080 + Kay + OK + US + 36.79 + -97.11 + 0 + 0 + OUN + + + TXZ103 + 431030 + Denton + TX + US + 33.21 + -97.11 + 0 + 0 + FWD + + + TXZ145 + 431450 + Hill + TX + US + 32.00 + -97.11 + 0 + 0 + FWD + + + NEZ018 + 270180 + Wayne + NE + US + 42.22 + -97.10 + 0 + 0 + OAX + + + KSZ052 + 160520 + Marion + KS + US + 38.34 + -97.09 + 0 + 0 + ICT + + + OKZ041 + 360410 + Murray + OK + US + 34.49 + -97.09 + 0 + 0 + OUN + + + KSZ009 + 160090 + Washington + KS + US + 39.78 + -97.08 + 0 + 0 + TOP + + + NEZ043 + 270430 + Colfax + NE + US + 41.56 + -97.08 + 0 + 0 + OAX + + + OKZ020 + 360200 + Payne + OK + US + 36.10 + -96.99 + 0 + 0 + OUN + + + SDZ070 + 410700 + Clay + SD + US + 42.90 + -96.99 + 0 + 0 + FSD + + + TXZ194 + 431940 + Lee + TX + US + 30.30 + -96.99 + 0 + 0 + EWX + + + TXZ234 + 432340 + Victoria + TX + US + 28.80 + -96.98 + 0 + 0 + CRP + + + TXZ174 + 431740 + Milam + TX + US + 30.80 + -96.97 + 0 + 0 + FWD + + + TXZ209 + 432090 + Fayette + TX + US + 29.90 + -96.95 + 0 + 0 + EWX + + + TXZ160 + 431600 + Falls + TX + US + 31.26 + -96.94 + 0 + 0 + FWD + + + NDZ053 + 340530 + Richland + ND + US + 46.28 + -96.92 + 0 + 0 + FGF + + + TXZ225 + 432250 + Lavaca + TX + US + 29.35 + -96.91 + 0 + 0 + EWX + + + OKZ026 + 360260 + Lincoln + OK + US + 35.71 + -96.88 + 0 + 0 + OUN + + + OKZ030 + 360300 + Pottawatomie + OK + US + 35.19 + -96.88 + 0 + 0 + OUN + + + TXZ245 + 432450 + Aransas + TX + US + 28.21 + -96.87 + 0 + 0 + CRP + + + SDZ008 + 410080 + Roberts + SD + US + 45.62 + -96.86 + 0 + 0 + ABR + + + SDZ021 + 410210 + Grant + SD + US + 45.15 + -96.84 + 0 + 0 + ABR + + + KSZ069 + 160690 + Butler + KS + US + 37.78 + -96.83 + 0 + 0 + ICT + + + KSZ093 + 160930 + Cowley + KS + US + 37.23 + -96.83 + 0 + 0 + ICT + + + NEZ013 + 270130 + Dixon + NE + US + 42.51 + -96.82 + 0 + 0 + FSD + + + MNZ004 + 230040 + Kittson + MN + US + 48.77 + -96.81 + 0 + 0 + FGF + + + NEZ033 + 270330 + Cuming + NE + US + 41.92 + -96.79 + 0 + 0 + OAX + + + SDZ040 + 410400 + Brookings + SD + US + 44.37 + -96.79 + 0 + 0 + FSD + + + SDZ062 + 410620 + Minnehaha + SD + US + 43.67 + -96.79 + 0 + 0 + FSD + + + MNZ007 + 230070 + West_Marshall + MN + US + 48.36 + -96.78 + 0 + 0 + FGF + + + TXZ119 + 431190 + Dallas + TX + US + 32.77 + -96.77 + 0 + 0 + FWD + + + OKZ051 + 360510 + Marshall + OK + US + 34.01 + -96.76 + 0 + 0 + OUN + + + MNZ001 + 230010 + West_Polk + MN + US + 47.84 + -96.75 + 0 + 0 + FGF + + + TXZ134 + 431340 + Ellis + TX + US + 32.31 + -96.74 + 0 + 0 + FWD + + + KSZ036 + 160360 + Geary + KS + US + 39.04 + -96.72 + 0 + 0 + TOP + + + SDZ067 + 410670 + Lincoln + SD + US + 43.29 + -96.69 + 0 + 0 + FSD + + + NEZ066 + 270660 + Lancaster + NE + US + 40.78 + -96.68 + 0 + 0 + OAX + + + NEZ089 + 270890 + Gage + NE + US + 40.26 + -96.68 + 0 + 0 + OAX + + + KSZ022 + 160220 + Riley + KS + US + 39.30 + -96.67 + 0 + 0 + TOP + + + OKZ047 + 360470 + Johnston + OK + US + 34.32 + -96.67 + 0 + 0 + OUN + + + SDZ023 + 410230 + Deuel + SD + US + 44.76 + -96.67 + 0 + 0 + ABR + + + SDZ056 + 410560 + Moody + SD + US + 44.02 + -96.67 + 0 + 0 + FSD + + + OKZ042 + 360420 + Pontotoc + OK + US + 34.74 + -96.66 + 0 + 0 + OUN + + + TXZ093 + 430930 + Grayson + TX + US + 33.68 + -96.65 + 0 + 0 + FWD + + + KSZ037 + 160370 + Morris + KS + US + 38.69 + -96.64 + 0 + 0 + TOP + + + OKZ059 + 360590 + Pawnee + OK + US + 36.37 + -96.64 + 0 + 0 + TSA + + + SDZ071 + 410710 + Union + SD + US + 42.79 + -96.64 + 0 + 0 + FSD + + + TXZ247 + 432470 + Calhoun + TX + US + 28.39 + -96.63 + 0 + 0 + CRP + + + NEZ044 + 270440 + Dodge + NE + US + 41.57 + -96.62 + 0 + 0 + OAX + + + TXZ195 + 431950 + Burleson + TX + US + 30.52 + -96.62 + 0 + 0 + HGX + + + TXZ235 + 432350 + Jackson + TX + US + 28.96 + -96.62 + 0 + 0 + HGX + + + NEZ051 + 270510 + Saunders + NE + US + 41.24 + -96.61 + 0 + 0 + OAX + + + OKZ031 + 360310 + Seminole + OK + US + 35.16 + -96.61 + 0 + 0 + OUN + + + KSZ053 + 160530 + Chase + KS + US + 38.30 + -96.59 + 0 + 0 + ICT + + + TXZ161 + 431610 + Limestone + TX + US + 31.53 + -96.58 + 0 + 0 + FWD + + + MNZ039 + 230390 + Traverse + MN + US + 45.80 + -96.56 + 0 + 0 + ABR + + + TXZ104 + 431040 + Collin + TX + US + 33.20 + -96.56 + 0 + 0 + FWD + + + NEZ015 + 270150 + Thurston + NE + US + 42.15 + -96.55 + 0 + 0 + OAX + + + OKZ054 + 360540 + Osage + OK + US + 36.58 + -96.54 + 0 + 0 + TSA + + + TXZ175 + 431750 + Robertson + TX + US + 31.04 + -96.54 + 0 + 0 + FWD + + + NEZ014 + 270140 + Dakota + NE + US + 42.40 + -96.53 + 0 + 0 + FSD + + + TXZ210 + 432100 + Colorado + TX + US + 29.60 + -96.53 + 0 + 0 + HGX + + + KSZ010 + 160100 + Marshall + KS + US + 39.78 + -96.52 + 0 + 0 + TOP + + + MNZ029 + 230290 + Wilkin + MN + US + 46.33 + -96.52 + 0 + 0 + FGF + + + MNZ003 + 230030 + Clay + MN + US + 46.89 + -96.51 + 0 + 0 + FGF + + + MNZ046 + 230460 + Big_Stone + MN + US + 45.38 + -96.48 + 0 + 0 + ABR + + + MNZ002 + 230020 + Norman + MN + US + 47.33 + -96.47 + 0 + 0 + FGF + + + TXZ146 + 431460 + Navarro + TX + US + 32.07 + -96.47 + 0 + 0 + FWD + + + TXZ197 + 431970 + Washington + TX + US + 30.23 + -96.44 + 0 + 0 + HGX + + + TXZ120 + 431200 + Rockwall + TX + US + 32.91 + -96.40 + 0 + 0 + FWD + + + KSZ023 + 160230 + Pottawatomie + KS + US + 39.34 + -96.37 + 0 + 0 + TOP + + + TXZ196 + 431960 + Brazos + TX + US + 30.66 + -96.34 + 0 + 0 + HGX + + + OKZ064 + 360640 + Creek + OK + US + 35.91 + -96.33 + 0 + 0 + TSA + + + TXZ211 + 432110 + Austin + TX + US + 29.85 + -96.32 + 0 + 0 + HGX + + + NEZ034 + 270340 + Burt + NE + US + 41.87 + -96.31 + 0 + 0 + OAX + + + OKZ043 + 360430 + Coal + OK + US + 34.60 + -96.30 + 0 + 0 + OUN + + + OKZ065 + 360650 + Okfuskee + OK + US + 35.47 + -96.30 + 0 + 0 + TSA + + + TXZ121 + 431210 + Kaufman + TX + US + 32.61 + -96.30 + 0 + 0 + FWD + + + MNZ071 + 230710 + Lincoln + MN + US + 44.41 + -96.27 + 0 + 0 + FSD + + + MNZ097 + 230970 + Pipestone + MN + US + 44.02 + -96.26 + 0 + 0 + FSD + + + MNZ098 + 230980 + Rock + MN + US + 43.67 + -96.26 + 0 + 0 + FSD + + + NEZ090 + 270900 + Johnson + NE + US + 40.39 + -96.26 + 0 + 0 + OAX + + + IAZ020 + 150200 + Plymouth + IA + US + 42.74 + -96.25 + 0 + 0 + FSD + + + TXZ226 + 432260 + Wharton + TX + US + 29.30 + -96.25 + 0 + 0 + HGX + + + KSZ070 + 160700 + Greenwood + KS + US + 37.88 + -96.24 + 0 + 0 + ICT + + + KSZ094 + 160940 + Elk + KS + US + 37.45 + -96.24 + 0 + 0 + ICT + + + KSZ098 + 160980 + Chautauqua + KS + US + 37.15 + -96.24 + 0 + 0 + ICT + + + IAZ001 + 150010 + Lyon + IA + US + 43.38 + -96.23 + 0 + 0 + FSD + + + NEZ092 + 270920 + Pawnee + NE + US + 40.13 + -96.23 + 0 + 0 + OAX + + + OKZ032 + 360320 + Hughes + OK + US + 35.03 + -96.23 + 0 + 0 + OUN + + + IAZ012 + 150120 + Sioux + IA + US + 43.09 + -96.22 + 0 + 0 + FSD + + + KSZ038 + 160380 + Wabaunsee + KS + US + 38.97 + -96.22 + 0 + 0 + TOP + + + OKZ052 + 360520 + Bryan + OK + US + 33.93 + -96.19 + 0 + 0 + OUN + + + NEZ045 + 270450 + Washington + NE + US + 41.54 + -96.18 + 0 + 0 + OAX + + + NEZ052 + 270520 + Douglas + NE + US + 41.29 + -96.18 + 0 + 0 + OAX + + + KSZ054 + 160540 + Lyon + KS + US + 38.45 + -96.15 + 0 + 0 + TOP + + + NEZ067 + 270670 + Cass + NE + US + 40.93 + -96.15 + 0 + 0 + OAX + + + TXZ147 + 431470 + Freestone + TX + US + 31.72 + -96.14 + 0 + 0 + FWD + + + TXZ094 + 430940 + Fannin + TX + US + 33.62 + -96.11 + 0 + 0 + FWD + + + MNZ014 + 230140 + Red_Lake + MN + US + 47.86 + -96.10 + 0 + 0 + FGF + + + MNZ054 + 230540 + Lac_qui_Parle + MN + US + 45.04 + -96.09 + 0 + 0 + MPX + + + NEZ053 + 270530 + Sarpy + NE + US + 41.09 + -96.09 + 0 + 0 + OAX + + + NEZ068 + 270680 + Otoe + NE + US + 40.66 + -96.09 + 0 + 0 + OAX + + + IAZ031 + 150310 + Woodbury + IA + US + 42.39 + -96.08 + 0 + 0 + FSD + + + TXZ105 + 431050 + Hunt + TX + US + 33.13 + -96.07 + 0 + 0 + FWD + + + MNZ013 + 230130 + Pennington + MN + US + 48.05 + -96.04 + 0 + 0 + FGF + + + OKZ048 + 360480 + Atoka + OK + US + 34.43 + -96.04 + 0 + 0 + OUN + + + OKZ060 + 360600 + Tulsa + OK + US + 36.15 + -96.03 + 0 + 0 + TSA + + + IAZ043 + 150430 + Monona + IA + US + 42.04 + -96.02 + 0 + 0 + OAX + + + MNZ030 + 230300 + West_Otter_Tail + MN + US + 46.41 + -96.02 + 0 + 0 + FGF + + + KSZ011 + 160110 + Nemaha + KS + US + 39.78 + -96.01 + 0 + 0 + TOP + + + MNZ040 + 230400 + Grant + MN + US + 45.93 + -96.01 + 0 + 0 + FGF + + + MNZ047 + 230470 + Stevens + MN + US + 45.59 + -96.00 + 0 + 0 + MPX + + + TXZ212 + 432120 + Waller + TX + US + 29.99 + -96.00 + 0 + 0 + HGX + + + MNZ008 + 230080 + East_Marshall + MN + US + 48.36 + -95.99 + 0 + 0 + FGF + + + TXZ162 + 431620 + Leon + TX + US + 31.32 + -95.99 + 0 + 0 + FWD + + + TXZ198 + 431980 + Grimes + TX + US + 30.55 + -95.99 + 0 + 0 + HGX + + + MNZ015 + 230150 + East_Polk + MN + US + 47.72 + -95.95 + 0 + 0 + FGF + + + OKZ066 + 360660 + Okmulgee + OK + US + 35.62 + -95.95 + 0 + 0 + TSA + + + TXZ135 + 431350 + Henderson + TX + US + 32.19 + -95.94 + 0 + 0 + FWD + + + TXZ236 + 432360 + Matagorda + TX + US + 28.81 + -95.94 + 0 + 0 + HGX + + + MNZ027 + 230270 + West_Becker + MN + US + 46.94 + -95.93 + 0 + 0 + FGF + + + TXZ176 + 431760 + Madison + TX + US + 30.97 + -95.93 + 0 + 0 + HGX + + + MNZ064 + 230640 + Yellow_Medicine + MN + US + 44.74 + -95.91 + 0 + 0 + MPX + + + OKZ055 + 360550 + Washington + OK + US + 36.71 + -95.90 + 0 + 0 + TSA + + + MNZ072 + 230720 + Lyon + MN + US + 44.41 + -95.84 + 0 + 0 + FSD + + + IAZ055 + 150550 + Harrison + IA + US + 41.69 + -95.82 + 0 + 0 + OAX + + + MNZ022 + 230220 + Mahnomen + MN + US + 47.33 + -95.81 + 0 + 0 + FGF + + + NEZ091 + 270910 + Nemaha + NE + US + 40.41 + -95.80 + 0 + 0 + OAX + + + TXZ123 + 431230 + Rains + TX + US + 32.85 + -95.80 + 0 + 0 + FWD + + + KSZ024 + 160240 + Jackson + KS + US + 39.43 + -95.79 + 0 + 0 + TOP + + + MNZ080 + 230800 + Murray + MN + US + 44.02 + -95.77 + 0 + 0 + FSD + + + KSZ039 + 160390 + Shawnee + KS + US + 39.04 + -95.76 + 0 + 0 + TOP + + + MNZ089 + 230890 + Nobles + MN + US + 43.67 + -95.76 + 0 + 0 + FSD + + + TXZ122 + 431220 + Van_Zandt + TX + US + 32.61 + -95.76 + 0 + 0 + FWD + + + MNZ005 + 230050 + Roseau + MN + US + 48.77 + -95.75 + 0 + 0 + FGF + + + TXZ227 + 432270 + Fort_Bend + TX + US + 29.53 + -95.75 + 0 + 0 + HGX + + + KSZ095 + 160950 + Wilson + KS + US + 37.56 + -95.74 + 0 + 0 + ICT + + + KSZ099 + 160990 + Montgomery + KS + US + 37.19 + -95.74 + 0 + 0 + ICT + + + KSZ058 + 160580 + Coffey + KS + US + 38.23 + -95.73 + 0 + 0 + TOP + + + KSZ071 + 160710 + Woodson + KS + US + 37.88 + -95.73 + 0 + 0 + ICT + + + KSZ055 + 160550 + Osage + KS + US + 38.65 + -95.72 + 0 + 0 + TOP + + + OKZ073 + 360730 + Pittsburg + OK + US + 34.95 + -95.72 + 0 + 0 + TSA + + + MNZ055 + 230550 + Swift + MN + US + 45.28 + -95.69 + 0 + 0 + MPX + + + OKZ071 + 360710 + McIntosh + OK + US + 35.35 + -95.66 + 0 + 0 + TSA + + + TXZ148 + 431480 + Anderson + TX + US + 31.80 + -95.66 + 0 + 0 + FWD + + + MNZ056 + 230560 + Chippewa + MN + US + 44.96 + -95.65 + 0 + 0 + MPX + + + NEZ093 + 270930 + Richardson + NE + US + 40.13 + -95.65 + 0 + 0 + OAX + + + IAZ079 + 150790 + Mills + IA + US + 41.03 + -95.64 + 0 + 0 + OAX + + + IAZ002 + 150020 + Osceola + IA + US + 43.38 + -95.63 + 0 + 0 + FSD + + + IAZ013 + 150130 + O'Brien + IA + US + 43.09 + -95.63 + 0 + 0 + FSD + + + IAZ021 + 150210 + Cherokee + IA + US + 42.74 + -95.63 + 0 + 0 + FSD + + + IAZ090 + 150900 + Fremont + IA + US + 40.75 + -95.63 + 0 + 0 + OAX + + + OKZ056 + 360560 + Nowata + OK + US + 36.80 + -95.61 + 0 + 0 + TSA + + + TXZ177 + 431770 + Walker + TX + US + 30.79 + -95.60 + 0 + 0 + HGX + + + IAZ069 + 150690 + Pottawattamie + IA + US + 41.34 + -95.59 + 0 + 0 + OAX + + + TXZ095 + 430950 + Lamar + TX + US + 33.66 + -95.58 + 0 + 0 + FWD + + + TXZ106 + 431060 + Delta + TX + US + 33.36 + -95.58 + 0 + 0 + FWD + + + TXZ107 + 431070 + Hopkins + TX + US + 33.18 + -95.58 + 0 + 0 + FWD + + + OKZ053 + 360530 + Choctaw + OK + US + 34.02 + -95.57 + 0 + 0 + TSA + + + OKZ061 + 360610 + Rogers + OK + US + 36.34 + -95.57 + 0 + 0 + TSA + + + KSZ012 + 160120 + Brown + KS + US + 39.82 + -95.56 + 0 + 0 + TOP + + + IAZ032 + 150320 + Ida + IA + US + 42.39 + -95.54 + 0 + 0 + FSD + + + OKZ067 + 360670 + Wagoner + OK + US + 35.97 + -95.51 + 0 + 0 + TSA + + + MOZ001 + 250010 + Atchison + MO + US + 40.43 + -95.48 + 0 + 0 + EAX + + + TXZ237 + 432370 + Brazoria + TX + US + 29.21 + -95.47 + 0 + 0 + HGX + + + MNZ031 + 230310 + East_Otter_Tail + MN + US + 46.41 + -95.46 + 0 + 0 + FGF + + + TXZ199 + 431990 + Montgomery + TX + US + 30.33 + -95.46 + 0 + 0 + HGX + + + MNZ041 + 230410 + Douglas + MN + US + 45.93 + -95.45 + 0 + 0 + MPX + + + MNZ048 + 230480 + Pope + MN + US + 45.58 + -95.44 + 0 + 0 + MPX + + + TXZ213 + 432130 + Harris + TX + US + 29.84 + -95.44 + 0 + 0 + HGX + + + OKZ070 + 360700 + Muskogee + OK + US + 35.57 + -95.42 + 0 + 0 + TSA + + + MNZ028 + 230280 + East_Becker + MN + US + 46.93 + -95.41 + 0 + 0 + FGF + + + TXZ124 + 431240 + Wood + TX + US + 32.78 + -95.40 + 0 + 0 + SHV + + + IAZ044 + 150440 + Crawford + IA + US + 42.04 + -95.39 + 0 + 0 + DMX + + + MNZ016 + 230160 + North_Clearwater + MN + US + 47.76 + -95.39 + 0 + 0 + FGF + + + KSZ026 + 160260 + Jefferson + KS + US + 39.22 + -95.38 + 0 + 0 + TOP + + + TXZ163 + 431630 + Houston + TX + US + 31.27 + -95.37 + 0 + 0 + HGX + + + MNZ023 + 230230 + South_Clearwater + MN + US + 47.32 + -95.36 + 0 + 0 + FGF + + + OKZ049 + 360490 + Pushmataha + OK + US + 34.42 + -95.36 + 0 + 0 + TSA + + + IAZ056 + 150560 + Shelby + IA + US + 41.68 + -95.31 + 0 + 0 + OAX + + + KSZ072 + 160720 + Allen + KS + US + 37.88 + -95.30 + 0 + 0 + ICT + + + KSZ096 + 160960 + Neosho + KS + US + 37.56 + -95.30 + 0 + 0 + ICT + + + KSZ059 + 160590 + Anderson + KS + US + 38.21 + -95.29 + 0 + 0 + TOP + + + KSZ100 + 161000 + Labette + KS + US + 37.19 + -95.29 + 0 + 0 + ICT + + + TXZ136 + 431360 + Smith + TX + US + 32.42 + -95.29 + 0 + 0 + SHV + + + KSZ056 + 160560 + Franklin + KS + US + 38.56 + -95.28 + 0 + 0 + TOP + + + KSZ040 + 160400 + Douglas + KS + US + 38.90 + -95.27 + 0 + 0 + TOP + + + KSZ025 + 160250 + Atchison + KS + US + 39.53 + -95.26 + 0 + 0 + EAX + + + MOZ011 + 250110 + Holt + MO + US + 40.07 + -95.26 + 0 + 0 + EAX + + + MNZ073 + 230730 + Redwood + MN + US + 44.45 + -95.23 + 0 + 0 + MPX + + + OKZ062 + 360620 + Mayes + OK + US + 36.30 + -95.23 + 0 + 0 + TSA + + + OKZ057 + 360570 + Craig + OK + US + 36.76 + -95.22 + 0 + 0 + TSA + + + OKZ075 + 360750 + Latimer + OK + US + 34.88 + -95.22 + 0 + 0 + TSA + + + TXZ108 + 431080 + Franklin + TX + US + 33.18 + -95.21 + 0 + 0 + SHV + + + MNZ081 + 230810 + Cottonwood + MN + US + 44.02 + -95.17 + 0 + 0 + FSD + + + TXZ149 + 431490 + Cherokee + TX + US + 31.79 + -95.17 + 0 + 0 + SHV + + + IAZ003 + 150030 + Dickinson + IA + US + 43.38 + -95.16 + 0 + 0 + FSD + + + IAZ014 + 150140 + Clay + IA + US + 43.08 + -95.16 + 0 + 0 + FSD + + + IAZ022 + 150220 + Buena_Vista + IA + US + 42.74 + -95.16 + 0 + 0 + FSD + + + IAZ080 + 150800 + Montgomery + IA + US + 41.04 + -95.16 + 0 + 0 + OAX + + + IAZ091 + 150910 + Page + IA + US + 40.74 + -95.16 + 0 + 0 + OAX + + + MNZ090 + 230900 + Jackson + MN + US + 43.67 + -95.16 + 0 + 0 + FSD + + + IAZ033 + 150330 + Sac + IA + US + 42.39 + -95.13 + 0 + 0 + DMX + + + OKZ074 + 360740 + Haskell + OK + US + 35.27 + -95.13 + 0 + 0 + TSA + + + TXZ164 + 431640 + Trinity + TX + US + 31.11 + -95.13 + 0 + 0 + HGX + + + KSZ102 + 161020 + Doniphan + KS + US + 39.81 + -95.10 + 0 + 0 + EAX + + + TXZ178 + 431780 + San_Jacinto + TX + US + 30.62 + -95.10 + 0 + 0 + HGX + + + OKZ068 + 360680 + Cherokee + OK + US + 35.91 + -95.04 + 0 + 0 + TSA + + + TXZ096 + 430960 + Red_River + TX + US + 33.65 + -95.02 + 0 + 0 + SHV + + + MNZ009 + 230090 + North_Beltrami + MN + US + 48.20 + -95.01 + 0 + 0 + FGF + + + MNZ057 + 230570 + Kandiyohi + MN + US + 45.15 + -95.01 + 0 + 0 + MPX + + + KSZ103 + 161030 + Leavenworth + KS + US + 39.19 + -94.99 + 0 + 0 + EAX + + + MNZ065 + 230650 + Renville + MN + US + 44.67 + -94.99 + 0 + 0 + MPX + + + TXZ109 + 431090 + Titus + TX + US + 33.19 + -94.97 + 0 + 0 + SHV + + + MNZ032 + 230320 + Wadena + MN + US + 46.59 + -94.95 + 0 + 0 + FGF + + + IAZ070 + 150700 + Cass + IA + US + 41.33 + -94.94 + 0 + 0 + DMX + + + TXZ110 + 431100 + Camp + TX + US + 33.00 + -94.94 + 0 + 0 + SHV + + + MNZ024 + 230240 + Hubbard + MN + US + 47.11 + -94.92 + 0 + 0 + FGF + + + TXZ125 + 431250 + Upshur + TX + US + 32.72 + -94.92 + 0 + 0 + SHV + + + IAZ057 + 150570 + Audubon + IA + US + 41.68 + -94.91 + 0 + 0 + DMX + + + MOZ002 + 250020 + Nodaway + MO + US + 40.36 + -94.91 + 0 + 0 + EAX + + + MNZ042 + 230420 + Todd + MN + US + 46.07 + -94.90 + 0 + 0 + MPX + + + MNZ006 + 230060 + Lake_of_The_Woods + MN + US + 48.87 + -94.89 + 0 + 0 + FGF + + + IAZ045 + 150450 + Carroll + IA + US + 42.03 + -94.87 + 0 + 0 + DMX + + + TXZ179 + 431790 + Polk + TX + US + 30.82 + -94.87 + 0 + 0 + HGX + + + MOZ020 + 250200 + Buchanan + MO + US + 39.68 + -94.86 + 0 + 0 + EAX + + + KSZ073 + 160730 + Bourbon + KS + US + 37.85 + -94.85 + 0 + 0 + SGF + + + KSZ097 + 160970 + Crawford + KS + US + 37.50 + -94.85 + 0 + 0 + SGF + + + KSZ101 + 161010 + Cherokee + KS + US + 37.16 + -94.85 + 0 + 0 + SGF + + + MOZ028 + 250280 + Platte + MO + US + 39.34 + -94.85 + 0 + 0 + EAX + + + KSZ057 + 160570 + Miami + KS + US + 38.56 + -94.84 + 0 + 0 + EAX + + + KSZ060 + 160600 + Linn + KS + US + 38.21 + -94.84 + 0 + 0 + EAX + + + MOZ012 + 250120 + Andrew + MO + US + 39.97 + -94.84 + 0 + 0 + EAX + + + KSZ105 + 161050 + Johnson + KS + US + 38.89 + -94.83 + 0 + 0 + EAX + + + OKZ058 + 360580 + Ottawa + OK + US + 36.83 + -94.83 + 0 + 0 + TSA + + + MNZ017 + 230170 + South_Beltrami + MN + US + 47.63 + -94.81 + 0 + 0 + FGF + + + OKZ077 + 360770 + McCurtain + OK + US + 34.07 + -94.81 + 0 + 0 + SHV + + + TXZ200 + 432000 + Liberty + TX + US + 30.19 + -94.81 + 0 + 0 + HGX + + + TXZ238 + 432380 + Galveston + TX + US + 29.34 + -94.81 + 0 + 0 + HGX + + + OKZ063 + 360630 + Delaware + OK + US + 36.42 + -94.79 + 0 + 0 + TSA + + + OKZ072 + 360720 + Sequoyah + OK + US + 35.46 + -94.78 + 0 + 0 + TSA + + + TXZ137 + 431370 + Gregg + TX + US + 32.51 + -94.78 + 0 + 0 + SHV + + + KSZ104 + 161040 + Wyandotte + KS + US + 39.09 + -94.75 + 0 + 0 + EAX + + + MNZ074 + 230740 + Brown + MN + US + 44.30 + -94.74 + 0 + 0 + MPX + + + OKZ076 + 360760 + Le_Flore + OK + US + 34.95 + -94.74 + 0 + 0 + TSA + + + TXZ111 + 431110 + Morris + TX + US + 33.13 + -94.74 + 0 + 0 + SHV + + + TXZ150 + 431500 + Rusk + TX + US + 32.13 + -94.72 + 0 + 0 + SHV + + + IAZ081 + 150810 + Adams + IA + US + 41.03 + -94.71 + 0 + 0 + DMX + + + IAZ092 + 150920 + Taylor + IA + US + 40.74 + -94.71 + 0 + 0 + DMX + + + IAZ004 + 150040 + Emmet + IA + US + 43.38 + -94.69 + 0 + 0 + DMX + + + IAZ015 + 150150 + Palo_Alto + IA + US + 43.08 + -94.69 + 0 + 0 + DMX + + + IAZ023 + 150230 + Pocahontas + IA + US + 42.74 + -94.69 + 0 + 0 + DMX + + + TXZ214 + 432140 + Chambers + TX + US + 29.71 + -94.67 + 0 + 0 + HGX + + + IAZ034 + 150340 + Calhoun + IA + US + 42.38 + -94.66 + 0 + 0 + DMX + + + OKZ069 + 360690 + Adair + OK + US + 35.91 + -94.64 + 0 + 0 + TSA + + + TXZ152 + 431520 + Nacogdoches + TX + US + 31.54 + -94.64 + 0 + 0 + SHV + + + MNZ082 + 230820 + Watonwan + MN + US + 43.98 + -94.62 + 0 + 0 + MPX + + + MNZ049 + 230490 + Stearns + MN + US + 45.53 + -94.59 + 0 + 0 + MPX + + + TXZ165 + 431650 + Angelina + TX + US + 31.28 + -94.57 + 0 + 0 + SHV + + + MNZ033 + 230330 + South_Cass + MN + US + 46.54 + -94.56 + 0 + 0 + DLH + + + MNZ091 + 230910 + Martin + MN + US + 43.67 + -94.55 + 0 + 0 + MPX + + + MNZ058 + 230580 + Meeker + MN + US + 45.11 + -94.51 + 0 + 0 + MPX + + + IAZ058 + 150580 + Guthrie + IA + US + 41.68 + -94.50 + 0 + 0 + DMX + + + IAZ071 + 150710 + Adair + IA + US + 41.33 + -94.48 + 0 + 0 + DMX + + + MOZ003 + 250030 + Worth + MO + US + 40.48 + -94.43 + 0 + 0 + EAX + + + MOZ004 + 250040 + Gentry + MO + US + 40.21 + -94.42 + 0 + 0 + EAX + + + MOZ021 + 250210 + Clinton + MO + US + 39.60 + -94.42 + 0 + 0 + EAX + + + MOZ029 + 250290 + Clay + MO + US + 39.28 + -94.42 + 0 + 0 + EAX + + + IAZ046 + 150460 + Greene + IA + US + 42.03 + -94.41 + 0 + 0 + DMX + + + MOZ013 + 250130 + De_Kalb + MO + US + 39.89 + -94.41 + 0 + 0 + EAX + + + TXZ201 + 432010 + Hardin + TX + US + 30.31 + -94.40 + 0 + 0 + LCH + + + TXZ097 + 430970 + Bowie + TX + US + 33.47 + -94.39 + 0 + 0 + SHV + + + TXZ126 + 431260 + Marion + TX + US + 32.79 + -94.38 + 0 + 0 + SHV + + + TXZ138 + 431380 + Harrison + TX + US + 32.56 + -94.37 + 0 + 0 + SHV + + + MNZ075 + 230750 + Nicollet + MN + US + 44.31 + -94.36 + 0 + 0 + MPX + + + MOZ037 + 250370 + Jackson + MO + US + 39.03 + -94.36 + 0 + 0 + EAX + + + MOZ077 + 250770 + Barton + MO + US + 37.50 + -94.35 + 0 + 0 + SGF + + + MOZ101 + 251010 + McDonald + MO + US + 36.63 + -94.35 + 0 + 0 + SGF + + + TXZ112 + 431120 + Cass + TX + US + 33.10 + -94.35 + 0 + 0 + SHV + + + TXZ180 + 431800 + Tyler + TX + US + 30.79 + -94.35 + 0 + 0 + LCH + + + MOZ043 + 250430 + Cass + MO + US + 38.64 + -94.34 + 0 + 0 + EAX + + + MOZ053 + 250530 + Bates + MO + US + 38.25 + -94.34 + 0 + 0 + EAX + + + MOZ066 + 250660 + Vernon + MO + US + 37.85 + -94.34 + 0 + 0 + SGF + + + MOZ088 + 250880 + Jasper + MO + US + 37.21 + -94.34 + 0 + 0 + SGF + + + MOZ093 + 250930 + Newton + MO + US + 36.90 + -94.34 + 0 + 0 + SGF + + + TXZ151 + 431510 + Panola + TX + US + 32.18 + -94.30 + 0 + 0 + SHV + + + MNZ066 + 230660 + McLeod + MN + US + 44.81 + -94.26 + 0 + 0 + MPX + + + IAZ082 + 150820 + Union + IA + US + 41.03 + -94.25 + 0 + 0 + DMX + + + IAZ093 + 150930 + Ringgold + IA + US + 40.74 + -94.25 + 0 + 0 + DMX + + + ARZ001 + 40010 + Benton + AR + US + 36.30 + -94.24 + 0 + 0 + TSA + + + ARZ029 + 40290 + Sebastian + AR + US + 35.19 + -94.24 + 0 + 0 + TSA + + + ARZ010 + 40100 + Washington + AR + US + 36.00 + -94.22 + 0 + 0 + TSA + + + ARZ050 + 40500 + Sevier + AR + US + 33.97 + -94.22 + 0 + 0 + SHV + + + IAZ005 + 150050 + Kossuth + IA + US + 43.21 + -94.22 + 0 + 0 + DMX + + + IAZ024 + 150240 + Humboldt + IA + US + 42.78 + -94.22 + 0 + 0 + DMX + + + MNZ025 + 230250 + North_Cass + MN + US + 47.14 + -94.22 + 0 + 0 + DLH + + + MNZ043 + 230430 + Morrison + MN + US + 46.06 + -94.21 + 0 + 0 + MPX + + + ARZ040 + 40400 + Polk + AR + US + 34.47 + -94.20 + 0 + 0 + LZK + + + MNZ067 + 230670 + Sibley + MN + US + 44.59 + -94.20 + 0 + 0 + MPX + + + ARZ019 + 40190 + Crawford + AR + US + 35.56 + -94.19 + 0 + 0 + TSA + + + IAZ035 + 150350 + Webster + IA + US + 42.43 + -94.19 + 0 + 0 + DMX + + + TXZ166 + 431660 + San_Augustine + TX + US + 31.38 + -94.19 + 0 + 0 + SHV + + + TXZ153 + 431530 + Shelby + TX + US + 31.78 + -94.15 + 0 + 0 + SHV + + + ARZ059 + 40590 + Little_River + AR + US + 33.74 + -94.14 + 0 + 0 + SHV + + + TXZ215 + 432150 + Jefferson + TX + US + 29.87 + -94.14 + 0 + 0 + LCH + + + ARZ037 + 40370 + Scott + AR + US + 34.89 + -94.08 + 0 + 0 + LZK + + + MNZ034 + 230340 + Crow_Wing + MN + US + 46.48 + -94.08 + 0 + 0 + DLH + + + MNZ083 + 230830 + Blue_Earth + MN + US + 44.06 + -94.07 + 0 + 0 + MPX + + + MNZ050 + 230500 + Benton + MN + US + 45.69 + -94.06 + 0 + 0 + MPX + + + IAZ059 + 150590 + Dallas + IA + US + 41.68 + -94.04 + 0 + 0 + DMX + + + ARZ051 + 40510 + Howard + AR + US + 34.05 + -94.03 + 0 + 0 + SHV + + + IAZ072 + 150720 + Madison + IA + US + 41.34 + -94.02 + 0 + 0 + DMX + + + MOZ005 + 250050 + Harrison + MO + US + 40.36 + -94.00 + 0 + 0 + EAX + + + MOZ014 + 250140 + Daviess + MO + US + 39.96 + -94.00 + 0 + 0 + EAX + + + TXZ181 + 431810 + Jasper + TX + US + 30.70 + -94.00 + 0 + 0 + LCH + + + MOZ022 + 250220 + Caldwell + MO + US + 39.66 + -93.99 + 0 + 0 + EAX + + + MOZ030 + 250300 + Ray + MO + US + 39.33 + -93.99 + 0 + 0 + EAX + + + MNZ092 + 230920 + Faribault + MN + US + 43.67 + -93.95 + 0 + 0 + MPX + + + IAZ047 + 150470 + Boone + IA + US + 42.03 + -93.94 + 0 + 0 + DMX + + + TXZ216 + 432160 + Orange + TX + US + 30.10 + -93.90 + 0 + 0 + LCH + + + MNZ059 + 230590 + Wright + MN + US + 45.20 + -93.89 + 0 + 0 + MPX + + + ARZ020 + 40200 + Franklin + AR + US + 35.49 + -93.88 + 0 + 0 + TSA + + + MOZ089 + 250890 + Dade + MO + US + 37.43 + -93.86 + 0 + 0 + SGF + + + ARZ070 + 40700 + Miller + AR + US + 33.31 + -93.85 + 0 + 0 + SHV + + + MOZ078 + 250780 + Cedar + MO + US + 37.73 + -93.85 + 0 + 0 + SGF + + + MOZ094 + 250940 + Lawrence + MO + US + 37.11 + -93.84 + 0 + 0 + SGF + + + MNZ051 + 230510 + Sherburne + MN + US + 45.41 + -93.83 + 0 + 0 + MPX + + + MOZ102 + 251020 + Barry + MO + US + 36.71 + -93.83 + 0 + 0 + SGF + + + MOZ044 + 250440 + Johnson + MO + US + 38.75 + -93.82 + 0 + 0 + EAX + + + TXZ167 + 431670 + Sabine + TX + US + 31.37 + -93.82 + 0 + 0 + SHV + + + MOZ038 + 250380 + Lafayette + MO + US + 39.09 + -93.80 + 0 + 0 + EAX + + + IAZ083 + 150830 + Clarke + IA + US + 41.03 + -93.79 + 0 + 0 + DMX + + + IAZ094 + 150940 + Decatur + IA + US + 40.74 + -93.79 + 0 + 0 + DMX + + + MOZ054 + 250540 + Henry + MO + US + 38.38 + -93.79 + 0 + 0 + EAX + + + MOZ067 + 250670 + St._Clair + MO + US + 38.02 + -93.79 + 0 + 0 + SGF + + + MNZ076 + 230760 + Le_Sueur + MN + US + 44.37 + -93.78 + 0 + 0 + MPX + + + LAZ001 + 180010 + Caddo + LA + US + 32.61 + -93.77 + 0 + 0 + SHV + + + MNZ068 + 230680 + Carver + MN + US + 44.81 + -93.77 + 0 + 0 + MPX + + + MNZ010 + 230100 + Koochiching + MN + US + 48.28 + -93.76 + 0 + 0 + DLH + + + IAZ006 + 150060 + Winnebago + IA + US + 43.38 + -93.74 + 0 + 0 + DMX + + + IAZ016 + 150160 + Hancock + IA + US + 43.08 + -93.74 + 0 + 0 + DMX + + + IAZ025 + 150250 + Wright + IA + US + 42.73 + -93.74 + 0 + 0 + DMX + + + MNZ018 + 230180 + North_Itasca + MN + US + 47.66 + -93.74 + 0 + 0 + DLH + + + IAZ036 + 150360 + Hamilton + IA + US + 42.38 + -93.72 + 0 + 0 + DMX + + + ARZ030 + 40300 + Logan + AR + US + 35.22 + -93.71 + 0 + 0 + LZK + + + ARZ060 + 40600 + Hempstead + AR + US + 33.75 + -93.71 + 0 + 0 + SHV + + + TXZ182 + 431820 + Newton + TX + US + 30.72 + -93.71 + 0 + 0 + LCH + + + ARZ011 + 40110 + Madison + AR + US + 36.03 + -93.70 + 0 + 0 + TSA + + + LAZ010 + 180100 + De_Soto + LA + US + 32.10 + -93.69 + 0 + 0 + SHV + + + ARZ041 + 40410 + Montgomery + AR + US + 34.55 + -93.66 + 0 + 0 + LZK + + + ARZ052 + 40520 + Pike + AR + US + 34.15 + -93.65 + 0 + 0 + LZK + + + MNZ044 + 230440 + Mille_Lacs + MN + US + 45.90 + -93.62 + 0 + 0 + MPX + + + ARZ071 + 40710 + Lafayette + AR + US + 33.25 + -93.61 + 0 + 0 + SHV + + + LAZ002 + 180020 + Bossier + LA + US + 32.63 + -93.61 + 0 + 0 + SHV + + + MNZ069 + 230690 + Scott + MN + US + 44.68 + -93.60 + 0 + 0 + MPX + + + MNZ084 + 230840 + Waseca + MN + US + 44.02 + -93.59 + 0 + 0 + MPX + + + ARZ002 + 40020 + Carroll + AR + US + 36.31 + -93.58 + 0 + 0 + TSA + + + MOZ006 + 250060 + Mercer + MO + US + 40.42 + -93.58 + 0 + 0 + EAX + + + IAZ060 + 150600 + Polk + IA + US + 41.68 + -93.57 + 0 + 0 + DMX + + + MNZ026 + 230260 + South_Itasca + MN + US + 47.24 + -93.57 + 0 + 0 + DLH + + + MOZ015 + 250150 + Grundy + MO + US + 40.11 + -93.57 + 0 + 0 + EAX + + + IAZ073 + 150730 + Warren + IA + US + 41.34 + -93.56 + 0 + 0 + DMX + + + LAZ017 + 180170 + Sabine + LA + US + 31.51 + -93.55 + 0 + 0 + SHV + + + MOZ023 + 250230 + Livingston + MO + US + 39.79 + -93.52 + 0 + 0 + EAX + + + IAZ048 + 150480 + Story + IA + US + 42.03 + -93.47 + 0 + 0 + DMX + + + MNZ060 + 230600 + Hennepin + MN + US + 45.02 + -93.47 + 0 + 0 + MPX + + + MOZ103 + 251030 + Stone + MO + US + 36.74 + -93.47 + 0 + 0 + SGF + + + MOZ031 + 250310 + Carroll + MO + US + 39.41 + -93.44 + 0 + 0 + EAX + + + ARZ021 + 40210 + Johnson + AR + US + 35.55 + -93.43 + 0 + 0 + LZK + + + MNZ036 + 230360 + South_Aitkin + MN + US + 46.39 + -93.43 + 0 + 0 + DLH + + + MNZ035 + 230350 + Northern_Aitkin + MN + US + 46.83 + -93.42 + 0 + 0 + DLH + + + MOZ079 + 250790 + Polk + MO + US + 37.62 + -93.41 + 0 + 0 + SGF + + + LAZ011 + 180110 + Red_River + LA + US + 32.07 + -93.36 + 0 + 0 + SHV + + + LAZ030 + 180300 + Beauregard + LA + US + 30.65 + -93.36 + 0 + 0 + LCH + + + MNZ093 + 230930 + Freeborn + MN + US + 43.67 + -93.35 + 0 + 0 + MPX + + + MOZ090 + 250900 + Greene + MO + US + 37.26 + -93.35 + 0 + 0 + SGF + + + IAZ084 + 150840 + Lucas + IA + US + 41.03 + -93.33 + 0 + 0 + DMX + + + IAZ095 + 150950 + Wayne + IA + US + 40.74 + -93.33 + 0 + 0 + DMX + + + LAZ003 + 180030 + Webster + LA + US + 32.72 + -93.33 + 0 + 0 + SHV + + + ARZ038 + 40380 + Yell + AR + US + 35.03 + -93.32 + 0 + 0 + LZK + + + LAZ041 + 180410 + Calcasieu + LA + US + 30.27 + -93.32 + 0 + 0 + LCH + + + MOZ068 + 250680 + Hickory + MO + US + 37.93 + -93.32 + 0 + 0 + SGF + + + ARZ061 + 40610 + Nevada + AR + US + 33.70 + -93.29 + 0 + 0 + SHV + + + MNZ045 + 230450 + Kanabec + MN + US + 45.95 + -93.29 + 0 + 0 + MPX + + + MNZ077 + 230770 + Rice + MN + US + 44.37 + -93.29 + 0 + 0 + MPX + + + MOZ045 + 250450 + Pettis + MO + US + 38.72 + -93.29 + 0 + 0 + EAX + + + MOZ055 + 250550 + Benton + MO + US + 38.30 + -93.29 + 0 + 0 + SGF + + + MNZ052 + 230520 + Isanti + MN + US + 45.57 + -93.27 + 0 + 0 + MPX + + + MNZ061 + 230610 + Anoka + MN + US + 45.23 + -93.27 + 0 + 0 + MPX + + + IAZ007 + 150070 + Worth + IA + US + 43.38 + -93.26 + 0 + 0 + DMX + + + IAZ017 + 150170 + Cerro_Gordo + IA + US + 43.08 + -93.26 + 0 + 0 + DMX + + + IAZ026 + 150260 + Franklin + IA + US + 42.73 + -93.26 + 0 + 0 + DMX + + + MOZ095 + 250950 + Christian + MO + US + 36.95 + -93.26 + 0 + 0 + SGF + + + IAZ037 + 150370 + Hardin + IA + US + 42.38 + -93.25 + 0 + 0 + DMX + + + LAZ051 + 180510 + Cameron + LA + US + 29.83 + -93.25 + 0 + 0 + LCH + + + MNZ085 + 230850 + Steele + MN + US + 44.02 + -93.23 + 0 + 0 + MPX + + + ARZ012 + 40120 + Newton + AR + US + 35.93 + -93.22 + 0 + 0 + LZK + + + ARZ072 + 40720 + Columbia + AR + US + 33.24 + -93.22 + 0 + 0 + SHV + + + ARZ053 + 40530 + Clark + AR + US + 34.06 + -93.19 + 0 + 0 + LZK + + + LAZ027 + 180270 + Vernon + LA + US + 31.12 + -93.19 + 0 + 0 + LCH + + + MOZ039 + 250390 + Saline + MO + US + 39.17 + -93.18 + 0 + 0 + EAX + + + MNZ062 + 230620 + Ramsey + MN + US + 45.01 + -93.11 + 0 + 0 + MPX + + + MOZ016 + 250160 + Sullivan + MO + US + 40.21 + -93.11 + 0 + 0 + EAX + + + MOZ024 + 250240 + Linn + MO + US + 39.87 + -93.11 + 0 + 0 + EAX + + + IAZ074 + 150740 + Marion + IA + US + 41.34 + -93.10 + 0 + 0 + DMX + + + LAZ012 + 180120 + Bienville + LA + US + 32.37 + -93.10 + 0 + 0 + SHV + + + ARZ042 + 40420 + Garland + AR + US + 34.58 + -93.09 + 0 + 0 + LZK + + + LAZ018 + 180180 + Natchitoches + LA + US + 31.75 + -93.08 + 0 + 0 + SHV + + + ARZ003 + 40030 + Boone + AR + US + 36.31 + -93.07 + 0 + 0 + LZK + + + IAZ061 + 150610 + Jasper + IA + US + 41.69 + -93.06 + 0 + 0 + DMX + + + ARZ022 + 40220 + Pope + AR + US + 35.43 + -93.05 + 0 + 0 + LZK + + + MOZ104 + 251040 + Taney + MO + US + 36.66 + -93.05 + 0 + 0 + SGF + + + ARZ054 + 40540 + Hot_Spring + AR + US + 34.33 + -93.04 + 0 + 0 + LZK + + + MNZ070 + 230700 + Dakota + MN + US + 44.71 + -93.03 + 0 + 0 + MPX + + + MOZ007 + 250070 + Putnam + MO + US + 40.46 + -93.02 + 0 + 0 + EAX + + + MOZ080 + 250800 + Dallas + MO + US + 37.66 + -93.02 + 0 + 0 + SGF + + + IAZ049 + 150490 + Marshall + IA + US + 42.04 + -93.01 + 0 + 0 + DMX + + + MOZ032 + 250320 + Chariton + MO + US + 39.46 + -92.99 + 0 + 0 + EAX + + + LAZ004 + 180040 + Claiborne + LA + US + 32.80 + -92.97 + 0 + 0 + SHV + + + ARZ039 + 40390 + Perry + AR + US + 34.94 + -92.92 + 0 + 0 + LZK + + + MNZ053 + 230530 + Chisago + MN + US + 45.52 + -92.89 + 0 + 0 + MPX + + + MNZ063 + 230630 + Washington + MN + US + 45.02 + -92.88 + 0 + 0 + MPX + + + MOZ091 + 250910 + Webster + MO + US + 37.28 + -92.88 + 0 + 0 + SGF + + + IAZ085 + 150850 + Monroe + IA + US + 41.03 + -92.87 + 0 + 0 + DMX + + + IAZ096 + 150960 + Appanoose + IA + US + 40.74 + -92.87 + 0 + 0 + DMX + + + MNZ086 + 230860 + Dodge + MN + US + 44.02 + -92.87 + 0 + 0 + ARX + + + LAZ031 + 180310 + Allen + LA + US + 30.66 + -92.85 + 0 + 0 + LCH + + + LAZ042 + 180420 + Jefferson_Davis + LA + US + 30.27 + -92.85 + 0 + 0 + LCH + + + MOZ056 + 250560 + Morgan + MO + US + 38.44 + -92.85 + 0 + 0 + SGF + + + ARZ066 + 40660 + Ouachita + AR + US + 33.60 + -92.83 + 0 + 0 + LZK + + + IAZ008 + 150080 + Mitchell + IA + US + 43.36 + -92.79 + 0 + 0 + ARX + + + IAZ018 + 150180 + Floyd + IA + US + 43.06 + -92.79 + 0 + 0 + ARX + + + IAZ027 + 150270 + Butler + IA + US + 42.73 + -92.79 + 0 + 0 + DMX + + + IAZ038 + 150380 + Grundy + IA + US + 42.38 + -92.79 + 0 + 0 + DMX + + + MOZ046 + 250460 + Cooper + MO + US + 38.87 + -92.78 + 0 + 0 + EAX + + + ARZ031 + 40310 + Conway + AR + US + 35.27 + -92.76 + 0 + 0 + LZK + + + MNZ094 + 230940 + Mower + MN + US + 43.67 + -92.75 + 0 + 0 + ARX + + + MOZ069 + 250690 + Camden + MO + US + 38.03 + -92.74 + 0 + 0 + SGF + + + MNZ038 + 230380 + Pine + MN + US + 46.07 + -92.71 + 0 + 0 + DLH + + + MOZ040 + 250400 + Howard + MO + US + 39.16 + -92.69 + 0 + 0 + EAX + + + ARZ013 + 40130 + Searcy + AR + US + 35.92 + -92.68 + 0 + 0 + LZK + + + ARZ004 + 40040 + Marion + AR + US + 36.28 + -92.65 + 0 + 0 + LZK + + + ARZ043 + 40430 + Saline + AR + US + 34.64 + -92.65 + 0 + 0 + LZK + + + ARZ062 + 40620 + Dallas + AR + US + 33.98 + -92.65 + 0 + 0 + LZK + + + IAZ075 + 150750 + Mahaska + IA + US + 41.34 + -92.65 + 0 + 0 + DMX + + + MNZ078 + 230780 + Goodhue + MN + US + 44.45 + -92.65 + 0 + 0 + MPX + + + LAZ005 + 180050 + Lincoln + LA + US + 32.61 + -92.64 + 0 + 0 + SHV + + + LAZ019 + 180190 + Winn + LA + US + 31.93 + -92.64 + 0 + 0 + SHV + + + MOZ047 + 250470 + Moniteau + MO + US + 38.67 + -92.62 + 0 + 0 + LSX + + + MOZ017 + 250170 + Adair + MO + US + 40.19 + -92.61 + 0 + 0 + EAX + + + LAZ020 + 180200 + Grant + LA + US + 31.60 + -92.58 + 0 + 0 + SHV + + + MOZ025 + 250250 + Macon + MO + US + 39.82 + -92.57 + 0 + 0 + EAX + + + LAZ013 + 180130 + Jackson + LA + US + 32.33 + -92.56 + 0 + 0 + SHV + + + MOZ081 + 250810 + Laclede + MO + US + 37.69 + -92.56 + 0 + 0 + SGF + + + ARZ023 + 40230 + Van_Buren + AR + US + 35.58 + -92.54 + 0 + 0 + LZK + + + ARZ067 + 40670 + Calhoun + AR + US + 33.54 + -92.54 + 0 + 0 + LZK + + + IAZ050 + 150500 + Tama + IA + US + 42.08 + -92.54 + 0 + 0 + DMX + + + IAZ062 + 150620 + Poweshiek + IA + US + 41.69 + -92.54 + 0 + 0 + DMX + + + MOZ008 + 250080 + Schuyler + MO + US + 40.47 + -92.54 + 0 + 0 + EAX + + + ARZ073 + 40730 + Union + AR + US + 33.20 + -92.52 + 0 + 0 + SHV + + + LAZ028 + 180280 + Rapides + LA + US + 31.21 + -92.52 + 0 + 0 + LCH + + + WIZ014 + 490140 + Polk + WI + US + 45.47 + -92.52 + 0 + 0 + MPX + + + MOZ033 + 250330 + Randolph + MO + US + 39.43 + -92.51 + 0 + 0 + EAX + + + MOZ096 + 250960 + Douglas + MO + US + 36.93 + -92.50 + 0 + 0 + SGF + + + MOZ092 + 250920 + Wright + MO + US + 37.27 + -92.47 + 0 + 0 + SGF + + + WIZ023 + 490230 + St._Croix + WI + US + 45.04 + -92.47 + 0 + 0 + MPX + + + WIZ024 + 490240 + Pierce + WI + US + 44.70 + -92.47 + 0 + 0 + MPX + + + WIZ006 + 490060 + Burnett + WI + US + 45.90 + -92.46 + 0 + 0 + DLH + + + MOZ105 + 251050 + Ozark + MO + US + 36.65 + -92.45 + 0 + 0 + SGF + + + ARZ055 + 40550 + Grant + AR + US + 34.28 + -92.44 + 0 + 0 + LZK + + + MNZ011 + 230110 + North_St._Louis + MN + US + 48.24 + -92.44 + 0 + 0 + DLH + + + MNZ019 + 230190 + Central_St._Louis + MN + US + 47.43 + -92.44 + 0 + 0 + DLH + + + MOZ057 + 250570 + Miller + MO + US + 38.22 + -92.44 + 0 + 0 + SGF + + + MNZ037 + 230370 + Carlton/South_St._Louis + MN + US + 46.72 + -92.43 + 0 + 0 + DLH + + + IAZ097 + 150970 + Davis + IA + US + 40.75 + -92.42 + 0 + 0 + DMX + + + IAZ086 + 150860 + Wapello + IA + US + 41.03 + -92.41 + 0 + 0 + DMX + + + ARZ044 + 40440 + Pulaski + AR + US + 34.76 + -92.39 + 0 + 0 + LZK + + + LAZ032 + 180320 + Evangeline + LA + US + 30.74 + -92.39 + 0 + 0 + LCH + + + MNZ087 + 230870 + Olmsted + MN + US + 44.01 + -92.39 + 0 + 0 + ARX + + + LAZ006 + 180060 + Union + LA + US + 32.80 + -92.38 + 0 + 0 + SHV + + + LAZ043 + 180430 + Acadia + LA + US + 30.28 + -92.38 + 0 + 0 + LCH + + + ARZ005 + 40050 + Baxter + AR + US + 36.24 + -92.37 + 0 + 0 + LZK + + + ARZ032 + 40320 + Faulkner + AR + US + 35.12 + -92.36 + 0 + 0 + LZK + + + LAZ052 + 180520 + Vermilion + LA + US + 29.85 + -92.34 + 0 + 0 + LCH + + + MOZ041 + 250410 + Boone + MO + US + 38.94 + -92.34 + 0 + 0 + LSX + + + IAZ009 + 150090 + Howard + IA + US + 43.36 + -92.32 + 0 + 0 + ARX + + + IAZ019 + 150190 + Chickasaw + IA + US + 43.07 + -92.32 + 0 + 0 + ARX + + + IAZ028 + 150280 + Bremer + IA + US + 42.78 + -92.32 + 0 + 0 + DMX + + + IAZ039 + 150390 + Black_Hawk + IA + US + 42.47 + -92.31 + 0 + 0 + DMX + + + MOZ048 + 250480 + Cole + MO + US + 38.53 + -92.22 + 0 + 0 + LSX + + + MOZ070 + 250700 + Pulaski + MO + US + 37.81 + -92.22 + 0 + 0 + SGF + + + ARZ063 + 40630 + Cleveland + AR + US + 33.89 + -92.20 + 0 + 0 + LZK + + + MNZ079 + 230790 + Wabasha + MN + US + 44.28 + -92.20 + 0 + 0 + ARX + + + LAZ022 + 180220 + La_Salle + LA + US + 31.63 + -92.19 + 0 + 0 + SHV + + + IAZ076 + 150760 + Keokuk + IA + US + 41.33 + -92.18 + 0 + 0 + DVN + + + ARZ068 + 40680 + Bradley + AR + US + 33.44 + -92.16 + 0 + 0 + LZK + + + LAZ014 + 180140 + Ouachita + LA + US + 32.50 + -92.16 + 0 + 0 + SHV + + + MOZ009 + 250090 + Scotland + MO + US + 40.46 + -92.15 + 0 + 0 + DVN + + + MOZ018 + 250180 + Knox + MO + US + 40.13 + -92.15 + 0 + 0 + LSX + + + ARZ014 + 40140 + Stone + AR + US + 35.91 + -92.12 + 0 + 0 + LZK + + + LAZ021 + 180210 + Caldwell + LA + US + 32.11 + -92.09 + 0 + 0 + SHV + + + LAZ044 + 180440 + Lafayette + LA + US + 30.22 + -92.09 + 0 + 0 + LCH + + + MNZ095 + 230950 + Fillmore + MN + US + 43.67 + -92.09 + 0 + 0 + ARX + + + WIZ026 + 490260 + Pepin + WI + US + 44.55 + -92.09 + 0 + 0 + MPX + + + LAZ033 + 180330 + St._Landry + LA + US + 30.58 + -92.08 + 0 + 0 + LCH + + + IAZ051 + 150510 + Benton + IA + US + 42.08 + -92.07 + 0 + 0 + DVN + + + MOZ026 + 250260 + Shelby + MO + US + 39.78 + -92.07 + 0 + 0 + LSX + + + IAZ063 + 150630 + Iowa + IA + US + 41.68 + -92.06 + 0 + 0 + DVN + + + ARZ024 + 40240 + Cleburne + AR + US + 35.54 + -92.02 + 0 + 0 + LZK + + + MOZ034 + 250340 + Monroe + MO + US + 39.50 + -92.01 + 0 + 0 + LSX + + + LAZ029 + 180290 + Avoyelles + LA + US + 31.10 + -91.97 + 0 + 0 + LCH + + + MOZ082 + 250820 + Texas + MO + US + 37.33 + -91.96 + 0 + 0 + SGF + + + IAZ087 + 150870 + Jefferson + IA + US + 41.03 + -91.95 + 0 + 0 + DVN + + + IAZ098 + 150980 + Van_Buren + IA + US + 40.75 + -91.95 + 0 + 0 + DVN + + + ARZ015 + 40150 + Izard + AR + US + 36.06 + -91.94 + 0 + 0 + LZK + + + MOZ050 + 250500 + Callaway + MO + US + 38.81 + -91.93 + 0 + 0 + LSX + + + MOZ049 + 250490 + Osage + MO + US + 38.50 + -91.92 + 0 + 0 + LSX + + + MOZ058 + 250580 + Maries + MO + US + 38.15 + -91.92 + 0 + 0 + SGF + + + WIZ001 + 490010 + Douglas + WI + US + 46.46 + -91.92 + 0 + 0 + DLH + + + LAZ024 + 180240 + Catahoula + LA + US + 31.60 + -91.91 + 0 + 0 + JAN + + + WIZ025 + 490250 + Dunn + WI + US + 44.95 + -91.91 + 0 + 0 + MPX + + + MOZ097 + 250970 + Howell + MO + US + 36.78 + -91.90 + 0 + 0 + SGF + + + ARZ045 + 40450 + Lonoke + AR + US + 34.78 + -91.88 + 0 + 0 + LZK + + + MOZ042 + 250420 + Audrain + MO + US + 39.21 + -91.87 + 0 + 0 + LSX + + + IAZ010 + 150100 + Winneshiek + IA + US + 43.29 + -91.85 + 0 + 0 + ARX + + + IAZ029 + 150290 + Fayette + IA + US + 42.86 + -91.85 + 0 + 0 + ARX + + + WIZ015 + 490150 + Barron + WI + US + 45.43 + -91.85 + 0 + 0 + MPX + + + IAZ040 + 150400 + Buchanan + IA + US + 42.47 + -91.84 + 0 + 0 + DVN + + + ARZ056 + 40560 + Jefferson + AR + US + 34.28 + -91.83 + 0 + 0 + LZK + + + LAZ053 + 180530 + Iberia + LA + US + 29.93 + -91.81 + 0 + 0 + LCH + + + WIZ032 + 490320 + Buffalo + WI + US + 44.32 + -91.81 + 0 + 0 + ARX + + + ARZ006 + 40060 + Fulton + AR + US + 36.38 + -91.80 + 0 + 0 + LZK + + + ARZ074 + 40740 + Ashley + AR + US + 33.20 + -91.79 + 0 + 0 + JAN + + + WIZ007 + 490070 + Washburn + WI + US + 45.90 + -91.79 + 0 + 0 + DLH + + + MOZ071 + 250710 + Phelps + MO + US + 37.88 + -91.78 + 0 + 0 + SGF + + + LAZ007 + 180070 + Morehouse + LA + US + 32.77 + -91.75 + 0 + 0 + JAN + + + ARZ033 + 40330 + White + AR + US + 35.28 + -91.73 + 0 + 0 + LZK + + + LAZ015 + 180150 + Richland + LA + US + 32.42 + -91.73 + 0 + 0 + JAN + + + ARZ069 + 40690 + Drew + AR + US + 33.59 + -91.72 + 0 + 0 + LZK + + + IAZ077 + 150770 + Washington + IA + US + 41.34 + -91.71 + 0 + 0 + DVN + + + MOZ010 + 250100 + Clark + MO + US + 40.43 + -91.70 + 0 + 0 + DVN + + + MOZ019 + 250190 + Lewis + MO + US + 40.10 + -91.70 + 0 + 0 + LSX + + + ARZ064 + 40640 + Lincoln + AR + US + 33.98 + -91.69 + 0 + 0 + LZK + + + MNZ088 + 230880 + Winona + MN + US + 44.02 + -91.69 + 0 + 0 + ARX + + + LAZ023 + 180230 + Franklin + LA + US + 32.14 + -91.68 + 0 + 0 + JAN + + + LAZ034 + 180340 + Pointe_Coupee + LA + US + 30.76 + -91.67 + 0 + 0 + LIX + + + LAZ045 + 180450 + Upper_St._Martin + LA + US + 30.27 + -91.67 + 0 + 0 + LCH + + + LAZ026 + 180260 + Concordia + LA + US + 31.37 + -91.61 + 0 + 0 + JAN + + + IAZ052 + 150520 + Linn + IA + US + 42.07 + -91.60 + 0 + 0 + DVN + + + IAZ064 + 150640 + Johnson + IA + US + 41.64 + -91.60 + 0 + 0 + DVN + + + MOZ027 + 250270 + Marion + MO + US + 39.80 + -91.58 + 0 + 0 + LSX + + + ARZ046 + 40460 + Prairie + AR + US + 34.79 + -91.57 + 0 + 0 + LZK + + + ARZ016 + 40160 + Independence + AR + US + 35.73 + -91.54 + 0 + 0 + LZK + + + IAZ088 + 150880 + Henry + IA + US + 40.99 + -91.54 + 0 + 0 + DVN + + + MNZ020 + 230200 + Southern_Lake/North_Shore + MN + US + 47.31 + -91.51 + 0 + 0 + DLH + + + MOZ059 + 250590 + Gasconade + MO + US + 38.44 + -91.51 + 0 + 0 + LSX + + + ARZ007 + 40070 + Sharp + AR + US + 36.19 + -91.49 + 0 + 0 + LZK + + + MOZ083 + 250830 + Dent + MO + US + 37.60 + -91.49 + 0 + 0 + SGF + + + MNZ096 + 230960 + Houston + MN + US + 43.67 + -91.48 + 0 + 0 + ARX + + + LAZ054 + 180540 + St._Mary + LA + US + 29.72 + -91.47 + 0 + 0 + LCH + + + LAZ035 + 180350 + West_Feliciana + LA + US + 30.86 + -91.46 + 0 + 0 + LIX + + + MOZ035 + 250350 + Ralls + MO + US + 39.50 + -91.46 + 0 + 0 + LSX + + + MOZ051 + 250510 + Montgomery + MO + US + 38.91 + -91.46 + 0 + 0 + LSX + + + LAZ008 + 180080 + West_Carroll + LA + US + 32.80 + -91.44 + 0 + 0 + JAN + + + IAZ099 + 150990 + Lee + IA + US + 40.59 + -91.42 + 0 + 0 + DVN + + + MNZ012 + 230120 + Northern_Cook/Northern_Lake + MN + US + 47.70 + -91.41 + 0 + 0 + DLH + + + MOZ106 + 251060 + Oregon + MO + US + 36.69 + -91.40 + 0 + 0 + SGF + + + MSZ060 + 240600 + Adams + MS + US + 31.49 + -91.40 + 0 + 0 + JAN + + + WIZ033 + 490330 + Trempealeau + WI + US + 44.29 + -91.38 + 0 + 0 + ARX + + + ARZ057 + 40570 + Arkansas + AR + US + 34.25 + -91.37 + 0 + 0 + LZK + + + IAZ041 + 150410 + Delaware + IA + US + 42.47 + -91.37 + 0 + 0 + DVN + + + LAZ046 + 180460 + Iberville + LA + US + 30.27 + -91.35 + 0 + 0 + LIX + + + MOZ098 + 250980 + Shannon + MO + US + 37.15 + -91.35 + 0 + 0 + SGF + + + IAZ011 + 150110 + Allamakee + IA + US + 43.29 + -91.34 + 0 + 0 + ARX + + + MSZ068 + 240680 + Wilkinson + MS + US + 31.19 + -91.34 + 0 + 0 + LIX + + + MOZ072 + 250720 + Crawford + MO + US + 37.95 + -91.32 + 0 + 0 + LSX + + + ARZ025 + 40250 + Jackson + AR + US + 35.63 + -91.31 + 0 + 0 + LZK + + + LAZ047 + 180470 + West_Baton_Rouge + LA + US + 30.49 + -91.31 + 0 + 0 + LIX + + + LAZ025 + 180250 + Tensas + LA + US + 32.00 + -91.30 + 0 + 0 + JAN + + + WIZ027 + 490270 + Chippewa + WI + US + 45.07 + -91.29 + 0 + 0 + MPX + + + WIZ028 + 490280 + Eau_Claire + WI + US + 44.73 + -91.29 + 0 + 0 + MPX + + + LAZ055 + 180550 + Lower_St._Martin + LA + US + 29.85 + -91.28 + 0 + 0 + LCH + + + ARZ034 + 40340 + Woodruff + AR + US + 35.18 + -91.26 + 0 + 0 + LZK + + + ARZ075 + 40750 + Chicot + AR + US + 33.29 + -91.25 + 0 + 0 + JAN + + + IAZ030 + 150300 + Clayton + IA + US + 42.86 + -91.25 + 0 + 0 + ARX + + + LAZ009 + 180090 + East_Carroll + LA + US + 32.78 + -91.23 + 0 + 0 + JAN + + + IAZ078 + 150780 + Louisa + IA + US + 41.25 + -91.22 + 0 + 0 + DVN + + + ILZ095 + 130950 + Adams + IL + US + 39.98 + -91.22 + 0 + 0 + LSX + + + ARZ047 + 40470 + Monroe + AR + US + 34.67 + -91.21 + 0 + 0 + LZK + + + ARZ065 + 40650 + Desha + AR + US + 33.82 + -91.21 + 0 + 0 + LZK + + + ILZ034 + 130340 + Hancock + IL + US + 40.42 + -91.21 + 0 + 0 + DVN + + + LAZ016 + 180160 + Madison + LA + US + 32.35 + -91.21 + 0 + 0 + JAN + + + MOZ060 + 250600 + Warren + MO + US + 38.77 + -91.19 + 0 + 0 + LSX + + + IAZ089 + 150890 + Des_Moines + IA + US + 40.89 + -91.18 + 0 + 0 + DVN + + + WIZ041 + 490410 + La_Crosse + WI + US + 43.91 + -91.17 + 0 + 0 + ARX + + + WIZ002 + 490020 + Bayfield + WI + US + 46.58 + -91.15 + 0 + 0 + DLH + + + IAZ065 + 150650 + Cedar + IA + US + 41.77 + -91.14 + 0 + 0 + DVN + + + IAZ053 + 150530 + Jones + IA + US + 42.12 + -91.13 + 0 + 0 + DVN + + + WIZ008 + 490080 + Sawyer + WI + US + 45.90 + -91.12 + 0 + 0 + DLH + + + WIZ016 + 490160 + Rusk + WI + US + 45.47 + -91.11 + 0 + 0 + MPX + + + MOZ036 + 250360 + Pike + MO + US + 39.37 + -91.10 + 0 + 0 + LSX + + + ARZ008 + 40080 + Randolph + AR + US + 36.32 + -91.08 + 0 + 0 + MEG + + + IAZ067 + 150670 + Muscatine + IA + US + 41.47 + -91.08 + 0 + 0 + DVN + + + LAZ048 + 180480 + East_Baton_Rouge + LA + US + 30.52 + -91.08 + 0 + 0 + LIX + + + LAZ036 + 180360 + East_Feliciana + LA + US + 30.83 + -91.07 + 0 + 0 + LIX + + + LAZ056 + 180560 + Assumption + LA + US + 29.86 + -91.07 + 0 + 0 + LIX + + + MOZ062 + 250620 + Franklin + MO + US + 38.45 + -91.06 + 0 + 0 + LSX + + + ARZ017 + 40170 + Lawrence + AR + US + 36.07 + -91.05 + 0 + 0 + MEG + + + MSZ059 + 240590 + Jefferson + MS + US + 31.75 + -91.05 + 0 + 0 + JAN + + + MOZ099 + 250990 + Reynolds + MO + US + 37.33 + -91.03 + 0 + 0 + LSX + + + MSZ040 + 240400 + Issaquena + MS + US + 32.73 + -91.01 + 0 + 0 + JAN + + + ILZ025 + 130250 + Henderson + IL + US + 40.85 + -91.00 + 0 + 0 + DVN + + + MSZ053 + 240530 + Claiborne + MS + US + 32.01 + -90.98 + 0 + 0 + JAN + + + ILZ097 + 130970 + Pike + IL + US + 39.62 + -90.97 + 0 + 0 + LSX + + + MOZ052 + 250520 + Lincoln + MO + US + 39.05 + -90.97 + 0 + 0 + LSX + + + MOZ107 + 251070 + Carter + MO + US + 36.96 + -90.95 + 0 + 0 + PAH + + + MSZ034 + 240340 + Washington + MS + US + 33.28 + -90.95 + 0 + 0 + JAN + + + MSZ018 + 240180 + Bolivar + MS + US + 33.83 + -90.94 + 0 + 0 + JAN + + + WIZ054 + 490540 + Crawford + WI + US + 43.21 + -90.94 + 0 + 0 + ARX + + + MSZ061 + 240610 + Franklin + MS + US + 31.47 + -90.89 + 0 + 0 + JAN + + + LAZ049 + 180490 + Ascension + LA + US + 30.21 + -90.87 + 0 + 0 + LIX + + + MOZ073 + 250730 + Washington + MO + US + 37.97 + -90.87 + 0 + 0 + LSX + + + LAZ066 + 180660 + Lower_Terrebonne + LA + US + 29.34 + -90.86 + 0 + 0 + LIX + + + MOZ108 + 251080 + Ripley + MO + US + 36.66 + -90.86 + 0 + 0 + PAH + + + MSZ047 + 240470 + Warren + MS + US + 32.34 + -90.86 + 0 + 0 + JAN + + + ARZ058 + 40580 + Phillips + AR + US + 34.39 + -90.82 + 0 + 0 + MEG + + + IAZ042 + 150420 + Dubuque + IA + US + 42.49 + -90.82 + 0 + 0 + DVN + + + LAZ065 + 180650 + Upper_Terrebonne + LA + US + 29.67 + -90.82 + 0 + 0 + LIX + + + MSZ069 + 240690 + Amite + MS + US + 31.18 + -90.82 + 0 + 0 + LIX + + + MSZ041 + 240410 + Sharkey + MS + US + 32.89 + -90.81 + 0 + 0 + JAN + + + LAZ057 + 180570 + St._James + LA + US + 30.03 + -90.80 + 0 + 0 + LIX + + + WIZ053 + 490530 + Vernon + WI + US + 43.58 + -90.79 + 0 + 0 + ARX + + + WIZ061 + 490610 + Grant + WI + US + 42.86 + -90.79 + 0 + 0 + ARX + + + ARZ035 + 40350 + Cross + AR + US + 35.30 + -90.77 + 0 + 0 + MEG + + + ARZ048 + 40480 + St._Francis + AR + US + 35.01 + -90.77 + 0 + 0 + MEG + + + ILZ024 + 130240 + Mercer + IL + US + 41.20 + -90.77 + 0 + 0 + DVN + + + ARZ049 + 40490 + Lee + AR + US + 34.77 + -90.75 + 0 + 0 + MEG + + + WIZ034 + 490340 + Jackson + WI + US + 44.33 + -90.74 + 0 + 0 + ARX + + + LAZ037 + 180370 + St._Helena + LA + US + 30.83 + -90.73 + 0 + 0 + LIX + + + ILZ096 + 130960 + Brown + IL + US + 39.98 + -90.72 + 0 + 0 + LSX + + + LAZ050 + 180500 + Livingston + LA + US + 30.42 + -90.72 + 0 + 0 + LIX + + + ILZ098 + 130980 + Calhoun + IL + US + 39.14 + -90.71 + 0 + 0 + LSX + + + ILZ035 + 130350 + McDonough + IL + US + 40.46 + -90.68 + 0 + 0 + DVN + + + MOZ084 + 250840 + Iron + MO + US + 37.51 + -90.67 + 0 + 0 + LSX + + + MSZ010 + 240100 + Coahoma + MS + US + 34.26 + -90.67 + 0 + 0 + MEG + + + ARZ026 + 40260 + Craighead + AR + US + 35.85 + -90.66 + 0 + 0 + MEG + + + ARZ027 + 40270 + Poinsett + AR + US + 35.58 + -90.66 + 0 + 0 + MEG + + + WIZ042 + 490420 + Monroe + WI + US + 43.94 + -90.64 + 0 + 0 + ARX + + + ILZ026 + 130260 + Warren + IL + US + 40.85 + -90.62 + 0 + 0 + DVN + + + MNZ021 + 230210 + Southern_Cook/North_Shore + MN + US + 47.75 + -90.62 + 0 + 0 + DLH + + + WIZ003 + 490030 + Ashland + WI + US + 46.53 + -90.62 + 0 + 0 + DLH + + + WIZ029 + 490290 + Clark + WI + US + 44.73 + -90.62 + 0 + 0 + ARX + + + IAZ068 + 150680 + Scott + IA + US + 41.61 + -90.61 + 0 + 0 + DVN + + + MSZ019 + 240190 + Sunflower + MS + US + 33.63 + -90.61 + 0 + 0 + JAN + + + ILZ040 + 130400 + Schuyler + IL + US + 40.13 + -90.57 + 0 + 0 + ILX + + + LAZ059 + 180590 + Upper_Lafourche + LA + US + 29.74 + -90.57 + 0 + 0 + LIX + + + MOZ061 + 250610 + St._Charles + MO + US + 38.75 + -90.54 + 0 + 0 + LSX + + + MOZ074 + 250740 + St._Francois + MO + US + 37.86 + -90.54 + 0 + 0 + LSX + + + MSZ035 + 240350 + Humphreys + MS + US + 33.13 + -90.53 + 0 + 0 + JAN + + + IAZ054 + 150540 + Jackson + IA + US + 42.21 + -90.52 + 0 + 0 + DVN + + + IAZ066 + 150660 + Clinton + IA + US + 41.88 + -90.52 + 0 + 0 + DVN + + + MOZ065 + 250650 + Jefferson + MO + US + 38.25 + -90.52 + 0 + 0 + LSX + + + ARZ018 + 40180 + Greene + AR + US + 36.12 + -90.51 + 0 + 0 + MEG + + + LAZ058 + 180580 + St._John_The_Baptist + LA + US + 30.09 + -90.50 + 0 + 0 + LIX + + + MSZ062 + 240620 + Lincoln + MS + US + 31.54 + -90.49 + 0 + 0 + JAN + + + WIZ017 + 490170 + Taylor + WI + US + 45.21 + -90.48 + 0 + 0 + ARX + + + ILZ049 + 130490 + Scott + IL + US + 39.66 + -90.47 + 0 + 0 + ILX + + + MOZ100 + 251000 + Wayne + MO + US + 37.12 + -90.45 + 0 + 0 + PAH + + + ARZ009 + 40090 + Clay + AR + US + 36.35 + -90.43 + 0 + 0 + MEG + + + MOZ063 + 250630 + St._Louis + MO + US + 38.64 + -90.43 + 0 + 0 + LSX + + + WIZ055 + 490550 + Richland + WI + US + 43.36 + -90.43 + 0 + 0 + ARX + + + MSZ054 + 240540 + Copiah + MS + US + 31.87 + -90.42 + 0 + 0 + JAN + + + MOZ109 + 251090 + Butler + MO + US + 36.71 + -90.41 + 0 + 0 + PAH + + + LAZ038 + 180380 + Tangipahoa + LA + US + 30.65 + -90.40 + 0 + 0 + LIX + + + MSZ070 + 240700 + Pike + MS + US + 31.18 + -90.40 + 0 + 0 + LIX + + + ILZ058 + 130580 + Greene + IL + US + 39.32 + -90.39 + 0 + 0 + LSX + + + MSZ007 + 240070 + Tunica + MS + US + 34.66 + -90.39 + 0 + 0 + MEG + + + MSZ048 + 240480 + Hinds + MS + US + 32.31 + -90.39 + 0 + 0 + JAN + + + ILZ099 + 130990 + Jersey + IL + US + 39.09 + -90.38 + 0 + 0 + LSX + + + MSZ042 + 240420 + Yazoo + MS + US + 32.77 + -90.36 + 0 + 0 + JAN + + + WIZ009 + 490090 + Price + WI + US + 45.68 + -90.36 + 0 + 0 + DLH + + + MOZ085 + 250850 + Madison + MO + US + 37.48 + -90.35 + 0 + 0 + LSX + + + LAZ060 + 180600 + St._Charles + LA + US + 29.89 + -90.34 + 0 + 0 + LIX + + + ILZ015 + 130150 + Rock_Island + IL + US + 41.56 + -90.31 + 0 + 0 + DVN + + + ILZ001 + 130010 + Jo_Daviess + IL + US + 42.35 + -90.29 + 0 + 0 + DVN + + + ILZ047 + 130470 + Cass + IL + US + 40.00 + -90.29 + 0 + 0 + ILX + + + LAZ067 + 180670 + Lower_Lafourche + LA + US + 29.31 + -90.29 + 0 + 0 + LIX + + + MSZ011 + 240110 + Quitman + MS + US + 34.30 + -90.29 + 0 + 0 + MEG + + + ARZ036 + 40360 + Crittenden + AR + US + 35.14 + -90.28 + 0 + 0 + MEG + + + ILZ050 + 130500 + Morgan + IL + US + 39.70 + -90.27 + 0 + 0 + ILX + + + MSZ025 + 240250 + Leflore + MS + US + 33.53 + -90.27 + 0 + 0 + JAN + + + MOZ064 + 250640 + St._Louis_City + MO + US + 38.65 + -90.24 + 0 + 0 + LSX + + + WIZ004 + 490040 + Iron + WI + US + 46.29 + -90.23 + 0 + 0 + DLH + + + ILZ027 + 130270 + Knox + IL + US + 40.93 + -90.22 + 0 + 0 + ILX + + + MOZ075 + 250750 + Ste._Genevieve + MO + US + 37.90 + -90.20 + 0 + 0 + LSX + + + MSZ020 + 240200 + Tallahatchie + MS + US + 33.93 + -90.19 + 0 + 0 + MEG + + + ILZ036 + 130360 + Fulton + IL + US + 40.45 + -90.16 + 0 + 0 + ILX + + + ILZ016 + 130160 + Henry + IL + US + 41.37 + -90.15 + 0 + 0 + DVN + + + ILZ102 + 131020 + Monroe + IL + US + 38.30 + -90.14 + 0 + 0 + LSX + + + LAZ061 + 180610 + Upper_Jefferson + LA + US + 29.81 + -90.14 + 0 + 0 + LIX + + + WIZ062 + 490620 + Iowa + WI + US + 43.01 + -90.13 + 0 + 0 + MKX + + + WIZ067 + 490670 + Lafayette + WI + US + 42.66 + -90.13 + 0 + 0 + MKX + + + MSZ063 + 240630 + Lawrence + MS + US + 31.55 + -90.10 + 0 + 0 + JAN + + + MSZ036 + 240360 + Holmes + MS + US + 33.13 + -90.09 + 0 + 0 + JAN + + + MSZ043 + 240430 + Madison + MS + US + 32.65 + -90.08 + 0 + 0 + JAN + + + LAZ068 + 180680 + Lower_Jefferson + LA + US + 29.56 + -90.07 + 0 + 0 + LIX + + + MSZ071 + 240710 + Walthall + MS + US + 31.18 + -90.05 + 0 + 0 + LIX + + + WIZ043 + 490430 + Juneau + WI + US + 43.95 + -90.05 + 0 + 0 + ARX + + + MOZ086 + 250860 + Bollinger + MO + US + 37.32 + -90.04 + 0 + 0 + PAH + + + LAZ039 + 180390 + Washington + LA + US + 30.84 + -90.03 + 0 + 0 + LIX + + + WIZ035 + 490350 + Wood + WI + US + 44.47 + -90.02 + 0 + 0 + GRB + + + ILZ007 + 130070 + Carroll + IL + US + 42.06 + -90.01 + 0 + 0 + DVN + + + MOZ113 + 251130 + Dunklin + MO + US + 36.31 + -90.01 + 0 + 0 + MEG + + + MSZ001 + 240010 + De_Soto + MS + US + 34.86 + -90.01 + 0 + 0 + MEG + + + ILZ101 + 131010 + St._Clair + IL + US + 38.44 + -89.99 + 0 + 0 + LSX + + + ILZ041 + 130410 + Mason + IL + US + 40.25 + -89.98 + 0 + 0 + ILX + + + MOZ110 + 251100 + Stoddard + MO + US + 36.88 + -89.98 + 0 + 0 + PAH + + + MSZ049 + 240490 + Rankin + MS + US + 32.33 + -89.98 + 0 + 0 + JAN + + + TNZ088 + 420880 + Shelby + TN + US + 35.21 + -89.97 + 0 + 0 + MEG + + + ARZ028 + 40280 + Mississippi + AR + US + 35.71 + -89.96 + 0 + 0 + MEG + + + LAZ063 + 180630 + Upper_Plaquemines + LA + US + 29.77 + -89.96 + 0 + 0 + LIX + + + MSZ012 + 240120 + Panola + MS + US + 34.36 + -89.96 + 0 + 0 + MEG + + + WIZ056 + 490560 + Sauk + WI + US + 43.40 + -89.96 + 0 + 0 + MKX + + + ILZ009 + 130090 + Whiteside + IL + US + 41.76 + -89.95 + 0 + 0 + DVN + + + MSZ008 + 240080 + Tate + MS + US + 34.67 + -89.95 + 0 + 0 + MEG + + + ILZ100 + 131000 + Madison + IL + US + 38.83 + -89.94 + 0 + 0 + LSX + + + MSZ055 + 240550 + Simpson + MS + US + 31.91 + -89.94 + 0 + 0 + JAN + + + ILZ059 + 130590 + Macoupin + IL + US + 39.26 + -89.93 + 0 + 0 + LSX + + + MSZ027 + 240270 + Carroll + MS + US + 33.45 + -89.91 + 0 + 0 + JAN + + + ILZ079 + 130790 + Randolph + IL + US + 38.01 + -89.90 + 0 + 0 + LSX + + + LAZ040 + 180400 + St._Tammany + LA + US + 30.44 + -89.89 + 0 + 0 + LIX + + + LAZ062 + 180620 + Orleans + LA + US + 30.03 + -89.88 + 0 + 0 + LIX + + + LAZ064 + 180640 + Upper_St._Bernard + LA + US + 29.91 + -89.86 + 0 + 0 + LIX + + + MSZ072 + 240720 + Marion + MS + US + 31.22 + -89.85 + 0 + 0 + JAN + + + MOZ076 + 250760 + Perry + MO + US + 37.74 + -89.83 + 0 + 0 + PAH + + + ILZ028 + 130280 + Stark + IL + US + 41.11 + -89.82 + 0 + 0 + ILX + + + MSZ026 + 240260 + Grenada + MS + US + 33.79 + -89.82 + 0 + 0 + JAN + + + TNZ049 + 420490 + Tipton + TN + US + 35.51 + -89.82 + 0 + 0 + MEG + + + WIZ044 + 490440 + Adams + WI + US + 43.95 + -89.81 + 0 + 0 + ARX + + + ILZ048 + 130480 + Menard + IL + US + 40.04 + -89.79 + 0 + 0 + ILX + + + MSZ064 + 240640 + Jefferson_Davis + MS + US + 31.59 + -89.78 + 0 + 0 + JAN + + + WIZ030 + 490300 + Marathon + WI + US + 44.90 + -89.76 + 0 + 0 + GRB + + + MOZ115 + 251150 + Pemiscot + MO + US + 36.21 + -89.75 + 0 + 0 + MEG + + + WIZ018 + 490180 + Lincoln + WI + US + 45.34 + -89.73 + 0 + 0 + GRB + + + ILZ029 + 130290 + Peoria + IL + US + 40.75 + -89.72 + 0 + 0 + ILX + + + MSZ021 + 240210 + Yalobusha + MS + US + 34.03 + -89.72 + 0 + 0 + MEG + + + MIZ009 + 220090 + Gogebic + MI + US + 46.44 + -89.70 + 0 + 0 + MQT + + + ILZ002 + 130020 + Stephenson + IL + US + 42.35 + -89.66 + 0 + 0 + DVN + + + MOZ114 + 251140 + New_Madrid + MO + US + 36.61 + -89.66 + 0 + 0 + PAH + + + MOZ087 + 250870 + Cape_Girardeau + MO + US + 37.37 + -89.65 + 0 + 0 + PAH + + + TNZ048 + 420480 + Lauderdale + TN + US + 35.75 + -89.65 + 0 + 0 + MEG + + + MSZ037 + 240370 + Attala + MS + US + 33.09 + -89.64 + 0 + 0 + JAN + + + ILZ051 + 130510 + Sangamon + IL + US + 39.75 + -89.61 + 0 + 0 + ILX + + + ILZ037 + 130370 + Tazewell + IL + US + 40.54 + -89.60 + 0 + 0 + ILX + + + WIZ068 + 490680 + Green + WI + US + 42.68 + -89.60 + 0 + 0 + MKX + + + LAZ070 + 180700 + Lower_St._Bernard + LA + US + 29.85 + -89.59 + 0 + 0 + LIX + + + MSZ077 + 240770 + Pearl_River + MS + US + 30.74 + -89.59 + 0 + 0 + LIX + + + MSZ028 + 240280 + Montgomery + MS + US + 33.49 + -89.58 + 0 + 0 + JAN + + + MSZ065 + 240650 + Covington + MS + US + 31.62 + -89.57 + 0 + 0 + JAN + + + MOZ111 + 251110 + Scott + MO + US + 37.06 + -89.55 + 0 + 0 + PAH + + + MSZ050 + 240500 + Scott + MS + US + 32.43 + -89.55 + 0 + 0 + JAN + + + WIZ010 + 490100 + Oneida + WI + US + 45.68 + -89.54 + 0 + 0 + GRB + + + MSZ056 + 240560 + Smith + MS + US + 32.01 + -89.53 + 0 + 0 + JAN + + + WIZ036 + 490360 + Portage + WI + US + 44.46 + -89.53 + 0 + 0 + GRB + + + ILZ017 + 130170 + Bureau + IL + US + 41.37 + -89.52 + 0 + 0 + DVN + + + MSZ044 + 240440 + Leake + MS + US + 32.76 + -89.52 + 0 + 0 + JAN + + + TNZ001 + 420010 + Lake + TN + US + 36.34 + -89.52 + 0 + 0 + MEG + + + MSZ073 + 240730 + Lamar + MS + US + 31.21 + -89.50 + 0 + 0 + JAN + + + MSZ080 + 240800 + Hancock + MS + US + 30.42 + -89.50 + 0 + 0 + LIX + + + LAZ069 + 180690 + Lower_Plaquemines + LA + US + 29.37 + -89.48 + 0 + 0 + LIX + + + MSZ002 + 240020 + Marshall + MS + US + 34.75 + -89.48 + 0 + 0 + MEG + + + MSZ013 + 240130 + Lafayette + MS + US + 34.37 + -89.48 + 0 + 0 + MEG + + + WIZ005 + 490050 + Vilas + WI + US + 46.08 + -89.48 + 0 + 0 + GRB + + + ILZ064 + 130640 + Bond + IL + US + 38.88 + -89.45 + 0 + 0 + LSX + + + TNZ019 + 420190 + Dyer + TN + US + 36.05 + -89.44 + 0 + 0 + MEG + + + ILZ069 + 130690 + Clinton + IL + US + 38.58 + -89.43 + 0 + 0 + LSX + + + ILZ074 + 130740 + Washington + IL + US + 38.36 + -89.43 + 0 + 0 + LSX + + + ILZ060 + 130600 + Montgomery + IL + US + 39.26 + -89.42 + 0 + 0 + LSX + + + ILZ084 + 130840 + Jackson + IL + US + 37.76 + -89.42 + 0 + 0 + PAH + + + TNZ089 + 420890 + Fayette + TN + US + 35.20 + -89.42 + 0 + 0 + MEG + + + WIZ063 + 490630 + Dane + WI + US + 43.07 + -89.42 + 0 + 0 + MKX + + + WIZ057 + 490570 + Columbia + WI + US + 43.47 + -89.39 + 0 + 0 + MKX + + + ILZ042 + 130420 + Logan + IL + US + 40.12 + -89.38 + 0 + 0 + ILX + + + WIZ046 + 490460 + Marquette + WI + US + 43.81 + -89.38 + 0 + 0 + MKX + + + MIZ002 + 220020 + Ontonagon + MI + US + 46.68 + -89.37 + 0 + 0 + MQT + + + ILZ080 + 130800 + Perry + IL + US + 38.08 + -89.36 + 0 + 0 + PAH + + + ILZ030 + 130300 + Marshall + IL + US + 41.04 + -89.35 + 0 + 0 + ILX + + + ILZ008 + 130080 + Ogle + IL + US + 42.04 + -89.32 + 0 + 0 + LOT + + + ILZ018 + 130180 + Putnam + IL + US + 41.21 + -89.32 + 0 + 0 + DVN + + + ILZ092 + 130920 + Alexander + IL + US + 37.16 + -89.32 + 0 + 0 + PAH + + + MOZ112 + 251120 + Mississippi + MO + US + 36.83 + -89.32 + 0 + 0 + PAH + + + MSZ022 + 240220 + Calhoun + MS + US + 33.95 + -89.32 + 0 + 0 + MEG + + + ILZ010 + 130100 + Lee + IL + US + 41.75 + -89.29 + 0 + 0 + LOT + + + ILZ052 + 130520 + Christian + IL + US + 39.58 + -89.29 + 0 + 0 + ILX + + + ILZ088 + 130880 + Union + IL + US + 37.47 + -89.29 + 0 + 0 + PAH + + + MSZ074 + 240740 + Forrest + MS + US + 31.18 + -89.29 + 0 + 0 + JAN + + + TNZ050 + 420500 + Haywood + TN + US + 35.61 + -89.29 + 0 + 0 + MEG + + + MSZ032 + 240320 + Choctaw + MS + US + 33.33 + -89.27 + 0 + 0 + JAN + + + MSZ029 + 240290 + Webster + MS + US + 33.60 + -89.26 + 0 + 0 + JAN + + + ILZ031 + 130310 + Woodford + IL + US + 40.76 + -89.25 + 0 + 0 + ILX + + + WIZ045 + 490450 + Waushara + WI + US + 44.11 + -89.24 + 0 + 0 + GRB + + + KYZ001 + 170010 + Fulton + KY + US + 36.58 + -89.20 + 0 + 0 + PAH + + + ILZ003 + 130030 + Winnebago + IL + US + 42.32 + -89.17 + 0 + 0 + LOT + + + MSZ003 + 240030 + Benton + MS + US + 34.80 + -89.17 + 0 + 0 + MEG + + + MSZ066 + 240660 + Jones + MS + US + 31.63 + -89.16 + 0 + 0 + JAN + + + TNZ002 + 420020 + Obion + TN + US + 36.35 + -89.14 + 0 + 0 + MEG + + + TNZ051 + 420510 + Crockett + TN + US + 35.84 + -89.13 + 0 + 0 + MEG + + + MSZ051 + 240510 + Newton + MS + US + 32.41 + -89.12 + 0 + 0 + JAN + + + MSZ045 + 240450 + Neshoba + MS + US + 32.76 + -89.11 + 0 + 0 + JAN + + + MSZ057 + 240570 + Jasper + MS + US + 32.02 + -89.11 + 0 + 0 + JAN + + + ILZ093 + 130930 + Pulaski + IL + US + 37.20 + -89.10 + 0 + 0 + PAH + + + MSZ078 + 240780 + Stone + MS + US + 30.78 + -89.10 + 0 + 0 + MOB + + + WIZ069 + 490690 + Rock + WI + US + 42.67 + -89.07 + 0 + 0 + MKX + + + MSZ038 + 240380 + Winston + MS + US + 33.11 + -89.06 + 0 + 0 + JAN + + + MSZ081 + 240810 + Harrison + MS + US + 30.44 + -89.06 + 0 + 0 + LIX + + + WIZ047 + 490470 + Green_Lake + WI + US + 43.81 + -89.06 + 0 + 0 + MKX + + + MSZ015 + 240150 + Pontotoc + MS + US + 34.23 + -89.03 + 0 + 0 + MEG + + + WIZ019 + 490190 + Langlade + WI + US + 45.25 + -89.03 + 0 + 0 + GRB + + + KYZ002 + 170020 + Hickman + KY + US + 36.65 + -89.01 + 0 + 0 + PAH + + + KYZ003 + 170030 + Carlisle + KY + US + 36.87 + -89.00 + 0 + 0 + PAH + + + KYZ004 + 170040 + Ballard + KY + US + 37.07 + -89.00 + 0 + 0 + PAH + + + ILZ053 + 130530 + Macon + IL + US + 39.86 + -88.99 + 0 + 0 + ILX + + + TNZ090 + 420900 + Hardeman + TN + US + 35.22 + -88.99 + 0 + 0 + MEG + + + ILZ065 + 130650 + Fayette + IL + US + 38.98 + -88.98 + 0 + 0 + LSX + + + MSZ014 + 240140 + Union + MS + US + 34.49 + -88.98 + 0 + 0 + MEG + + + MSZ075 + 240750 + Perry + MS + US + 31.18 + -88.98 + 0 + 0 + MOB + + + MSZ023 + 240230 + Chickasaw + MS + US + 33.91 + -88.95 + 0 + 0 + MEG + + + TNZ020 + 420200 + Gibson + TN + US + 36.01 + -88.95 + 0 + 0 + MEG + + + ILZ081 + 130810 + Franklin + IL + US + 38.00 + -88.94 + 0 + 0 + PAH + + + ILZ075 + 130750 + Jefferson + IL + US + 38.30 + -88.93 + 0 + 0 + PAH + + + ILZ085 + 130850 + Williamson + IL + US + 37.74 + -88.93 + 0 + 0 + PAH + + + ILZ070 + 130700 + Marion + IL + US + 38.65 + -88.92 + 0 + 0 + LSX + + + WIZ037 + 490370 + Waupaca + WI + US + 44.46 + -88.91 + 0 + 0 + GRB + + + MSZ004 + 240040 + Tippah + MS + US + 34.80 + -88.89 + 0 + 0 + MEG + + + ILZ019 + 130190 + La_Salle + IL + US + 41.28 + -88.88 + 0 + 0 + LOT + + + ILZ089 + 130890 + Johnson + IL + US + 37.45 + -88.88 + 0 + 0 + PAH + + + ILZ038 + 130380 + McLean + IL + US + 40.52 + -88.87 + 0 + 0 + ILX + + + ILZ043 + 130430 + De_Witt + IL + US + 40.17 + -88.87 + 0 + 0 + ILX + + + MSZ033 + 240330 + Oktibbeha + MS + US + 33.43 + -88.87 + 0 + 0 + JAN + + + MIZ001 + 220010 + Keweenaw + MI + US + 48.01 + -88.84 + 0 + 0 + MQT + + + TNZ052 + 420520 + Madison + TN + US + 35.62 + -88.84 + 0 + 0 + MEG + + + ILZ004 + 130040 + Boone + IL + US + 42.32 + -88.83 + 0 + 0 + LOT + + + MIZ084 + 220840 + Southern_Houghton + MI + US + 46.64 + -88.83 + 0 + 0 + MQT + + + ILZ061 + 130610 + Shelby + IL + US + 39.43 + -88.81 + 0 + 0 + ILX + + + ILZ011 + 130110 + DeKalb + IL + US + 41.89 + -88.77 + 0 + 0 + LOT + + + WIZ064 + 490640 + Jefferson + WI + US + 43.02 + -88.77 + 0 + 0 + MKX + + + MSZ030 + 240300 + Clay + MS + US + 33.66 + -88.75 + 0 + 0 + JAN + + + TNZ003 + 420030 + Weakley + TN + US + 36.28 + -88.73 + 0 + 0 + MEG + + + WIZ011 + 490110 + Forest + WI + US + 45.72 + -88.73 + 0 + 0 + GRB + + + WIZ020 + 490200 + Menominee + WI + US + 44.99 + -88.73 + 0 + 0 + GRB + + + WIZ031 + 490310 + Shawano + WI + US + 44.81 + -88.73 + 0 + 0 + GRB + + + ILZ094 + 130940 + Massac + IL + US + 37.20 + -88.71 + 0 + 0 + PAH + + + KYZ005 + 170050 + McCracken + KY + US + 37.08 + -88.71 + 0 + 0 + PAH + + + WIZ058 + 490580 + Dodge + WI + US + 43.42 + -88.70 + 0 + 0 + MKX + + + MSZ067 + 240670 + Wayne + MS + US + 31.66 + -88.69 + 0 + 0 + MOB + + + MSZ016 + 240160 + Lee + MS + US + 34.30 + -88.68 + 0 + 0 + MEG + + + MSZ058 + 240580 + Clarke + MS + US + 32.03 + -88.68 + 0 + 0 + JAN + + + KYZ006 + 170060 + Graves + KY + US + 36.73 + -88.66 + 0 + 0 + PAH + + + MSZ052 + 240520 + Lauderdale + MS + US + 32.40 + -88.66 + 0 + 0 + JAN + + + ILZ054 + 130540 + Moultrie + IL + US + 39.62 + -88.64 + 0 + 0 + ILX + + + MSZ079 + 240790 + George + MS + US + 30.87 + -88.64 + 0 + 0 + MOB + + + WIZ048 + 490480 + Winnebago + WI + US + 44.07 + -88.64 + 0 + 0 + GRB + + + MSZ046 + 240460 + Kemper + MS + US + 32.76 + -88.63 + 0 + 0 + JAN + + + MSZ076 + 240760 + Greene + MS + US + 31.22 + -88.63 + 0 + 0 + MOB + + + MSZ082 + 240820 + Jackson + MS + US + 30.47 + -88.63 + 0 + 0 + LIX + + + ILZ044 + 130440 + Piatt + IL + US + 40.04 + -88.61 + 0 + 0 + ILX + + + TNZ053 + 420530 + Chester + TN + US + 35.42 + -88.61 + 0 + 0 + MEG + + + ILZ032 + 130320 + Livingston + IL + US + 40.87 + -88.59 + 0 + 0 + LOT + + + ILZ066 + 130660 + Effingham + IL + US + 39.06 + -88.59 + 0 + 0 + ILX + + + MSZ005 + 240050 + Alcorn + MS + US + 34.88 + -88.58 + 0 + 0 + MEG + + + TNZ091 + 420910 + McNairy + TN + US + 35.20 + -88.58 + 0 + 0 + MEG + + + MIZ003 + 220030 + Northern_Houghton + MI + US + 47.05 + -88.57 + 0 + 0 + MQT + + + ILZ090 + 130900 + Pope + IL + US + 37.34 + -88.56 + 0 + 0 + PAH + + + MSZ039 + 240390 + Noxubee + MS + US + 33.11 + -88.56 + 0 + 0 + JAN + + + MIZ010 + 220100 + Iron + MI + US + 46.18 + -88.55 + 0 + 0 + MQT + + + ILZ082 + 130820 + Hamilton + IL + US + 38.08 + -88.54 + 0 + 0 + PAH + + + ILZ086 + 130860 + Saline + IL + US + 37.76 + -88.54 + 0 + 0 + PAH + + + WIZ070 + 490700 + Walworth + WI + US + 42.67 + -88.53 + 0 + 0 + MKX + + + MSZ009 + 240090 + Prentiss + MS + US + 34.61 + -88.52 + 0 + 0 + MEG + + + WIZ051 + 490510 + Fond_Du_Lac + WI + US + 43.74 + -88.52 + 0 + 0 + MKX + + + ILZ071 + 130710 + Clay + IL + US + 38.76 + -88.48 + 0 + 0 + ILX + + + MSZ024 + 240240 + Monroe + MS + US + 33.87 + -88.46 + 0 + 0 + MEG + + + MSZ031 + 240310 + Lowndes + MS + US + 33.52 + -88.46 + 0 + 0 + JAN + + + WIZ038 + 490380 + Outagamie + WI + US + 44.42 + -88.46 + 0 + 0 + GRB + + + ILZ005 + 130050 + McHenry + IL + US + 42.32 + -88.45 + 0 + 0 + LOT + + + ILZ020 + 130200 + Kendall + IL + US + 41.59 + -88.44 + 0 + 0 + LOT + + + TNZ021 + 420210 + Carroll + TN + US + 35.97 + -88.44 + 0 + 0 + MEG + + + ILZ012 + 130120 + Kane + IL + US + 41.94 + -88.43 + 0 + 0 + LOT + + + ILZ076 + 130760 + Wayne + IL + US + 38.43 + -88.43 + 0 + 0 + PAH + + + ILZ021 + 130210 + Grundy + IL + US + 41.29 + -88.42 + 0 + 0 + LOT + + + TNZ054 + 420540 + Henderson + TN + US + 35.62 + -88.39 + 0 + 0 + MEG + + + WIZ021 + 490210 + Northern_Oconto_County + WI + US + 45.20 + -88.39 + 0 + 0 + GRB + + + KYZ007 + 170070 + Livingston + KY + US + 37.20 + -88.38 + 0 + 0 + PAH + + + WIZ012 + 490120 + Florence + WI + US + 45.87 + -88.36 + 0 + 0 + GRB + + + MSZ017 + 240170 + Itawamba + MS + US + 34.28 + -88.35 + 0 + 0 + MEG + + + MIZ004 + 220040 + Baraga + MI + US + 46.69 + -88.33 + 0 + 0 + MQT + + + KYZ008 + 170080 + Marshall + KY + US + 36.91 + -88.31 + 0 + 0 + PAH + + + WIZ065 + 490650 + Waukesha + WI + US + 43.02 + -88.30 + 0 + 0 + MKX + + + KYZ009 + 170090 + Calloway + KY + US + 36.63 + -88.27 + 0 + 0 + PAH + + + TNZ004 + 420040 + Henry + TN + US + 36.32 + -88.26 + 0 + 0 + MEG + + + ILZ091 + 130910 + Hardin + IL + US + 37.51 + -88.25 + 0 + 0 + PAH + + + ILZ062 + 130620 + Cumberland + IL + US + 39.28 + -88.24 + 0 + 0 + ILX + + + ILZ056 + 130560 + Coles + IL + US + 39.53 + -88.22 + 0 + 0 + ILX + + + MSZ006 + 240060 + Tishomingo + MS + US + 34.73 + -88.22 + 0 + 0 + MEG + + + WIZ049 + 490490 + Calumet + WI + US + 44.07 + -88.22 + 0 + 0 + GRB + + + WIZ059 + 490590 + Washington + WI + US + 43.37 + -88.22 + 0 + 0 + MKX + + + ALZ063 + 10630 + Lower_Mobile + AL + US + 30.44 + -88.21 + 0 + 0 + MOB + + + ILZ055 + 130550 + Douglas + IL + US + 39.77 + -88.21 + 0 + 0 + ILX + + + ILZ087 + 130870 + Gallatin + IL + US + 37.75 + -88.21 + 0 + 0 + PAH + + + ALZ051 + 10510 + Choctaw + AL + US + 32.01 + -88.20 + 0 + 0 + MOB + + + ILZ039 + 130390 + Ford + IL + US + 40.70 + -88.20 + 0 + 0 + LOT + + + ILZ045 + 130450 + Champaign + IL + US + 40.14 + -88.20 + 0 + 0 + ILX + + + ALZ052 + 10520 + Washington + AL + US + 31.41 + -88.18 + 0 + 0 + MOB + + + ALZ061 + 10610 + Upper_Mobile + AL + US + 30.93 + -88.18 + 0 + 0 + MOB + + + TNZ092 + 420920 + Hardin + TN + US + 35.22 + -88.18 + 0 + 0 + MEG + + + ILZ067 + 130670 + Jasper + IL + US + 39.02 + -88.16 + 0 + 0 + ILX + + + ILZ083 + 130830 + White + IL + US + 38.08 + -88.15 + 0 + 0 + PAH + + + ALZ030 + 10300 + Sumter + AL + US + 32.65 + -88.13 + 0 + 0 + BMX + + + WIZ074 + 490740 + Southern_Oconto_County + WI + US + 44.85 + -88.12 + 0 + 0 + GRB + + + ALZ012 + 10120 + Lamar + AL + US + 33.80 + -88.11 + 0 + 0 + BMX + + + ILZ072 + 130720 + Richland + IL + US + 38.72 + -88.11 + 0 + 0 + ILX + + + TNZ055 + 420550 + Decatur + TN + US + 35.62 + -88.10 + 0 + 0 + MEG + + + WIZ013 + 490130 + Northern_Marinette_County + WI + US + 45.57 + -88.10 + 0 + 0 + GRB + + + ALZ022 + 10220 + Pickens + AL + US + 33.26 + -88.09 + 0 + 0 + BMX + + + ILZ013 + 130130 + DuPage + IL + US + 41.85 + -88.09 + 0 + 0 + LOT + + + KYZ010 + 170100 + Crittenden + KY + US + 37.34 + -88.09 + 0 + 0 + PAH + + + KYZ011 + 170110 + Lyon + KY + US + 37.03 + -88.07 + 0 + 0 + PAH + + + TNZ022 + 420220 + Benton + TN + US + 36.09 + -88.07 + 0 + 0 + OHX + + + ILZ077 + 130770 + Edwards + IL + US + 38.42 + -88.05 + 0 + 0 + PAH + + + WIZ072 + 490720 + Kenosha + WI + US + 42.58 + -88.05 + 0 + 0 + MKX + + + WIZ071 + 490710 + Racine + WI + US + 42.73 + -88.03 + 0 + 0 + MKX + + + WIZ039 + 490390 + Brown + WI + US + 44.46 + -87.99 + 0 + 0 + GRB + + + ILZ006 + 130060 + Lake + IL + US + 42.32 + -87.98 + 0 + 0 + LOT + + + ALZ031 + 10310 + Greene + AL + US + 32.84 + -87.96 + 0 + 0 + BMX + + + KYZ014 + 170140 + Union + KY + US + 37.69 + -87.95 + 0 + 0 + PAH + + + WIZ066 + 490660 + Milwaukee + WI + US + 43.02 + -87.94 + 0 + 0 + MKX + + + WIZ073 + 490730 + Southern_Marinette_County + WI + US + 45.18 + -87.94 + 0 + 0 + GRB + + + WIZ052 + 490520 + Sheboygan + WI + US + 43.72 + -87.93 + 0 + 0 + MKX + + + ALZ011 + 10110 + Marion + AL + US + 34.12 + -87.92 + 0 + 0 + BMX + + + KYZ012 + 170120 + Trigg + KY + US + 36.83 + -87.92 + 0 + 0 + PAH + + + WIZ060 + 490600 + Ozaukee + WI + US + 43.37 + -87.92 + 0 + 0 + MKX + + + ILZ014 + 130140 + Cook + IL + US + 41.81 + -87.90 + 0 + 0 + LOT + + + ILZ022 + 130220 + Will + IL + US + 41.47 + -87.90 + 0 + 0 + LOT + + + INZ085 + 140850 + Posey + IN + US + 38.01 + -87.90 + 0 + 0 + PAH + + + ILZ023 + 130230 + Kankakee + IL + US + 41.15 + -87.89 + 0 + 0 + LOT + + + KYZ013 + 170130 + Caldwell + KY + US + 37.17 + -87.89 + 0 + 0 + PAH + + + MIZ011 + 220110 + Dickinson + MI + US + 45.99 + -87.87 + 0 + 0 + MQT + + + ALZ003 + 10030 + Franklin + AL + US + 34.45 + -87.85 + 0 + 0 + HUN + + + TNZ056 + 420560 + Perry + TN + US + 35.64 + -87.85 + 0 + 0 + OHX + + + ALZ053 + 10530 + Clarke + AL + US + 31.60 + -87.84 + 0 + 0 + MOB + + + ILZ033 + 130330 + Iroquois + IL + US + 40.75 + -87.83 + 0 + 0 + LOT + + + TNZ005 + 420050 + Stewart + TN + US + 36.50 + -87.83 + 0 + 0 + OHX + + + ILZ078 + 130780 + Wabash + IL + US + 38.41 + -87.82 + 0 + 0 + PAH + + + TNZ093 + 420930 + Wayne + TN + US + 35.26 + -87.80 + 0 + 0 + OHX + + + ALZ039 + 10390 + Marengo + AL + US + 32.27 + -87.79 + 0 + 0 + BMX + + + ALZ002 + 10020 + Colbert + AL + US + 34.74 + -87.78 + 0 + 0 + HUN + + + ILZ063 + 130630 + Clark + IL + US + 39.33 + -87.78 + 0 + 0 + ILX + + + TNZ024 + 420240 + Humphreys + TN + US + 36.03 + -87.77 + 0 + 0 + OHX + + + WIZ050 + 490500 + Manitowoc + WI + US + 44.11 + -87.77 + 0 + 0 + GRB + + + ILZ057 + 130570 + Edgar + IL + US + 39.68 + -87.75 + 0 + 0 + ILX + + + TNZ023 + 420230 + Houston + TN + US + 36.28 + -87.75 + 0 + 0 + OHX + + + ILZ046 + 130460 + Vermilion + IL + US + 40.19 + -87.74 + 0 + 0 + ILX + + + ILZ068 + 130680 + Crawford + IL + US + 39.02 + -87.74 + 0 + 0 + ILX + + + ALZ062 + 10620 + Upper_Baldwin + AL + US + 31.01 + -87.72 + 0 + 0 + MOB + + + ILZ073 + 130730 + Lawrence + IL + US + 38.72 + -87.71 + 0 + 0 + ILX + + + ALZ001 + 10010 + Lauderdale + AL + US + 34.88 + -87.70 + 0 + 0 + HUN + + + ALZ064 + 10640 + Lower_Baldwin + AL + US + 30.45 + -87.70 + 0 + 0 + MOB + + + ALZ013 + 10130 + Fayette + AL + US + 33.73 + -87.68 + 0 + 0 + BMX + + + KYZ015 + 170150 + Webster + KY + US + 37.50 + -87.66 + 0 + 0 + PAH + + + INZ081 + 140810 + Gibson + IN + US + 38.35 + -87.65 + 0 + 0 + PAH + + + ALZ032 + 10320 + Hale + AL + US + 32.75 + -87.64 + 0 + 0 + BMX + + + KYZ018 + 170180 + Henderson + KY + US + 37.81 + -87.61 + 0 + 0 + PAH + + + MIZ005 + 220050 + Marquette + MI + US + 46.48 + -87.61 + 0 + 0 + MQT + + + INZ086 + 140860 + Vanderburgh + IN + US + 38.00 + -87.58 + 0 + 0 + PAH + + + KYZ016 + 170160 + Hopkins + KY + US + 37.34 + -87.58 + 0 + 0 + PAH + + + MIZ012 + 220120 + Menominee + MI + US + 45.55 + -87.57 + 0 + 0 + MQT + + + WIZ040 + 490400 + Kewaunee + WI + US + 44.50 + -87.57 + 0 + 0 + GRB + + + KYZ017 + 170170 + Christian + KY + US + 36.90 + -87.50 + 0 + 0 + PAH + + + TNZ058 + 420580 + Lewis + TN + US + 35.53 + -87.49 + 0 + 0 + OHX + + + TNZ057 + 420570 + Hickman + TN + US + 35.81 + -87.47 + 0 + 0 + OHX + + + INZ060 + 140600 + Sullivan + IN + US + 39.08 + -87.46 + 0 + 0 + IND + + + ALZ023 + 10230 + Tuscaloosa + AL + US + 33.32 + -87.45 + 0 + 0 + BMX + + + INZ043 + 140430 + Vermillion + IN + US + 39.89 + -87.45 + 0 + 0 + IND + + + INZ067 + 140670 + Knox + IN + US + 38.66 + -87.43 + 0 + 0 + IND + + + INZ051 + 140510 + Vigo + IN + US + 39.43 + -87.42 + 0 + 0 + IND + + + FLZ001 + 90010 + Inland_Escambia + FL + US + 30.86 + -87.40 + 0 + 0 + MOB + + + INZ010 + 140100 + Newton + IN + US + 40.98 + -87.40 + 0 + 0 + LOT + + + TNZ094 + 420940 + Lawrence + TN + US + 35.24 + -87.40 + 0 + 0 + OHX + + + INZ001 + 140010 + Lake + IN + US + 41.44 + -87.38 + 0 + 0 + LOT + + + TNZ006 + 420060 + Montgomery + TN + US + 36.49 + -87.38 + 0 + 0 + OHX + + + ALZ014 + 10140 + Winston + AL + US + 34.15 + -87.37 + 0 + 0 + BMX + + + ALZ055 + 10550 + Monroe + AL + US + 31.54 + -87.35 + 0 + 0 + MOB + + + TNZ025 + 420250 + Dickson + TN + US + 36.15 + -87.35 + 0 + 0 + OHX + + + ALZ004 + 10040 + Lawrence + AL + US + 34.56 + -87.32 + 0 + 0 + HUN + + + INZ019 + 140190 + Benton + IN + US + 40.61 + -87.32 + 0 + 0 + LOT + + + INZ028 + 140280 + Warren + IN + US + 40.31 + -87.32 + 0 + 0 + IND + + + ALZ015 + 10150 + Walker + AL + US + 33.76 + -87.30 + 0 + 0 + BMX + + + INZ082 + 140820 + Pike + IN + US + 38.39 + -87.28 + 0 + 0 + PAH + + + KYZ020 + 170200 + McLean + KY + US + 37.54 + -87.28 + 0 + 0 + PAH + + + ALZ033 + 10330 + Perry + AL + US + 32.59 + -87.27 + 0 + 0 + BMX + + + INZ035 + 140350 + Fountain + IN + US + 40.17 + -87.27 + 0 + 0 + IND + + + WIZ022 + 490220 + Door + WI + US + 45.05 + -87.27 + 0 + 0 + GRB + + + ALZ054 + 10540 + Wilcox + AL + US + 32.05 + -87.26 + 0 + 0 + MOB + + + INZ087 + 140870 + Warrick + IN + US + 38.06 + -87.25 + 0 + 0 + PAH + + + INZ044 + 140440 + Parke + IN + US + 39.79 + -87.23 + 0 + 0 + IND + + + FLZ002 + 90020 + Coastal_Escambia + FL + US + 30.50 + -87.20 + 0 + 0 + MOB + + + KYZ022 + 170220 + Todd + KY + US + 36.86 + -87.20 + 0 + 0 + PAH + + + ALZ059 + 10590 + Escambia + AL + US + 31.13 + -87.16 + 0 + 0 + MOB + + + ALZ034 + 10340 + Bibb + AL + US + 33.04 + -87.15 + 0 + 0 + BMX + + + ALZ040 + 10400 + Dallas + AL + US + 32.38 + -87.14 + 0 + 0 + BMX + + + KYZ021 + 170210 + Muhlenberg + KY + US + 37.23 + -87.14 + 0 + 0 + PAH + + + KYZ019 + 170190 + Daviess + KY + US + 37.75 + -87.12 + 0 + 0 + PAH + + + INZ011 + 140110 + Jasper + IN + US + 41.01 + -87.11 + 0 + 0 + LOT + + + INZ052 + 140520 + Clay + IN + US + 39.39 + -87.10 + 0 + 0 + IND + + + INZ068 + 140680 + Daviess + IN + US + 38.70 + -87.10 + 0 + 0 + IND + + + TNZ026 + 420260 + Cheatham + TN + US + 36.26 + -87.09 + 0 + 0 + OHX + + + INZ002 + 140020 + Porter + IN + US + 41.47 + -87.08 + 0 + 0 + LOT + + + TNZ060 + 420600 + Maury + TN + US + 35.64 + -87.07 + 0 + 0 + OHX + + + ALZ056 + 10560 + Conecuh + AL + US + 31.47 + -87.04 + 0 + 0 + MOB + + + FLZ003 + 90030 + Inland_Santa_Rosa + FL + US + 30.86 + -87.04 + 0 + 0 + MOB + + + ALZ005 + 10050 + Limestone + AL + US + 34.78 + -87.02 + 0 + 0 + HUN + + + INZ088 + 140880 + Spencer + IN + US + 37.99 + -87.02 + 0 + 0 + PAH + + + TNZ095 + 420950 + Giles + TN + US + 35.23 + -87.02 + 0 + 0 + OHX + + + INZ061 + 140610 + Greene + IN + US + 39.03 + -86.98 + 0 + 0 + IND + + + ALZ024 + 10240 + Jefferson + AL + US + 33.55 + -86.93 + 0 + 0 + BMX + + + MIZ013 + 220130 + Delta + MI + US + 45.82 + -86.91 + 0 + 0 + MQT + + + TNZ059 + 420590 + Williamson + TN + US + 35.88 + -86.91 + 0 + 0 + OHX + + + INZ029 + 140290 + Tippecanoe + IN + US + 40.40 + -86.90 + 0 + 0 + IND + + + INZ036 + 140360 + Montgomery + IN + US + 40.05 + -86.90 + 0 + 0 + IND + + + FLZ004 + 90040 + Coastal_Santa_Rosa + FL + US + 30.53 + -86.89 + 0 + 0 + MOB + + + INZ083 + 140830 + Dubois + IN + US + 38.36 + -86.88 + 0 + 0 + LMK + + + KYZ026 + 170260 + Ohio + KY + US + 37.48 + -86.86 + 0 + 0 + LMK + + + INZ053 + 140530 + Owen + IN + US + 39.31 + -86.85 + 0 + 0 + IND + + + KYZ070 + 170700 + Logan + KY + US + 36.86 + -86.85 + 0 + 0 + LMK + + + INZ020 + 140200 + White + IN + US + 40.75 + -86.84 + 0 + 0 + IWX + + + ALZ007 + 10070 + Morgan + AL + US + 34.50 + -86.83 + 0 + 0 + HUN + + + INZ045 + 140450 + Putnam + IN + US + 39.67 + -86.83 + 0 + 0 + IND + + + TNZ007 + 420070 + Robertson + TN + US + 36.50 + -86.82 + 0 + 0 + OHX + + + INZ069 + 140690 + Martin + IN + US + 38.70 + -86.81 + 0 + 0 + IND + + + KYZ023 + 170230 + Hancock + KY + US + 37.83 + -86.81 + 0 + 0 + LMK + + + ALZ016 + 10160 + Cullman + AL + US + 34.09 + -86.78 + 0 + 0 + HUN + + + TNZ027 + 420270 + Davidson + TN + US + 36.19 + -86.78 + 0 + 0 + OHX + + + TNZ061 + 420610 + Marshall + TN + US + 35.49 + -86.77 + 0 + 0 + OHX + + + INZ003 + 140030 + La_Porte + IN + US + 41.50 + -86.71 + 0 + 0 + IWX + + + ALZ035 + 10350 + Chilton + AL + US + 32.87 + -86.70 + 0 + 0 + BMX + + + INZ012 + 140120 + Starke + IN + US + 41.31 + -86.70 + 0 + 0 + IWX + + + INZ013 + 140130 + Pulaski + IN + US + 41.05 + -86.70 + 0 + 0 + IWX + + + ALZ025 + 10250 + Shelby + AL + US + 33.29 + -86.68 + 0 + 0 + BMX + + + ALZ057 + 10570 + Butler + AL + US + 31.75 + -86.68 + 0 + 0 + MOB + + + KYZ061 + 170610 + Butler + KY + US + 37.20 + -86.67 + 0 + 0 + LMK + + + ALZ041 + 10410 + Autauga + AL + US + 32.52 + -86.66 + 0 + 0 + BMX + + + ALZ042 + 10420 + Lowndes + AL + US + 32.19 + -86.66 + 0 + 0 + BMX + + + ALZ017 + 10170 + Blount + AL + US + 34.01 + -86.64 + 0 + 0 + BMX + + + INZ089 + 140890 + Perry + IN + US + 38.05 + -86.63 + 0 + 0 + LMK + + + FLZ006 + 90060 + Coastal_Okaloosa + FL + US + 30.55 + -86.59 + 0 + 0 + MOB + + + KYZ072 + 170720 + Simpson + KY + US + 36.77 + -86.59 + 0 + 0 + LMK + + + FLZ005 + 90050 + Inland_Okaloosa + FL + US + 30.86 + -86.58 + 0 + 0 + MOB + + + INZ021 + 140210 + Carroll + IN + US + 40.59 + -86.57 + 0 + 0 + IND + + + TNZ096 + 420960 + Lincoln + TN + US + 35.19 + -86.57 + 0 + 0 + HUN + + + MIZ077 + 220770 + Berrien + MI + US + 42.01 + -86.53 + 0 + 0 + IWX + + + ALZ006 + 10060 + Madison + AL + US + 34.74 + -86.52 + 0 + 0 + HUN + + + INZ046 + 140460 + Hendricks + IN + US + 39.77 + -86.52 + 0 + 0 + IND + + + INZ062 + 140620 + Monroe + IN + US + 39.16 + -86.52 + 0 + 0 + IND + + + INZ076 + 140760 + Orange + IN + US + 38.54 + -86.50 + 0 + 0 + LMK + + + INZ070 + 140700 + Lawrence + IN + US + 38.84 + -86.49 + 0 + 0 + IND + + + INZ037 + 140370 + Boone + IN + US + 40.06 + -86.48 + 0 + 0 + IND + + + INZ054 + 140540 + Morgan + IN + US + 39.48 + -86.48 + 0 + 0 + IND + + + MIZ006 + 220060 + Alger + MI + US + 46.43 + -86.48 + 0 + 0 + MQT + + + TNZ008 + 420080 + Sumner + TN + US + 36.45 + -86.48 + 0 + 0 + OHX + + + INZ030 + 140300 + Clinton + IN + US + 40.31 + -86.47 + 0 + 0 + IND + + + INZ084 + 140840 + Crawford + IN + US + 38.26 + -86.46 + 0 + 0 + LMK + + + TNZ075 + 420750 + Bedford + TN + US + 35.52 + -86.45 + 0 + 0 + OHX + + + ALZ060 + 10600 + Covington + AL + US + 31.26 + -86.44 + 0 + 0 + MOB + + + KYZ024 + 170240 + Breckinridge + KY + US + 37.81 + -86.42 + 0 + 0 + LMK + + + TNZ062 + 420620 + Rutherford + TN + US + 35.86 + -86.41 + 0 + 0 + OHX + + + KYZ071 + 170710 + Warren + KY + US + 36.99 + -86.40 + 0 + 0 + LMK + + + INZ022 + 140220 + Cass + IN + US + 40.75 + -86.38 + 0 + 0 + IWX + + + TNZ076 + 420760 + Moore + TN + US + 35.28 + -86.38 + 0 + 0 + HUN + + + KYZ027 + 170270 + Grayson + KY + US + 37.47 + -86.35 + 0 + 0 + LMK + + + ALZ008 + 10080 + Marshall + AL + US + 34.36 + -86.32 + 0 + 0 + HUN + + + ALZ058 + 10580 + Crenshaw + AL + US + 31.75 + -86.32 + 0 + 0 + MOB + + + ALZ026 + 10260 + St._Clair + AL + US + 33.69 + -86.31 + 0 + 0 + BMX + + + INZ004 + 140040 + St._Joseph + IN + US + 41.60 + -86.30 + 0 + 0 + IWX + + + MIZ043 + 220430 + Oceana + MI + US + 43.64 + -86.29 + 0 + 0 + GRR + + + TNZ028 + 420280 + Wilson + TN + US + 36.15 + -86.29 + 0 + 0 + OHX + + + MIZ037 + 220370 + Mason + MI + US + 44.00 + -86.28 + 0 + 0 + GRR + + + ALZ036 + 10360 + Coosa + AL + US + 32.93 + -86.27 + 0 + 0 + BMX + + + INZ014 + 140140 + Marshall + IN + US + 41.33 + -86.27 + 0 + 0 + IWX + + + KYZ062 + 170620 + Edmonson + KY + US + 37.20 + -86.27 + 0 + 0 + LMK + + + INZ063 + 140630 + Brown + IN + US + 39.19 + -86.24 + 0 + 0 + IND + + + KYZ025 + 170250 + Meade + KY + US + 38.00 + -86.24 + 0 + 0 + LMK + + + MIZ085 + 220850 + Northern_Schoolcraft + MI + US + 46.33 + -86.23 + 0 + 0 + MQT + + + ALZ044 + 10440 + Montgomery + AL + US + 32.24 + -86.21 + 0 + 0 + BMX + + + FLZ007 + 90070 + Inland_Walton + FL + US + 30.85 + -86.21 + 0 + 0 + TAE + + + INZ015 + 140150 + Fulton + IN + US + 41.05 + -86.21 + 0 + 0 + IWX + + + KYZ073 + 170730 + Allen + KY + US + 36.78 + -86.19 + 0 + 0 + LMK + + + MIZ014 + 220140 + Southern_Schoolcraft + MI + US + 46.00 + -86.17 + 0 + 0 + MQT + + + ALZ027 + 10270 + Talladega + AL + US + 33.40 + -86.15 + 0 + 0 + BMX + + + ALZ043 + 10430 + Elmore + AL + US + 32.59 + -86.14 + 0 + 0 + BMX + + + INZ047 + 140470 + Marion + IN + US + 39.78 + -86.14 + 0 + 0 + IND + + + INZ090 + 140900 + Harrison + IN + US + 38.19 + -86.13 + 0 + 0 + LMK + + + MIZ050 + 220500 + Muskegon + MI + US + 43.30 + -86.13 + 0 + 0 + GRR + + + TNZ029 + 420290 + Trousdale + TN + US + 36.40 + -86.13 + 0 + 0 + OHX + + + FLZ008 + 90080 + Coastal_Walton + FL + US + 30.49 + -86.12 + 0 + 0 + TAE + + + INZ031 + 140310 + Howard + IN + US + 40.48 + -86.12 + 0 + 0 + IND + + + INZ055 + 140550 + Johnson + IN + US + 39.49 + -86.11 + 0 + 0 + IND + + + MIZ031 + 220310 + Manistee + MI + US + 44.35 + -86.10 + 0 + 0 + APX + + + TNZ097 + 420970 + Franklin + TN + US + 35.18 + -86.10 + 0 + 0 + HUN + + + INZ077 + 140770 + Washington + IN + US + 38.60 + -86.09 + 0 + 0 + LMK + + + INZ071 + 140710 + Jackson + IN + US + 38.90 + -86.07 + 0 + 0 + IND + + + MIZ071 + 220710 + Van_Buren + MI + US + 42.25 + -86.07 + 0 + 0 + GRR + + + TNZ077 + 420770 + Coffee + TN + US + 35.50 + -86.07 + 0 + 0 + OHX + + + INZ039 + 140390 + Hamilton + IN + US + 40.08 + -86.06 + 0 + 0 + IND + + + ALZ018 + 10180 + Etowah + AL + US + 34.03 + -86.05 + 0 + 0 + BMX + + + INZ038 + 140380 + Tipton + IN + US + 40.32 + -86.05 + 0 + 0 + IND + + + TNZ063 + 420630 + Cannon + TN + US + 35.81 + -86.05 + 0 + 0 + OHX + + + MIZ025 + 220250 + Benzie + MI + US + 44.65 + -86.04 + 0 + 0 + APX + + + MIZ056 + 220560 + Ottawa + MI + US + 42.99 + -86.03 + 0 + 0 + GRR + + + INZ023 + 140230 + Miami + IN + US + 40.79 + -86.02 + 0 + 0 + IWX + + + MIZ078 + 220780 + Cass + MI + US + 41.92 + -86.00 + 0 + 0 + IWX + + + TNZ009 + 420090 + Macon + TN + US + 36.53 + -86.00 + 0 + 0 + OHX + + + ALZ065 + 10650 + Coffee + AL + US + 31.41 + -85.99 + 0 + 0 + TAE + + + KYZ028 + 170280 + Hardin + KY + US + 37.72 + -85.98 + 0 + 0 + LMK + + + ALZ009 + 10090 + Jackson + AL + US + 34.74 + -85.97 + 0 + 0 + HUN + + + KYZ074 + 170740 + Barren + KY + US + 36.95 + -85.96 + 0 + 0 + LMK + + + TNZ030 + 420300 + Smith + TN + US + 36.26 + -85.96 + 0 + 0 + OHX + + + ALZ049 + 10490 + Pike + AL + US + 31.85 + -85.93 + 0 + 0 + BMX + + + ALZ028 + 10280 + Clay + AL + US + 33.30 + -85.91 + 0 + 0 + BMX + + + KYZ063 + 170630 + Hart + KY + US + 37.30 + -85.91 + 0 + 0 + LMK + + + MIZ064 + 220640 + Allegan + MI + US + 42.60 + -85.91 + 0 + 0 + GRR + + + INZ064 + 140640 + Bartholomew + IN + US + 39.19 + -85.90 + 0 + 0 + IND + + + INZ091 + 140910 + Floyd + IN + US + 38.30 + -85.90 + 0 + 0 + LMK + + + INZ016 + 140160 + Kosciusko + IN + US + 41.25 + -85.87 + 0 + 0 + IWX + + + INZ005 + 140050 + Elkhart + IN + US + 41.60 + -85.86 + 0 + 0 + IWX + + + TNZ064 + 420640 + DeKalb + TN + US + 35.98 + -85.84 + 0 + 0 + OHX + + + ALZ019 + 10190 + Calhoun + AL + US + 33.76 + -85.83 + 0 + 0 + BMX + + + ALZ068 + 10680 + Geneva + AL + US + 31.10 + -85.83 + 0 + 0 + TAE + + + ALZ010 + 10100 + De_Kalb + AL + US + 34.53 + -85.82 + 0 + 0 + HUN + + + ALZ037 + 10370 + Tallapoosa + AL + US + 32.81 + -85.80 + 0 + 0 + BMX + + + INZ024 + 140240 + Wabash + IN + US + 40.85 + -85.80 + 0 + 0 + IWX + + + INZ056 + 140560 + Shelby + IN + US + 39.52 + -85.80 + 0 + 0 + IND + + + MIZ038 + 220380 + Lake + MI + US + 43.99 + -85.80 + 0 + 0 + GRR + + + MIZ044 + 220440 + Newaygo + MI + US + 43.56 + -85.80 + 0 + 0 + GRR + + + FLZ009 + 90090 + Holmes + FL + US + 30.86 + -85.77 + 0 + 0 + TAE + + + INZ048 + 140480 + Hancock + IN + US + 39.83 + -85.77 + 0 + 0 + IND + + + TNZ078 + 420780 + Warren + TN + US + 35.68 + -85.77 + 0 + 0 + OHX + + + INZ078 + 140780 + Scott + IN + US + 38.69 + -85.74 + 0 + 0 + LMK + + + ALZ045 + 10450 + Macon + AL + US + 32.42 + -85.72 + 0 + 0 + BMX + + + INZ040 + 140400 + Madison + IN + US + 40.17 + -85.72 + 0 + 0 + IND + + + ALZ046 + 10460 + Bullock + AL + US + 32.10 + -85.71 + 0 + 0 + BMX + + + FLZ010 + 90100 + Washington + FL + US + 30.62 + -85.71 + 0 + 0 + TAE + + + INZ092 + 140920 + Clark + IN + US + 38.44 + -85.71 + 0 + 0 + LMK + + + KYZ075 + 170750 + Monroe + KY + US + 36.73 + -85.71 + 0 + 0 + LMK + + + MIZ020 + 220200 + Leelanau + MI + US + 44.99 + -85.71 + 0 + 0 + APX + + + KYZ029 + 170290 + Bullitt + KY + US + 37.97 + -85.70 + 0 + 0 + LMK + + + TNZ079 + 420790 + Grundy + TN + US + 35.38 + -85.70 + 0 + 0 + OHX + + + KYZ030 + 170300 + Jefferson + KY + US + 38.19 + -85.69 + 0 + 0 + LMK + + + KYZ053 + 170530 + Larue + KY + US + 37.57 + -85.69 + 0 + 0 + LMK + + + FLZ012 + 90120 + Bay + FL + US + 30.31 + -85.68 + 0 + 0 + TAE + + + TNZ031 + 420310 + Jackson + TN + US + 36.37 + -85.67 + 0 + 0 + OHX + + + INZ032 + 140320 + Grant + IN + US + 40.53 + -85.66 + 0 + 0 + IWX + + + INZ072 + 140720 + Jennings + IN + US + 39.00 + -85.63 + 0 + 0 + IND + + + ALZ020 + 10200 + Cherokee + AL + US + 34.23 + -85.62 + 0 + 0 + BMX + + + KYZ076 + 170760 + Metcalfe + KY + US + 37.01 + -85.62 + 0 + 0 + LMK + + + TNZ098 + 420980 + Marion + TN + US + 35.16 + -85.62 + 0 + 0 + MRX + + + ALZ066 + 10660 + Dale + AL + US + 31.41 + -85.61 + 0 + 0 + TAE + + + ALZ021 + 10210 + Cleburne + AL + US + 33.72 + -85.60 + 0 + 0 + BMX + + + MIZ026 + 220260 + Grand_Traverse + MI + US + 44.75 + -85.58 + 0 + 0 + APX + + + MIZ032 + 220320 + Wexford + MI + US + 44.34 + -85.58 + 0 + 0 + APX + + + MIZ057 + 220570 + Kent + MI + US + 43.03 + -85.56 + 0 + 0 + GRR + + + MIZ079 + 220790 + St._Joseph + MI + US + 41.92 + -85.55 + 0 + 0 + IWX + + + MIZ007 + 220070 + Luce + MI + US + 46.50 + -85.54 + 0 + 0 + MQT + + + TNZ010 + 420100 + Clay + TN + US + 36.52 + -85.54 + 0 + 0 + OHX + + + KYZ064 + 170640 + Green + KY + US + 37.29 + -85.53 + 0 + 0 + LMK + + + MIZ072 + 220720 + Kalamazoo + MI + US + 42.25 + -85.53 + 0 + 0 + GRR + + + INZ017 + 140170 + Whitley + IN + US + 41.15 + -85.50 + 0 + 0 + IWX + + + INZ065 + 140650 + Decatur + IN + US + 39.29 + -85.50 + 0 + 0 + IND + + + INZ025 + 140250 + Huntington + IN + US + 40.84 + -85.49 + 0 + 0 + IWX + + + GAZ001 + 100010 + Dade + GA + US + 34.81 + -85.48 + 0 + 0 + FFC + + + INZ057 + 140570 + Rush + IN + US + 39.62 + -85.48 + 0 + 0 + IND + + + KYZ031 + 170310 + Oldham + KY + US + 38.42 + -85.47 + 0 + 0 + LMK + + + INZ079 + 140790 + Jefferson + IN + US + 38.75 + -85.45 + 0 + 0 + LMK + + + KYZ045 + 170450 + Nelson + KY + US + 37.76 + -85.45 + 0 + 0 + LMK + + + TNZ032 + 420320 + Putnam + TN + US + 36.15 + -85.45 + 0 + 0 + OHX + + + ALZ029 + 10290 + Randolph + AL + US + 33.31 + -85.44 + 0 + 0 + BMX + + + TNZ065 + 420650 + White + TN + US + 35.94 + -85.44 + 0 + 0 + OHX + + + INZ006 + 140060 + Lagrange + IN + US + 41.65 + -85.43 + 0 + 0 + IWX + + + INZ008 + 140080 + Noble + IN + US + 41.41 + -85.43 + 0 + 0 + IWX + + + TNZ080 + 420800 + Van_Buren + TN + US + 35.69 + -85.43 + 0 + 0 + OHX + + + KYZ081 + 170810 + Cumberland + KY + US + 36.78 + -85.42 + 0 + 0 + LMK + + + TNZ081 + 420810 + Sequatchie + TN + US + 35.36 + -85.42 + 0 + 0 + MRX + + + ALZ050 + 10500 + Barbour + AL + US + 31.89 + -85.40 + 0 + 0 + BMX + + + INZ041 + 140410 + Delaware + IN + US + 40.24 + -85.40 + 0 + 0 + IND + + + INZ049 + 140490 + Henry + IN + US + 39.94 + -85.40 + 0 + 0 + IND + + + ALZ038 + 10380 + Chambers + AL + US + 32.93 + -85.36 + 0 + 0 + BMX + + + ALZ069 + 10690 + Houston + AL + US + 31.16 + -85.35 + 0 + 0 + TAE + + + ALZ047 + 10470 + Lee + AL + US + 32.58 + -85.34 + 0 + 0 + BMX + + + KYZ065 + 170650 + Taylor + KY + US + 37.33 + -85.34 + 0 + 0 + LMK + + + MIZ039 + 220390 + Osceola + MI + US + 43.99 + -85.33 + 0 + 0 + GRR + + + MIZ045 + 220450 + Mecosta + MI + US + 43.64 + -85.33 + 0 + 0 + GRR + + + INZ033 + 140330 + Blackford + IN + US + 40.49 + -85.32 + 0 + 0 + IWX + + + GAZ011 + 100110 + Chattooga + GA + US + 34.44 + -85.31 + 0 + 0 + FFC + + + KYZ032 + 170320 + Trimble + KY + US + 38.62 + -85.31 + 0 + 0 + LMK + + + KYZ038 + 170380 + Spencer + KY + US + 38.05 + -85.31 + 0 + 0 + LMK + + + MIZ065 + 220650 + Barry + MI + US + 42.60 + -85.31 + 0 + 0 + GRR + + + GAZ002 + 100020 + Walker + GA + US + 34.79 + -85.29 + 0 + 0 + FFC + + + KYZ077 + 170770 + Adair + KY + US + 37.12 + -85.29 + 0 + 0 + LMK + + + KYZ054 + 170540 + Marion + KY + US + 37.57 + -85.28 + 0 + 0 + LMK + + + TNZ033 + 420330 + Overton + TN + US + 36.35 + -85.28 + 0 + 0 + OHX + + + INZ073 + 140730 + Ripley + IN + US + 39.11 + -85.27 + 0 + 0 + ILN + + + INZ026 + 140260 + Wells + IN + US + 40.76 + -85.26 + 0 + 0 + IWX + + + ALZ067 + 10670 + Henry + AL + US + 31.55 + -85.23 + 0 + 0 + TAE + + + FLZ011 + 90110 + Jackson + FL + US + 30.79 + -85.23 + 0 + 0 + TAE + + + GAZ019 + 100190 + Floyd + GA + US + 34.34 + -85.23 + 0 + 0 + FFC + + + FLZ014 + 90140 + Gulf + FL + US + 29.94 + -85.22 + 0 + 0 + TAE + + + KYZ034 + 170340 + Shelby + KY + US + 38.20 + -85.22 + 0 + 0 + LMK + + + GAZ041 + 100410 + Haralson + GA + US + 33.78 + -85.21 + 0 + 0 + FFC + + + KYZ046 + 170460 + Washington + KY + US + 37.77 + -85.20 + 0 + 0 + LMK + + + MIZ051 + 220510 + Montcalm + MI + US + 43.30 + -85.20 + 0 + 0 + GRR + + + TNZ099 + 420990 + Hamilton + TN + US + 35.23 + -85.20 + 0 + 0 + MRX + + + GAZ030 + 100300 + Polk + GA + US + 34.00 + -85.17 + 0 + 0 + FFC + + + INZ058 + 140580 + Fayette + IN + US + 39.65 + -85.17 + 0 + 0 + ILN + + + ALZ048 + 10480 + Russell + AL + US + 32.29 + -85.16 + 0 + 0 + BMX + + + FLZ013 + 90130 + Calhoun + FL + US + 30.40 + -85.16 + 0 + 0 + TAE + + + TNZ082 + 420820 + Bledsoe + TN + US + 35.57 + -85.16 + 0 + 0 + MRX + + + KYZ082 + 170820 + Clinton + KY + US + 36.75 + -85.15 + 0 + 0 + LMK + + + MIZ021 + 220210 + Antrim + MI + US + 45.01 + -85.15 + 0 + 0 + APX + + + KYZ089 + 170890 + Carroll + KY + US + 38.68 + -85.14 + 0 + 0 + ILN + + + TNZ011 + 420110 + Pickett + TN + US + 36.52 + -85.14 + 0 + 0 + OHX + + + GAZ003 + 100030 + Catoosa + GA + US + 34.88 + -85.12 + 0 + 0 + FFC + + + KYZ033 + 170330 + Henry + KY + US + 38.47 + -85.12 + 0 + 0 + LMK + + + GAZ052 + 100520 + Heard + GA + US + 33.28 + -85.11 + 0 + 0 + FFC + + + MIZ033 + 220330 + Missaukee + MI + US + 44.34 + -85.10 + 0 + 0 + APX + + + MIZ027 + 220270 + Kalkaska + MI + US + 44.69 + -85.09 + 0 + 0 + APX + + + MIZ058 + 220580 + Ionia + MI + US + 42.95 + -85.08 + 0 + 0 + GRR + + + GAZ042 + 100420 + Carroll + GA + US + 33.62 + -85.07 + 0 + 0 + FFC + + + INZ018 + 140180 + Allen + IN + US + 41.11 + -85.07 + 0 + 0 + IWX + + + KYZ078 + 170780 + Russell + KY + US + 37.01 + -85.07 + 0 + 0 + LMK + + + INZ066 + 140660 + Franklin + IN + US + 39.39 + -85.06 + 0 + 0 + ILN + + + MIZ019 + 220190 + Charlevoix + MI + US + 45.25 + -85.06 + 0 + 0 + APX + + + MIZ080 + 220800 + Branch + MI + US + 41.92 + -85.06 + 0 + 0 + IWX + + + GAZ066 + 100660 + Troup + GA + US + 33.04 + -85.04 + 0 + 0 + FFC + + + GAZ120 + 101200 + Quitman + GA + US + 31.88 + -85.02 + 0 + 0 + TAE + + + INZ050 + 140500 + Wayne + IN + US + 39.87 + -85.02 + 0 + 0 + ILN + + + INZ034 + 140340 + Jay + IN + US + 40.45 + -85.01 + 0 + 0 + IWX + + + INZ042 + 140420 + Randolph + IN + US + 40.17 + -85.01 + 0 + 0 + IND + + + MIZ073 + 220730 + Calhoun + MI + US + 42.25 + -85.01 + 0 + 0 + GRR + + + INZ080 + 140800 + Switzerland + IN + US + 38.81 + -85.00 + 0 + 0 + ILN + + + KYZ039 + 170390 + Anderson + KY + US + 38.00 + -85.00 + 0 + 0 + LMK + + + INZ007 + 140070 + Steuben + IN + US + 41.65 + -84.99 + 0 + 0 + IWX + + + INZ009 + 140090 + De_Kalb + IN + US + 41.41 + -84.99 + 0 + 0 + IWX + + + INZ075 + 140750 + Ohio + IN + US + 38.97 + -84.99 + 0 + 0 + ILN + + + MIZ015 + 220150 + Mackinac + MI + US + 46.04 + -84.99 + 0 + 0 + APX + + + GAZ004 + 100040 + Whitfield + GA + US + 34.80 + -84.98 + 0 + 0 + FFC + + + INZ074 + 140740 + Dearborn + IN + US + 39.12 + -84.98 + 0 + 0 + ILN + + + TNZ066 + 420660 + Cumberland + TN + US + 35.96 + -84.98 + 0 + 0 + OHX + + + GAZ121 + 101210 + Clay + GA + US + 31.64 + -84.96 + 0 + 0 + TAE + + + KYZ066 + 170660 + Casey + KY + US + 37.33 + -84.95 + 0 + 0 + LMK + + + MIZ016 + 220160 + Emmet + MI + US + 45.53 + -84.95 + 0 + 0 + APX + + + INZ027 + 140270 + Adams + IN + US + 40.76 + -84.94 + 0 + 0 + IWX + + + INZ059 + 140590 + Union + IN + US + 39.62 + -84.93 + 0 + 0 + ILN + + + GAZ078 + 100780 + Harris + GA + US + 32.73 + -84.92 + 0 + 0 + FFC + + + TNZ083 + 420830 + Rhea + TN + US + 35.62 + -84.92 + 0 + 0 + MRX + + + KYZ035 + 170350 + Franklin + KY + US + 38.23 + -84.89 + 0 + 0 + LMK + + + TNZ034 + 420340 + Fentress + TN + US + 36.36 + -84.89 + 0 + 0 + OHX + + + GAZ031 + 100310 + Paulding + GA + US + 33.93 + -84.88 + 0 + 0 + FFC + + + GAZ012 + 100120 + Gordon + GA + US + 34.51 + -84.87 + 0 + 0 + FFC + + + GAZ089 + 100890 + Muscogee + GA + US + 32.49 + -84.87 + 0 + 0 + FFC + + + GAZ142 + 101420 + Early + GA + US + 31.30 + -84.87 + 0 + 0 + TAE + + + GAZ155 + 101550 + Seminole + GA + US + 30.90 + -84.87 + 0 + 0 + TAE + + + KYZ047 + 170470 + Mercer + KY + US + 37.82 + -84.87 + 0 + 0 + LMK + + + KYZ055 + 170550 + Boyle + KY + US + 37.63 + -84.86 + 0 + 0 + LMK + + + FLZ026 + 90260 + Liberty + FL + US + 30.29 + -84.85 + 0 + 0 + TAE + + + GAZ102 + 101020 + Stewart + GA + US + 32.07 + -84.85 + 0 + 0 + FFC + + + KYZ090 + 170900 + Gallatin + KY + US + 38.77 + -84.85 + 0 + 0 + ILN + + + MIZ040 + 220400 + Clare + MI + US + 43.99 + -84.85 + 0 + 0 + GRR + + + MIZ046 + 220460 + Isabella + MI + US + 43.64 + -84.85 + 0 + 0 + GRR + + + TNZ100 + 421000 + Bradley + TN + US + 35.18 + -84.85 + 0 + 0 + MRX + + + GAZ020 + 100200 + Bartow + GA + US + 34.25 + -84.84 + 0 + 0 + FFC + + + MIZ066 + 220660 + Eaton + MI + US + 42.60 + -84.84 + 0 + 0 + GRR + + + KYZ083 + 170830 + Wayne + KY + US + 36.80 + -84.83 + 0 + 0 + JKL + + + KYZ094 + 170940 + Owen + KY + US + 38.53 + -84.83 + 0 + 0 + ILN + + + GAZ090 + 100900 + Chattahoochee + GA + US + 32.38 + -84.82 + 0 + 0 + FFC + + + TNZ084 + 420840 + Meigs + TN + US + 35.52 + -84.82 + 0 + 0 + MRX + + + FLZ015 + 90150 + Franklin + FL + US + 29.80 + -84.77 + 0 + 0 + TAE + + + GAZ005 + 100050 + Murray + GA + US + 34.79 + -84.76 + 0 + 0 + FFC + + + KYZ040 + 170400 + Woodford + KY + US + 38.02 + -84.76 + 0 + 0 + LMK + + + GAZ053 + 100530 + Coweta + GA + US + 33.35 + -84.75 + 0 + 0 + FFC + + + KYZ091 + 170910 + Boone + KY + US + 38.96 + -84.75 + 0 + 0 + ILN + + + GAZ043 + 100430 + Douglas + GA + US + 33.69 + -84.74 + 0 + 0 + FFC + + + GAZ122 + 101220 + Randolph + GA + US + 31.77 + -84.74 + 0 + 0 + TAE + + + GAZ143 + 101430 + Miller + GA + US + 31.17 + -84.72 + 0 + 0 + TAE + + + GAZ067 + 100670 + Meriwether + GA + US + 33.03 + -84.67 + 0 + 0 + FFC + + + KYZ067 + 170670 + Lincoln + KY + US + 37.44 + -84.66 + 0 + 0 + LMK + + + OHZ060 + 350600 + Preble + OH + US + 39.74 + -84.65 + 0 + 0 + ILN + + + KYZ095 + 170950 + Grant + KY + US + 38.64 + -84.64 + 0 + 0 + ILN + + + TNZ085 + 420850 + McMinn + TN + US + 35.45 + -84.63 + 0 + 0 + MRX + + + GAZ123 + 101230 + Calhoun + GA + US + 31.54 + -84.62 + 0 + 0 + TAE + + + GAZ156 + 101560 + Decatur + GA + US + 30.89 + -84.62 + 0 + 0 + TAE + + + MIZ022 + 220220 + Otsego + MI + US + 45.03 + -84.62 + 0 + 0 + APX + + + OHZ034 + 350340 + Mercer + OH + US + 40.54 + -84.62 + 0 + 0 + ILN + + + OHZ042 + 350420 + Darke + OH + US + 40.14 + -84.62 + 0 + 0 + ILN + + + TNZ035 + 420350 + Morgan + TN + US + 36.14 + -84.62 + 0 + 0 + MRX + + + FLZ016 + 90160 + Gadsden + FL + US + 30.56 + -84.61 + 0 + 0 + TAE + + + KYZ079 + 170790 + Pulaski + KY + US + 37.12 + -84.61 + 0 + 0 + JKL + + + MIZ028 + 220280 + Crawford + MI + US + 44.69 + -84.61 + 0 + 0 + APX + + + MIZ034 + 220340 + Roscommon + MI + US + 44.34 + -84.61 + 0 + 0 + APX + + + MIZ052 + 220520 + Gratiot + MI + US + 43.30 + -84.61 + 0 + 0 + GRR + + + MIZ059 + 220590 + Clinton + MI + US + 42.95 + -84.60 + 0 + 0 + GRR + + + MIZ081 + 220810 + Hillsdale + MI + US + 41.89 + -84.60 + 0 + 0 + IWX + + + GAZ044 + 100440 + South_Fulton + GA + US + 33.62 + -84.59 + 0 + 0 + FFC + + + KYZ036 + 170360 + Scott + KY + US + 38.30 + -84.59 + 0 + 0 + LMK + + + KYZ048 + 170480 + Jessamine + KY + US + 37.87 + -84.59 + 0 + 0 + LMK + + + OHZ070 + 350700 + Butler + OH + US + 39.44 + -84.58 + 0 + 0 + ILN + + + OHZ015 + 350150 + Paulding + OH + US + 41.12 + -84.57 + 0 + 0 + IWX + + + OHZ024 + 350240 + Van_Wert + OH + US + 40.84 + -84.57 + 0 + 0 + IWX + + + TNZ101 + 421010 + West_Polk + TN + US + 35.14 + -84.57 + 0 + 0 + MRX + + + GAZ032 + 100320 + Cobb + GA + US + 33.93 + -84.56 + 0 + 0 + FFC + + + OHZ001 + 350010 + Williams + OH + US + 41.57 + -84.56 + 0 + 0 + IWX + + + KYZ056 + 170560 + Garrard + KY + US + 37.65 + -84.55 + 0 + 0 + LMK + + + GAZ103 + 101030 + Webster + GA + US + 32.07 + -84.54 + 0 + 0 + FFC + + + OHZ077 + 350770 + Hamilton + OH + US + 39.16 + -84.54 + 0 + 0 + ILN + + + GAZ091 + 100910 + Marion + GA + US + 32.35 + -84.52 + 0 + 0 + FFC + + + KYZ084 + 170840 + McCreary + KY + US + 36.78 + -84.52 + 0 + 0 + JKL + + + KYZ092 + 170920 + Kenton + KY + US + 38.94 + -84.52 + 0 + 0 + ILN + + + TNZ067 + 420670 + Roane + TN + US + 35.85 + -84.52 + 0 + 0 + MRX + + + OHZ004 + 350040 + Defiance + OH + US + 41.29 + -84.51 + 0 + 0 + IWX + + + TNZ012 + 420120 + Scott + TN + US + 36.39 + -84.51 + 0 + 0 + MRX + + + GAZ054 + 100540 + Fayette + GA + US + 33.41 + -84.49 + 0 + 0 + FFC + + + GAZ079 + 100790 + Talbot + GA + US + 32.70 + -84.49 + 0 + 0 + FFC + + + KYZ041 + 170410 + Fayette + KY + US + 38.03 + -84.48 + 0 + 0 + LMK + + + MIZ017 + 220170 + Cheboygan + MI + US + 45.49 + -84.47 + 0 + 0 + APX + + + GAZ013 + 100130 + Pickens + GA + US + 34.47 + -84.46 + 0 + 0 + FFC + + + GAZ021 + 100210 + Cherokee + GA + US + 34.25 + -84.46 + 0 + 0 + FFC + + + TNZ102 + 421020 + East_Polk + TN + US + 35.12 + -84.44 + 0 + 0 + MRX + + + MIZ074 + 220740 + Jackson + MI + US + 42.25 + -84.43 + 0 + 0 + GRR + + + GAZ007 + 100070 + Gilmer + GA + US + 34.70 + -84.42 + 0 + 0 + FFC + + + GAZ124 + 101240 + Terrell + GA + US + 31.79 + -84.42 + 0 + 0 + TAE + + + FLZ027 + 90270 + Wakulla + FL + US + 30.14 + -84.40 + 0 + 0 + TAE + + + GAZ068 + 100680 + Pike + GA + US + 33.09 + -84.39 + 0 + 0 + FFC + + + GAZ144 + 101440 + Baker + GA + US + 31.27 + -84.39 + 0 + 0 + TAE + + + MIZ041 + 220410 + Gladwin + MI + US + 43.99 + -84.39 + 0 + 0 + APX + + + MIZ047 + 220470 + Midland + MI + US + 43.65 + -84.39 + 0 + 0 + DTX + + + KYZ093 + 170930 + Campbell + KY + US + 38.96 + -84.37 + 0 + 0 + ILN + + + KYZ096 + 170960 + Pendleton + KY + US + 38.70 + -84.37 + 0 + 0 + ILN + + + MIZ067 + 220670 + Ingham + MI + US + 42.60 + -84.37 + 0 + 0 + GRR + + + GAZ033 + 100330 + North_Fulton + GA + US + 33.92 + -84.35 + 0 + 0 + FFC + + + GAZ055 + 100550 + Clayton + GA + US + 33.50 + -84.35 + 0 + 0 + FFC + + + MIZ008 + 220080 + Chippewa + MI + US + 46.34 + -84.35 + 0 + 0 + APX + + + TNZ068 + 420680 + Loudon + TN + US + 35.76 + -84.35 + 0 + 0 + MRX + + + FLZ017 + 90170 + Leon + FL + US + 30.49 + -84.34 + 0 + 0 + TAE + + + KYZ037 + 170370 + Harrison + KY + US + 38.43 + -84.33 + 0 + 0 + LMK + + + KYZ068 + 170680 + Rockcastle + KY + US + 37.35 + -84.33 + 0 + 0 + JKL + + + GAZ069 + 100690 + Upson + GA + US + 32.85 + -84.32 + 0 + 0 + FFC + + + KYZ057 + 170570 + Madison + KY + US + 37.72 + -84.31 + 0 + 0 + LMK + + + GAZ092 + 100920 + Schley + GA + US + 32.29 + -84.30 + 0 + 0 + FFC + + + GAZ056 + 100560 + Spalding + GA + US + 33.27 + -84.29 + 0 + 0 + FFC + + + TNZ086 + 420860 + Northwest_Monroe + TN + US + 35.46 + -84.28 + 0 + 0 + MRX + + + OHZ061 + 350610 + Montgomery + OH + US + 39.75 + -84.27 + 0 + 0 + ILN + + + GAZ145 + 101450 + Mitchell + GA + US + 31.26 + -84.25 + 0 + 0 + TAE + + + GAZ080 + 100800 + Taylor + GA + US + 32.55 + -84.23 + 0 + 0 + FFC + + + GAZ006 + 100060 + Fannin + GA + US + 34.80 + -84.22 + 0 + 0 + FFC + + + GAZ157 + 101570 + Grady + GA + US + 30.88 + -84.22 + 0 + 0 + TAE + + + OHZ051 + 350510 + Miami + OH + US + 40.04 + -84.22 + 0 + 0 + ILN + + + GAZ125 + 101250 + Dougherty + GA + US + 31.55 + -84.21 + 0 + 0 + TAE + + + KYZ042 + 170420 + Bourbon + KY + US + 38.22 + -84.21 + 0 + 0 + LMK + + + OHZ043 + 350430 + Shelby + OH + US + 40.33 + -84.21 + 0 + 0 + ILN + + + TNZ036 + 420360 + Anderson + TN + US + 36.10 + -84.20 + 0 + 0 + MRX + + + GAZ045 + 100450 + DeKalb + GA + US + 33.79 + -84.19 + 0 + 0 + FFC + + + GAZ104 + 101040 + Sumter + GA + US + 32.05 + -84.18 + 0 + 0 + FFC + + + KYZ049 + 170490 + Clark + KY + US + 37.97 + -84.17 + 0 + 0 + LMK + + + OHZ071 + 350710 + Warren + OH + US + 39.42 + -84.17 + 0 + 0 + ILN + + + OHZ035 + 350350 + Auglaize + OH + US + 40.52 + -84.16 + 0 + 0 + ILN + + + GAZ014 + 100140 + Dawson + GA + US + 34.48 + -84.15 + 0 + 0 + FFC + + + GAZ070 + 100700 + Lamar + GA + US + 33.06 + -84.15 + 0 + 0 + FFC + + + MIZ060 + 220600 + Shiawassee + MI + US + 42.96 + -84.15 + 0 + 0 + DTX + + + OHZ078 + 350780 + Clermont + OH + US + 39.02 + -84.15 + 0 + 0 + ILN + + + TNZ087 + 420870 + Southeast_Monroe + TN + US + 35.38 + -84.15 + 0 + 0 + MRX + + + GAZ057 + 100570 + Henry + GA + US + 33.48 + -84.14 + 0 + 0 + FFC + + + TNZ013 + 420130 + Campbell + TN + US + 36.39 + -84.14 + 0 + 0 + MRX + + + GAZ126 + 101260 + Lee + GA + US + 31.77 + -84.13 + 0 + 0 + TAE + + + MIZ023 + 220230 + Montmorency + MI + US + 45.03 + -84.13 + 0 + 0 + APX + + + MIZ029 + 220290 + Oscoda + MI + US + 44.68 + -84.13 + 0 + 0 + APX + + + MIZ035 + 220350 + Ogemaw + MI + US + 44.34 + -84.13 + 0 + 0 + APX + + + OHZ016 + 350160 + Putnam + OH + US + 41.01 + -84.13 + 0 + 0 + IWX + + + OHZ025 + 350250 + Allen + OH + US + 40.78 + -84.13 + 0 + 0 + IWX + + + KYZ080 + 170800 + Laurel + KY + US + 37.13 + -84.12 + 0 + 0 + JKL + + + KYZ085 + 170850 + Whitley + KY + US + 36.78 + -84.12 + 0 + 0 + JKL + + + OHZ002 + 350020 + Fulton + OH + US + 41.60 + -84.12 + 0 + 0 + IWX + + + OHZ005 + 350050 + Henry + OH + US + 41.32 + -84.10 + 0 + 0 + IWX + + + GAZ022 + 100220 + Forsyth + GA + US + 34.19 + -84.09 + 0 + 0 + FFC + + + KYZ097 + 170970 + Bracken + KY + US + 38.68 + -84.08 + 0 + 0 + ILN + + + KYZ098 + 170980 + Robertson + KY + US + 38.51 + -84.08 + 0 + 0 + ILN + + + MIZ082 + 220820 + Lenawee + MI + US + 41.90 + -84.07 + 0 + 0 + DTX + + + MIZ048 + 220480 + Bay + MI + US + 43.74 + -84.06 + 0 + 0 + DTX + + + GAZ046 + 100460 + Rockdale + GA + US + 33.66 + -84.04 + 0 + 0 + FFC + + + GAZ093 + 100930 + Macon + GA + US + 32.35 + -84.04 + 0 + 0 + FFC + + + GAZ034 + 100340 + Gwinnett + GA + US + 33.96 + -84.03 + 0 + 0 + FFC + + + MIZ053 + 220530 + Saginaw + MI + US + 43.35 + -84.03 + 0 + 0 + DTX + + + KYZ043 + 170430 + Nicholas + KY + US + 38.33 + -84.02 + 0 + 0 + LMK + + + GAZ015 + 100150 + Lumpkin + GA + US + 34.57 + -84.01 + 0 + 0 + FFC + + + NCZ060 + 330600 + Cherokee + NC + US + 35.14 + -84.01 + 0 + 0 + MRX + + + KYZ069 + 170690 + Jackson + KY + US + 37.42 + -84.00 + 0 + 0 + JKL + + + GAZ008 + 100080 + Union + GA + US + 34.81 + -83.98 + 0 + 0 + FFC + + + GAZ058 + 100580 + Butts + GA + US + 33.32 + -83.97 + 0 + 0 + FFC + + + GAZ081 + 100810 + Crawford + GA + US + 32.69 + -83.97 + 0 + 0 + FFC + + + TNZ069 + 420690 + Knox + TN + US + 35.99 + -83.96 + 0 + 0 + MRX + + + KYZ058 + 170580 + Estill + KY + US + 37.70 + -83.93 + 0 + 0 + JKL + + + GAZ071 + 100710 + Monroe + GA + US + 33.02 + -83.92 + 0 + 0 + FFC + + + GAZ158 + 101580 + Thomas + GA + US + 30.87 + -83.92 + 0 + 0 + TAE + + + KYZ050 + 170500 + Montgomery + KY + US + 38.05 + -83.92 + 0 + 0 + JKL + + + TNZ071 + 420710 + NW_Blount + TN + US + 35.71 + -83.92 + 0 + 0 + MRX + + + MIZ068 + 220680 + Livingston + MI + US + 42.61 + -83.91 + 0 + 0 + DTX + + + OHZ062 + 350620 + Greene + OH + US + 39.70 + -83.88 + 0 + 0 + ILN + + + MIZ042 + 220420 + Arenac + MI + US + 44.04 + -83.87 + 0 + 0 + APX + + + GAZ048 + 100480 + Newton + GA + US + 33.56 + -83.86 + 0 + 0 + FFC + + + GAZ094 + 100940 + Peach + GA + US + 32.56 + -83.86 + 0 + 0 + FFC + + + OHZ079 + 350790 + Brown + OH + US + 38.95 + -83.86 + 0 + 0 + ILN + + + FLZ018 + 90180 + Jefferson + FL + US + 30.38 + -83.84 + 0 + 0 + TAE + + + GAZ023 + 100230 + Hall + GA + US + 34.30 + -83.84 + 0 + 0 + FFC + + + GAZ127 + 101270 + Worth + GA + US + 31.59 + -83.84 + 0 + 0 + TAE + + + KYZ059 + 170590 + Powell + KY + US + 37.83 + -83.84 + 0 + 0 + JKL + + + KYZ086 + 170860 + Knox + KY + US + 36.87 + -83.84 + 0 + 0 + JKL + + + MIZ075 + 220750 + Washtenaw + MI + US + 42.26 + -83.84 + 0 + 0 + DTX + + + TNZ037 + 420370 + Union + TN + US + 36.30 + -83.84 + 0 + 0 + MRX + + + TNZ072 + 420720 + Blount_Smoky_Mountains + TN + US + 35.57 + -83.84 + 0 + 0 + MRX + + + GAZ105 + 101050 + Dooly + GA + US + 32.16 + -83.82 + 0 + 0 + FFC + + + KYZ099 + 170990 + Mason + KY + US + 38.62 + -83.82 + 0 + 0 + ILN + + + MIZ018 + 220180 + Presque_Isle + MI + US + 45.42 + -83.82 + 0 + 0 + APX + + + NCZ058 + 330580 + Graham + NC + US + 35.34 + -83.81 + 0 + 0 + GSP + + + OHZ072 + 350720 + Clinton + OH + US + 39.39 + -83.79 + 0 + 0 + ILN + + + GAZ106 + 101060 + Crisp + GA + US + 31.91 + -83.78 + 0 + 0 + FFC + + + OHZ053 + 350530 + Clark + OH + US + 39.90 + -83.78 + 0 + 0 + ILN + + + OHZ044 + 350440 + Logan + OH + US + 40.38 + -83.76 + 0 + 0 + ILN + + + OHZ052 + 350520 + Champaign + OH + US + 40.14 + -83.76 + 0 + 0 + ILN + + + GAZ016 + 100160 + White + GA + US + 34.65 + -83.75 + 0 + 0 + FFC + + + GAZ047 + 100470 + Walton + GA + US + 33.76 + -83.75 + 0 + 0 + FFC + + + GAZ146 + 101460 + Colquitt + GA + US + 31.18 + -83.75 + 0 + 0 + TAE + + + NCZ061 + 330610 + Clay + NC + US + 35.07 + -83.75 + 0 + 0 + MRX + + + GAZ009 + 100090 + Towns + GA + US + 34.89 + -83.74 + 0 + 0 + FFC + + + KYZ116 + 171160 + Clay + KY + US + 37.15 + -83.74 + 0 + 0 + JKL + + + OHZ003 + 350030 + Lucas + OH + US + 41.57 + -83.74 + 0 + 0 + CLE + + + KYZ051 + 170510 + Bath + KY + US + 38.15 + -83.73 + 0 + 0 + JKL + + + KYZ044 + 170440 + Fleming + KY + US + 38.36 + -83.72 + 0 + 0 + JKL + + + KYZ111 + 171110 + Lee + KY + US + 37.60 + -83.72 + 0 + 0 + JKL + + + KYZ087 + 170870 + Bell + KY + US + 36.77 + -83.71 + 0 + 0 + JKL + + + KYZ114 + 171140 + Owsley + KY + US + 37.40 + -83.71 + 0 + 0 + JKL + + + GAZ035 + 100350 + Barrow + GA + US + 34.01 + -83.70 + 0 + 0 + FFC + + + GAZ059 + 100590 + Jasper + GA + US + 33.33 + -83.69 + 0 + 0 + FFC + + + GAZ082 + 100820 + Bibb + GA + US + 32.80 + -83.69 + 0 + 0 + FFC + + + MIZ061 + 220610 + Genesee + MI + US + 43.00 + -83.69 + 0 + 0 + DTX + + + TNZ014 + 420140 + Claiborne + TN + US + 36.47 + -83.69 + 0 + 0 + MRX + + + GAZ095 + 100950 + Houston + GA + US + 32.49 + -83.67 + 0 + 0 + FFC + + + FLZ028 + 90280 + Taylor + FL + US + 29.99 + -83.65 + 0 + 0 + TAE + + + OHZ026 + 350260 + Hardin + OH + US + 40.66 + -83.65 + 0 + 0 + ILN + + + OHZ006 + 350060 + Wood + OH + US + 41.39 + -83.64 + 0 + 0 + CLE + + + OHZ017 + 350170 + Hancock + OH + US + 40.99 + -83.64 + 0 + 0 + CLE + + + GAZ128 + 101280 + Turner + GA + US + 31.71 + -83.63 + 0 + 0 + TAE + + + KYZ060 + 170600 + Menifee + KY + US + 37.94 + -83.61 + 0 + 0 + JKL + + + OHZ080 + 350800 + Highland + OH + US + 39.20 + -83.61 + 0 + 0 + ILN + + + MIZ036 + 220360 + Iosco + MI + US + 44.34 + -83.60 + 0 + 0 + APX + + + GAZ025 + 100250 + Jackson + GA + US + 34.13 + -83.59 + 0 + 0 + FFC + + + MIZ030 + 220300 + Alcona + MI + US + 44.69 + -83.59 + 0 + 0 + APX + + + GAZ072 + 100720 + Jones + GA + US + 33.01 + -83.58 + 0 + 0 + FFC + + + NCZ051 + 330510 + Swain + NC + US + 35.48 + -83.56 + 0 + 0 + GSP + + + GAZ159 + 101590 + Brooks + GA + US + 30.85 + -83.55 + 0 + 0 + TAE + + + MIZ024 + 220240 + Alpena + MI + US + 45.03 + -83.54 + 0 + 0 + APX + + + TNZ073 + 420730 + North_Sevier + TN + US + 35.87 + -83.53 + 0 + 0 + MRX + + + GAZ017 + 100170 + Habersham + GA + US + 34.63 + -83.51 + 0 + 0 + GSP + + + GAZ024 + 100240 + Banks + GA + US + 34.35 + -83.50 + 0 + 0 + FFC + + + GAZ129 + 101290 + Tift + GA + US + 31.46 + -83.50 + 0 + 0 + TAE + + + TNZ038 + 420380 + Grainger + TN + US + 36.25 + -83.50 + 0 + 0 + MRX + + + FLZ019 + 90190 + Madison + FL + US + 30.46 + -83.49 + 0 + 0 + TAE + + + OHZ081 + 350810 + Adams + OH + US + 38.82 + -83.49 + 0 + 0 + ILN + + + GAZ049 + 100490 + Morgan + GA + US + 33.62 + -83.48 + 0 + 0 + FFC + + + KYZ108 + 171080 + Wolfe + KY + US + 37.75 + -83.48 + 0 + 0 + JKL + + + MIZ083 + 220830 + Monroe + MI + US + 41.91 + -83.48 + 0 + 0 + DTX + + + TNZ070 + 420700 + Jefferson + TN + US + 36.04 + -83.47 + 0 + 0 + MRX + + + GAZ037 + 100370 + Oconee + GA + US + 33.83 + -83.46 + 0 + 0 + FFC + + + GAZ107 + 101070 + Pulaski + GA + US + 32.25 + -83.46 + 0 + 0 + FFC + + + OHZ063 + 350630 + Fayette + OH + US + 39.54 + -83.46 + 0 + 0 + ILN + + + TNZ074 + 420740 + Sevier_Smoky_Mountains + TN + US + 35.69 + -83.46 + 0 + 0 + MRX + + + GAZ147 + 101470 + Cook + GA + US + 31.19 + -83.43 + 0 + 0 + TAE + + + OHZ054 + 350540 + Madison + OH + US + 39.90 + -83.43 + 0 + 0 + ILN + + + KYZ052 + 170520 + Rowan + KY + US + 38.21 + -83.42 + 0 + 0 + JKL + + + NCZ062 + 330620 + Macon + NC + US + 35.16 + -83.42 + 0 + 0 + GSP + + + GAZ083 + 100830 + Twiggs + GA + US + 32.67 + -83.41 + 0 + 0 + FFC + + + MIZ054 + 220540 + Tuscola + MI + US + 43.51 + -83.40 + 0 + 0 + DTX + + + GAZ108 + 101080 + Wilcox + GA + US + 31.98 + -83.39 + 0 + 0 + FFC + + + MIZ069 + 220690 + Oakland + MI + US + 42.66 + -83.39 + 0 + 0 + DTX + + + GAZ010 + 100100 + Rabun + GA + US + 34.85 + -83.38 + 0 + 0 + GSP + + + GAZ036 + 100360 + Clarke + GA + US + 33.95 + -83.38 + 0 + 0 + FFC + + + KYZ117 + 171170 + Leslie + KY + US + 37.11 + -83.36 + 0 + 0 + JKL + + + OHZ045 + 350450 + Union + OH + US + 40.30 + -83.36 + 0 + 0 + ILN + + + GAZ060 + 100600 + Putnam + GA + US + 33.32 + -83.34 + 0 + 0 + FFC + + + KYZ100 + 171000 + Lewis + KY + US + 38.52 + -83.34 + 0 + 0 + ILN + + + GAZ096 + 100960 + Bleckley + GA + US + 32.42 + -83.32 + 0 + 0 + FFC + + + OHZ027 + 350270 + Wyandot + OH + US + 40.84 + -83.31 + 0 + 0 + CLE + + + GAZ018 + 100180 + Stephens + GA + US + 34.57 + -83.29 + 0 + 0 + GSP + + + KYZ112 + 171120 + Breathitt + KY + US + 37.52 + -83.28 + 0 + 0 + JKL + + + KYZ115 + 171150 + Perry + KY + US + 37.22 + -83.28 + 0 + 0 + JKL + + + TNZ039 + 420390 + Hamblen + TN + US + 36.23 + -83.28 + 0 + 0 + MRX + + + GAZ131 + 101310 + Irwin + GA + US + 31.62 + -83.25 + 0 + 0 + TAE + + + GAZ160 + 101600 + Lowndes + GA + US + 30.82 + -83.25 + 0 + 0 + TAE + + + GAZ073 + 100730 + Baldwin + GA + US + 33.05 + -83.24 + 0 + 0 + FFC + + + GAZ130 + 101300 + Ben_Hill + GA + US + 31.75 + -83.24 + 0 + 0 + TAE + + + GAZ026 + 100260 + Franklin + GA + US + 34.39 + -83.23 + 0 + 0 + GSP + + + GAZ148 + 101480 + Berrien + GA + US + 31.25 + -83.23 + 0 + 0 + TAE + + + KYZ106 + 171060 + Morgan + KY + US + 37.92 + -83.23 + 0 + 0 + JKL + + + MIZ062 + 220620 + Lapeer + MI + US + 43.11 + -83.22 + 0 + 0 + DTX + + + MIZ076 + 220760 + Wayne + MI + US + 42.25 + -83.21 + 0 + 0 + DTX + + + GAZ027 + 100270 + Madison + GA + US + 34.13 + -83.19 + 0 + 0 + FFC + + + KYZ088 + 170880 + Harlan + KY + US + 36.85 + -83.19 + 0 + 0 + JKL + + + GAZ050 + 100500 + Greene + GA + US + 33.56 + -83.18 + 0 + 0 + FFC + + + GAZ084 + 100840 + Wilkinson + GA + US + 32.79 + -83.18 + 0 + 0 + FFC + + + FLZ034 + 90340 + Dixie + FL + US + 29.56 + -83.16 + 0 + 0 + TAE + + + NCZ059 + 330590 + Northern_Jackson + NC + US + 35.37 + -83.14 + 0 + 0 + GSP + + + OHZ036 + 350360 + Marion + OH + US + 40.57 + -83.14 + 0 + 0 + CLE + + + TNZ015 + 420150 + Hancock + TN + US + 36.50 + -83.14 + 0 + 0 + MRX + + + TNZ040 + 420400 + Northwest_Cocke + TN + US + 36.00 + -83.13 + 0 + 0 + MRX + + + FLZ029 + 90290 + Lafayette + FL + US + 30.04 + -83.12 + 0 + 0 + TAE + + + GAZ109 + 101090 + Dodge + GA + US + 32.17 + -83.12 + 0 + 0 + FFC + + + OHZ008 + 350080 + Sandusky + OH + US + 41.37 + -83.12 + 0 + 0 + CLE + + + OHZ018 + 350180 + Seneca + OH + US + 41.12 + -83.12 + 0 + 0 + CLE + + + SCZ001 + 400010 + Oconee_Mountains + SC + US + 34.83 + -83.12 + 0 + 0 + GSP + + + TNZ041 + 420410 + Cocke_Smoky_Mountains + TN + US + 35.86 + -83.09 + 0 + 0 + MRX + + + GAZ161 + 101610 + Lanier + GA + US + 31.02 + -83.08 + 0 + 0 + TAE + + + KYZ104 + 171040 + Elliott + KY + US + 38.14 + -83.08 + 0 + 0 + JKL + + + KYZ109 + 171090 + Magoffin + KY + US + 37.69 + -83.08 + 0 + 0 + JKL + + + OHZ082 + 350820 + Pike + OH + US + 39.07 + -83.08 + 0 + 0 + ILN + + + NCZ063 + 330630 + Southern_Jackson + NC + US + 35.15 + -83.07 + 0 + 0 + GSP + + + OHZ073 + 350730 + Ross + OH + US + 39.34 + -83.07 + 0 + 0 + ILN + + + KYZ102 + 171020 + Carter + KY + US + 38.34 + -83.06 + 0 + 0 + RLX + + + OHZ007 + 350070 + Ottawa + OH + US + 41.54 + -83.06 + 0 + 0 + CLE + + + GAZ038 + 100380 + Oglethorpe + GA + US + 33.87 + -83.04 + 0 + 0 + FFC + + + MIZ049 + 220490 + Huron + MI + US + 43.87 + -83.04 + 0 + 0 + DTX + + + GAZ061 + 100610 + Hancock + GA + US + 33.27 + -83.02 + 0 + 0 + FFC + + + OHZ055 + 350550 + Franklin + OH + US + 39.96 + -83.01 + 0 + 0 + ILN + + + FLZ021 + 90210 + Suwannee + FL + US + 30.17 + -83.00 + 0 + 0 + JAX + + + NCZ052 + 330520 + Haywood + NC + US + 35.54 + -83.00 + 0 + 0 + GSP + + + OHZ064 + 350640 + Pickaway + OH + US + 39.63 + -83.00 + 0 + 0 + ILN + + + SCZ004 + 400040 + Greater_Oconee + SC + US + 34.64 + -83.00 + 0 + 0 + GSP + + + VAZ001 + 460010 + Lee + VA + US + 36.74 + -83.00 + 0 + 0 + MRX + + + OHZ046 + 350460 + Delaware + OH + US + 40.28 + -82.99 + 0 + 0 + ILN + + + FLZ020 + 90200 + Hamilton + FL + US + 30.48 + -82.96 + 0 + 0 + JAX + + + OHZ088 + 350880 + Scioto + OH + US + 38.79 + -82.96 + 0 + 0 + ILN + + + GAZ028 + 100280 + Hart + GA + US + 34.35 + -82.95 + 0 + 0 + GSP + + + TNZ016 + 420160 + Hawkins + TN + US + 36.42 + -82.94 + 0 + 0 + MRX + + + GAZ097 + 100970 + Laurens + GA + US + 32.43 + -82.93 + 0 + 0 + FFC + + + GAZ110 + 101100 + Telfair + GA + US + 31.96 + -82.93 + 0 + 0 + FFC + + + KYZ101 + 171010 + Greenup + KY + US + 38.56 + -82.92 + 0 + 0 + RLX + + + KYZ113 + 171130 + Knott + KY + US + 37.36 + -82.92 + 0 + 0 + JKL + + + MIZ070 + 220700 + Macomb + MI + US + 42.68 + -82.92 + 0 + 0 + DTX + + + OHZ028 + 350280 + Crawford + OH + US + 40.85 + -82.91 + 0 + 0 + CLE + + + GAZ149 + 101490 + Atkinson + GA + US + 31.30 + -82.88 + 0 + 0 + JAX + + + TNZ042 + 420420 + Northwest_Greene + TN + US + 36.21 + -82.88 + 0 + 0 + MRX + + + GAZ132 + 101320 + Coffee + GA + US + 31.59 + -82.87 + 0 + 0 + JAX + + + GAZ162 + 101620 + Echols + GA + US + 30.73 + -82.86 + 0 + 0 + JAX + + + KYZ118 + 171180 + Letcher + KY + US + 37.12 + -82.86 + 0 + 0 + JKL + + + GAZ051 + 100510 + Taliaferro + GA + US + 33.59 + -82.85 + 0 + 0 + FFC + + + GAZ029 + 100290 + Elbert + GA + US + 34.12 + -82.84 + 0 + 0 + GSP + + + KYZ107 + 171070 + Johnson + KY + US + 37.86 + -82.82 + 0 + 0 + JKL + + + OHZ037 + 350370 + Morrow + OH + US + 40.53 + -82.82 + 0 + 0 + CLE + + + FLZ035 + 90350 + Gilchrist + FL + US + 29.75 + -82.81 + 0 + 0 + JAX + + + MIZ055 + 220550 + Sanilac + MI + US + 43.43 + -82.81 + 0 + 0 + DTX + + + NCZ064 + 330640 + Transylvania + NC + US + 35.22 + -82.81 + 0 + 0 + GSP + + + GAZ074 + 100740 + Washington + GA + US + 32.99 + -82.79 + 0 + 0 + FFC + + + FLZ039 + 90390 + Levy + FL + US + 29.30 + -82.78 + 0 + 0 + TBW + + + TNZ043 + 420430 + Southeast_Greene + TN + US + 36.01 + -82.77 + 0 + 0 + MRX + + + KYZ110 + 171100 + Floyd + KY + US + 37.52 + -82.76 + 0 + 0 + JKL + + + GAZ111 + 101110 + Wheeler + GA + US + 32.11 + -82.75 + 0 + 0 + FFC + + + KYZ105 + 171050 + Lawrence + KY + US + 38.08 + -82.75 + 0 + 0 + RLX + + + GAZ039 + 100390 + Wilkes + GA + US + 33.79 + -82.74 + 0 + 0 + FFC + + + SCZ002 + 400020 + Pickens_Mountains + SC + US + 34.95 + -82.73 + 0 + 0 + GSP + + + FLZ050 + 90500 + Pinellas + FL + US + 27.89 + -82.71 + 0 + 0 + TBW + + + MIZ063 + 220630 + St._Clair + MI + US + 42.85 + -82.71 + 0 + 0 + DTX + + + GAZ085 + 100850 + Johnson + GA + US + 32.67 + -82.70 + 0 + 0 + FFC + + + KYZ103 + 171030 + Boyd + KY + US + 38.37 + -82.70 + 0 + 0 + RLX + + + GAZ163 + 101630 + Clinch + GA + US + 30.88 + -82.69 + 0 + 0 + JAX + + + SCZ005 + 400050 + Greater_Pickens + SC + US + 34.79 + -82.69 + 0 + 0 + GSP + + + NCZ048 + 330480 + Madison + NC + US + 35.87 + -82.68 + 0 + 0 + GSP + + + SCZ010 + 400100 + Anderson + SC + US + 34.51 + -82.65 + 0 + 0 + GSP + + + VAZ005 + 460050 + Scott + VA + US + 36.74 + -82.64 + 0 + 0 + MRX + + + GAZ062 + 100620 + Warren + GA + US + 33.43 + -82.63 + 0 + 0 + FFC + + + GAZ133 + 101330 + Jeff_Davis + GA + US + 31.82 + -82.63 + 0 + 0 + JAX + + + FLZ022 + 90220 + Columbia + FL + US + 30.21 + -82.62 + 0 + 0 + JAX + + + OHZ009 + 350090 + Erie + OH + US + 41.39 + -82.62 + 0 + 0 + CLE + + + OHZ083 + 350830 + Jackson + OH + US + 39.02 + -82.62 + 0 + 0 + RLX + + + OHZ065 + 350650 + Fairfield + OH + US + 39.74 + -82.60 + 0 + 0 + ILN + + + GAZ075 + 100750 + Glascock + GA + US + 33.23 + -82.59 + 0 + 0 + FFC + + + VAZ002 + 460020 + Wise + VA + US + 37.00 + -82.59 + 0 + 0 + MRX + + + OHZ019 + 350190 + Huron + OH + US + 41.14 + -82.58 + 0 + 0 + CLE + + + GAZ098 + 100980 + Treutlen + GA + US + 32.40 + -82.56 + 0 + 0 + FFC + + + OHZ087 + 350870 + Lawrence + OH + US + 38.62 + -82.56 + 0 + 0 + RLX + + + GAZ112 + 101120 + Montgomery + GA + US + 32.15 + -82.53 + 0 + 0 + FFC + + + NCZ053 + 330530 + Buncombe + NC + US + 35.62 + -82.53 + 0 + 0 + GSP + + + OHZ029 + 350290 + Richland + OH + US + 40.77 + -82.53 + 0 + 0 + CLE + + + OHZ084 + 350840 + Vinton + OH + US + 39.21 + -82.51 + 0 + 0 + RLX + + + KYZ119 + 171190 + Martin + KY + US + 37.82 + -82.50 + 0 + 0 + JKL + + + NCZ065 + 330650 + Henderson + NC + US + 35.32 + -82.50 + 0 + 0 + GSP + + + SCZ003 + 400030 + Greenville_Mountains + SC + US + 35.09 + -82.49 + 0 + 0 + GSP + + + SCZ011 + 400110 + Abbeville + SC + US + 34.25 + -82.49 + 0 + 0 + GSP + + + TNZ044 + 420440 + Washington + TN + US + 36.27 + -82.49 + 0 + 0 + MRX + + + OHZ056 + 350560 + Licking + OH + US + 40.09 + -82.48 + 0 + 0 + ILN + + + GAZ063 + 100630 + McDuffie + GA + US + 33.49 + -82.47 + 0 + 0 + CAE + + + FLZ042 + 90420 + Citrus + FL + US + 28.86 + -82.46 + 0 + 0 + TBW + + + OHZ047 + 350470 + Knox + OH + US + 40.40 + -82.46 + 0 + 0 + CLE + + + FLZ049 + 90490 + Pasco + FL + US + 28.32 + -82.45 + 0 + 0 + TBW + + + OHZ074 + 350740 + Hocking + OH + US + 39.50 + -82.45 + 0 + 0 + ILN + + + GAZ040 + 100400 + Lincoln + GA + US + 33.81 + -82.44 + 0 + 0 + CAE + + + GAZ076 + 100760 + Jefferson + GA + US + 33.04 + -82.44 + 0 + 0 + FFC + + + GAZ134 + 101340 + Bacon + GA + US + 31.56 + -82.42 + 0 + 0 + JAX + + + GAZ150 + 101500 + Ware + GA + US + 31.02 + -82.41 + 0 + 0 + JAX + + + TNZ045 + 420450 + Unicoi + TN + US + 36.11 + -82.41 + 0 + 0 + MRX + + + WVZ005 + 480050 + Wayne + WV + US + 38.14 + -82.41 + 0 + 0 + RLX + + + FLZ055 + 90550 + Manatee + FL + US + 27.43 + -82.40 + 0 + 0 + TBW + + + FLZ048 + 90480 + Hernando + FL + US + 28.56 + -82.37 + 0 + 0 + TBW + + + FLZ030 + 90300 + Union + FL + US + 30.03 + -82.35 + 0 + 0 + JAX + + + FLZ036 + 90360 + Alachua + FL + US + 29.68 + -82.35 + 0 + 0 + JAX + + + FLZ051 + 90510 + Hillsborough + FL + US + 27.91 + -82.35 + 0 + 0 + TBW + + + FLZ060 + 90600 + Sarasota + FL + US + 27.17 + -82.35 + 0 + 0 + TBW + + + KYZ120 + 171200 + Pike + KY + US + 37.47 + -82.35 + 0 + 0 + JKL + + + OHZ086 + 350860 + Gallia + OH + US + 38.81 + -82.34 + 0 + 0 + RLX + + + SCZ006 + 400060 + Greater_Greenville + SC + US + 34.77 + -82.34 + 0 + 0 + GSP + + + VAZ003 + 460030 + Dickenson + VA + US + 37.13 + -82.34 + 0 + 0 + RLX + + + GAZ113 + 101130 + Toombs + GA + US + 32.13 + -82.33 + 0 + 0 + FFC + + + GAZ086 + 100860 + Emanuel + GA + US + 32.56 + -82.32 + 0 + 0 + FFC + + + SCZ018 + 400180 + McCormick + SC + US + 33.83 + -82.32 + 0 + 0 + CAE + + + NCZ049 + 330490 + Yancey + NC + US + 35.89 + -82.31 + 0 + 0 + GSP + + + NCZ509 + 335090 + Polk_Mountains + NC + US + 35.29 + -82.31 + 0 + 0 + GSP + + + GAZ135 + 101350 + Appling + GA + US + 31.72 + -82.30 + 0 + 0 + JAX + + + OHZ030 + 350300 + Ashland + OH + US + 40.81 + -82.28 + 0 + 0 + CLE + + + WVZ006 + 480060 + Cabell + WV + US + 38.41 + -82.27 + 0 + 0 + RLX + + + TNZ017 + 420170 + Sullivan + TN + US + 36.51 + -82.26 + 0 + 0 + MRX + + + FLZ023 + 90230 + Baker + FL + US + 30.36 + -82.25 + 0 + 0 + JAX + + + GAZ064 + 100640 + Columbia + GA + US + 33.53 + -82.24 + 0 + 0 + CAE + + + OHZ066 + 350660 + Perry + OH + US + 39.74 + -82.24 + 0 + 0 + RLX + + + FLZ031 + 90310 + Bradford + FL + US + 29.93 + -82.23 + 0 + 0 + JAX + + + GAZ151 + 101510 + Pierce + GA + US + 31.37 + -82.20 + 0 + 0 + JAX + + + NCZ507 + 335070 + Rutherford_Mountains + NC + US + 35.46 + -82.18 + 0 + 0 + GSP + + + GAZ164 + 101640 + Charlton + GA + US + 30.71 + -82.15 + 0 + 0 + JAX + + + TNZ046 + 420460 + Northwest_Carter + TN + US + 36.38 + -82.15 + 0 + 0 + MRX + + + FLZ043 + 90430 + Sumter + FL + US + 28.63 + -82.13 + 0 + 0 + TBW + + + NCZ510 + 335100 + Eastern_Polk + NC + US + 35.29 + -82.13 + 0 + 0 + GSP + + + NCZ050 + 330500 + Mitchell + NC + US + 35.98 + -82.12 + 0 + 0 + GSP + + + OHZ010 + 350100 + Lorain + OH + US + 41.29 + -82.11 + 0 + 0 + CLE + + + TNZ047 + 420470 + Southeast_Carter + TN + US + 36.23 + -82.11 + 0 + 0 + MRX + + + WVZ024 + 480240 + Mingo + WV + US + 37.74 + -82.11 + 0 + 0 + RLX + + + NCZ505 + 335050 + McDowell_Mountains + NC + US + 35.74 + -82.10 + 0 + 0 + GSP + + + SCZ019 + 400190 + Greenwood + SC + US + 34.18 + -82.10 + 0 + 0 + GSP + + + FLZ040 + 90400 + Marion + FL + US + 29.24 + -82.09 + 0 + 0 + JAX + + + GAZ065 + 100650 + Richmond + GA + US + 33.39 + -82.09 + 0 + 0 + CAE + + + VAZ006 + 460060 + Russell + VA + US + 36.93 + -82.09 + 0 + 0 + MRX + + + GAZ099 + 100990 + Candler + GA + US + 32.41 + -82.08 + 0 + 0 + CHS + + + WVZ013 + 480130 + Lincoln + WV + US + 38.16 + -82.04 + 0 + 0 + RLX + + + OHZ085 + 350850 + Meigs + OH + US + 39.04 + -82.03 + 0 + 0 + RLX + + + OHZ075 + 350750 + Athens + OH + US + 39.36 + -82.01 + 0 + 0 + RLX + + + VAZ004 + 460040 + Buchanan + VA + US + 37.29 + -82.01 + 0 + 0 + RLX + + + GAZ114 + 101140 + Tattnall + GA + US + 32.05 + -82.00 + 0 + 0 + CHS + + + GAZ152 + 101520 + Brantley + GA + US + 31.19 + -82.00 + 0 + 0 + JAX + + + WVZ007 + 480070 + Mason + WV + US + 38.75 + -82.00 + 0 + 0 + RLX + + + SCZ012 + 400120 + Laurens + SC + US + 34.49 + -81.98 + 0 + 0 + GSP + + + FLZ062 + 90620 + Charlotte + FL + US + 26.90 + -81.97 + 0 + 0 + TBW + + + VAZ008 + 460080 + Washington + VA + US + 36.76 + -81.97 + 0 + 0 + MRX + + + GAZ087 + 100870 + Jenkins + GA + US + 32.78 + -81.96 + 0 + 0 + CHS + + + OHZ057 + 350570 + Muskingum + OH + US + 39.96 + -81.96 + 0 + 0 + PBZ + + + SCZ007 + 400070 + Spartanburg + SC + US + 34.89 + -81.96 + 0 + 0 + GSP + + + NCZ506 + 335060 + Eastern_McDowell + NC + US + 35.64 + -81.95 + 0 + 0 + GSP + + + GAZ077 + 100770 + Burke + GA + US + 33.05 + -81.94 + 0 + 0 + CAE + + + NCZ508 + 335080 + Greater_Rutherford + NC + US + 35.39 + -81.94 + 0 + 0 + GSP + + + OHZ038 + 350380 + Holmes + OH + US + 40.56 + -81.93 + 0 + 0 + CLE + + + FLZ065 + 90650 + Lee + FL + US + 26.55 + -81.92 + 0 + 0 + TBW + + + OHZ020 + 350200 + Medina + OH + US + 41.13 + -81.92 + 0 + 0 + CLE + + + NCZ033 + 330330 + Avery + NC + US + 36.10 + -81.91 + 0 + 0 + GSP + + + SCZ025 + 400250 + Edgefield + SC + US + 33.76 + -81.91 + 0 + 0 + CAE + + + OHZ048 + 350480 + Coshocton + OH + US + 40.30 + -81.90 + 0 + 0 + PBZ + + + WVZ025 + 480250 + Logan + WV + US + 37.83 + -81.90 + 0 + 0 + RLX + + + GAZ136 + 101360 + Wayne + GA + US + 31.58 + -81.88 + 0 + 0 + JAX + + + OHZ031 + 350310 + Wayne + OH + US + 40.83 + -81.88 + 0 + 0 + CLE + + + WVZ014 + 480140 + Putnam + WV + US + 38.48 + -81.88 + 0 + 0 + RLX + + + GAZ115 + 101150 + Evans + GA + US + 32.16 + -81.87 + 0 + 0 + CHS + + + NCZ503 + 335030 + Burke_Mountains + NC + US + 35.88 + -81.85 + 0 + 0 + GSP + + + TNZ018 + 420180 + Johnson + TN + US + 36.44 + -81.85 + 0 + 0 + MRX + + + OHZ067 + 350670 + Morgan + OH + US + 39.61 + -81.83 + 0 + 0 + RLX + + + FLZ032 + 90320 + Clay + FL + US + 29.96 + -81.82 + 0 + 0 + JAX + + + FLZ056 + 90560 + Hardee + FL + US + 27.49 + -81.81 + 0 + 0 + TBW + + + FLZ061 + 90610 + De_Soto + FL + US + 27.19 + -81.81 + 0 + 0 + TBW + + + FLZ144 + 91440 + Southern_Lake_County + FL + US + 28.56 + -81.80 + 0 + 0 + MLB + + + GAZ165 + 101650 + Inland_Camden + GA + US + 30.95 + -81.76 + 0 + 0 + JAX + + + FLZ037 + 90370 + Putnam + FL + US + 29.58 + -81.75 + 0 + 0 + JAX + + + FLZ024 + 90240 + Nassau + FL + US + 30.54 + -81.74 + 0 + 0 + JAX + + + SCZ026 + 400260 + Saluda + SC + US + 33.99 + -81.74 + 0 + 0 + CAE + + + FLZ069 + 90690 + Coastal_Collier_County + FL + US + 26.07 + -81.73 + 0 + 0 + MFL + + + GAZ100 + 101000 + Bulloch + GA + US + 32.40 + -81.73 + 0 + 0 + CHS + + + GAZ137 + 101370 + Long + GA + US + 31.77 + -81.73 + 0 + 0 + CHS + + + WVZ026 + 480260 + Boone + WV + US + 38.00 + -81.72 + 0 + 0 + RLX + + + FLZ025 + 90250 + Duval + FL + US + 30.34 + -81.71 + 0 + 0 + JAX + + + WVZ008 + 480080 + Jackson + WV + US + 38.83 + -81.71 + 0 + 0 + RLX + + + NCZ018 + 330180 + Watauga + NC + US + 36.25 + -81.68 + 0 + 0 + RNK + + + NCZ504 + 335040 + Greater_Burke + NC + US + 35.72 + -81.66 + 0 + 0 + GSP + + + OHZ011 + 350110 + Cuyahoga + OH + US + 41.45 + -81.66 + 0 + 0 + CLE + + + WVZ033 + 480330 + McDowell + WV + US + 37.38 + -81.65 + 0 + 0 + RLX + + + FLZ044 + 90440 + Northern_Lake_County + FL + US + 29.03 + -81.64 + 0 + 0 + MLB + + + SCZ013 + 400130 + Union + SC + US + 34.68 + -81.64 + 0 + 0 + GSP + + + GAZ088 + 100880 + Screven + GA + US + 32.77 + -81.63 + 0 + 0 + CHS + + + GAZ153 + 101530 + Inland_Glynn + GA + US + 31.28 + -81.63 + 0 + 0 + JAX + + + FLZ052 + 90520 + Polk + FL + US + 28.00 + -81.62 + 0 + 0 + TBW + + + SCZ008 + 400080 + Cherokee + SC + US + 35.01 + -81.62 + 0 + 0 + GSP + + + SCZ020 + 400200 + Newberry + SC + US + 34.29 + -81.62 + 0 + 0 + CAE + + + NCZ501 + 335010 + Caldwell_Mountains + NC + US + 36.01 + -81.61 + 0 + 0 + GSP + + + SCZ030 + 400300 + Aiken + SC + US + 33.54 + -81.60 + 0 + 0 + CAE + + + VAZ007 + 460070 + Tazewell + VA + US + 37.14 + -81.56 + 0 + 0 + RNK + + + WVZ015 + 480150 + Kanawha + WV + US + 38.30 + -81.56 + 0 + 0 + RLX + + + FLZ078 + 90780 + Monroe/Lower_Keys + FL + US + 24.64 + -81.55 + 0 + 0 + KEY + + + GAZ166 + 101660 + Coastal_Camden + GA + US + 30.91 + -81.55 + 0 + 0 + JAX + + + GAZ138 + 101380 + Inland_Liberty + GA + US + 31.87 + -81.54 + 0 + 0 + CHS + + + NCZ068 + 330680 + Cleveland + NC + US + 35.36 + -81.54 + 0 + 0 + GSP + + + VAZ009 + 460090 + Smyth + VA + US + 36.82 + -81.54 + 0 + 0 + RNK + + + WVZ034 + 480340 + Wyoming + WV + US + 37.60 + -81.54 + 0 + 0 + RLX + + + OHZ021 + 350210 + Summit + OH + US + 41.13 + -81.53 + 0 + 0 + CLE + + + NCZ502 + 335020 + Greater_Caldwell + NC + US + 35.91 + -81.52 + 0 + 0 + GSP + + + GAZ116 + 101160 + Inland_Bryan + GA + US + 32.00 + -81.50 + 0 + 0 + CHS + + + WVZ009 + 480090 + Wood + WV + US + 39.22 + -81.50 + 0 + 0 + RLX + + + NCZ001 + 330010 + Ashe + NC + US + 36.41 + -81.49 + 0 + 0 + RNK + + + OHZ039 + 350390 + Tuscarawas + OH + US + 40.43 + -81.49 + 0 + 0 + PBZ + + + GAZ140 + 101400 + Inland_McIntosh + GA + US + 31.52 + -81.48 + 0 + 0 + CHS + + + SCZ035 + 400350 + Barnwell + SC + US + 33.29 + -81.48 + 0 + 0 + CAE + + + OHZ058 + 350580 + Guernsey + OH + US + 40.02 + -81.47 + 0 + 0 + PBZ + + + OHZ068 + 350680 + Noble + OH + US + 39.76 + -81.46 + 0 + 0 + PBZ + + + FLZ033 + 90330 + St._Johns + FL + US + 29.94 + -81.45 + 0 + 0 + JAX + + + OHZ076 + 350760 + Washington + OH + US + 39.43 + -81.45 + 0 + 0 + RLX + + + GAZ154 + 101540 + Coastal_Glynn + GA + US + 31.23 + -81.41 + 0 + 0 + JAX + + + WVZ017 + 480170 + Wirt + WV + US + 39.04 + -81.38 + 0 + 0 + RLX + + + FLZ041 + 90410 + Inland_Volusia_County + FL + US + 29.10 + -81.37 + 0 + 0 + MLB + + + OHZ032 + 350320 + Stark + OH + US + 40.81 + -81.36 + 0 + 0 + CLE + + + SCZ040 + 400400 + Allendale + SC + US + 32.95 + -81.34 + 0 + 0 + CHS + + + GAZ101 + 101010 + Effingham + GA + US + 32.35 + -81.33 + 0 + 0 + CHS + + + GAZ141 + 101410 + Coastal_McIntosh + GA + US + 31.46 + -81.33 + 0 + 0 + CHS + + + WVZ016 + 480160 + Roane + WV + US + 38.74 + -81.32 + 0 + 0 + RLX + + + FLZ038 + 90380 + Flagler + FL + US + 29.47 + -81.31 + 0 + 0 + JAX + + + FLZ070 + 90700 + Inland_Collier_County + FL + US + 26.16 + -81.31 + 0 + 0 + MFL + + + FLZ045 + 90450 + Orange + FL + US + 28.56 + -81.27 + 0 + 0 + MLB + + + FLZ053 + 90530 + Osceola + FL + US + 27.99 + -81.26 + 0 + 0 + MLB + + + FLZ057 + 90570 + Highlands + FL + US + 27.34 + -81.26 + 0 + 0 + TBW + + + VAZ015 + 460150 + Grayson + VA + US + 36.69 + -81.26 + 0 + 0 + RNK + + + GAZ118 + 101180 + Inland_Chatham + GA + US + 32.07 + -81.24 + 0 + 0 + CHS + + + OHZ012 + 350120 + Lake + OH + US + 41.71 + -81.24 + 0 + 0 + CLE + + + SCZ027 + 400270 + Lexington + SC + US + 33.92 + -81.24 + 0 + 0 + CAE + + + NCZ056 + 330560 + Catawba + NC + US + 35.68 + -81.23 + 0 + 0 + GSP + + + NCZ069 + 330690 + Lincoln + NC + US + 35.48 + -81.23 + 0 + 0 + GSP + + + FLZ046 + 90460 + Seminole + FL + US + 28.74 + -81.22 + 0 + 0 + MLB + + + FLZ063 + 90630 + Glades + FL + US + 26.99 + -81.22 + 0 + 0 + MFL + + + FLZ066 + 90660 + Hendry + FL + US + 26.52 + -81.22 + 0 + 0 + MFL + + + WVZ035 + 480350 + Raleigh + WV + US + 37.75 + -81.22 + 0 + 0 + RLX + + + GAZ139 + 101390 + Coastal_Liberty + GA + US + 31.66 + -81.21 + 0 + 0 + CHS + + + NCZ019 + 330190 + Wilkes + NC + US + 36.21 + -81.21 + 0 + 0 + RNK + + + GAZ117 + 101170 + Coastal_Bryan + GA + US + 31.83 + -81.20 + 0 + 0 + CHS + + + OHZ013 + 350130 + Geauga + OH + US + 41.53 + -81.19 + 0 + 0 + CLE + + + OHZ022 + 350220 + Portage + OH + US + 41.17 + -81.19 + 0 + 0 + CLE + + + WVZ010 + 480100 + Pleasants + WV + US + 39.37 + -81.19 + 0 + 0 + RLX + + + NCZ070 + 330700 + Gaston + NC + US + 35.28 + -81.18 + 0 + 0 + GSP + + + SCZ009 + 400090 + York + SC + US + 34.99 + -81.18 + 0 + 0 + GSP + + + SCZ014 + 400140 + Chester + SC + US + 34.68 + -81.18 + 0 + 0 + GSP + + + NCZ035 + 330350 + Alexander + NC + US + 35.90 + -81.17 + 0 + 0 + GSP + + + VAZ010 + 460100 + Bland + VA + US + 37.13 + -81.15 + 0 + 0 + RNK + + + WVZ018 + 480180 + Calhoun + WV + US + 38.83 + -81.13 + 0 + 0 + RLX + + + FLZ075 + 90750 + Mainland_Monroe + FL + US + 25.46 + -81.12 + 0 + 0 + MFL + + + NCZ002 + 330020 + Alleghany + NC + US + 36.47 + -81.12 + 0 + 0 + RNK + + + SCZ042 + 400420 + Hampton + SC + US + 32.79 + -81.12 + 0 + 0 + CHS + + + OHZ049 + 350490 + Harrison + OH + US + 40.29 + -81.10 + 0 + 0 + PBZ + + + SCZ021 + 400210 + Fairfield + SC + US + 34.37 + -81.10 + 0 + 0 + CAE + + + WVZ042 + 480420 + Mercer + WV + US + 37.42 + -81.10 + 0 + 0 + RNK + + + OHZ040 + 350400 + Carroll + OH + US + 40.57 + -81.09 + 0 + 0 + PBZ + + + OHZ069 + 350690 + Monroe + OH + US + 39.70 + -81.07 + 0 + 0 + PBZ + + + WVZ019 + 480190 + Ritchie + WV + US + 39.20 + -81.07 + 0 + 0 + RLX + + + WVZ036 + 480360 + Fayette + WV + US + 38.04 + -81.07 + 0 + 0 + RLX + + + VAZ012 + 460120 + Wythe + VA + US + 36.92 + -81.06 + 0 + 0 + RNK + + + SCZ047 + 400470 + Inland_Jasper + SC + US + 32.42 + -81.05 + 0 + 0 + CHS + + + WVZ027 + 480270 + Clay + WV + US + 38.47 + -81.05 + 0 + 0 + RLX + + + FLZ141 + 91410 + Coastal_Volusia_County + FL + US + 29.02 + -81.03 + 0 + 0 + MLB + + + GAZ119 + 101190 + Coastal_Chatham + GA + US + 31.91 + -81.02 + 0 + 0 + CHS + + + SCZ041 + 400410 + Bamberg + SC + US + 33.23 + -81.01 + 0 + 0 + CAE + + + SCZ051 + 400510 + Coastal_Jasper + SC + US + 32.27 + -81.00 + 0 + 0 + CHS + + + OHZ059 + 350590 + Belmont + OH + US + 40.00 + -80.97 + 0 + 0 + PBZ + + + SCZ028 + 400280 + Richland + SC + US + 34.00 + -80.97 + 0 + 0 + CAE + + + FLZ077 + 90770 + Monroe/Middle_Keys + FL + US + 24.76 + -80.96 + 0 + 0 + KEY + + + FLZ058 + 90580 + Okeechobee + FL + US + 27.38 + -80.94 + 0 + 0 + MLB + + + NCZ036 + 330360 + Iredell + NC + US + 35.78 + -80.90 + 0 + 0 + GSP + + + WVZ011 + 480110 + Tyler + WV + US + 39.45 + -80.87 + 0 + 0 + RLX + + + WVZ043 + 480430 + Summers + WV + US + 37.65 + -80.87 + 0 + 0 + RNK + + + FLZ147 + 91470 + Northern_Brevard_County + FL + US + 28.56 + -80.86 + 0 + 0 + MLB + + + WVZ037 + 480370 + Nicholas + WV + US + 38.32 + -80.84 + 0 + 0 + RLX + + + WVZ029 + 480290 + Gilmer + WV + US + 38.92 + -80.83 + 0 + 0 + RLX + + + NCZ071 + 330710 + Mecklenburg + NC + US + 35.26 + -80.80 + 0 + 0 + GSP + + + OHZ033 + 350330 + Mahoning + OH + US + 41.01 + -80.80 + 0 + 0 + CLE + + + OHZ041 + 350410 + Columbiana + OH + US + 40.76 + -80.80 + 0 + 0 + PBZ + + + SCZ036 + 400360 + Orangeburg + SC + US + 33.44 + -80.79 + 0 + 0 + CAE + + + OHZ050 + 350500 + Jefferson + OH + US + 40.37 + -80.77 + 0 + 0 + PBZ + + + SCZ037 + 400370 + Calhoun + SC + US + 33.67 + -80.77 + 0 + 0 + CAE + + + OHZ014 + 350140 + Ashtabula_Inland + OH + US + 41.71 + -80.76 + 0 + 0 + CLE + + + OHZ023 + 350230 + Trumbull + OH + US + 41.31 + -80.76 + 0 + 0 + CLE + + + OHZ089 + 350890 + Ashtabula_Lakeshore + OH + US + 41.88 + -80.76 + 0 + 0 + CLE + + + VAZ016 + 460160 + Carroll + VA + US + 36.74 + -80.75 + 0 + 0 + RNK + + + WVZ028 + 480280 + Braxton + WV + US + 38.71 + -80.74 + 0 + 0 + RLX + + + SCZ043 + 400430 + Inland_Colleton + SC + US + 32.92 + -80.73 + 0 + 0 + CHS + + + WVZ020 + 480200 + Doddridge + WV + US + 39.27 + -80.73 + 0 + 0 + RLX + + + SCZ048 + 400480 + Beaufort + SC + US + 32.39 + -80.72 + 0 + 0 + CHS + + + VAZ011 + 460110 + Giles + VA + US + 37.31 + -80.72 + 0 + 0 + RNK + + + VAZ013 + 460130 + Pulaski + VA + US + 37.06 + -80.72 + 0 + 0 + RNK + + + NCZ003 + 330030 + Surry + NC + US + 36.40 + -80.70 + 0 + 0 + RNK + + + WVZ004 + 480040 + Marshall + WV + US + 39.88 + -80.70 + 0 + 0 + PBZ + + + WVZ012 + 480120 + Wetzel + WV + US + 39.58 + -80.67 + 0 + 0 + PBZ + + + FLZ047 + 90470 + Southern_Brevard_County + FL + US + 28.08 + -80.66 + 0 + 0 + MLB + + + NCZ020 + 330200 + Yadkin + NC + US + 36.16 + -80.66 + 0 + 0 + RNK + + + SCZ015 + 400150 + Lancaster + SC + US + 34.76 + -80.66 + 0 + 0 + CAE + + + FLZ174 + 91740 + Far_South_Miami-Dade_County + FL + US + 25.30 + -80.63 + 0 + 0 + MFL + + + WVZ003 + 480030 + Ohio + WV + US + 40.11 + -80.63 + 0 + 0 + PBZ + + + FLZ073 + 90730 + Inland_Miami-Dade_County + FL + US + 25.69 + -80.61 + 0 + 0 + MFL + + + FLZ054 + 90540 + Indian_River + FL + US + 27.71 + -80.60 + 0 + 0 + MLB + + + WVZ001 + 480010 + Hancock + WV + US + 40.52 + -80.60 + 0 + 0 + PBZ + + + WVZ002 + 480020 + Brooke + WV + US + 40.28 + -80.60 + 0 + 0 + PBZ + + + FLZ071 + 90710 + Inland_Broward_County + FL + US + 26.15 + -80.59 + 0 + 0 + MFL + + + SCZ022 + 400220 + Kershaw + SC + US + 34.34 + -80.58 + 0 + 0 + CAE + + + NCZ082 + 330820 + Union + NC + US + 35.01 + -80.56 + 0 + 0 + GSP + + + FLZ067 + 90670 + Inland_Palm_Beach_County + FL + US + 26.64 + -80.54 + 0 + 0 + MFL + + + NCZ072 + 330720 + Cabarrus + NC + US + 35.35 + -80.54 + 0 + 0 + GSP + + + WVZ044 + 480440 + Monroe + WV + US + 37.55 + -80.54 + 0 + 0 + RNK + + + NCZ037 + 330370 + Davie + NC + US + 35.90 + -80.53 + 0 + 0 + GSP + + + WVZ030 + 480300 + Lewis + WV + US + 38.94 + -80.52 + 0 + 0 + RLX + + + NCZ057 + 330570 + Rowan + NC + US + 35.67 + -80.47 + 0 + 0 + GSP + + + SCZ049 + 400490 + Coastal_Colleton + SC + US + 32.61 + -80.46 + 0 + 0 + CHS + + + FLZ059 + 90590 + St._Lucie + FL + US + 27.38 + -80.44 + 0 + 0 + MLB + + + SCZ044 + 400440 + Dorchester + SC + US + 33.07 + -80.44 + 0 + 0 + CHS + + + WVZ038 + 480380 + Webster + WV + US + 38.49 + -80.43 + 0 + 0 + RLX + + + WVZ045 + 480450 + Greenbrier + WV + US + 37.98 + -80.43 + 0 + 0 + RNK + + + VAZ014 + 460140 + Montgomery + VA + US + 37.17 + -80.40 + 0 + 0 + RNK + + + WVZ031 + 480310 + Harrison + WV + US + 39.28 + -80.39 + 0 + 0 + RLX + + + FLZ064 + 90640 + Martin + FL + US + 27.11 + -80.38 + 0 + 0 + MLB + + + FLZ076 + 90760 + Monroe/Upper_Keys + FL + US + 25.15 + -80.38 + 0 + 0 + KEY + + + VAZ017 + 460170 + Floyd + VA + US + 36.92 + -80.37 + 0 + 0 + RNK + + + PAZ020 + 380200 + Beaver + PA + US + 40.67 + -80.34 + 0 + 0 + PBZ + + + VAZ032 + 460320 + Patrick + VA + US + 36.71 + -80.33 + 0 + 0 + RNK + + + PAZ013 + 380130 + Lawrence + PA + US + 40.99 + -80.31 + 0 + 0 + PBZ + + + FLZ173 + 91730 + Coastal_Miami_Dade_County + FL + US + 25.64 + -80.30 + 0 + 0 + MFL + + + FLZ072 + 90720 + Metro_Broward_County + FL + US + 26.15 + -80.28 + 0 + 0 + MFL + + + FLZ074 + 90740 + Metropolitan_Miami_Dade + FL + US + 25.78 + -80.28 + 0 + 0 + MFL + + + NCZ073 + 330730 + Stanly + NC + US + 35.33 + -80.28 + 0 + 0 + RAH + + + NCZ021 + 330210 + Forsyth + NC + US + 36.11 + -80.27 + 0 + 0 + RAH + + + SCZ031 + 400310 + Sumter + SC + US + 33.90 + -80.27 + 0 + 0 + CAE + + + NCZ038 + 330380 + Davidson + NC + US + 35.76 + -80.26 + 0 + 0 + RAH + + + PAZ007 + 380070 + Mercer + PA + US + 41.28 + -80.26 + 0 + 0 + PBZ + + + NCZ004 + 330040 + Stokes + NC + US + 36.40 + -80.24 + 0 + 0 + RNK + + + SCZ029 + 400290 + Lee + SC + US + 34.16 + -80.23 + 0 + 0 + CAE + + + WVZ039 + 480390 + Upshur + WV + US + 38.90 + -80.23 + 0 + 0 + RLX + + + PAZ031 + 380310 + Greene + PA + US + 39.87 + -80.22 + 0 + 0 + PBZ + + + VAZ018 + 460180 + Craig + VA + US + 37.49 + -80.22 + 0 + 0 + RNK + + + WVZ021 + 480210 + Marion + WV + US + 39.51 + -80.22 + 0 + 0 + PBZ + + + SCZ038 + 400380 + Clarendon + SC + US + 33.69 + -80.21 + 0 + 0 + CAE + + + PAZ029 + 380290 + Washington + PA + US + 40.22 + -80.19 + 0 + 0 + PBZ + + + SCZ016 + 400160 + Chesterfield + SC + US + 34.59 + -80.17 + 0 + 0 + CAE + + + FLZ068 + 90680 + Metro_Palm_Beach_County + FL + US + 26.64 + -80.14 + 0 + 0 + MFL + + + PAZ001 + 380010 + Northern_Erie + PA + US + 42.10 + -80.14 + 0 + 0 + CLE + + + FLZ172 + 91720 + Coastal_Broward_County + FL + US + 26.15 + -80.12 + 0 + 0 + MFL + + + WVZ022 + 480220 + Monongalia + WV + US + 39.58 + -80.10 + 0 + 0 + PBZ + + + NCZ083 + 330830 + Anson + NC + US + 35.01 + -80.09 + 0 + 0 + RAH + + + PAZ002 + 380020 + Southern_Erie + PA + US + 42.03 + -80.07 + 0 + 0 + CLE + + + PAZ003 + 380030 + Crawford + PA + US + 41.67 + -80.07 + 0 + 0 + CLE + + + FLZ168 + 91680 + Coastal_Palm_Beach_County + FL + US + 26.65 + -80.06 + 0 + 0 + MFL + + + WVZ032 + 480320 + Taylor + WV + US + 39.34 + -80.06 + 0 + 0 + RLX + + + VAZ022 + 460220 + Roanoke + VA + US + 37.26 + -80.05 + 0 + 0 + RNK + + + PAZ021 + 380210 + Allegheny + PA + US + 40.44 + -80.03 + 0 + 0 + PBZ + + + WVZ040 + 480400 + Barbour + WV + US + 39.12 + -80.02 + 0 + 0 + RLX + + + WVZ046 + 480460 + Pocahontas + WV + US + 38.39 + -80.00 + 0 + 0 + RLX + + + SCZ023 + 400230 + Darlington + SC + US + 34.31 + -79.98 + 0 + 0 + ILM + + + VAZ019 + 460190 + Alleghany + VA + US + 37.78 + -79.95 + 0 + 0 + RNK + + + PAZ014 + 380140 + Butler + PA + US + 40.92 + -79.93 + 0 + 0 + PBZ + + + VAZ033 + 460330 + Franklin + VA + US + 37.01 + -79.92 + 0 + 0 + RNK + + + SCZ045 + 400450 + Berkeley + SC + US + 33.17 + -79.90 + 0 + 0 + CHS + + + NCZ074 + 330740 + Montgomery + NC + US + 35.32 + -79.89 + 0 + 0 + RAH + + + VAZ043 + 460430 + Henry + VA + US + 36.70 + -79.87 + 0 + 0 + RNK + + + SCZ050 + 400500 + Charleston + SC + US + 32.85 + -79.86 + 0 + 0 + CHS + + + WVZ047 + 480470 + Randolph + WV + US + 38.75 + -79.81 + 0 + 0 + RLX + + + NCZ039 + 330390 + Randolph + NC + US + 35.71 + -79.80 + 0 + 0 + RAH + + + NCZ022 + 330220 + Guilford + NC + US + 36.07 + -79.79 + 0 + 0 + RAH + + + VAZ023 + 460230 + Botetourt + VA + US + 37.55 + -79.79 + 0 + 0 + RNK + + + NCZ005 + 330050 + Rockingham + NC + US + 36.39 + -79.77 + 0 + 0 + RNK + + + NCZ084 + 330840 + Richmond + NC + US + 34.99 + -79.76 + 0 + 0 + RAH + + + VAZ020 + 460200 + Bath + VA + US + 38.06 + -79.75 + 0 + 0 + RNK + + + PAZ008 + 380080 + Venango + PA + US + 41.40 + -79.74 + 0 + 0 + PBZ + + + SCZ039 + 400390 + Williamsburg + SC + US + 33.59 + -79.71 + 0 + 0 + ILM + + + WVZ023 + 480230 + Preston + WV + US + 39.46 + -79.70 + 0 + 0 + PBZ + + + SCZ017 + 400170 + Marlboro + SC + US + 34.55 + -79.69 + 0 + 0 + ILM + + + SCZ032 + 400320 + Florence + SC + US + 34.04 + -79.69 + 0 + 0 + ILM + + + PAZ032 + 380320 + Fayette + PA + US + 39.93 + -79.66 + 0 + 0 + PBZ + + + WVZ041 + 480410 + Tucker + WV + US + 39.11 + -79.57 + 0 + 0 + PBZ + + + VAZ021 + 460210 + Highland + VA + US + 38.39 + -79.56 + 0 + 0 + LWX + + + VAZ034 + 460340 + Bedford + VA + US + 37.31 + -79.52 + 0 + 0 + RNK + + + NCZ085 + 330850 + Scotland + NC + US + 34.84 + -79.51 + 0 + 0 + RAH + + + PAZ015 + 380150 + Clarion + PA + US + 41.20 + -79.46 + 0 + 0 + PBZ + + + PAZ022 + 380220 + Armstrong + PA + US + 40.85 + -79.46 + 0 + 0 + PBZ + + + PAZ030 + 380300 + Westmoreland + PA + US + 40.36 + -79.44 + 0 + 0 + PBZ + + + WVZ501 + 485010 + Western_Grant + WV + US + 39.20 + -79.44 + 0 + 0 + LWX + + + NCZ075 + 330750 + Moore + NC + US + 35.28 + -79.43 + 0 + 0 + RAH + + + NYZ019 + 320190 + Chautauqua + NY + US + 42.29 + -79.41 + 0 + 0 + BUF + + + VAZ024 + 460240 + Rockbridge + VA + US + 37.81 + -79.41 + 0 + 0 + RNK + + + VAZ044 + 460440 + Pittsylvania + VA + US + 36.84 + -79.41 + 0 + 0 + RNK + + + NCZ023 + 330230 + Alamance + NC + US + 36.04 + -79.39 + 0 + 0 + RAH + + + SCZ024 + 400240 + Dillon + SC + US + 34.42 + -79.36 + 0 + 0 + ILM + + + SCZ033 + 400330 + Marion + SC + US + 34.00 + -79.35 + 0 + 0 + ILM + + + WVZ054 + 480540 + Pendleton + WV + US + 38.68 + -79.35 + 0 + 0 + LWX + + + NCZ006 + 330060 + Caswell + NC + US + 36.39 + -79.34 + 0 + 0 + RNK + + + SCZ046 + 400460 + Georgetown + SC + US + 33.45 + -79.34 + 0 + 0 + ILM + + + PAZ004 + 380040 + Warren + PA + US + 41.81 + -79.27 + 0 + 0 + CTP + + + NCZ086 + 330860 + Hoke + NC + US + 35.02 + -79.24 + 0 + 0 + RAH + + + PAZ009 + 380090 + Forest + PA + US + 41.47 + -79.24 + 0 + 0 + PBZ + + + NCZ040 + 330400 + Chatham + NC + US + 35.69 + -79.23 + 0 + 0 + RAH + + + MDZ001 + 200010 + Garrett + MD + US + 39.46 + -79.21 + 0 + 0 + PBZ + + + NCZ076 + 330760 + Lee + NC + US + 35.46 + -79.17 + 0 + 0 + RAH + + + WVZ502 + 485020 + Eastern_Grant + WV + US + 39.06 + -79.17 + 0 + 0 + LWX + + + VAZ035 + 460350 + Amherst + VA + US + 37.59 + -79.16 + 0 + 0 + RNK + + + PAZ023 + 380230 + Indiana + PA + US + 40.64 + -79.14 + 0 + 0 + PBZ + + + NCZ087 + 330870 + Robeson + NC + US + 34.63 + -79.13 + 0 + 0 + ILM + + + VAZ025 + 460250 + Augusta + VA + US + 38.18 + -79.13 + 0 + 0 + LWX + + + VAZ045 + 460450 + Campbell + VA + US + 37.25 + -79.13 + 0 + 0 + RNK + + + WVZ503 + 485030 + Western_Mineral + WV + US + 39.40 + -79.13 + 0 + 0 + LWX + + + NCZ024 + 330240 + Orange + NC + US + 36.04 + -79.11 + 0 + 0 + RAH + + + PAZ033 + 380330 + Somerset + PA + US + 40.00 + -79.04 + 0 + 0 + CTP + + + NCZ007 + 330070 + Person + NC + US + 36.39 + -78.98 + 0 + 0 + RAH + + + PAZ016 + 380160 + Jefferson + PA + US + 41.14 + -78.96 + 0 + 0 + PBZ + + + SCZ034 + 400340 + Horry + SC + US + 33.94 + -78.94 + 0 + 0 + ILM + + + MDZ501 + 205010 + Extreme_Western_Allegany + MD + US + 39.58 + -78.92 + 0 + 0 + LWX + + + VAZ036 + 460360 + Nelson + VA + US + 37.79 + -78.92 + 0 + 0 + LWX + + + WVZ504 + 485040 + Eastern_Mineral + WV + US + 39.44 + -78.89 + 0 + 0 + LWX + + + NCZ077 + 330770 + Harnett + NC + US + 35.38 + -78.88 + 0 + 0 + RAH + + + VAZ058 + 460580 + Halifax + VA + US + 36.80 + -78.88 + 0 + 0 + RNK + + + NCZ025 + 330250 + Durham + NC + US + 36.05 + -78.86 + 0 + 0 + RAH + + + VAZ026 + 460260 + Rockingham + VA + US + 38.53 + -78.86 + 0 + 0 + LWX + + + VAZ046 + 460460 + Appomattox + VA + US + 37.38 + -78.81 + 0 + 0 + RNK + + + WVZ055 + 480550 + Hardy + WV + US + 39.00 + -78.81 + 0 + 0 + LWX + + + NCZ088 + 330880 + Cumberland + NC + US + 35.04 + -78.80 + 0 + 0 + RAH + + + NYZ085 + 320850 + Southern_Erie + NY + US + 42.62 + -78.80 + 0 + 0 + BUF + + + NYZ001 + 320010 + Niagara + NY + US + 43.20 + -78.77 + 0 + 0 + BUF + + + NYZ010 + 320100 + Northern_Erie + NY + US + 42.94 + -78.74 + 0 + 0 + BUF + + + PAZ024 + 380240 + Cambria + PA + US + 40.48 + -78.71 + 0 + 0 + CTP + + + NYZ020 + 320200 + Cattaraugus + NY + US + 42.27 + -78.68 + 0 + 0 + BUF + + + VAZ059 + 460590 + Charlotte + VA + US + 36.98 + -78.68 + 0 + 0 + RNK + + + PAZ010 + 380100 + Elk + PA + US + 41.42 + -78.67 + 0 + 0 + CTP + + + WVZ050 + 480500 + Hampshire + WV + US + 39.32 + -78.66 + 0 + 0 + LWX + + + MDZ502 + 205020 + Central_and_Eastern_Allegany + MD + US + 39.58 + -78.65 + 0 + 0 + LWX + + + NCZ008 + 330080 + Granville + NC + US + 36.28 + -78.63 + 0 + 0 + RAH + + + NCZ041 + 330410 + Wake + NC + US + 35.79 + -78.63 + 0 + 0 + RAH + + + NCZ099 + 330990 + Columbus + NC + US + 34.21 + -78.61 + 0 + 0 + ILM + + + PAZ005 + 380050 + McKean + PA + US + 41.80 + -78.58 + 0 + 0 + CTP + + + VAZ027 + 460270 + Shenandoah + VA + US + 38.86 + -78.58 + 0 + 0 + LWX + + + VAZ047 + 460470 + Buckingham + VA + US + 37.56 + -78.55 + 0 + 0 + RNK + + + NCZ096 + 330960 + Bladen + NC + US + 34.61 + -78.53 + 0 + 0 + ILM + + + VAZ037 + 460370 + Albemarle + VA + US + 38.00 + -78.52 + 0 + 0 + LWX + + + PAZ034 + 380340 + Bedford + PA + US + 40.02 + -78.48 + 0 + 0 + CTP + + + VAZ029 + 460290 + Page + VA + US + 38.62 + -78.48 + 0 + 0 + LWX + + + VAZ038 + 460380 + Greene + VA + US + 38.33 + -78.47 + 0 + 0 + LWX + + + VAZ060 + 460600 + Prince_Edward + VA + US + 37.24 + -78.46 + 0 + 0 + AKQ + + + PAZ017 + 380170 + Clearfield + PA + US + 40.99 + -78.43 + 0 + 0 + CTP + + + NCZ009 + 330090 + Vance + NC + US + 36.35 + -78.40 + 0 + 0 + RAH + + + NCZ042 + 330420 + Johnston + NC + US + 35.53 + -78.39 + 0 + 0 + RAH + + + NCZ089 + 330890 + Sampson + NC + US + 34.93 + -78.39 + 0 + 0 + RAH + + + VAZ065 + 460650 + Mecklenburg + VA + US + 36.72 + -78.39 + 0 + 0 + AKQ + + + PAZ025 + 380250 + Blair + PA + US + 40.50 + -78.37 + 0 + 0 + CTP + + + NCZ100 + 331000 + Brunswick + NC + US + 34.10 + -78.30 + 0 + 0 + ILM + + + VAZ028 + 460280 + Frederick + VA + US + 39.23 + -78.29 + 0 + 0 + LWX + + + NCZ026 + 330260 + Franklin + NC + US + 36.04 + -78.28 + 0 + 0 + RAH + + + VAZ048 + 460480 + Fluvanna + VA + US + 37.85 + -78.28 + 0 + 0 + AKQ + + + VAZ061 + 460610 + Cumberland + VA + US + 37.52 + -78.28 + 0 + 0 + AKQ + + + VAZ039 + 460390 + Madison + VA + US + 38.43 + -78.27 + 0 + 0 + LWX + + + VAZ066 + 460660 + Lunenburg + VA + US + 36.95 + -78.25 + 0 + 0 + AKQ + + + WVZ051 + 480510 + Morgan + WV + US + 39.54 + -78.25 + 0 + 0 + LWX + + + NYZ002 + 320020 + Orleans + NY + US + 43.25 + -78.23 + 0 + 0 + BUF + + + NYZ012 + 320120 + Wyoming + NY + US + 42.70 + -78.22 + 0 + 0 + BUF + + + PAZ011 + 380110 + Cameron + PA + US + 41.42 + -78.21 + 0 + 0 + CTP + + + VAZ030 + 460300 + Warren + VA + US + 38.90 + -78.20 + 0 + 0 + LWX + + + NYZ011 + 320110 + Genesee + NY + US + 43.00 + -78.18 + 0 + 0 + BUF + + + VAZ040 + 460400 + Rappahannock + VA + US + 38.69 + -78.14 + 0 + 0 + LWX + + + PAZ035 + 380350 + Fulton + PA + US + 39.94 + -78.13 + 0 + 0 + CTP + + + NCZ010 + 330100 + Warren + NC + US + 36.37 + -78.11 + 0 + 0 + RAH + + + NCZ078 + 330780 + Wayne + NC + US + 35.37 + -78.06 + 0 + 0 + RAH + + + VAZ050 + 460500 + Orange + VA + US + 38.26 + -78.04 + 0 + 0 + LWX + + + VAZ067 + 460670 + Nottoway + VA + US + 37.14 + -78.03 + 0 + 0 + AKQ + + + WVZ052 + 480520 + Berkeley + WV + US + 39.44 + -78.03 + 0 + 0 + LWX + + + NYZ021 + 320210 + Allegany + NY + US + 42.26 + -78.01 + 0 + 0 + BUF + + + PAZ018 + 380180 + Northern_Centre + PA + US + 41.00 + -78.01 + 0 + 0 + CTP + + + VAZ049 + 460490 + Louisa + VA + US + 37.94 + -78.00 + 0 + 0 + AKQ + + + VAZ031 + 460310 + Clarke + VA + US + 39.12 + -77.99 + 0 + 0 + LWX + + + NCZ027 + 330270 + Nash + NC + US + 35.96 + -77.98 + 0 + 0 + RAH + + + PAZ026 + 380260 + Huntingdon + PA + US + 40.40 + -77.97 + 0 + 0 + CTP + + + VAZ068 + 460680 + Amelia + VA + US + 37.34 + -77.95 + 0 + 0 + AKQ + + + NCZ043 + 330430 + Wilson + NC + US + 35.71 + -77.93 + 0 + 0 + RAH + + + NCZ090 + 330900 + Duplin + NC + US + 34.95 + -77.93 + 0 + 0 + MHX + + + VAZ051 + 460510 + Culpeper + VA + US + 38.51 + -77.93 + 0 + 0 + LWX + + + PAZ006 + 380060 + Potter + PA + US + 41.74 + -77.91 + 0 + 0 + CTP + + + VAZ062 + 460620 + Goochland + VA + US + 37.73 + -77.90 + 0 + 0 + AKQ + + + VAZ069 + 460690 + Powhatan + VA + US + 37.55 + -77.90 + 0 + 0 + AKQ + + + NCZ097 + 330970 + Pender + NC + US + 34.51 + -77.89 + 0 + 0 + ILM + + + NCZ101 + 331010 + New_Hanover + NC + US + 34.16 + -77.88 + 0 + 0 + ILM + + + WVZ053 + 480530 + Jefferson + WV + US + 39.32 + -77.88 + 0 + 0 + LWX + + + VAZ079 + 460790 + Brunswick + VA + US + 36.79 + -77.86 + 0 + 0 + AKQ + + + VAZ041 + 460410 + Fauquier + VA + US + 38.71 + -77.84 + 0 + 0 + LWX + + + PAZ036 + 380360 + Franklin + PA + US + 40.01 + -77.78 + 0 + 0 + CTP + + + NYZ013 + 320130 + Livingston + NY + US + 42.73 + -77.77 + 0 + 0 + BUF + + + MDZ003 + 200030 + Washington + MD + US + 39.52 + -77.72 + 0 + 0 + LWX + + + PAZ012 + 380120 + Northern_Clinton + PA + US + 41.28 + -77.71 + 0 + 0 + CTP + + + PAZ019 + 380190 + Southern_Centre + PA + US + 40.89 + -77.69 + 0 + 0 + CTP + + + NYZ003 + 320030 + Monroe + NY + US + 43.16 + -77.68 + 0 + 0 + BUF + + + VAZ056 + 460560 + Spotsylvania + VA + US + 38.19 + -77.66 + 0 + 0 + LWX + + + NCZ079 + 330790 + Greene + NC + US + 35.50 + -77.65 + 0 + 0 + MHX + + + VAZ080 + 460800 + Dinwiddie + VA + US + 37.07 + -77.65 + 0 + 0 + AKQ + + + VAZ042 + 460420 + Loudoun + VA + US + 39.09 + -77.64 + 0 + 0 + LWX + + + NCZ011 + 330110 + Halifax + NC + US + 36.25 + -77.62 + 0 + 0 + RAH + + + NCZ091 + 330910 + Lenoir + NC + US + 35.21 + -77.61 + 0 + 0 + MHX + + + PAZ027 + 380270 + Mifflin + PA + US + 40.61 + -77.60 + 0 + 0 + CTP + + + NCZ028 + 330280 + Edgecombe + NC + US + 35.91 + -77.59 + 0 + 0 + RAH + + + VAZ070 + 460700 + Chesterfield + VA + US + 37.39 + -77.56 + 0 + 0 + AKQ + + + VAZ087 + 460870 + Greensville + VA + US + 36.72 + -77.56 + 0 + 0 + AKQ + + + PAZ028 + 380280 + Juniata + PA + US + 40.48 + -77.50 + 0 + 0 + CTP + + + NCZ012 + 330120 + Northampton + NC + US + 36.36 + -77.49 + 0 + 0 + AKQ + + + VAZ052 + 460520 + Pr_William/Manassas/Manassas_Pk + VA + US + 38.72 + -77.47 + 0 + 0 + LWX + + + VAZ055 + 460550 + Stafford + VA + US + 38.42 + -77.46 + 0 + 0 + LWX + + + VAZ063 + 460630 + Hanover + VA + US + 37.78 + -77.46 + 0 + 0 + AKQ + + + VAZ071 + 460710 + Henrico + VA + US + 37.53 + -77.42 + 0 + 0 + AKQ + + + MDZ004 + 200040 + Frederick + MD + US + 39.47 + -77.40 + 0 + 0 + LWX + + + NCZ044 + 330440 + Pitt + NC + US + 35.58 + -77.40 + 0 + 0 + MHX + + + NCZ092 + 330920 + Jones + NC + US + 35.01 + -77.39 + 0 + 0 + MHX + + + PAZ045 + 380450 + Southern_Clinton + PA + US + 41.09 + -77.39 + 0 + 0 + CTP + + + NYZ022 + 320220 + Steuben + NY + US + 42.29 + -77.36 + 0 + 0 + BGM + + + VAZ064 + 460640 + Caroline + VA + US + 38.01 + -77.36 + 0 + 0 + AKQ + + + NYZ014 + 320140 + Ontario + NY + US + 42.81 + -77.29 + 0 + 0 + BUF + + + PAZ056 + 380560 + Perry + PA + US + 40.41 + -77.29 + 0 + 0 + CTP + + + VAZ053 + 460530 + Fairfax + VA + US + 38.84 + -77.29 + 0 + 0 + LWX + + + VAZ088 + 460880 + Sussex + VA + US + 36.91 + -77.29 + 0 + 0 + AKQ + + + NCZ098 + 330980 + Onslow + NC + US + 34.72 + -77.26 + 0 + 0 + MHX + + + PAZ037 + 380370 + Tioga + PA + US + 41.77 + -77.25 + 0 + 0 + CTP + + + PAZ063 + 380630 + Cumberland + PA + US + 40.14 + -77.24 + 0 + 0 + CTP + + + PAZ064 + 380640 + Adams + PA + US + 39.90 + -77.22 + 0 + 0 + CTP + + + VAZ081 + 460810 + Prince_George + VA + US + 37.16 + -77.22 + 0 + 0 + AKQ + + + MDZ009 + 200090 + Montgomery + MD + US + 39.14 + -77.20 + 0 + 0 + LWX + + + VAZ057 + 460570 + King_George + VA + US + 38.28 + -77.18 + 0 + 0 + LWX + + + VAZ092 + 460920 + Southampton + VA + US + 36.78 + -77.16 + 0 + 0 + AKQ + + + NYZ015 + 320150 + Yates + NY + US + 42.61 + -77.13 + 0 + 0 + BGM + + + VAZ054 + 460540 + Arlington/Falls_Ch/Alexandria + VA + US + 38.86 + -77.12 + 0 + 0 + LWX + + + PAZ041 + 380410 + Northern_Lycoming + PA + US + 41.41 + -77.11 + 0 + 0 + CTP + + + PAZ049 + 380490 + Union + PA + US + 40.98 + -77.10 + 0 + 0 + CTP + + + NCZ029 + 330290 + Martin + NC + US + 35.86 + -77.09 + 0 + 0 + MHX + + + PAZ050 + 380500 + Snyder + PA + US + 40.76 + -77.09 + 0 + 0 + CTP + + + VAZ082 + 460820 + Charles_City + VA + US + 37.36 + -77.08 + 0 + 0 + AKQ + + + VAZ072 + 460720 + King_William + VA + US + 37.71 + -77.06 + 0 + 0 + AKQ + + + MDZ005 + 200050 + Carroll + MD + US + 39.53 + -77.05 + 0 + 0 + LWX + + + NCZ093 + 330930 + Craven + NC + US + 35.13 + -77.05 + 0 + 0 + MHX + + + NYZ004 + 320040 + Wayne + NY + US + 43.18 + -77.04 + 0 + 0 + BUF + + + DCZ001 + 510010 + District_of_Columbia + DC + US + 38.89 + -77.02 + 0 + 0 + LWX + + + NCZ030 + 330300 + Bertie + NC + US + 36.03 + -77.01 + 0 + 0 + AKQ + + + VAZ083 + 460830 + New_Kent + VA + US + 37.50 + -76.99 + 0 + 0 + AKQ + + + MDZ016 + 200160 + Charles + MD + US + 38.48 + -76.98 + 0 + 0 + LWX + + + NCZ013 + 330130 + Hertford + NC + US + 36.39 + -76.96 + 0 + 0 + AKQ + + + MDZ010 + 200100 + Howard + MD + US + 39.23 + -76.94 + 0 + 0 + LWX + + + VAZ074 + 460740 + Essex + VA + US + 37.95 + -76.93 + 0 + 0 + AKQ + + + VAZ073 + 460730 + King_and_Queen + VA + US + 37.70 + -76.92 + 0 + 0 + AKQ + + + VAZ089 + 460890 + Surry + VA + US + 37.10 + -76.91 + 0 + 0 + AKQ + + + MDZ013 + 200130 + Prince_Georges + MD + US + 38.83 + -76.88 + 0 + 0 + LWX + + + PAZ046 + 380460 + Southern_Lycoming + PA + US + 41.22 + -76.88 + 0 + 0 + CTP + + + NYZ023 + 320230 + Schuyler + NY + US + 42.40 + -76.86 + 0 + 0 + BGM + + + NCZ080 + 330800 + Beaufort + NC + US + 35.48 + -76.84 + 0 + 0 + MHX + + + VAZ075 + 460750 + Westmoreland + VA + US + 38.12 + -76.80 + 0 + 0 + AKQ + + + PAZ057 + 380570 + Dauphin + PA + US + 40.40 + -76.79 + 0 + 0 + CTP + + + NYZ016 + 320160 + Seneca + NY + US + 42.79 + -76.78 + 0 + 0 + BGM + + + NYZ024 + 320240 + Chemung + NY + US + 42.15 + -76.75 + 0 + 0 + BGM + + + VAZ090 + 460900 + James_City + VA + US + 37.32 + -76.75 + 0 + 0 + AKQ + + + VAZ076 + 460760 + Richmond + VA + US + 37.95 + -76.73 + 0 + 0 + AKQ + + + NCZ014 + 330140 + Gates + NC + US + 36.42 + -76.71 + 0 + 0 + AKQ + + + NCZ094 + 330940 + Pamlico + NC + US + 35.15 + -76.71 + 0 + 0 + MHX + + + VAZ093 + 460930 + Isle_of_Wight + VA + US + 36.89 + -76.71 + 0 + 0 + AKQ + + + PAZ065 + 380650 + York + PA + US + 39.97 + -76.69 + 0 + 0 + CTP + + + PAZ052 + 380520 + Northumberland + PA + US + 40.89 + -76.67 + 0 + 0 + CTP + + + VAZ096 + 460960 + Suffolk + VA + US + 36.74 + -76.67 + 0 + 0 + AKQ + + + NCZ031 + 330310 + Chowan + NC + US + 36.17 + -76.66 + 0 + 0 + AKQ + + + PAZ051 + 380510 + Montour + PA + US + 41.02 + -76.66 + 0 + 0 + CTP + + + MDZ006 + 200060 + Northern_Baltimore + MD + US + 39.57 + -76.64 + 0 + 0 + LWX + + + VAZ085 + 460850 + Middlesex + VA + US + 37.65 + -76.64 + 0 + 0 + AKQ + + + MDZ011 + 200110 + Southern_Baltimore + MD + US + 39.31 + -76.61 + 0 + 0 + LWX + + + MDZ014 + 200140 + Anne_Arundel + MD + US + 38.97 + -76.61 + 0 + 0 + LWX + + + NCZ045 + 330450 + Washington + NC + US + 35.84 + -76.60 + 0 + 0 + MHX + + + NCZ095 + 330950 + Carteret + NC + US + 34.85 + -76.60 + 0 + 0 + MHX + + + NYZ005 + 320050 + Northern_Cayuga + NY + US + 43.22 + -76.60 + 0 + 0 + BUF + + + MDZ017 + 200170 + St._Marys + MD + US + 38.28 + -76.59 + 0 + 0 + LWX + + + VAZ084 + 460840 + Gloucester + VA + US + 37.43 + -76.55 + 0 + 0 + AKQ + + + MDZ018 + 200180 + Calvert + MD + US + 38.54 + -76.54 + 0 + 0 + LWX + + + PAZ038 + 380380 + Bradford + PA + US + 41.77 + -76.53 + 0 + 0 + BGM + + + PAZ042 + 380420 + Sullivan + PA + US + 41.44 + -76.52 + 0 + 0 + CTP + + + VAZ091 + 460910 + York + VA + US + 37.23 + -76.51 + 0 + 0 + AKQ + + + NYZ017 + 320170 + Southern_Cayuga + NY + US + 42.82 + -76.50 + 0 + 0 + BGM + + + VAZ094 + 460940 + Newport_News/Hampton + VA + US + 37.10 + -76.50 + 0 + 0 + AKQ + + + NYZ025 + 320250 + Tompkins + NY + US + 42.45 + -76.47 + 0 + 0 + BGM + + + VAZ078 + 460780 + Lancaster + VA + US + 37.73 + -76.45 + 0 + 0 + AKQ + + + VAZ077 + 460770 + Northumberland + VA + US + 37.86 + -76.44 + 0 + 0 + AKQ + + + PAZ053 + 380530 + Columbia + PA + US + 41.04 + -76.43 + 0 + 0 + CTP + + + PAZ059 + 380590 + Lebanon + PA + US + 40.38 + -76.42 + 0 + 0 + CTP + + + NCZ032 + 330320 + Perquimans + NC + US + 36.22 + -76.40 + 0 + 0 + AKQ + + + MDZ007 + 200070 + Harford + MD + US + 39.50 + -76.32 + 0 + 0 + LWX + + + NYZ055 + 320550 + Tioga + NY + US + 42.20 + -76.32 + 0 + 0 + BGM + + + PAZ066 + 380660 + Lancaster + PA + US + 40.02 + -76.31 + 0 + 0 + CTP + + + VAZ095 + 460950 + Norfolk/Portsmouth + VA + US + 36.87 + -76.30 + 0 + 0 + AKQ + + + VAZ086 + 460860 + Mathews + VA + US + 37.42 + -76.29 + 0 + 0 + AKQ + + + NCZ015 + 330150 + Pasquotank + NC + US + 36.31 + -76.28 + 0 + 0 + AKQ + + + VAZ097 + 460970 + Chesapeake + VA + US + 36.71 + -76.28 + 0 + 0 + AKQ + + + NCZ081 + 330810 + Western_Hyde + NC + US + 35.51 + -76.26 + 0 + 0 + MHX + + + PAZ058 + 380580 + Schuylkill + PA + US + 40.72 + -76.23 + 0 + 0 + CTP + + + NCZ046 + 330460 + Tyrrell + NC + US + 35.79 + -76.21 + 0 + 0 + MHX + + + NYZ006 + 320060 + Oswego + NY + US + 43.43 + -76.19 + 0 + 0 + BUF + + + NYZ018 + 320180 + Onondaga + NY + US + 43.02 + -76.19 + 0 + 0 + BGM + + + NCZ016 + 330160 + Camden + NC + US + 36.36 + -76.17 + 0 + 0 + AKQ + + + MDZ012 + 200120 + Kent + MD + US + 39.20 + -76.15 + 0 + 0 + PHI + + + MDZ019 + 200190 + Talbot + MD + US + 38.76 + -76.15 + 0 + 0 + PHI + + + NYZ044 + 320440 + Cortland + NY + US + 42.60 + -76.07 + 0 + 0 + BGM + + + MDZ015 + 200150 + Queen_Anne's + MD + US + 39.06 + -76.06 + 0 + 0 + PHI + + + VAZ098 + 460980 + Virginia_Beach + VA + US + 36.74 + -76.05 + 0 + 0 + AKQ + + + MDZ021 + 200210 + Dorchester + MD + US + 38.41 + -76.03 + 0 + 0 + AKQ + + + PAZ043 + 380430 + Wyoming + PA + US + 41.52 + -76.01 + 0 + 0 + BGM + + + PAZ060 + 380600 + Berks + PA + US + 40.41 + -75.99 + 0 + 0 + PHI + + + PAZ047 + 380470 + Luzerne + PA + US + 41.16 + -75.96 + 0 + 0 + BGM + + + NYZ007 + 320070 + Jefferson + NY + US + 44.03 + -75.95 + 0 + 0 + BUF + + + VAZ100 + 461000 + Northampton + VA + US + 37.34 + -75.95 + 0 + 0 + AKQ + + + NCZ017 + 330170 + Western_Currituck + NC + US + 36.31 + -75.94 + 0 + 0 + AKQ + + + MDZ008 + 200080 + Cecil + MD + US + 39.55 + -75.93 + 0 + 0 + PHI + + + NCZ104 + 331040 + Eastern_Hyde + NC + US + 35.13 + -75.92 + 0 + 0 + MHX + + + NCZ047 + 330470 + Western_Dare + NC + US + 35.77 + -75.87 + 0 + 0 + MHX + + + MDZ020 + 200200 + Caroline + MD + US + 38.90 + -75.86 + 0 + 0 + PHI + + + NCZ102 + 331020 + Eastern_Currituck + NC + US + 36.37 + -75.84 + 0 + 0 + AKQ + + + PAZ039 + 380390 + Susquehanna + PA + US + 41.82 + -75.81 + 0 + 0 + BGM + + + MDZ023 + 200230 + Somerset + MD + US + 38.10 + -75.80 + 0 + 0 + AKQ + + + NYZ056 + 320560 + Broome + NY + US + 42.21 + -75.76 + 0 + 0 + BGM + + + PAZ067 + 380670 + Chester + PA + US + 39.99 + -75.76 + 0 + 0 + PHI + + + PAZ054 + 380540 + Carbon + PA + US + 40.94 + -75.74 + 0 + 0 + PHI + + + PAZ044 + 380440 + Lackawanna + PA + US + 41.40 + -75.64 + 0 + 0 + BGM + + + VAZ099 + 460990 + Accomack + VA + US + 37.74 + -75.64 + 0 + 0 + AKQ + + + MDZ022 + 200220 + Wicomico + MD + US + 38.39 + -75.62 + 0 + 0 + AKQ + + + NYZ036 + 320360 + Madison + NY + US + 42.96 + -75.62 + 0 + 0 + BGM + + + PAZ061 + 380610 + Lehigh + PA + US + 40.60 + -75.62 + 0 + 0 + PHI + + + DEZ001 + 80010 + New_Castle + DE + US + 39.57 + -75.60 + 0 + 0 + PHI + + + NYZ045 + 320450 + Chenango + NY + US + 42.47 + -75.59 + 0 + 0 + BGM + + + DEZ002 + 80020 + Kent + DE + US + 39.10 + -75.53 + 0 + 0 + PHI + + + NCZ103 + 331030 + Eastern_Dare + NC + US + 35.48 + -75.48 + 0 + 0 + MHX + + + NYZ008 + 320080 + Lewis + NY + US + 43.82 + -75.48 + 0 + 0 + BUF + + + NYZ009 + 320090 + Northern_Oneida + NY + US + 43.38 + -75.48 + 0 + 0 + BGM + + + PAZ070 + 380700 + Delaware + PA + US + 39.93 + -75.43 + 0 + 0 + PHI + + + DEZ003 + 80030 + Inland_Sussex + DE + US + 38.70 + -75.42 + 0 + 0 + PHI + + + NYZ037 + 320370 + Southern_Oneida + NY + US + 43.08 + -75.41 + 0 + 0 + BGM + + + MDZ024 + 200240 + Inland_Worcester + MD + US + 38.23 + -75.39 + 0 + 0 + AKQ + + + PAZ068 + 380680 + Montgomery + PA + US + 40.21 + -75.36 + 0 + 0 + PHI + + + PAZ062 + 380620 + Northampton + PA + US + 40.75 + -75.34 + 0 + 0 + PHI + + + NJZ016 + 300160 + Salem + NJ + US + 39.58 + -75.32 + 0 + 0 + PHI + + + PAZ055 + 380550 + Monroe + PA + US + 41.03 + -75.31 + 0 + 0 + PHI + + + PAZ072 + 380720 + Southern_Wayne + PA + US + 41.44 + -75.28 + 0 + 0 + BGM + + + PAZ040 + 380400 + Northern_Wayne + PA + US + 41.80 + -75.27 + 0 + 0 + BGM + + + NYZ087 + 320870 + Southwestern_St._Lawrence + NY + US + 44.46 + -75.23 + 0 + 0 + BTV + + + MDZ025 + 200250 + Maryland_Beaches + MD + US + 38.17 + -75.18 + 0 + 0 + AKQ + + + NJZ017 + 300170 + Gloucester + NJ + US + 39.70 + -75.16 + 0 + 0 + PHI + + + NJZ021 + 300210 + Cumberland + NJ + US + 39.37 + -75.14 + 0 + 0 + PHI + + + PAZ071 + 380710 + Philadelphia + PA + US + 39.99 + -75.13 + 0 + 0 + PHI + + + PAZ069 + 380690 + Bucks + PA + US + 40.32 + -75.11 + 0 + 0 + PHI + + + DEZ004 + 80040 + Delaware_Beaches + DE + US + 38.63 + -75.09 + 0 + 0 + PHI + + + PAZ048 + 380480 + Pike + PA + US + 41.34 + -75.03 + 0 + 0 + BGM + + + NYZ046 + 320460 + Otsego + NY + US + 42.61 + -75.02 + 0 + 0 + BGM + + + NJZ007 + 300070 + Warren + NJ + US + 40.83 + -74.99 + 0 + 0 + PHI + + + NYZ026 + 320260 + Northern_St._Lawrence + NY + US + 44.86 + -74.99 + 0 + 0 + BTV + + + NYZ032 + 320320 + Northern_Herkimer + NY + US + 43.71 + -74.97 + 0 + 0 + ALY + + + NJZ009 + 300090 + Hunterdon + NJ + US + 40.56 + -74.96 + 0 + 0 + PHI + + + NJZ018 + 300180 + Camden + NJ + US + 39.79 + -74.95 + 0 + 0 + PHI + + + NYZ038 + 320380 + Southern_Herkimer + NY + US + 43.08 + -74.95 + 0 + 0 + ALY + + + NYZ029 + 320290 + Southeastern_St._Lawrence + NY + US + 44.39 + -74.93 + 0 + 0 + BTV + + + NYZ057 + 320570 + Delaware + NY + US + 42.19 + -74.93 + 0 + 0 + BGM + + + NJZ023 + 300230 + Cape_May + NJ + US + 39.15 + -74.81 + 0 + 0 + PHI + + + NJZ019 + 300190 + Northwestern_Burlington + NJ + US + 39.97 + -74.77 + 0 + 0 + PHI + + + NJZ024 + 300240 + Atlantic_Coastal_Cape_May + NJ + US + 39.11 + -74.76 + 0 + 0 + PHI + + + NYZ062 + 320620 + Sullivan + NY + US + 41.72 + -74.76 + 0 + 0 + BGM + + + NJZ015 + 300150 + Mercer + NJ + US + 40.27 + -74.71 + 0 + 0 + PHI + + + NJZ022 + 300220 + Atlantic + NJ + US + 39.50 + -74.69 + 0 + 0 + PHI + + + NJZ001 + 300010 + Sussex + NJ + US + 41.13 + -74.68 + 0 + 0 + PHI + + + NJZ010 + 300100 + Somerset + NJ + US + 40.56 + -74.60 + 0 + 0 + PHI + + + NJZ027 + 300270 + Southeastern_Burlington + NJ + US + 39.73 + -74.60 + 0 + 0 + PHI + + + NJZ008 + 300080 + Morris + NJ + US + 40.86 + -74.58 + 0 + 0 + PHI + + + NJZ025 + 300250 + Coastal_Atlantic + NJ + US + 39.40 + -74.46 + 0 + 0 + PHI + + + NYZ033 + 320330 + Hamilton + NY + US + 43.66 + -74.46 + 0 + 0 + ALY + + + NYZ039 + 320390 + Southern_Fulton + NY + US + 43.05 + -74.44 + 0 + 0 + ALY + + + NYZ047 + 320470 + Schoharie + NY + US + 42.59 + -74.44 + 0 + 0 + ALY + + + NYZ082 + 320820 + Northern_Fulton + NY + US + 43.17 + -74.44 + 0 + 0 + ALY + + + NJZ012 + 300120 + Middlesex + NJ + US + 40.42 + -74.43 + 0 + 0 + PHI + + + NYZ040 + 320400 + Montgomery + NY + US + 42.91 + -74.43 + 0 + 0 + ALY + + + NYZ063 + 320630 + Western_Ulster + NY + US + 41.88 + -74.43 + 0 + 0 + ALY + + + NYZ027 + 320270 + Northern_Franklin + NY + US + 44.86 + -74.39 + 0 + 0 + BTV + + + NJZ002 + 300020 + Western_Passaic + NJ + US + 41.09 + -74.36 + 0 + 0 + OKX + + + NYZ067 + 320670 + Orange + NY + US + 41.39 + -74.36 + 0 + 0 + OKX + + + NJZ013 + 300130 + Western_Monmouth + NJ + US + 40.26 + -74.32 + 0 + 0 + PHI + + + NJZ020 + 300200 + Ocean + NJ + US + 39.85 + -74.32 + 0 + 0 + PHI + + + NJZ011 + 300110 + Union + NJ + US + 40.66 + -74.31 + 0 + 0 + OKX + + + NYZ058 + 320580 + Western_Greene + NY + US + 42.26 + -74.28 + 0 + 0 + ALY + + + NJZ026 + 300260 + Coastal_Ocean + NJ + US + 39.64 + -74.26 + 0 + 0 + PHI + + + NYZ030 + 320300 + Southern_Franklin + NY + US + 44.54 + -74.26 + 0 + 0 + BTV + + + NJZ005 + 300050 + Essex + NJ + US + 40.79 + -74.25 + 0 + 0 + OKX + + + NJZ004 + 300040 + Eastern_Passaic + NJ + US + 40.91 + -74.20 + 0 + 0 + OKX + + + NYZ048 + 320480 + Western_Schenectady + NY + US + 42.80 + -74.17 + 0 + 0 + ALY + + + NYZ074 + 320740 + Richmond_(Staten_Is.) + NY + US + 40.58 + -74.15 + 0 + 0 + OKX + + + NYZ051 + 320510 + Western_Albany + NY + US + 42.58 + -74.14 + 0 + 0 + ALY + + + NYZ064 + 320640 + Eastern_Ulster + NY + US + 41.88 + -74.09 + 0 + 0 + ALY + + + NJZ003 + 300030 + Bergen + NJ + US + 40.94 + -74.08 + 0 + 0 + OKX + + + NJZ006 + 300060 + Hudson + NJ + US + 40.74 + -74.07 + 0 + 0 + OKX + + + NYZ069 + 320690 + Rockland + NY + US + 41.16 + -74.07 + 0 + 0 + OKX + + + NJZ014 + 300140 + Eastern_Monmouth + NJ + US + 40.28 + -74.03 + 0 + 0 + PHI + + + NYZ049 + 320490 + Eastern_Schenectady + NY + US + 42.85 + -73.96 + 0 + 0 + ALY + + + NYZ072 + 320720 + New_York_(Manhattan) + NY + US + 40.79 + -73.96 + 0 + 0 + OKX + + + NYZ075 + 320750 + Kings_(Brooklyn) + NY + US + 40.66 + -73.94 + 0 + 0 + OKX + + + NYZ059 + 320590 + Eastern_Greene + NY + US + 42.30 + -73.91 + 0 + 0 + ALY + + + NYZ034 + 320340 + Western_Essex + NY + US + 44.10 + -73.90 + 0 + 0 + BTV + + + NYZ050 + 320500 + Southern_Saratoga + NY + US + 42.94 + -73.88 + 0 + 0 + ALY + + + NYZ041 + 320410 + Northern_Saratoga + NY + US + 43.17 + -73.87 + 0 + 0 + ALY + + + NYZ052 + 320520 + Eastern_Albany + NY + US + 42.62 + -73.86 + 0 + 0 + ALY + + + NYZ065 + 320650 + Western_Dutchess + NY + US + 41.76 + -73.85 + 0 + 0 + ALY + + + NYZ073 + 320730 + Bronx + NY + US + 40.86 + -73.85 + 0 + 0 + OKX + + + NYZ042 + 320420 + Northern_Warren + NY + US + 43.58 + -73.84 + 0 + 0 + ALY + + + NYZ076 + 320760 + Queens + NY + US + 40.68 + -73.83 + 0 + 0 + OKX + + + NYZ031 + 320310 + Western_Clinton + NY + US + 44.71 + -73.79 + 0 + 0 + BTV + + + NYZ071 + 320710 + Southern_Westchester + NY + US + 40.99 + -73.78 + 0 + 0 + OKX + + + NYZ068 + 320680 + Putnam + NY + US + 41.43 + -73.76 + 0 + 0 + OKX + + + NYZ060 + 320600 + Western_Columbia + NY + US + 42.24 + -73.75 + 0 + 0 + ALY + + + NYZ083 + 320830 + Southeast_Warren + NY + US + 43.34 + -73.74 + 0 + 0 + ALY + + + NYZ070 + 320700 + Northern_Westchester + NY + US + 41.18 + -73.73 + 0 + 0 + OKX + + + NYZ053 + 320530 + Western_Rensselaer + NY + US + 42.70 + -73.62 + 0 + 0 + ALY + + + NYZ066 + 320660 + Eastern_Dutchess + NY + US + 41.78 + -73.62 + 0 + 0 + ALY + + + NYZ077 + 320770 + Nassau + NY + US + 40.75 + -73.59 + 0 + 0 + OKX + + + NYZ028 + 320280 + Eastern_Clinton + NY + US + 44.74 + -73.57 + 0 + 0 + BTV + + + NYZ061 + 320610 + Eastern_Columbia + NY + US + 42.24 + -73.52 + 0 + 0 + ALY + + + NYZ043 + 320430 + Northern_Washington + NY + US + 43.56 + -73.44 + 0 + 0 + ALY + + + NYZ084 + 320840 + Southern_Washington + NY + US + 43.18 + -73.44 + 0 + 0 + ALY + + + NYZ035 + 320350 + Eastern_Essex + NY + US + 44.17 + -73.43 + 0 + 0 + BTV + + + NYZ054 + 320540 + Eastern_Rensselaer + NY + US + 42.72 + -73.42 + 0 + 0 + ALY + + + CTZ009 + 70090 + Southern_Fairfield + CT + US + 41.13 + -73.41 + 0 + 0 + OKX + + + CTZ005 + 70050 + Northern_Fairfield + CT + US + 41.41 + -73.31 + 0 + 0 + OKX + + + VTZ001 + 450010 + Grand_Isle + VT + US + 44.78 + -73.29 + 0 + 0 + BTV + + + MAZ025 + 210250 + Southern_Berkshire + MA + US + 42.23 + -73.25 + 0 + 0 + ALY + + + CTZ013 + 70130 + Southern_Litchfield + CT + US + 41.64 + -73.24 + 0 + 0 + ALY + + + VTZ009 + 450090 + Western_Addison + VT + US + 44.02 + -73.23 + 0 + 0 + BTV + + + CTZ001 + 70010 + Northern_Litchfield + CT + US + 41.86 + -73.20 + 0 + 0 + ALY + + + NYZ078 + 320780 + Northwest_Suffolk + NY + US + 40.88 + -73.18 + 0 + 0 + OKX + + + VTZ011 + 450110 + Western_Rutland + VT + US + 43.57 + -73.18 + 0 + 0 + BTV + + + MAZ001 + 210010 + Northern_Berkshire + MA + US + 42.56 + -73.16 + 0 + 0 + ALY + + + NYZ080 + 320800 + Southwest_Suffolk + NY + US + 40.73 + -73.15 + 0 + 0 + OKX + + + VTZ005 + 450050 + Western_Chittenden + VT + US + 44.49 + -73.13 + 0 + 0 + BTV + + + VTZ013 + 450130 + Bennington + VT + US + 43.02 + -73.06 + 0 + 0 + ALY + + + CTZ006 + 70060 + Northern_New_Haven + CT + US + 41.47 + -73.03 + 0 + 0 + OKX + + + VTZ002 + 450020 + Western_Franklin + VT + US + 44.82 + -73.03 + 0 + 0 + BTV + + + VTZ017 + 450170 + Eastern_Chittenden + VT + US + 44.40 + -72.94 + 0 + 0 + BTV + + + VTZ018 + 450180 + Eastern_Addison + VT + US + 44.05 + -72.94 + 0 + 0 + BTV + + + MAZ009 + 210090 + Western_Hampden + MA + US + 42.19 + -72.93 + 0 + 0 + BOX + + + MAZ008 + 210080 + Western_Hampshire + MA + US + 42.39 + -72.87 + 0 + 0 + BOX + + + VTZ019 + 450190 + Eastern_Rutland + VT + US + 43.57 + -72.86 + 0 + 0 + BTV + + + CTZ010 + 70100 + Southern_New_Haven + CT + US + 41.30 + -72.82 + 0 + 0 + OKX + + + MAZ002 + 210020 + Western_Franklin + MA + US + 42.59 + -72.80 + 0 + 0 + BOX + + + VTZ014 + 450140 + Western_Windham + VT + US + 43.00 + -72.78 + 0 + 0 + ALY + + + VTZ016 + 450160 + Eastern_Franklin + VT + US + 44.83 + -72.77 + 0 + 0 + BTV + + + CTZ002 + 70020 + Hartford + CT + US + 41.79 + -72.72 + 0 + 0 + BOX + + + VTZ006 + 450060 + Lamoille + VT + US + 44.60 + -72.65 + 0 + 0 + BTV + + + VTZ012 + 450120 + Windsor + VT + US + 43.59 + -72.59 + 0 + 0 + BTV + + + VTZ008 + 450080 + Washington + VT + US + 44.26 + -72.58 + 0 + 0 + BTV + + + VTZ015 + 450150 + Eastern_Windham + VT + US + 42.98 + -72.57 + 0 + 0 + ALY + + + CTZ007 + 70070 + Northern_Middlesex + CT + US + 41.48 + -72.53 + 0 + 0 + OKX + + + MAZ010 + 210100 + Eastern_Hampshire + MA + US + 42.31 + -72.51 + 0 + 0 + BOX + + + MAZ011 + 210110 + Eastern_Hampden + MA + US + 42.14 + -72.50 + 0 + 0 + BOX + + + CTZ011 + 70110 + Southern_Middlesex + CT + US + 41.33 + -72.46 + 0 + 0 + OKX + + + MAZ003 + 210030 + Eastern_Franklin + MA + US + 42.52 + -72.46 + 0 + 0 + BOX + + + NYZ079 + 320790 + Northeast_Suffolk + NY + US + 41.07 + -72.41 + 0 + 0 + OKX + + + VTZ010 + 450100 + Orange + VT + US + 43.99 + -72.41 + 0 + 0 + BTV + + + NYZ081 + 320810 + Southeast_Suffolk + NY + US + 40.90 + -72.37 + 0 + 0 + OKX + + + CTZ003 + 70030 + Tolland + CT + US + 41.81 + -72.31 + 0 + 0 + BOX + + + NHZ011 + 290110 + Cheshire + NH + US + 42.94 + -72.24 + 0 + 0 + BOX + + + VTZ003 + 450030 + Orleans + VT + US + 44.77 + -72.23 + 0 + 0 + BTV + + + NHZ007 + 290070 + Sullivan + NH + US + 43.36 + -72.20 + 0 + 0 + GYX + + + CTZ008 + 70080 + Northern_New_London + CT + US + 41.53 + -72.13 + 0 + 0 + OKX + + + VTZ007 + 450070 + Caledonia + VT + US + 44.46 + -72.13 + 0 + 0 + BTV + + + CTZ004 + 70040 + Windham + CT + US + 41.83 + -72.02 + 0 + 0 + BOX + + + CTZ012 + 70120 + Southern_New_London + CT + US + 41.36 + -71.96 + 0 + 0 + OKX + + + NHZ005 + 290050 + Southern_Grafton + NH + US + 43.71 + -71.93 + 0 + 0 + GYX + + + MAZ004 + 210040 + Northern_Worcester + MA + US + 42.43 + -71.92 + 0 + 0 + BOX + + + MAZ012 + 210120 + Southern_Worcester + MA + US + 42.18 + -71.81 + 0 + 0 + BOX + + + NHZ015 + 290150 + Wrn_And_Central_Hillsborough + NH + US + 42.95 + -71.78 + 0 + 0 + BOX + + + NHZ003 + 290030 + Northern_Grafton + NH + US + 44.13 + -71.76 + 0 + 0 + GYX + + + VTZ004 + 450040 + Essex + VT + US + 44.68 + -71.74 + 0 + 0 + BTV + + + NHZ008 + 290080 + Merrimack + NH + US + 43.31 + -71.67 + 0 + 0 + GYX + + + RIZ003 + 390030 + Western_Kent + RI + US + 41.66 + -71.66 + 0 + 0 + BOX + + + RIZ006 + 390060 + Washington + RI + US + 41.48 + -71.66 + 0 + 0 + BOX + + + MAZ026 + 210260 + Northwest_Middlesex_County + MA + US + 42.61 + -71.59 + 0 + 0 + BOX + + + RIZ001 + 390010 + Northwest_Providence + RI + US + 41.87 + -71.59 + 0 + 0 + BOX + + + RIZ008 + 390080 + Block_Island + RI + US + 41.19 + -71.57 + 0 + 0 + BOX + + + NHZ012 + 290120 + Eastern_Hillsborough + NH + US + 42.88 + -71.50 + 0 + 0 + BOX + + + RIZ004 + 390040 + Eastern_Kent + RI + US + 41.68 + -71.46 + 0 + 0 + BOX + + + NHZ009 + 290090 + Belknap + NH + US + 43.52 + -71.45 + 0 + 0 + GYX + + + RIZ002 + 390020 + Southeast_Providence + RI + US + 41.81 + -71.45 + 0 + 0 + BOX + + + NHZ002 + 290020 + Southern_Coos + NH + US + 44.41 + -71.39 + 0 + 0 + GYX + + + MAZ005 + 210050 + Central_Middlesex_County + MA + US + 42.44 + -71.33 + 0 + 0 + BOX + + + NHZ001 + 290010 + Northern_Coos + NH + US + 45.02 + -71.33 + 0 + 0 + GYX + + + RIZ005 + 390050 + Bristol + RI + US + 41.71 + -71.27 + 0 + 0 + BOX + + + NHZ006 + 290060 + Southern_Carroll + NH + US + 43.71 + -71.26 + 0 + 0 + GYX + + + RIZ007 + 390070 + Newport + RI + US + 41.56 + -71.26 + 0 + 0 + BOX + + + MAZ013 + 210130 + Western_Norfolk + MA + US + 42.15 + -71.24 + 0 + 0 + BOX + + + NHZ004 + 290040 + Northern_Carroll + NH + US + 44.10 + -71.22 + 0 + 0 + GYX + + + MAZ017 + 210170 + Northern_Bristol + MA + US + 41.93 + -71.18 + 0 + 0 + BOX + + + NHZ013 + 290130 + Interior_Rockingham + NH + US + 43.01 + -71.17 + 0 + 0 + GYX + + + MAZ014 + 210140 + Southeast_Middlesex + MA + US + 42.41 + -71.16 + 0 + 0 + BOX + + + MAZ006 + 210060 + Western_Essex + MA + US + 42.72 + -71.08 + 0 + 0 + BOX + + + MAZ015 + 210150 + Suffolk + MA + US + 42.34 + -71.07 + 0 + 0 + BOX + + + MAZ020 + 210200 + Southern_Bristol + MA + US + 41.65 + -71.07 + 0 + 0 + BOX + + + NHZ010 + 290100 + Strafford + NH + US + 43.33 + -71.03 + 0 + 0 + GYX + + + MAZ016 + 210160 + Eastern_Norfolk + MA + US + 42.22 + -71.02 + 0 + 0 + BOX + + + MAZ018 + 210180 + Western_Plymouth + MA + US + 42.00 + -70.88 + 0 + 0 + BOX + + + MAZ007 + 210070 + Eastern_Essex + MA + US + 42.65 + -70.83 + 0 + 0 + BOX + + + NHZ014 + 290140 + Coastal_Rockingham + NH + US + 42.99 + -70.82 + 0 + 0 + GYX + + + MEZ007 + 190070 + Northern_Oxford + ME + US + 44.88 + -70.80 + 0 + 0 + GYX + + + MAZ021 + 210210 + Southern_Plymouth + MA + US + 41.72 + -70.77 + 0 + 0 + BOX + + + MAZ019 + 210190 + Eastern_Plymouth + MA + US + 42.03 + -70.73 + 0 + 0 + BOX + + + MEZ018 + 190180 + Interior_York + ME + US + 43.52 + -70.73 + 0 + 0 + GYX + + + MAZ023 + 210230 + Dukes + MA + US + 41.38 + -70.70 + 0 + 0 + BOX + + + MEZ012 + 190120 + Southern_Oxford + ME + US + 44.20 + -70.63 + 0 + 0 + GYX + + + MEZ023 + 190230 + Coastal_York + ME + US + 43.34 + -70.58 + 0 + 0 + GYX + + + MEZ019 + 190190 + Interior_Cumberland + ME + US + 43.91 + -70.49 + 0 + 0 + GYX + + + MEZ008 + 190080 + Northern_Franklin + ME + US + 45.14 + -70.48 + 0 + 0 + GYX + + + MEZ024 + 190240 + Coastal_Cumberland + ME + US + 43.75 + -70.26 + 0 + 0 + GYX + + + MEZ020 + 190200 + Androscoggin + ME + US + 44.20 + -70.24 + 0 + 0 + GYX + + + MEZ013 + 190130 + Southern_Franklin + ME + US + 44.67 + -70.23 + 0 + 0 + GYX + + + MEZ009 + 190090 + Central_Somerset + ME + US + 45.42 + -70.10 + 0 + 0 + GYX + + + MEZ003 + 190030 + Northern_Somerset + ME + US + 46.27 + -70.01 + 0 + 0 + CAR + + + MAZ024 + 210240 + Nantucket + MA + US + 41.31 + -70.00 + 0 + 0 + BOX + + + MAZ022 + 210220 + Barnstable + MA + US + 41.80 + -69.99 + 0 + 0 + BOX + + + MEZ025 + 190250 + Sagadahoc + ME + US + 43.94 + -69.89 + 0 + 0 + GYX + + + MEZ021 + 190210 + Kennebec + ME + US + 44.42 + -69.75 + 0 + 0 + GYX + + + MEZ014 + 190140 + Southern_Somerset + ME + US + 44.85 + -69.67 + 0 + 0 + GYX + + + MEZ026 + 190260 + Lincoln + ME + US + 44.05 + -69.54 + 0 + 0 + GYX + + + MEZ010 + 190100 + Central_Piscataquis + ME + US + 45.55 + -69.38 + 0 + 0 + CAR + + + MEZ004 + 190040 + Northern_Piscataquis + ME + US + 46.12 + -69.27 + 0 + 0 + CAR + + + MEZ027 + 190270 + Knox + ME + US + 44.14 + -69.23 + 0 + 0 + GYX + + + MEZ031 + 190310 + Southern_Piscataquis + ME + US + 45.27 + -69.22 + 0 + 0 + CAR + + + MEZ022 + 190220 + Interior_Waldo + ME + US + 44.53 + -69.16 + 0 + 0 + GYX + + + MEZ001 + 190010 + Northwest_Aroostook + ME + US + 47.01 + -69.06 + 0 + 0 + CAR + + + MEZ028 + 190280 + Coastal_Waldo + ME + US + 44.36 + -69.04 + 0 + 0 + GYX + + + MEZ015 + 190150 + Southern_Penobscot + ME + US + 44.93 + -68.81 + 0 + 0 + CAR + + + MEZ005 + 190050 + Northern_Penobscot + ME + US + 45.95 + -68.69 + 0 + 0 + CAR + + + MEZ011 + 190110 + Central_Penobscot + ME + US + 45.39 + -68.41 + 0 + 0 + CAR + + + MEZ016 + 190160 + Interior_Hancock + ME + US + 44.88 + -68.41 + 0 + 0 + CAR + + + MEZ029 + 190290 + Coastal_Hancock + ME + US + 44.45 + -68.39 + 0 + 0 + CAR + + + MEZ002 + 190020 + Northeast_Aroostook + ME + US + 46.83 + -68.30 + 0 + 0 + CAR + + + MEZ006 + 190060 + Southeast_Aroostook + ME + US + 45.97 + -68.09 + 0 + 0 + CAR + + + MEZ032 + 190320 + Northern_Washington + ME + US + 45.48 + -67.73 + 0 + 0 + CAR + + + MEZ017 + 190170 + Central_Washington + ME + US + 45.00 + -67.57 + 0 + 0 + CAR + + + MEZ030 + 190300 + Coastal_Washington + ME + US + 44.67 + -67.49 + 0 + 0 + CAR + + + PRZ010 + 530100 + Mayaguez_and_Vicinity + PR + US + 18.26 + -67.12 + 0 + 0 + SJU + + + PRZ011 + 530110 + Southwest + PR + US + 18.05 + -67.04 + 0 + 0 + SJU + + + PRZ008 + 530080 + Northwest + PR + US + 18.42 + -66.97 + 0 + 0 + SJU + + + PRZ009 + 530090 + Western_Interior + PR + US + 18.21 + -66.82 + 0 + 0 + SJU + + + PRZ007 + 530070 + Ponce_and_Vicinity + PR + US + 18.03 + -66.63 + 0 + 0 + SJU + + + PRZ005 + 530050 + North_Central + PR + US + 18.40 + -66.48 + 0 + 0 + SJU + + + PRZ006 + 530060 + Central_Interior + PR + US + 18.20 + -66.43 + 0 + 0 + SJU + + + PRZ001 + 530010 + San_Juan_and_Vicinity + PR + US + 18.37 + -66.11 + 0 + 0 + SJU + + + PRZ003 + 530030 + Southeast + PR + US + 18.02 + -66.07 + 0 + 0 + SJU + + + PRZ004 + 530040 + Eastern_Interior + PR + US + 18.17 + -66.04 + 0 + 0 + SJU + + + PRZ002 + 530020 + Northeast + PR + US + 18.26 + -65.76 + 0 + 0 + SJU + + + PRZ013 + 530130 + Vieques + PR + US + 18.13 + -65.42 + 0 + 0 + SJU + + + PRZ012 + 530120 + Culebra + PR + US + 18.32 + -65.31 + 0 + 0 + SJU + + + VIZ001 + 520010 + St._Thomas...St._John..._and_Adj + VI + US + 18.34 + -64.87 + 0 + 0 + SJU + + + VIZ002 + 520020 + St_Croix + VI + US + 17.73 + -64.73 + 0 + 0 + SJU + + + CAZ000 + 50000 + No_name + CA + US + 32.92 + -118.48 + 0 + 0 + + + + GUZ012 + 540120 + Sonsorol + GU + US + 5.30 + 132.22 + 0 + 0 + GUM + + + GUZ011 + 540110 + Koror + GU + US + 7.53 + 134.56 + 0 + 0 + GUM + + + GUZ013 + 540130 + Kayangel + GU + US + 8.08 + 134.72 + 0 + 0 + GUM + + + GUZ022 + 540220 + Ngulu + GU + US + 8.30 + 137.51 + 0 + 0 + GUM + + + GUZ021 + 540210 + Yap + GU + US + 9.54 + 138.12 + 0 + 0 + GUM + + + GUZ023 + 540230 + Ulithi + GU + US + 10.02 + 139.79 + 0 + 0 + GUM + + + GUZ024 + 540240 + Sorol + GU + US + 8.21 + 140.70 + 0 + 0 + GUM + + + GUZ025 + 540250 + Woleai + GU + US + 7.38 + 143.92 + 0 + 0 + GUM + + + GUZ001 + 540010 + Guam + GU + US + 13.44 + 144.79 + 0 + 0 + GUM + + + GUZ002 + 540020 + Rota + GU + US + 14.15 + 145.20 + 0 + 0 + GUM + + + GUZ003 + 540030 + Tinian + GU + US + 15.01 + 145.63 + 0 + 0 + GUM + + + GUZ005 + 540050 + Agrihan + GU + US + 18.76 + 145.66 + 0 + 0 + GUM + + + GUZ004 + 540040 + Saipan + GU + US + 15.19 + 145.76 + 0 + 0 + GUM + + + GUZ026 + 540260 + Satawal + GU + US + 7.36 + 147.04 + 0 + 0 + GUM + + + GUZ032 + 540320 + Puluwat + GU + US + 7.38 + 149.18 + 0 + 0 + GUM + + + GUZ031 + 540310 + Chuuk + GU + US + 7.35 + 151.83 + 0 + 0 + GUM + + + GUZ033 + 540330 + Lukunor + GU + US + 5.50 + 153.82 + 0 + 0 + GUM + + + GUZ041 + 540410 + Pohnpei + GU + US + 6.88 + 158.22 + 0 + 0 + GUM + + + GUZ042 + 540420 + Mokil + GU + US + 6.68 + 159.79 + 0 + 0 + GUM + + + GUZ043 + 540430 + Pingelap + GU + US + 6.21 + 160.71 + 0 + 0 + GUM + + + GUZ062 + 540620 + Ujelang + GU + US + 9.76 + 160.97 + 0 + 0 + GUM + + + GUZ063 + 540630 + Enewetak + GU + US + 11.34 + 162.33 + 0 + 0 + GUM + + + GUZ051 + 540510 + Kosrae + GU + US + 5.32 + 162.97 + 0 + 0 + GUM + + + GUZ081 + 540810 + Wake_Island + GU + US + 19.30 + 166.63 + 0 + 0 + GUM + + + GUZ064 + 540640 + Ailinglaplap + GU + US + 7.29 + 168.75 + 0 + 0 + GUM + + + GUZ065 + 540650 + Jaluit + GU + US + 5.85 + 169.53 + 0 + 0 + GUM + + + GUZ066 + 540660 + Utirik + GU + US + 11.24 + 169.86 + 0 + 0 + GUM + + + GUZ067 + 540670 + Wotje + GU + US + 9.55 + 170.24 + 0 + 0 + GUM + + + GUZ061 + 540610 + Majuro + GU + US + 7.11 + 171.08 + 0 + 0 + GUM + + + GUZ068 + 540680 + Mili + GU + US + 6.04 + 171.95 + 0 + 0 + GUM + + + AKZ191 + 21910 + Western_Aleutians + AK + US + 51.51 + 179.05 + 0 + 0 + AFC + + + PKZ175 + 691750 + Adak_to_Kiska + + US + 51.71 + -178.59 + 0 + 0 + AFC + + + PKZ185 + 691850 + St_Matthew_Island_Waters + + US + 60.43 + -174.18 + 0 + 0 + AFC + + + PKZ172 + 691720 + Nikolski_to_Adak + + US + 52.26 + -173.19 + 0 + 0 + AFC + + + PSZ152 + 721520 + Coastal_waters_of_Swain's_I + + US + -11.08 + -171.03 + 0 + 0 + STU + + + PSZ150 + 721500 + Cstal_wtrs_of_Tututila_and_Aunuu + + US + -14.31 + -170.77 + 0 + 0 + STU + + + PKZ179 + 691790 + Pribilof_Is_Nearshore_Waters + + US + 56.90 + -169.97 + 0 + 0 + AFC + + + PKZ210 + 692100 + Dall_Point_to_Wales + + US + 63.31 + -169.57 + 0 + 0 + AFG + + + PSZ151 + 721510 + Coastal_waters_of_Manua + + US + -14.21 + -169.45 + 0 + 0 + STU + + + PKZ225 + 692250 + Cape_Thompson_to_Cape_Beaufort + + US + 69.01 + -167.45 + 0 + 0 + AFG + + + PKZ170 + 691700 + Cape_Sarichef_to_Nikoski + + US + 53.72 + -166.78 + 0 + 0 + AFC + + + PKZ220 + 692200 + Wales_to_Cape_Thompson + + US + 66.97 + -166.69 + 0 + 0 + AFG + + + PKZ171 + 691710 + Unalaska_Bay + + US + 53.92 + -166.59 + 0 + 0 + AFC + + + PKZ180 + 691800 + Cape_Newenham_to_Dall_Point + + US + 59.92 + -165.98 + 0 + 0 + AFC + + + PKZ200 + 692000 + Norton_Sound + + US + 63.99 + -163.30 + 0 + 0 + AFG + + + PKZ230 + 692300 + Cape_Beaufort_to_Point_Franklin + + US + 70.53 + -163.03 + 0 + 0 + AFG + + + PKZ165 + 691650 + Port_Heiden_to_Cape_Sarichef + + US + 56.01 + -162.88 + 0 + 0 + AFC + + + PKZ215 + 692150 + Kotzebue_Sound + + US + 66.65 + -162.83 + 0 + 0 + AFG + + + PKZ155 + 691550 + Castle_Cape_to_Cape_Sarichef + + US + 54.50 + -160.72 + 0 + 0 + AFC + + + PKZ160 + 691600 + Cape_Newenham_to_Port_Heiden + + US + 57.98 + -160.52 + 0 + 0 + AFC + + + PHZ110 + 701100 + Kauai_Northwest_Waters + + US + 22.44 + -159.99 + 0 + 0 + HFO + + + PHZ112 + 701120 + Kauai_Leeward_Waters + + US + 21.64 + -159.99 + 0 + 0 + HFO + + + PHZ111 + 701110 + Kauai_Windward_Waters + + US + 22.41 + -159.03 + 0 + 0 + HFO + + + PHZ113 + 701130 + Kauai_Channel + + US + 21.62 + -159.00 + 0 + 0 + HFO + + + PHZ115 + 701150 + Oahu_Leeward_Waters + + US + 21.04 + -158.18 + 0 + 0 + HFO + + + PHZ114 + 701140 + Oahu_Windward_Waters + + US + 21.88 + -157.59 + 0 + 0 + HFO + + + PHZ116 + 701160 + Kaiwi_Channel + + US + 21.22 + -157.49 + 0 + 0 + HFO + + + PHZ118 + 701180 + Maui_County_Leeward_Waters + + US + 20.70 + -157.49 + 0 + 0 + HFO + + + PHZ120 + 701200 + Pailolo_Channel + + US + 21.03 + -156.91 + 0 + 0 + HFO + + + PHZ119 + 701190 + Maalaea_Bay + + US + 20.75 + -156.53 + 0 + 0 + HFO + + + PHZ121 + 701210 + Alenuihaha_Channel + + US + 20.30 + -156.44 + 0 + 0 + HFO + + + PHZ123 + 701230 + Big_Island_Leeward_Waters + + US + 19.34 + -156.40 + 0 + 0 + HFO + + + PHZ117 + 701170 + Maui_County_Windward_Waters + + US + 21.32 + -156.39 + 0 + 0 + HFO + + + PKZ235 + 692350 + Point_Franklin_to_Cape_Halkett + + US + 71.66 + -156.01 + 0 + 0 + AFG + + + PKZ150 + 691500 + Sitkinak_to_Castle_Cape + + US + 55.91 + -155.76 + 0 + 0 + AFC + + + PHZ124 + 701240 + Big_Island_Southeast_Waters + + US + 18.71 + -155.37 + 0 + 0 + HFO + + + PHZ122 + 701220 + Big_Island_Windward_Waters + + US + 19.92 + -154.97 + 0 + 0 + HFO + + + PKZ138 + 691380 + _Shelikof_Strait + + US + 57.83 + -153.52 + 0 + 0 + AFC + + + PKZ137 + 691370 + _Marmot_Bay + + US + 58.00 + -152.62 + 0 + 0 + AFC + + + PKZ136 + 691360 + _Chiniak_Bay + + US + 57.70 + -152.37 + 0 + 0 + AFC + + + PKZ132 + 691320 + Shuyak_Island_To_Sitkinak + + US + 56.92 + -152.20 + 0 + 0 + AFC + + + PKZ140 + 691400 + Cook_Inlt_N_of_Kamishak_Bay_and_ + + US + 60.34 + -151.89 + 0 + 0 + AFC + + + PKZ141 + 691410 + Kachemak_Bay + + US + 59.56 + -151.45 + 0 + 0 + AFC + + + PKZ130 + 691300 + Barren_Is_And_Kamishak_Bay_Wtrs + + US + 58.64 + -151.33 + 0 + 0 + AFC + + + PKZ121 + 691210 + _Resurrection_Bay + + US + 60.06 + -149.39 + 0 + 0 + AFC + + + PKZ240 + 692400 + Cape_Halkett_to_Flaxman_Island + + US + 71.09 + -149.19 + 0 + 0 + AFG + + + PKZ129 + 691290 + Passage_Canal + + US + 60.81 + -148.58 + 0 + 0 + AFC + + + PKZ125 + 691250 + Prince_William_Sound + + US + 60.48 + -147.34 + 0 + 0 + AFC + + + PKZ120 + 691200 + Cape_Suckling_to_Gore_Point + + US + 59.42 + -147.01 + 0 + 0 + AFC + + + PKZ128 + 691280 + _Valdez_Arm + + US + 60.94 + -146.86 + 0 + 0 + AFC + + + PKZ127 + 691270 + _Valdez_Narrows + + US + 61.05 + -146.67 + 0 + 0 + AFC + + + PKZ126 + 691260 + _Port_of_Valdez + + US + 61.11 + -146.44 + 0 + 0 + AFC + + + PKZ245 + 692450 + Flaxman_I_to_Demarcation_Point + + US + 70.60 + -143.39 + 0 + 0 + AFG + + + PKZ052 + 690520 + Icy_Cape_to_Cape_Suckling + + US + 59.40 + -142.97 + 0 + 0 + AJK + + + PKZ051 + 690510 + Cape_Fairweather_to_Icy_Cape + + US + 58.95 + -140.30 + 0 + 0 + AJK + + + PKZ053 + 690530 + Yakutat_Bay + + US + 59.80 + -139.76 + 0 + 0 + AJK + + + PKZ043 + 690430 + SE_AK_Outside_Wtrs_From_C_Edgecu + + US + 57.59 + -137.69 + 0 + 0 + AJK + + + PKZ022 + 690220 + Cross_Sound + + US + 58.14 + -136.36 + 0 + 0 + AJK + + + PKZ011 + 690110 + _Glacier_Bay + + US + 58.72 + -136.23 + 0 + 0 + AJK + + + PKZ042 + 690420 + Cape_Decision_to_Cape_Edgecumbe + + US + 56.23 + -136.12 + 0 + 0 + AJK + + + PKZ021 + 690210 + Icy_Strait + + US + 58.27 + -135.73 + 0 + 0 + AJK + + + PKZ012 + 690120 + Northern_Lynn_Canal + + US + 59.10 + -135.30 + 0 + 0 + AJK + + + PKZ013 + 690130 + Southern_Lynn_Canal + + US + 58.59 + -135.07 + 0 + 0 + AJK + + + PKZ032 + 690320 + Northern_Chatham_Strait + + US + 57.61 + -134.77 + 0 + 0 + AJK + + + PKZ033 + 690330 + Southern_Chatham_Strait + + US + 56.54 + -134.55 + 0 + 0 + AJK + + + PKZ041 + 690410 + Dixon_Entrance_to_Cape_Decision + + US + 55.04 + -134.31 + 0 + 0 + AJK + + + PKZ031 + 690310 + Stephens_Passage + + US + 57.94 + -134.29 + 0 + 0 + AJK + + + PKZ034 + 690340 + Frederick_Sound + + US + 56.99 + -134.28 + 0 + 0 + AJK + + + PKZ035 + 690350 + Sumner_Strait + + US + 56.40 + -133.28 + 0 + 0 + AJK + + + PKZ036 + 690360 + Clarence_Strait + + US + 55.40 + -131.52 + 0 + 0 + AJK + + + PZZ170 + 611700 + Cstal_Wtrs_From_C_Flattery_To_Ja + + US + 48.22 + -125.73 + 0 + 0 + SEW + + + PZZ173 + 611730 + Wtrs_From_James_I_To_Pt_Grenvl_2 + + US + 47.57 + -125.40 + 0 + 0 + SEW + + + PZZ376 + 613760 + Wtrs_fr_C_Blanco_OR_to_Pt._St._G + + US + 42.33 + -125.39 + 0 + 0 + MFR + + + PZZ370 + 613700 + Wtrs_fr_Florence_to_C_Blanco_OR_ + + US + 43.40 + -125.19 + 0 + 0 + MFR + + + PZZ275 + 612750 + Wtrs_fr_Cascade_Hd_to_Florence_O + + US + 44.59 + -125.15 + 0 + 0 + PQR + + + PZZ470 + 614700 + Wtrs_fr_Pt._St._Geo_to_C_Mendoci + + US + 41.14 + -125.08 + 0 + 0 + EKA + + + PZZ176 + 611760 + Cstal_Wtrs_From_Pt_Grenvl_To_C_S + + US + 46.97 + -125.06 + 0 + 0 + SEW + + + PZZ153 + 611530 + Cstal_Wtrs_From_James_I_To_Pt_Gr + + US + 47.74 + -124.99 + 0 + 0 + SEW + + + PZZ270 + 612700 + Wtrs_fr_C_Shoalwtr_WA_to_Cascade + + US + 45.92 + -124.99 + 0 + 0 + PQR + + + PZZ150 + 611500 + Cstal_Wtrs_From_C_Flattery_To_Ja + + US + 48.17 + -124.89 + 0 + 0 + SEW + + + PZZ475 + 614750 + Wtrs_fr_C_Mendocino_to_Pt._Arena + + US + 39.69 + -124.74 + 0 + 0 + EKA + + + PZZ350 + 613500 + Cstal_wtrs_fr_Florence_to_C_Blan + + US + 43.47 + -124.68 + 0 + 0 + MFR + + + PZZ330 + 613300 + Chetco_River_Bar + + US + 42.31 + -124.60 + 0 + 0 + MFR + + + PZZ130 + 611300 + W_Entr_U.S._Wtrs_St_Of_Juan_De_F + + US + 48.37 + -124.48 + 0 + 0 + SEW + + + PZZ310 + 613100 + Coos_Bay_Bar + + US + 43.43 + -124.47 + 0 + 0 + MFR + + + PZZ156 + 611560 + Cstal_Wtrs_From_Pt_Grenvl_To_C_S + + US + 47.02 + -124.44 + 0 + 0 + SEW + + + PZZ356 + 613560 + Cstal_wtrs_fr_C_Blanco_OR_to_Pt. + + US + 42.24 + -124.43 + 0 + 0 + MFR + + + PZZ450 + 614500 + Cstal_wtrs_fr_Pt._St._Geo_to_C_M + + US + 41.11 + -124.33 + 0 + 0 + EKA + + + PZZ250 + 612500 + Cstal_wtrs_fr_C_Shoalwtr_WA_to_C + + US + 45.93 + -124.20 + 0 + 0 + PQR + + + PZZ410 + 614100 + Humboldt_Bay_Bar + + US + 40.77 + -124.19 + 0 + 0 + EKA + + + PZZ255 + 612550 + Cstal_wtrs_fr_Cascade_Hd_to_Flor + + US + 44.47 + -124.10 + 0 + 0 + PQR + + + PZZ110 + 611100 + Grays_Harbor_Bar + + US + 46.93 + -123.99 + 0 + 0 + SEW + + + PZZ570 + 615700 + Wtrs_fr_Pt._Arena_to_Pigeon_Pt._ + + US + 38.08 + -123.99 + 0 + 0 + MTR + + + PZZ455 + 614550 + Cstal_wtrs_fr_C_Mendocino_to_Pt. + + US + 39.69 + -123.91 + 0 + 0 + EKA + + + PZZ131 + 611310 + Ctrl_U.S._Wtrs_St_Of_Juan_De_Fuc + + US + 48.27 + -123.68 + 0 + 0 + SEW + + + PZZ210 + 612100 + Columbia_River_Bar + + US + 46.21 + -123.68 + 0 + 0 + PQR + + + PZZ540 + 615400 + Cstal_Wtrs_fr_Pt_Arena_to_Pt_Rey + + US + 38.48 + -123.53 + 0 + 0 + MTR + + + PZZ132 + 611320 + E_Entr_U.S._Wtrs_St_Of_Juan_De_F + + US + 48.21 + -122.96 + 0 + 0 + SEW + + + PZZ133 + 611330 + Nrn_Inlnd_Wtrs_Incl_The_Sn_Juan_ + + US + 48.58 + -122.78 + 0 + 0 + SEW + + + PZZ575 + 615750 + Wtrs_fr_Pigeon_Pt._to_Pt._Piedra + + US + 36.41 + -122.76 + 0 + 0 + MTR + + + PZZ545 + 615450 + Cstal_Wtrs_fr_Pt_Reyes_to_Pigeon + + US + 37.58 + -122.72 + 0 + 0 + MTR + + + PZZ134 + 611340 + Admiralty_Inlet + + US + 48.06 + -122.68 + 0 + 0 + SEW + + + PZZ560 + 615600 + Cstal_Wtrs_fr_Pigeon_Pt_to_Pt_Pi + + US + 36.99 + -122.59 + 0 + 0 + MTR + + + PZZ135 + 611350 + Puget_Sound_and_Hood_Canal + + US + 47.56 + -122.47 + 0 + 0 + SEW + + + PZZ530 + 615300 + Sn_Francisco/Sn_Pablo/Suisun_Bay + + US + 37.83 + -122.39 + 0 + 0 + MTR + + + PZZ535 + 615350 + Monterey_Bay + + US + 36.79 + -121.89 + 0 + 0 + MTR + + + PZZ565 + 615650 + Cstal_Wtrs_fr_Pt_Pinos_to_Pt_Pie + + US + 36.11 + -121.84 + 0 + 0 + MTR + + + PZZ670 + 616700 + The_Wtrs_fr_Pt._Piedras_Blancas_ + + US + 35.14 + -121.55 + 0 + 0 + LOX + + + PZZ673 + 616730 + Wtrs_fr_Pt._Arguello_to_Sta_Cruz + + US + 34.18 + -120.98 + 0 + 0 + LOX + + + PZZ650 + 616500 + E_Sta_Barbara_Chnl_fr_Pt._Concep + + US + 34.28 + -119.87 + 0 + 0 + LOX + + + PZZ676 + 616760 + Out_wtrs_fr_Sta_Cruz_I_to_Sn_Cle + + US + 33.54 + -119.79 + 0 + 0 + LOX + + + PZZ655 + 616550 + Inr_wtrs_fr_Pt_Mugu_to_Sn_Mateo_ + + US + 33.59 + -118.55 + 0 + 0 + LOX + + + PZZ775 + 617750 + Wtrs_fr_Sn_Mateo_point_to_the_Me + + US + 32.83 + -118.20 + 0 + 0 + SGX + + + PZZ750 + 617500 + Cstal_Wtrs_fr_Sn_Mateo_Pt_to_the + + US + 32.92 + -117.55 + 0 + 0 + SGX + + + GMZ135 + 681350 + Laguna_Madre_From_5_nm_N_Of_Port + + US + 26.93 + -97.44 + 0 + 0 + BRO + + + GMZ132 + 681320 + Laguna_Madre_From_The_Arroyo_Col + + US + 26.49 + -97.37 + 0 + 0 + BRO + + + GMZ230 + 682300 + Bays_and_Wtrways_fr_Baffin_Bay_t + + US + 27.54 + -97.31 + 0 + 0 + CRP + + + GMZ130 + 681300 + Laguna_Madre_From_the_Port_Of_Br + + US + 26.19 + -97.30 + 0 + 0 + BRO + + + GMZ155 + 681550 + Cstal_wtrs_fr_Baffin_Bay_to_Port + + US + 26.92 + -97.23 + 0 + 0 + BRO + + + GMZ250 + 682500 + Cstal_wtrs_fr_Baffin_Bay_to_Port + + US + 27.52 + -97.10 + 0 + 0 + CRP + + + GMZ150 + 681500 + Cstal_wtrs_fr_Port_Mansfield_TX_ + + US + 26.28 + -97.04 + 0 + 0 + BRO + + + GMZ235 + 682350 + Bays_and_Wtrways_fr_Port_Aransas + + US + 28.16 + -96.82 + 0 + 0 + CRP + + + GMZ175 + 681750 + Wtrs_fr_Baffin_Bay_to_Port_Mansf + + US + 26.87 + -96.68 + 0 + 0 + BRO + + + GMZ255 + 682550 + Cstal_wtrs_fr_Port_Aransas_to_Ma + + US + 28.06 + -96.66 + 0 + 0 + CRP + + + GMZ270 + 682700 + Wtrs_fr_Baffin_Bay_to_Port_Arans + + US + 27.35 + -96.51 + 0 + 0 + CRP + + + GMZ170 + 681700 + Wtrs_fr_Port_Mansfield_TX_to_the + + US + 26.26 + -96.50 + 0 + 0 + BRO + + + GMZ330 + 683300 + Matagorda_Bay + + US + 28.60 + -96.32 + 0 + 0 + HGX + + + GMZ275 + 682750 + Wtrs_fr_Port_Aransas_to_Matagord + + US + 27.74 + -96.12 + 0 + 0 + CRP + + + GMZ350 + 683500 + Cstal_wtrs_fr_Freeport_to_Matago + + US + 28.52 + -95.70 + 0 + 0 + HGX + + + GMZ370 + 683700 + Wtrs_fr_Freeport_to_Matagorda_Sh + + US + 28.13 + -95.38 + 0 + 0 + HGX + + + GMZ335 + 683350 + Galveston_Bay + + US + 29.41 + -94.87 + 0 + 0 + HGX + + + GMZ355 + 683550 + Cstal_wtrs_fr_Hi_I_to_Freeport_T + + US + 29.10 + -94.78 + 0 + 0 + HGX + + + GMZ375 + 683750 + Wtrs_fr_Hi_I_to_Freeport_TX_fr_2 + + US + 28.66 + -94.60 + 0 + 0 + HGX + + + GMZ450 + 684500 + Cstal_wtrs_fr_Cameron_LA_to_Hi_I + + US + 29.58 + -93.95 + 0 + 0 + LCH + + + GMZ430 + 684300 + Sabine_Lake + + US + 29.62 + -93.85 + 0 + 0 + LCH + + + GMZ470 + 684700 + Wtrs_fr_Cameron_LA_to_Hi_I_TX_fr + + US + 29.07 + -93.82 + 0 + 0 + LCH + + + GMZ432 + 684320 + Calcasieu_Lake + + US + 29.92 + -93.31 + 0 + 0 + LCH + + + GMZ452 + 684520 + Cstal_wtrs_fr_Intracoastal_Cty_t + + US + 29.48 + -92.72 + 0 + 0 + LCH + + + GMZ472 + 684720 + Wtrs_fr__Intracoastal_Cty_to_Cam + + US + 28.95 + -92.68 + 0 + 0 + LCH + + + LSZ145 + 651450 + Duluth_MN_to_Port_Wing_WI + + US + 46.76 + -91.84 + 0 + 0 + DLH + + + LSZ144 + 651440 + Two_Harbors_to_Duluth_MN + + US + 46.89 + -91.82 + 0 + 0 + DLH + + + GMZ475 + 684750 + Wtrs_fr_Lwr_Atchafalaya_Riv_to_I + + US + 28.70 + -91.72 + 0 + 0 + LCH + + + GMZ435 + 684350 + Vermillion_Bay + + US + 29.38 + -91.70 + 0 + 0 + LCH + + + GMZ455 + 684550 + Cstal_wtrs_fr_Lwr_Atchafalaya_Ri + + US + 29.32 + -91.69 + 0 + 0 + LCH + + + LSZ143 + 651430 + Silver_Bay_Hbr_to_2_Hbrs_MN + + US + 47.13 + -91.40 + 0 + 0 + DLH + + + LSZ146 + 651460 + Port_Wing_to_Sand_Island_WI + + US + 46.91 + -91.19 + 0 + 0 + DLH + + + LSZ142 + 651420 + Taconite_Hbr_to_Silver_Bay_Hbr_M + + US + 47.38 + -91.05 + 0 + 0 + DLH + + + LSZ121 + 651210 + Chequamegon_Bay-Bayfield_to_Oak_ + + US + 46.69 + -90.81 + 0 + 0 + DLH + + + LSZ147 + 651470 + Sand_Island_to_Bayfield_WI + + US + 46.91 + -90.71 + 0 + 0 + DLH + + + LSZ148 + 651480 + Oak_Point_to_Saxon_Harbor_WI + + US + 46.67 + -90.59 + 0 + 0 + DLH + + + LSZ141 + 651410 + Grand_Marais_to_Taconite_Hbr_MN + + US + 47.58 + -90.57 + 0 + 0 + DLH + + + LSZ162 + 651620 + L_Sup_W_of_a_line_fr_Saxon_Hbr_W + + US + 47.28 + -90.56 + 0 + 0 + DLH + + + LSZ240 + 652400 + Saxon_Harbor_WI_to_Black_Riv_MI + + US + 46.66 + -90.24 + 0 + 0 + MQT + + + GMZ550 + 685500 + Cstal_wtrs_fr_the_SW_pass_of_the + + US + 29.00 + -90.19 + 0 + 0 + LIX + + + GMZ570 + 685700 + Wtrs_fr_the_SW_Pass_of_the_MS_Ri + + US + 28.39 + -90.18 + 0 + 0 + LIX + + + GMZ530 + 685300 + L_Pontchartrain_and_L_Maurepas + + US + 30.17 + -90.10 + 0 + 0 + LIX + + + LSZ241 + 652410 + Black_River_To_Ontonagon_MI + + US + 46.81 + -89.91 + 0 + 0 + MQT + + + LSZ140 + 651400 + Gnd_Portage_to_Gnd_Marais_MN + + US + 47.84 + -89.85 + 0 + 0 + DLH + + + LSZ263 + 652630 + L_Sup_fr_Saxon_Hbr_WI_to_Upr_Ent + + US + 47.45 + -89.29 + 0 + 0 + MQT + + + GMZ555 + 685550 + Cstal_wtrs_fr_Pascagoula_MS_to_t + + US + 29.72 + -89.09 + 0 + 0 + LIX + + + LSZ242 + 652420 + Ontonagon_to_Upr_Entr_of_Portage + + US + 47.10 + -88.96 + 0 + 0 + MQT + + + GMZ575 + 685750 + Wtrs_fr_Pascagoula_MS_to_the_SW_ + + US + 28.86 + -88.56 + 0 + 0 + LIX + + + LSZ243 + 652430 + Upr_Entr_of_Portage_Canal_to_Eag + + US + 47.37 + -88.47 + 0 + 0 + MQT + + + LSZ247 + 652470 + Portage_L_to_Huron_I_MI_to_Lwr_E + + US + 46.90 + -88.37 + 0 + 0 + MQT + + + LSZ246 + 652460 + Pt_Isabelle_to_Lwr_Entr_of_Porta + + US + 47.15 + -88.22 + 0 + 0 + MQT + + + LSZ264 + 652640 + L_Sup_fr_Upr_Entr_to_Portage_Can + + US + 47.83 + -88.08 + 0 + 0 + MQT + + + GMZ650 + 686500 + Cstal_wtrs_fr_Pensacola_FL_to_Pa + + US + 30.19 + -88.01 + 0 + 0 + MOB + + + LSZ244 + 652440 + Eagle_River_to_Manitou_I_MI + + US + 47.49 + -87.95 + 0 + 0 + MQT + + + GMZ630 + 686300 + Mobile_Bay + + US + 30.53 + -87.93 + 0 + 0 + MOB + + + LMZ644 + 646440 + Port_Washington_to_N_Pt_Lt_WI + + US + 43.24 + -87.87 + 0 + 0 + MKX + + + LMZ522 + 645220 + Grn_Bay_S_of_line_fr__Oconto_WI_ + + US + 44.71 + -87.79 + 0 + 0 + GRB + + + LMZ645 + 646450 + N_Point_Light_to_Wind_Point_WI + + US + 42.93 + -87.77 + 0 + 0 + MKX + + + LMZ740 + 647400 + Winthrop_Hbr_to_Wilmette_Hbr_IL + + US + 42.28 + -87.77 + 0 + 0 + LOT + + + LSZ265 + 652650 + L_Sup_W_of_Line_fr_Manitou_I_to_ + + US + 47.00 + -87.73 + 0 + 0 + MQT + + + LMZ643 + 646430 + Sheboygan_to_Port_Washington_WI + + US + 43.55 + -87.72 + 0 + 0 + MKX + + + LMZ646 + 646460 + Wind_Pt_WI_to_Winthrop_Hbr_IL + + US + 42.64 + -87.72 + 0 + 0 + MKX + + + LSZ245 + 652450 + Manitou_I_to_Point_Isabelle_MI + + US + 47.32 + -87.71 + 0 + 0 + MQT + + + GMZ670 + 686700 + Wtrs_fr_Pensacola_FL_to_Pascagou + + US + 29.60 + -87.65 + 0 + 0 + MOB + + + LMZ543 + 645430 + Two_Rivers_to_Sheboygan_WI + + US + 43.95 + -87.64 + 0 + 0 + GRB + + + LMZ742 + 647420 + Nerly_I_to_Calumet_Harbor_IL + + US + 41.84 + -87.60 + 0 + 0 + LOT + + + LMZ741 + 647410 + Wilmette_Harbor_to_Nerly_I_IL + + US + 41.98 + -87.58 + 0 + 0 + LOT + + + LSZ248 + 652480 + Huron_Islands_to_Marquette_MI + + US + 46.77 + -87.52 + 0 + 0 + MQT + + + LMZ669 + 646690 + L_MI_fr_Sheboygan_to_Port_Washin + + US + 43.63 + -87.44 + 0 + 0 + MKX + + + LMZ743 + 647430 + Calumet_Harbor_IL_to_Gary_IN + + US + 41.70 + -87.42 + 0 + 0 + LOT + + + LMZ671 + 646710 + L_MI_fr_Port_Washington_to_N_Pt_ + + US + 43.20 + -87.41 + 0 + 0 + MKX + + + LMZ673 + 646730 + L_MI_fr_N_Pt_Lt_to_Wind_Pt_WI_5N + + US + 42.93 + -87.40 + 0 + 0 + MKX + + + LMZ521 + 645210 + Grn_Bay_S_of_line_fr__Cedar_Riv_ + + US + 45.11 + -87.39 + 0 + 0 + GRB + + + LMZ542 + 645420 + Sturgeon_Bay_to_Two_Rivers_WI + + US + 44.49 + -87.37 + 0 + 0 + GRB + + + LMZ777 + 647770 + L_MI_fr_Winthrop_Hbr_to_Wilmette + + US + 42.31 + -87.37 + 0 + 0 + LOT + + + LMZ567 + 645670 + L_MI_fr_2_Rivs_to_Sheboygan_WI_5 + + US + 44.05 + -87.33 + 0 + 0 + GRB + + + LMZ675 + 646750 + L_MI_fr_Wind_Pt_WI_to_Winthrop_H + + US + 42.61 + -87.32 + 0 + 0 + MKX + + + LMZ779 + 647790 + L_MI_fr_Wilmette_Hbr_to_MI_Cty_i + + US + 41.95 + -87.26 + 0 + 0 + LOT + + + LMZ744 + 647440 + Gary_to_Burns_Harbor_IN + + US + 41.67 + -87.25 + 0 + 0 + LOT + + + LMZ565 + 645650 + L_MI_fr_Sturgeon_Bay_to_2_Rivs_W + + US + 44.47 + -87.11 + 0 + 0 + GRB + + + LSZ249 + 652490 + Marquette_to_Munising_MI + + US + 46.60 + -87.05 + 0 + 0 + MQT + + + LMZ745 + 647450 + Burns_Harbor_to_MI_City_IN + + US + 41.72 + -87.04 + 0 + 0 + LOT + + + LMZ541 + 645410 + Rock_I_Passage_to_Sturgeon_Bay_W + + US + 45.07 + -86.96 + 0 + 0 + GRB + + + LMZ870 + 648700 + L_MI_fr_Whthall_to_Pentwtr_MI_5N + + US + 43.63 + -86.96 + 0 + 0 + GRR + + + LMZ221 + 642210 + Grn_Bay_N_of_line_fr_Cedar_Riv_M + + US + 45.66 + -86.94 + 0 + 0 + MQT + + + LMZ046 + 640460 + MI_City_IN_to_New_Buffalo_MI + + US + 41.80 + -86.86 + 0 + 0 + IWX + + + LSZ266 + 652660 + L_Sup_E_of_a_line_fr_Manitou_I_t + + US + 47.21 + -86.85 + 0 + 0 + MQT + + + LMZ878 + 648780 + L_MI_fr_St_Joseph_to_S_Haven_MI_ + + US + 42.36 + -86.84 + 0 + 0 + GRR + + + GMZ675 + 686750 + Wtrs_fr_Destin_to_Pensacola_FL_f + + US + 29.72 + -86.83 + 0 + 0 + MOB + + + LMZ080 + 640800 + L_MI_MI_Cty_IN_to_St._Joseph_MI_ + + US + 41.97 + -86.79 + 0 + 0 + IWX + + + LMZ872 + 648720 + L_MI_fr_Gnd_Haven_to_Whthall_MI_ + + US + 43.22 + -86.78 + 0 + 0 + GRR + + + LMZ874 + 648740 + L_MI_fr_Holland_to_Gnd_Haven_MI_ + + US + 42.95 + -86.78 + 0 + 0 + GRR + + + LMZ366 + 643660 + L_MI_fr_Pt_Betsie_to_Manistee_MI + + US + 44.53 + -86.75 + 0 + 0 + APX + + + GMZ655 + 686550 + Cstal_wtrs_fr_Destin_to_Pensacol + + US + 30.24 + -86.72 + 0 + 0 + MOB + + + LMZ043 + 640430 + New_Buffalo_MI_to_St_Joseph_MI + + US + 41.97 + -86.67 + 0 + 0 + IWX + + + LMZ563 + 645630 + L_MI_fr_Rock_I_Passage_to_Sturge + + US + 45.02 + -86.67 + 0 + 0 + GRB + + + LMZ250 + 642500 + 5NM_E_of_a_line_fr_Fairport_MI_t + + US + 45.49 + -86.66 + 0 + 0 + MQT + + + LMZ868 + 648680 + L_MI_fr_Pentwtr_to_Manistee_MI_5 + + US + 43.95 + -86.65 + 0 + 0 + GRR + + + LMZ876 + 648760 + L_MI_fr_S_Haven_to_Holland_MI_5N + + US + 42.60 + -86.65 + 0 + 0 + GRR + + + LMZ849 + 648490 + Pentwater_to_Manistee_MI + + US + 44.03 + -86.57 + 0 + 0 + GRR + + + LMZ848 + 648480 + Whitehall_to_Pentwater_MI + + US + 43.59 + -86.53 + 0 + 0 + GRR + + + LSZ250 + 652500 + Munising_to_Grand_Marais_MI + + US + 46.59 + -86.49 + 0 + 0 + MQT + + + LMZ844 + 648440 + St_Joseph_to_South_Haven_MI + + US + 42.28 + -86.46 + 0 + 0 + GRR + + + LMZ847 + 648470 + Grand_Haven_to_Whitehall_MI + + US + 43.22 + -86.36 + 0 + 0 + GRR + + + LMZ346 + 643460 + Manistee_to_Point_Betsie_MI + + US + 44.48 + -86.33 + 0 + 0 + APX + + + LMZ261 + 642610 + L_MI_fr_Seul_Choix_Pt_to_Rock_I_ + + US + 45.60 + -86.32 + 0 + 0 + MQT + + + LMZ846 + 648460 + Holland_to_Grand_Haven_MI + + US + 42.91 + -86.30 + 0 + 0 + GRR + + + LMZ845 + 648450 + South_Haven_to_Holland_MI + + US + 42.59 + -86.28 + 0 + 0 + GRR + + + LMZ248 + 642480 + Seul_Choix_Pt_to_Pt_Detour_MI + + US + 45.79 + -86.27 + 0 + 0 + MQT + + + LMZ364 + 643640 + L_MI_fr_Charlevoix_to_Pt_Betsie_ + + US + 45.02 + -86.19 + 0 + 0 + APX + + + LMZ345 + 643450 + Pt_Betsie_to_Sleeping_Bear_Pt_MI + + US + 44.82 + -86.18 + 0 + 0 + APX + + + LMZ344 + 643440 + Sleeping_Bear_Pt_to_Gnd_Traverse + + US + 45.09 + -85.79 + 0 + 0 + APX + + + GMZ770 + 687700 + Wtrs_fr_Apalachicola_to_Destin_F + + US + 29.27 + -85.76 + 0 + 0 + TAE + + + LMZ341 + 643410 + Seul_Choix_Pt_to_5NM_W_of_Mackin + + US + 45.96 + -85.71 + 0 + 0 + APX + + + GMZ750 + 687500 + Cstal_wtrs_fr_Apalachicola_to_De + + US + 29.84 + -85.65 + 0 + 0 + TAE + + + LSZ267 + 652670 + L_Sup_fr_Gnd_Marais_MI_to_Whtfis + + US + 47.00 + -85.61 + 0 + 0 + MQT + + + LMZ362 + 643620 + L_MI_S_of_a_line_fr_Seul_Choix_P + + US + 45.60 + -85.57 + 0 + 0 + APX + + + LMZ323 + 643230 + Gnd_Traverse_Bay_S_of_a_line_Gnd + + US + 44.98 + -85.56 + 0 + 0 + APX + + + LSZ251 + 652510 + Grand_Marais_to_Whitefish_Pt_MI + + US + 46.75 + -85.41 + 0 + 0 + MQT + + + LMZ342 + 643420 + Norwood_MI_to_5NM_W_of_Mackinac_ + + US + 45.53 + -85.20 + 0 + 0 + APX + + + LSZ321 + 653210 + Whtfish_Bay_(U.S._Portion)/Whtfi + + US + 46.54 + -84.77 + 0 + 0 + APX + + + LHZ345 + 743450 + Sts_of_Mackinac_within_5NM_of_Ma + + US + 45.81 + -84.71 + 0 + 0 + APX + + + GMZ755 + 687550 + Cstal_Wtrs_From__Ochlockonee_Riv + + US + 29.61 + -84.54 + 0 + 0 + TAE + + + GMZ775 + 687750 + Wtrs_fr__Suwannee_Riv_to_Apalach + + US + 29.15 + -84.35 + 0 + 0 + TAE + + + LHZ347 + 743470 + 5NM_E_of_Mackinac_Br_to_Presque_ + + US + 45.73 + -84.31 + 0 + 0 + APX + + + LHZ346 + 743460 + St_Ignace_to_False_Detour_Chnl + + US + 45.94 + -84.13 + 0 + 0 + APX + + + LSZ322 + 653220 + St._Marys_Riv_Pt_Iroquois_to_E._ + + US + 46.26 + -84.11 + 0 + 0 + APX + + + GMZ730 + 687300 + Apalachee_Bay_or_Cstal_Wtrs_From + + US + 29.90 + -83.95 + 0 + 0 + TAE + + + LHZ361 + 743610 + L_Huron_fr_5NM_E_of_Mackinac_Br_ + + US + 45.63 + -83.69 + 0 + 0 + APX + + + LHZ422 + 744220 + Inr_Saginaw_Bay_SW_of_Pt_Au_Gres + + US + 43.80 + -83.67 + 0 + 0 + DTX + + + GMZ870 + 688700 + Wtrs_fr_Tarpon_Spgs_to_Suwannee_ + + US + 28.60 + -83.54 + 0 + 0 + TBW + + + GMZ765 + 687650 + Cstal_wtrs_fr__Suwannee_Riv_to_K + + US + 29.50 + -83.53 + 0 + 0 + TAE + + + LHZ421 + 744210 + Out_Saginaw_Bay_SW_of_Alabaster_ + + US + 44.07 + -83.38 + 0 + 0 + DTX + + + GMZ873 + 688730 + Wtrs_fr_Englewood_to_Tarpon_Spgs + + US + 27.42 + -83.36 + 0 + 0 + TBW + + + LEZ142 + 631420 + Maumee_Bay_to_Reno_Beach_OH + + US + 41.74 + -83.35 + 0 + 0 + CLE + + + LHZ348 + 743480 + Presque_I_Lt_to_Sturgeon_Pt_MI_I + + US + 45.06 + -83.32 + 0 + 0 + APX + + + LEZ444 + 634440 + MI_Wtrs_of_L_Erie_fr_Detroit_Riv + + US + 41.89 + -83.29 + 0 + 0 + DTX + + + LHZ349 + 743490 + Sturgeon_Point_to_Alabaster_MI + + US + 44.45 + -83.26 + 0 + 0 + APX + + + LEZ162 + 631620 + Detroit_Riv_Lt._to_Maumee_Bay_OH + + US + 41.86 + -83.20 + 0 + 0 + CLE + + + LCZ423 + 604230 + Detroit_River + + US + 42.18 + -83.16 + 0 + 0 + DTX + + + GMZ850 + 688500 + Cstal_wtrs_fr_Tarpon_Spgs_to_Suw + + US + 28.74 + -82.94 + 0 + 0 + TBW + + + LEZ143 + 631430 + Reno_Beach_to_The_Islands_OH + + US + 41.63 + -82.94 + 0 + 0 + CLE + + + LEZ163 + 631630 + Reno_Beach_to_The_Is_OH_beyond_5 + + US + 41.73 + -82.92 + 0 + 0 + CLE + + + GMZ853 + 688530 + Cstal_wtrs_fr_Englewood_to_Tarpo + + US + 27.53 + -82.87 + 0 + 0 + TBW + + + GMZ876 + 688760 + Wtrs_fr_Bonita_Beach_to_Englewoo + + US + 26.39 + -82.86 + 0 + 0 + TBW + + + LHZ362 + 743620 + L_Huron_fr_Presque_I_Lt_to_Sturg + + US + 45.10 + -82.84 + 0 + 0 + APX + + + LCZ460 + 604600 + L_St._Clair_Open_L_(U.S._Portion + + US + 42.52 + -82.76 + 0 + 0 + DTX + + + LHZ363 + 743630 + L_Huron_fr_Sturgeon_Pt_to_Alabas + + US + 44.42 + -82.75 + 0 + 0 + APX + + + LEZ144 + 631440 + The_Islands_to_Vermilion_OH + + US + 41.48 + -82.71 + 0 + 0 + CLE + + + GMZ830 + 688300 + Tampa_Bay_waters + + US + 27.76 + -82.60 + 0 + 0 + TBW + + + LHZ441 + 744410 + Port_Austin_to_Harbor_Beach_MI + + US + 43.93 + -82.59 + 0 + 0 + DTX + + + LHZ442 + 744420 + Harbor_Beach_to_Port_Sanilac_MI + + US + 43.64 + -82.53 + 0 + 0 + DTX + + + GMZ075 + 680750 + Wtrs_fr_Key_W_to_20_NM_W_of_Dry_ + + US + 24.26 + -82.51 + 0 + 0 + KEY + + + LHZ462 + 744620 + L_Huron_fr_Port_Austin_to_Hbr_Be + + US + 44.05 + -82.51 + 0 + 0 + DTX + + + LEZ164 + 631640 + The_Is_to_Vermilion_OH_beyond_5n + + US + 41.59 + -82.48 + 0 + 0 + CLE + + + LCZ422 + 604220 + St._Clair_River + + US + 42.77 + -82.47 + 0 + 0 + DTX + + + LHZ443 + 744430 + Port_Sanilac_to_Port_Huron_MI + + US + 43.21 + -82.43 + 0 + 0 + DTX + + + GMZ676 + 686760 + Wtrs_fr_Chokoloskee_to_Bonita_Be + + US + 25.80 + -82.42 + 0 + 0 + MFL + + + LHZ463 + 744630 + L_Huron_fr_Hbr_Beach_to_Port_Sni + + US + 43.70 + -82.41 + 0 + 0 + DTX + + + LHZ464 + 744640 + L_Huron_fr_Port_Snilac_to_Port_H + + US + 43.33 + -82.40 + 0 + 0 + DTX + + + GMZ856 + 688560 + Cstal_wtrs_fr_Bonita_Beach_to_En + + US + 26.56 + -82.28 + 0 + 0 + TBW + + + LEZ145 + 631450 + Vermilion_to_Avon_Point_OH + + US + 41.51 + -82.17 + 0 + 0 + CLE + + + LEZ165 + 631650 + Vermilion_to_Avon_Pt_OH_beyond_5 + + US + 41.61 + -82.04 + 0 + 0 + CLE + + + GMZ033 + 680330 + Wtrs_fr_E_C_Sable_to_Chokoloskee + + US + 25.27 + -82.00 + 0 + 0 + KEY + + + GMZ656 + 686560 + Cstal_wtrs_fr_Chokoloskee_to_Bon + + US + 25.96 + -81.92 + 0 + 0 + MFL + + + LEZ166 + 631660 + Avon_Pt_to_Willowick_OH_beyond_5 + + US + 41.82 + -81.81 + 0 + 0 + CLE + + + LEZ146 + 631460 + Avon_Point_to_Willowick_OH + + US + 41.54 + -81.66 + 0 + 0 + CLE + + + GMZ054 + 680540 + Cstal_wtrs_fr_the_W_end_of_the_S + + US + 24.48 + -81.61 + 0 + 0 + KEY + + + GMZ032 + 680320 + Gulf_Side_of_the_Lwr_Keys_out_20 + + US + 24.86 + -81.48 + 0 + 0 + KEY + + + GMZ074 + 680740 + Wtrs_fr_the_W_end_of_the_Seven_M + + US + 23.93 + -81.44 + 0 + 0 + KEY + + + GMZ657 + 686570 + Cstal_wtrs_fr_E_C_Sable_to_Choko + + US + 25.47 + -81.41 + 0 + 0 + MFL + + + AMZ450 + 664500 + Cstal_wtrs_fr_Altamaha_Snd_to_Fe + + US + 30.99 + -81.28 + 0 + 0 + JAX + + + LEZ147 + 631470 + Willowick_to_Geneva-on-the_L_OH + + US + 41.80 + -81.22 + 0 + 0 + CLE + + + AMZ452 + 664520 + Cstal_wtrs_fr_Fernandina_Beach_t + + US + 30.28 + -81.18 + 0 + 0 + JAX + + + LEZ167 + 631670 + Willowick_to_Geneva-on-the-L_OH_ + + US + 42.00 + -81.16 + 0 + 0 + CLE + + + AMZ354 + 663540 + Cstal_wtrs_fr_Savannah_GA_to_Alt + + US + 31.67 + -81.05 + 0 + 0 + CHS + + + AMZ550 + 665500 + Flagler_Beach_to_Volusia-Brevard + + US + 29.22 + -80.97 + 0 + 0 + MLB + + + AMZ454 + 664540 + Cstal_wtrs_fr_St._Augustine_to_F + + US + 29.66 + -80.94 + 0 + 0 + JAX + + + GMZ053 + 680530 + Cstal_wtrs_fr_Craig_Key_to_the_W + + US + 24.57 + -80.90 + 0 + 0 + KEY + + + GMZ031 + 680310 + Florida_Bay + + US + 24.99 + -80.86 + 0 + 0 + KEY + + + AMZ610 + 666100 + Lake_Okeechobee + + US + 26.94 + -80.82 + 0 + 0 + MFL + + + GMZ073 + 680730 + Wtrs_fr_Craig_Key_to_the_W_end_o + + US + 24.10 + -80.79 + 0 + 0 + KEY + + + LEZ148 + 631480 + Geneva-on-the-L_to_Conneaut_OH + + US + 41.96 + -80.75 + 0 + 0 + CLE + + + AMZ472 + 664720 + Wtrs_fr_Fernandina_Beach_to_St._ + + US + 30.27 + -80.73 + 0 + 0 + JAX + + + AMZ470 + 664700 + Wtrs_fr_Altamaha_Snd_GA_to_Ferna + + US + 30.90 + -80.71 + 0 + 0 + JAX + + + LEZ168 + 631680 + Geneva-on-the-L_to_Conneaut_OH_b + + US + 42.11 + -80.69 + 0 + 0 + CLE + + + AMZ474 + 664740 + Wtrs_fr_St._Augustine_to_Flagler + + US + 29.71 + -80.54 + 0 + 0 + JAX + + + AMZ552 + 665520 + Volusia-Brevard_Cnty_Line_to_Seb + + US + 28.39 + -80.48 + 0 + 0 + MLB + + + AMZ352 + 663520 + Cstal_wtrs_fr_Edisto_Beach_SC_to + + US + 32.18 + -80.47 + 0 + 0 + CHS + + + AMZ374 + 663740 + Wtrs_fr_Savannah_GA_to_Altamaha_ + + US + 31.48 + -80.45 + 0 + 0 + CHS + + + LEZ169 + 631690 + Conneaut_OH_to_Ripley_NY_beyond_ + + US + 42.33 + -80.35 + 0 + 0 + CLE + + + GMZ052 + 680520 + Cstal_wtrs_fr_O_Reef_to_Craig_Ke + + US + 24.94 + -80.34 + 0 + 0 + KEY + + + AMZ630 + 666300 + Biscayne_Bay + + US + 25.58 + -80.28 + 0 + 0 + MFL + + + AMZ570 + 665700 + Flagler_Beach_to_Volusia-Brevard + + US + 29.20 + -80.22 + 0 + 0 + MLB + + + LEZ149 + 631490 + Conneaut_OH_to_Ripley_NY + + US + 42.15 + -80.15 + 0 + 0 + CLE + + + GMZ072 + 680720 + Wtrs_fr_O_Reef_to_Craig_Key_fr_2 + + US + 24.53 + -80.05 + 0 + 0 + KEY + + + AMZ555 + 665550 + Sebastian_Inlt_to_Jupiter_Inlt_0 + + US + 27.40 + -80.03 + 0 + 0 + MLB + + + AMZ651 + 666510 + Cstal_wtrs_fr_Deerfield_Beach_to + + US + 25.77 + -80.01 + 0 + 0 + MFL + + + AMZ330 + 663300 + Charleston_Harbor + + US + 32.78 + -79.89 + 0 + 0 + CHS + + + AMZ572 + 665720 + Volusia-Brevard_Cnty_Line_to_Seb + + US + 28.42 + -79.87 + 0 + 0 + MLB + + + AMZ650 + 666500 + Cstal_wtrs_fr_Jupiter_Inlt_to_De + + US + 26.59 + -79.74 + 0 + 0 + MFL + + + AMZ370 + 663700 + Wtrs_fr_S_Sntee_Riv_SC_to_Savann + + US + 32.35 + -79.63 + 0 + 0 + CHS + + + LEZ040 + 630400 + Ripley_to_Dunkirk_NY + + US + 42.43 + -79.56 + 0 + 0 + BUF + + + AMZ575 + 665750 + Sebastian_Inlt_to_Jupiter_Inlt_2 + + US + 27.46 + -79.52 + 0 + 0 + MLB + + + AMZ350 + 663500 + Cstal_wtrs_fr_S_Sntee_Riv_to_Edi + + US + 32.65 + -79.51 + 0 + 0 + CHS + + + AMZ671 + 666710 + Wtrs_fr_Deerfield_Beach_to_O_Ree + + US + 25.50 + -79.50 + 0 + 0 + MFL + + + LEZ061 + 630610 + Ripley_to_Buffalo_NY_extending_f + + US + 42.55 + -79.49 + 0 + 0 + BUF + + + AMZ670 + 666700 + Wtrs_fr_Jupiter_Inlt_to_Deerfiel + + US + 26.58 + -79.34 + 0 + 0 + MFL + + + LEZ041 + 630410 + Dunkirk_to_Buffalo_NY + + US + 42.69 + -79.11 + 0 + 0 + BUF + + + LEZ020 + 630200 + Buffalo_Hbr_and_the_Upr_Niagara_ + + US + 43.11 + -79.06 + 0 + 0 + BUF + + + AMZ256 + 662560 + Cstal_wtrs_fr_Murrells_Inlt_to_S + + US + 33.21 + -78.86 + 0 + 0 + ILM + + + LOZ042 + 620420 + Niagara_Riv_to_Hamlin_Beach_NY + + US + 43.36 + -78.79 + 0 + 0 + BUF + + + LOZ062 + 620620 + Niagara_Riv_to_Hamlin_Beach_NY_b + + US + 43.55 + -78.63 + 0 + 0 + BUF + + + AMZ254 + 662540 + Cstal_wtrs_fr_Ltl_Riv_Inlt_to_Mu + + US + 33.62 + -78.59 + 0 + 0 + ILM + + + AMZ252 + 662520 + Cstal_wtrs_fr_C_Fear_NC_to_Ltl_R + + US + 33.69 + -78.01 + 0 + 0 + ILM + + + AMZ270 + 662700 + Wtrs_fr_Surf_Cty_NC_to_S_Sntee_R + + US + 33.49 + -77.96 + 0 + 0 + ILM + + + AMZ250 + 662500 + Cstal_wtrs_fr_Surf_Cty_to_C_Fear + + US + 34.07 + -77.60 + 0 + 0 + ILM + + + LOZ043 + 620430 + Hamlin_Beach_to_Sodus_Bay_NY + + US + 43.33 + -77.46 + 0 + 0 + BUF + + + LOZ063 + 620630 + Hamlin_Beach_to_Sodus_Bay_NY_bey + + US + 43.47 + -77.38 + 0 + 0 + BUF + + + ANZ536 + 675360 + Tidal_Potomac_fr_Ind_Hd_to_Cobb_ + + US + 38.42 + -77.12 + 0 + 0 + LWX + + + ANZ535 + 675350 + Tidal_Potomac_fr_Key_Br_to_Ind_H + + US + 38.75 + -77.04 + 0 + 0 + LWX + + + AMZ158 + 661580 + Cstal_wtrs_fr_C_Lookout_to_Surf_ + + US + 34.52 + -76.95 + 0 + 0 + MHX + + + LOZ064 + 620640 + Sodus_Bay_to_Mex_Bay_NY_beyond_5 + + US + 43.62 + -76.75 + 0 + 0 + BUF + + + LOZ044 + 620440 + Sodus_Bay_to_Mexico_Bay_NY + + US + 43.44 + -76.62 + 0 + 0 + BUF + + + ANZ537 + 675370 + Tidal_Potomac_fr_Cobb_I_MD_to_Sm + + US + 38.15 + -76.58 + 0 + 0 + LWX + + + ANZ533 + 675330 + Chsapke_Bay_fr_N_Beach_to_Drum_P + + US + 38.56 + -76.41 + 0 + 0 + LWX + + + LOZ065 + 620650 + Mex_Bay_NY_to_the_St._Lawrence_R + + US + 43.78 + -76.39 + 0 + 0 + BUF + + + LOZ045 + 620450 + Mex_Bay_NY_to_the_St._Lawrence_R + + US + 43.86 + -76.36 + 0 + 0 + BUF + + + ANZ531 + 675310 + Chsapke_Bay_fr_Pooles_I_to_Sndy_ + + US + 39.18 + -76.35 + 0 + 0 + LWX + + + AMZ156 + 661560 + Cstal_wtrs_fr_Ocracoke_Inlt_to_C + + US + 34.80 + -76.27 + 0 + 0 + MHX + + + ANZ532 + 675320 + Chsapke_Bay_fr_Sndy_Pt_to_N_Beac + + US + 38.90 + -76.27 + 0 + 0 + LWX + + + AMZ135 + 661350 + Pamlico_Sound + + US + 35.30 + -76.13 + 0 + 0 + MHX + + + ANZ632 + 676320 + Chsapke_Bay_fr_New_Pt_Comfort_to + + US + 37.10 + -76.13 + 0 + 0 + AKQ + + + ANZ534 + 675340 + Chsapke_Bay_fr_Drum_Pt_MD_to_Smi + + US + 38.13 + -76.11 + 0 + 0 + LWX + + + AMZ130 + 661300 + Albemarle_Sound + + US + 36.00 + -76.09 + 0 + 0 + MHX + + + ANZ631 + 676310 + Chsapke_Bay_fr_Windmill_Pt_to_Ne + + US + 37.46 + -76.09 + 0 + 0 + AKQ + + + ANZ530 + 675300 + Chesapeake_Bay_N_of_Pooles_I_MD + + US + 39.46 + -76.06 + 0 + 0 + LWX + + + ANZ630 + 676300 + Chsapke_Bay_fr_Smith_Pt_to_Windm + + US + 37.80 + -76.04 + 0 + 0 + AKQ + + + ANZ633 + 676330 + Currituck_Sound + + US + 36.40 + -75.92 + 0 + 0 + AKQ + + + SLZ022 + 730220 + St._Lawrence_Riv_above_Ogdensbg_ + + US + 44.45 + -75.79 + 0 + 0 + BUF + + + ANZ656 + 676560 + Cstal_wtrs_fr_C_Charles_Lt_VA_to + + US + 36.78 + -75.68 + 0 + 0 + AKQ + + + AMZ170 + 661700 + Wtrs_fr_Currituck_Beach_Lt_to_Su + + US + 34.83 + -75.64 + 0 + 0 + MHX + + + ANZ654 + 676540 + Cstal_wtrs_fr_Parramore_I_to_C_C + + US + 37.31 + -75.62 + 0 + 0 + AKQ + + + ANZ658 + 676580 + Cstal_wtrs_fr_NC_VA_border_to_Cu + + US + 36.36 + -75.60 + 0 + 0 + AKQ + + + AMZ154 + 661540 + Cstal_wtrs_fr_C_Hatteras_to_Ocra + + US + 35.05 + -75.58 + 0 + 0 + MHX + + + AMZ150 + 661500 + Cstal_wtrs_fr_Currituck_Beach_Lt + + US + 36.02 + -75.50 + 0 + 0 + MHX + + + ANZ652 + 676520 + Cstal_wtrs_fr_Chincoteague_to_Pa + + US + 37.81 + -75.39 + 0 + 0 + AKQ + + + AMZ152 + 661520 + Cstal_wtrs_fr_Oregon_Inlt_to_C_H + + US + 35.50 + -75.38 + 0 + 0 + MHX + + + ANZ430 + 674300 + DE_Bay_wtrs_N_of_E_Pt_NJ_to_Slau + + US + 39.32 + -75.34 + 0 + 0 + PHI + + + SLZ024 + 730240 + St._Lawrence_Riv_fr_Ogdensbg_to_ + + US + 44.86 + -75.23 + 0 + 0 + BUF + + + ANZ431 + 674310 + DE_Bay_wtrs_S_of_E_Pt_NJ_to_Slau + + US + 39.00 + -75.10 + 0 + 0 + PHI + + + ANZ670 + 676700 + Wtrs_fr_Fenwick_I_DE_to_Currituc + + US + 37.28 + -75.10 + 0 + 0 + AKQ + + + ANZ650 + 676500 + Cstal_wtrs_fr_Fenwick_I_DE_to_Ch + + US + 38.23 + -75.07 + 0 + 0 + AKQ + + + ANZ454 + 674540 + Cstal_wtrs_fr_C_May_NJ_to_C_Henl + + US + 38.80 + -74.89 + 0 + 0 + PHI + + + ANZ455 + 674550 + Cstal_wtrs_fr_C_Henlopen_to_Fenw + + US + 38.48 + -74.74 + 0 + 0 + PHI + + + ANZ453 + 674530 + Cstal_wtrs_fr_Gt_Egg_Inlt_to_C_M + + US + 38.97 + -74.57 + 0 + 0 + PHI + + + ANZ452 + 674520 + Cstal_wtrs_fr_Ltl_Egg_Inlt_to_Gt + + US + 39.26 + -74.36 + 0 + 0 + PHI + + + ANZ338 + 673380 + New_York_Harbor + + US + 40.55 + -74.09 + 0 + 0 + OKX + + + ANZ470 + 674700 + Wtrs_fr_Sndy_Hook_NJ_to_Fenwick_ + + US + 39.18 + -74.02 + 0 + 0 + PHI + + + ANZ451 + 674510 + Cstal_wtrs_fr_Manasquan_Inlt_to_ + + US + 39.65 + -73.95 + 0 + 0 + PHI + + + ANZ450 + 674500 + Cstal_wtrs_fr_Sndy_Hook_to_Manas + + US + 40.16 + -73.78 + 0 + 0 + PHI + + + ANZ355 + 673550 + Sndy_Hook_NJ_to_Fire_I_Inlt_NY_o + + US + 40.41 + -73.51 + 0 + 0 + OKX + + + ANZ335 + 673350 + Long_I_Snd_W_of_New_Haven_CT/Por + + US + 41.04 + -73.36 + 0 + 0 + OKX + + + ANZ353 + 673530 + Fire_I_Inlt_NY_to_Moriches_Inlt_ + + US + 40.55 + -73.04 + 0 + 0 + OKX + + + ANZ345 + 673450 + S_Shore_Bays_fr_Jones_Inlt_throu + + US + 40.74 + -73.00 + 0 + 0 + OKX + + + ANZ370 + 673700 + Wtrs_fr_Montauk_Pt_NY_to_Sndy_Ho + + US + 40.31 + -72.48 + 0 + 0 + OKX + + + ANZ330 + 673300 + Long_I_Snd_E_of_New_Haven_CT/Por + + US + 41.15 + -72.44 + 0 + 0 + OKX + + + ANZ340 + 673400 + Peconic_and_Gardiners_Bays + + US + 41.02 + -72.33 + 0 + 0 + OKX + + + ANZ350 + 673500 + Moriches_Inlt_NY_to_Montauk_Pt_N + + US + 40.75 + -72.21 + 0 + 0 + OKX + + + ANZ237 + 672370 + Block_Island_Sound + + US + 41.21 + -71.61 + 0 + 0 + BOX + + + ANZ236 + 672360 + Narragansett_Bay + + US + 41.62 + -71.29 + 0 + 0 + BOX + + + ANZ235 + 672350 + Rhode_Island_Sound + + US + 41.32 + -71.13 + 0 + 0 + BOX + + + ANZ230 + 672300 + Boston_Harbor + + US + 42.34 + -70.94 + 0 + 0 + BOX + + + ANZ233 + 672330 + Vineyard_Sound + + US + 41.43 + -70.78 + 0 + 0 + BOX + + + ANZ234 + 672340 + Buzzards_Bay + + US + 41.52 + -70.74 + 0 + 0 + BOX + + + ANZ255 + 672550 + Cstal_wtrs_fr_Nantucket_MA_to_Ma + + US + 41.07 + -70.74 + 0 + 0 + BOX + + + ANZ250 + 672500 + Cstal_wtrs_fr_Merrimack_Riv_MA_o + + US + 42.44 + -70.37 + 0 + 0 + BOX + + + ANZ231 + 672310 + Cape_Cod_Bay + + US + 41.92 + -70.34 + 0 + 0 + BOX + + + ANZ154 + 671540 + Cstal_Wtrs_fr_C_Elizabeth,_ME_to + + US + 43.11 + -70.26 + 0 + 0 + GYX + + + ANZ232 + 672320 + Nantucket_Sound + + US + 41.48 + -70.26 + 0 + 0 + BOX + + + ANZ153 + 671530 + Casco_Bay + + US + 43.72 + -70.06 + 0 + 0 + GYX + + + ANZ254 + 672540 + Cstal_wtrs_fr_Provincetown_MA_to + + US + 41.66 + -69.75 + 0 + 0 + BOX + + + ANZ152 + 671520 + Cstal_Wtrs_fr_Port_Clyde,_ME_to_ + + US + 43.57 + -69.47 + 0 + 0 + GYX + + + ANZ170 + 671700 + Wtrs_fr_Stonington_ME_to_Merrima + + US + 43.32 + -69.31 + 0 + 0 + GYX + + + ANZ270 + 672700 + Wtrs_fr_Merrimack_Riv_MA_to_Watc + + US + 41.69 + -69.29 + 0 + 0 + BOX + + + ANZ150 + 671500 + Cstal_Wtrs_fr_Stonington,_ME_to_ + + US + 43.84 + -68.91 + 0 + 0 + GYX + + + ANZ151 + 671510 + Penobscot_Bay + + US + 44.18 + -68.77 + 0 + 0 + GYX + + + ANZ051 + 670510 + Cstal_Wtrs_fr_Schoodic_Pt,_ME_to + + US + 44.00 + -68.25 + 0 + 0 + CAR + + + ANZ052 + 670520 + Intra_Cstal_Wtrs_fr_Schoodic_Pt, + + US + 44.19 + -68.25 + 0 + 0 + CAR + + + ANZ070 + 670700 + Wtrs_fr_Eport_ME_to_Stonington_( + + US + 43.84 + -67.86 + 0 + 0 + CAR + + + AMZ741 + 667410 + Mona_Passage_Southward_to_17N + + US + 17.74 + -67.69 + 0 + 0 + SJU + + + ANZ050 + 670500 + Cstal_Wtrs_fr_Eport,_ME_to_Schoo + + US + 44.30 + -67.48 + 0 + 0 + CAR + + + AMZ742 + 667420 + Cstal_Wtrs_OF_NWrn_Puerto_Rico_o + + US + 18.34 + -67.30 + 0 + 0 + SJU + + + AMZ745 + 667450 + Cstal_Wtrs_OF_SWrn_Puerto_Rico_o + + US + 18.06 + -67.28 + 0 + 0 + SJU + + + AMZ712 + 667120 + Cstal_Wtrs_of_Nrn_Puerto_Rico_ou + + US + 18.60 + -66.63 + 0 + 0 + SJU + + + AMZ735 + 667350 + Cstal_Wtrs_of_Srn_Puerto_Rico_ou + + US + 17.84 + -66.43 + 0 + 0 + SJU + + + AMZ710 + 667100 + Atl_Wtrs_of_Puerto_Rico_AND_USVI + + US + 19.04 + -66.01 + 0 + 0 + SJU + + + AMZ732 + 667320 + Carib_Wtrs_of_Puerto_Rico_fr_10_ + + US + 17.49 + -65.58 + 0 + 0 + SJU + + + AMZ725 + 667250 + Cstal_Wtrs_of_Srn_USVI,_Vieques, + + US + 18.24 + -65.16 + 0 + 0 + SJU + + + AMZ715 + 667150 + Cstal_Wtrs_of_Nrn_USVI_and_Culeb + + US + 18.47 + -64.85 + 0 + 0 + SJU + + + AMZ722 + 667220 + Anegada_Passage_Sward_to_17N + + US + 17.75 + -64.08 + 0 + 0 + SJU + + + PMZ161 + 711610 + Koror_Palau_Coastal_Waters + + US + 7.34 + 134.48 + 0 + 0 + GUM + + + PMZ171 + 711710 + Yap_Coastal_Waters + + US + 9.48 + 138.08 + 0 + 0 + GUM + + + PMZ151 + 711510 + Guam_Coastal_Waters + + US + 13.32 + 144.66 + 0 + 0 + GUM + + + PMZ152 + 711520 + Rota_Coastal_Waters + + US + 14.18 + 145.24 + 0 + 0 + GUM + + + PMZ153 + 711530 + Tinian_Coastal_Waters + + US + 14.83 + 145.45 + 0 + 0 + GUM + + + PMZ154 + 711540 + Saipan_Coastal_Waters + + US + 15.40 + 145.81 + 0 + 0 + GUM + + + PMZ172 + 711720 + Chuuk_Coastal_Waters + + US + 7.45 + 151.83 + 0 + 0 + GUM + + + PMZ173 + 711730 + Pohnpei_Coastal_Waters + + US + 6.97 + 158.23 + 0 + 0 + GUM + + + PMZ174 + 711740 + Kosrae_Coastal_Waters + + US + 5.35 + 162.95 + 0 + 0 + GUM + + + PMZ191 + 711910 + Waters_out_to_40_Nautical_Miles + + US + 19.30 + 166.64 + 0 + 0 + GUM + + + PMZ181 + 711810 + Majuro_Coastal_Waters + + US + 7.08 + 171.38 + 0 + 0 + GUM + + + PKZ176 + 691760 + Kiska_to_Attu + + US + 52.48 + 174.46 + 0 + 0 + AFC + + diff --git a/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/component-deploy.xml index c3598b995d..fb1c43db63 100644 --- a/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.ingest.util/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.ingest.util/component-deploy.xml index 09801d8934..8d51753ef0 100644 --- a/ncep/gov.noaa.nws.ncep.edex.ingest.util/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.ingest.util/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/component-deploy.xml old mode 100755 new mode 100644 index e0a87287f5..bd77886ad1 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-common.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-common.xml old mode 100755 new mode 100644 index 6571acc876..f0ee3212ee --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-common.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-common.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml old mode 100755 new mode 100644 index 8eca038a2c..ee3df1d67d --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/res/spring/airmet-ingest.xml @@ -1,72 +1,72 @@ - - - - - - - - - - - - - - - - - - - - - - - - airmet - - - - - - - - - - - - - java.lang.Throwable - - - - - - - java.lang.Throwable - - - - - + + + + + + + + + + + + + + + + + + + + + + + + airmet + + + + + + + + + + + + + java.lang.Throwable + + + + + + + java.lang.Throwable + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetDecoder.java old mode 100755 new mode 100644 index 7aad148a39..37f7f4498c --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetDecoder.java @@ -1,317 +1,317 @@ -/** - * - * Airmet Decoder - * - * This java class decodes AIRMET raw data. - * HISTORY - * - * * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 39 L. Lin Initial creation - * 06/2009 39 L. Lin Set updateNumber before constructing dataURI. - * 07/2009 39 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.airmet.decoder; - -import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetRecord; -import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetReport; -import gov.noaa.nws.ncep.edex.plugin.airmet.util.AirmetParser; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.exception.DecoderException; -import com.raytheon.edex.plugin.AbstractDecoder; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.PluginException; -import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class AirmetDecoder extends AbstractDecoder { - - private final String pluginName; - - /** - * Constructor - * - * @param name - * The name (usually pluginName) for this decoder. - * @throws DecoderException - */ - public AirmetDecoder(String name) throws DecoderException { - pluginName = name; - } - - /** - * - * @param data - * @param headers - * @return - * @throws DecoderException - */ - public PluginDataObject[] decode(byte[] data, Headers headers) - throws DecoderException { - - String traceId = ""; - if (headers != null) { - traceId = (String) headers.get("traceId"); - } - - String sectionDelim = "OTLK|AIRMET IFR|AIRMET MTN OBSCN|AIRMET TURB|AIRMET ICE|AIRMET STG SFC WNDS|LLWS POTENTIAL]"; - String etx = IDecoderConstants.ETX; - String theBulletin = null; - - Calendar startTime = null; - byte[] messageData = null; - - AirmetRecord record = null; - // Default equal to six hours from start time if there is no valid time - // in report - final int validPeriod = 6; - - AirmetSeparator sep = AirmetSeparator.separate(data, headers); - messageData = sep.next(); - String theMessage = new String(messageData); - - /* - * May have multiple duplicate bulletins, only get the first bulletin - * and eliminate the remaining bulletins after the first bulletin. - */ - Scanner cc = new Scanner(theMessage).useDelimiter(etx); - if (cc.hasNext()) { - theBulletin = cc.next(); - } else { - theBulletin = theMessage; - } - - // record = new AirmetRecord(); - // Decode and set WMO line - record = AirmetParser.processWMO(theBulletin, headers); - - Calendar issueTime = record.getIssueTime(); - - // Decode the reportName: ZULU, TANGO, or SIERRA - String reportName = AirmetParser.getReportName(theBulletin); - - /* - * Check the Airmet record object. If not, throws exception. - */ - if (record != null) { - record.setTraceId(traceId); - record.setPluginName(pluginName); - record.setReportType(pluginName); - record.setReportName(reportName); - // Decode and set the update number - record.setUpdateNumber(AirmetParser.getUpdateNumber(theBulletin)); - try { - record.constructDataURI(); - } catch (PluginException e) { - logger.error("Error constructing dataURI", e); - } - } - - if (record != null) { - try { - // Replace special characters to a blank so that it may be - // readable - record.setBullMessage(UtilN - .removeLeadingWhiteSpaces((theBulletin.substring(5)) - .replace('\036', ' ').replace('\r', ' ') - .replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' '))); - - // Decode the starting time - startTime = AirmetParser.getStartTime(theBulletin, headers); - if (startTime == null) { - startTime = issueTime; - } - - // Decode the end time - Calendar endTime = AirmetParser - .getEndTime(theBulletin, headers); - if (endTime == null) { - /* - * if no end time available, end time will be the start time - * plus a valid period; the default is six hours for now. - */ - endTime = startTime; - endTime.add(Calendar.HOUR, validPeriod); - } - - Calendar validStartTime = TimeTools.copy(endTime); - validStartTime.add(Calendar.HOUR, -validPeriod); - - // Airmet report valid time lasts only six hours from start to - // end - if (startTime.before(validStartTime)) { - startTime = validStartTime; - } - - // Decode the correction flag and set - record.setCorrectionFlag(AirmetParser - .getCorrectionFlag(theBulletin)); - - /* - * Break the bulletin message into sections by a "OTLK" or - * "AIRMET [IFR|MTN OBSCN|TURB|ICE|STG SFC WNDS|LLWS PTENTIAL]". - */ - Scanner sc = new Scanner(theBulletin) - .useDelimiter(sectionDelim); - - ArrayList segmentList = new ArrayList(); - segmentList.clear(); - // throw away the prefix section - String segPrefix = sc.next(); - - while (sc.hasNext()) { - String segment = sc.next(); - segmentList.add(segment); - } - - if (segmentList.size() == 0) { - // This is NIL/EXPIRE AIRMET report containing header only. - record.setCorrectionFlag(4); - } else { - /* - * Process each report. - */ - Integer series = 1; - // Get forecastRegion - String forecastRegion = AirmetParser.getRegion(reportName); - // Get valid day - String validDay = AirmetParser.getValidDay(theBulletin); - - // System.out.println("Process a report=\n" + segment); - for (String segment : segmentList) { - // starts a new section - Scanner sc2 = new Scanner(segment); - String whatReport = sc2.next(); - - if (whatReport.equals("VALID")) { - segment = "OTLK".concat(segment); - - // process this section which starts with - // "OTLK VALID". - Scanner scOutlook = new Scanner(segment) - .useDelimiter("AREA "); - ArrayList outlookList = new ArrayList(); - outlookList.clear(); - - // Check if "OUTLOOK" section contains more than one - // "AREA". - while (scOutlook.hasNext()) { - String outlookSegment = scOutlook.next(); - outlookList.add(outlookSegment); - } - - if (outlookList.size() <= 1) { - // only one outlook report - AirmetReport outlook = AirmetParser - .processOutLook(segment, forecastRegion); - AirmetParser.processValidTime(segment, outlook, - validDay, headers); - record.addAirmetReport(outlook); - } else { - /* - * Here are more than one outlook areas Store - * the header section and remove it from the - * outlook list - */ - String outlookHeader = outlookList.get(0); - outlookList.remove(outlookHeader); - // process multiple outlook sections - for (String outlookReport : outlookList) { - outlookReport = outlookHeader.concat( - "AREA ").concat(outlookReport); - AirmetReport outlook = AirmetParser - .processOutLook(outlookReport, - forecastRegion); - AirmetParser.processValidTime( - outlookReport, outlook, validDay, - headers); - record.addAirmetReport(outlook); - } - } - } else { - // Regular expression AIRMET report - final String HAZARD_EXP = "(ICE|TURB|CIG BLW|VIS BLW|MTNS|LLWS|SUSTAINED) "; - - // Pattern used for extracting hazard - final Pattern hazardTypePattern = Pattern - .compile(HAZARD_EXP); - Matcher theMatcher = hazardTypePattern - .matcher(segment); - - if (theMatcher.find()) { - // prefix the report type - if (theMatcher.group(1).equals("ICE")) { - segment = "AIRMET ICE".concat(segment); - } else if (theMatcher.group(1).equals("TURB")) { - segment = "AIRMET TURB".concat(segment); - } else if (theMatcher.group(1) - .equals("CIG BLW")) { - segment = "AIRMET IFR".concat(segment); - } else if (theMatcher.group(1) - .equals("VIS BLW")) { - segment = "AIRMET IFR".concat(segment); - } else if (theMatcher.group(1).equals("MTNS")) { - segment = "AIRMET MTN OBSCN" - .concat(segment); - } else if (theMatcher.group(1).equals( - "SUSTAINED")) { - segment = "AIRMET STG SFC WNDS" - .concat(segment); - } else if (theMatcher.group(1).equals("LLWS")) { - segment = "LLWS POTENTIAL".concat(segment); - } - } - - // process this report which starts with "AIRMET" or - // "LLWS". - AirmetReport report = AirmetParser - .processReport(segment); - if (report != null) { - // Decode and set the sequenceID - report.setSequenceID(AirmetParser - .getSequenceID(theBulletin, series)); - report.setStartTime(startTime); - report.setEndTime(endTime); - record.addAirmetReport(report); - } else { - logger.error("Error decoding segment " - + segment); - } - } - series++; - } - } - - } catch (Exception e) { - logger.error("Error postprocessing airmet", e); - record = null; - } - } - - /* - * Return the AirmetRecord record object. - */ - if (record == null) { - return new PluginDataObject[0]; - } else { - return new PluginDataObject[] { record }; - } - - } - -} +/** + * + * Airmet Decoder + * + * This java class decodes AIRMET raw data. + * HISTORY + * + * * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 39 L. Lin Initial creation + * 06/2009 39 L. Lin Set updateNumber before constructing dataURI. + * 07/2009 39 L. Lin Migration to TO11 + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.airmet.decoder; + +import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetRecord; +import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetReport; +import gov.noaa.nws.ncep.edex.plugin.airmet.util.AirmetParser; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.exception.DecoderException; +import com.raytheon.edex.plugin.AbstractDecoder; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class AirmetDecoder extends AbstractDecoder { + + private final String pluginName; + + /** + * Constructor + * + * @param name + * The name (usually pluginName) for this decoder. + * @throws DecoderException + */ + public AirmetDecoder(String name) throws DecoderException { + pluginName = name; + } + + /** + * + * @param data + * @param headers + * @return + * @throws DecoderException + */ + public PluginDataObject[] decode(byte[] data, Headers headers) + throws DecoderException { + + String traceId = ""; + if (headers != null) { + traceId = (String) headers.get("traceId"); + } + + String sectionDelim = "OTLK|AIRMET IFR|AIRMET MTN OBSCN|AIRMET TURB|AIRMET ICE|AIRMET STG SFC WNDS|LLWS POTENTIAL]"; + String etx = IDecoderConstants.ETX; + String theBulletin = null; + + Calendar startTime = null; + byte[] messageData = null; + + AirmetRecord record = null; + // Default equal to six hours from start time if there is no valid time + // in report + final int validPeriod = 6; + + AirmetSeparator sep = AirmetSeparator.separate(data, headers); + messageData = sep.next(); + String theMessage = new String(messageData); + + /* + * May have multiple duplicate bulletins, only get the first bulletin + * and eliminate the remaining bulletins after the first bulletin. + */ + Scanner cc = new Scanner(theMessage).useDelimiter(etx); + if (cc.hasNext()) { + theBulletin = cc.next(); + } else { + theBulletin = theMessage; + } + + // record = new AirmetRecord(); + // Decode and set WMO line + record = AirmetParser.processWMO(theBulletin, headers); + + Calendar issueTime = record.getIssueTime(); + + // Decode the reportName: ZULU, TANGO, or SIERRA + String reportName = AirmetParser.getReportName(theBulletin); + + /* + * Check the Airmet record object. If not, throws exception. + */ + if (record != null) { + record.setTraceId(traceId); + record.setPluginName(pluginName); + record.setReportType(pluginName); + record.setReportName(reportName); + // Decode and set the update number + record.setUpdateNumber(AirmetParser.getUpdateNumber(theBulletin)); + try { + record.constructDataURI(); + } catch (PluginException e) { + logger.error("Error constructing dataURI", e); + } + } + + if (record != null) { + try { + // Replace special characters to a blank so that it may be + // readable + record.setBullMessage(UtilN + .removeLeadingWhiteSpaces((theBulletin.substring(5)) + .replace('\036', ' ').replace('\r', ' ') + .replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' '))); + + // Decode the starting time + startTime = AirmetParser.getStartTime(theBulletin, headers); + if (startTime == null) { + startTime = issueTime; + } + + // Decode the end time + Calendar endTime = AirmetParser + .getEndTime(theBulletin, headers); + if (endTime == null) { + /* + * if no end time available, end time will be the start time + * plus a valid period; the default is six hours for now. + */ + endTime = startTime; + endTime.add(Calendar.HOUR, validPeriod); + } + + Calendar validStartTime = TimeTools.copy(endTime); + validStartTime.add(Calendar.HOUR, -validPeriod); + + // Airmet report valid time lasts only six hours from start to + // end + if (startTime.before(validStartTime)) { + startTime = validStartTime; + } + + // Decode the correction flag and set + record.setCorrectionFlag(AirmetParser + .getCorrectionFlag(theBulletin)); + + /* + * Break the bulletin message into sections by a "OTLK" or + * "AIRMET [IFR|MTN OBSCN|TURB|ICE|STG SFC WNDS|LLWS PTENTIAL]". + */ + Scanner sc = new Scanner(theBulletin) + .useDelimiter(sectionDelim); + + ArrayList segmentList = new ArrayList(); + segmentList.clear(); + // throw away the prefix section + String segPrefix = sc.next(); + + while (sc.hasNext()) { + String segment = sc.next(); + segmentList.add(segment); + } + + if (segmentList.size() == 0) { + // This is NIL/EXPIRE AIRMET report containing header only. + record.setCorrectionFlag(4); + } else { + /* + * Process each report. + */ + Integer series = 1; + // Get forecastRegion + String forecastRegion = AirmetParser.getRegion(reportName); + // Get valid day + String validDay = AirmetParser.getValidDay(theBulletin); + + // System.out.println("Process a report=\n" + segment); + for (String segment : segmentList) { + // starts a new section + Scanner sc2 = new Scanner(segment); + String whatReport = sc2.next(); + + if (whatReport.equals("VALID")) { + segment = "OTLK".concat(segment); + + // process this section which starts with + // "OTLK VALID". + Scanner scOutlook = new Scanner(segment) + .useDelimiter("AREA "); + ArrayList outlookList = new ArrayList(); + outlookList.clear(); + + // Check if "OUTLOOK" section contains more than one + // "AREA". + while (scOutlook.hasNext()) { + String outlookSegment = scOutlook.next(); + outlookList.add(outlookSegment); + } + + if (outlookList.size() <= 1) { + // only one outlook report + AirmetReport outlook = AirmetParser + .processOutLook(segment, forecastRegion); + AirmetParser.processValidTime(segment, outlook, + validDay, headers); + record.addAirmetReport(outlook); + } else { + /* + * Here are more than one outlook areas Store + * the header section and remove it from the + * outlook list + */ + String outlookHeader = outlookList.get(0); + outlookList.remove(outlookHeader); + // process multiple outlook sections + for (String outlookReport : outlookList) { + outlookReport = outlookHeader.concat( + "AREA ").concat(outlookReport); + AirmetReport outlook = AirmetParser + .processOutLook(outlookReport, + forecastRegion); + AirmetParser.processValidTime( + outlookReport, outlook, validDay, + headers); + record.addAirmetReport(outlook); + } + } + } else { + // Regular expression AIRMET report + final String HAZARD_EXP = "(ICE|TURB|CIG BLW|VIS BLW|MTNS|LLWS|SUSTAINED) "; + + // Pattern used for extracting hazard + final Pattern hazardTypePattern = Pattern + .compile(HAZARD_EXP); + Matcher theMatcher = hazardTypePattern + .matcher(segment); + + if (theMatcher.find()) { + // prefix the report type + if (theMatcher.group(1).equals("ICE")) { + segment = "AIRMET ICE".concat(segment); + } else if (theMatcher.group(1).equals("TURB")) { + segment = "AIRMET TURB".concat(segment); + } else if (theMatcher.group(1) + .equals("CIG BLW")) { + segment = "AIRMET IFR".concat(segment); + } else if (theMatcher.group(1) + .equals("VIS BLW")) { + segment = "AIRMET IFR".concat(segment); + } else if (theMatcher.group(1).equals("MTNS")) { + segment = "AIRMET MTN OBSCN" + .concat(segment); + } else if (theMatcher.group(1).equals( + "SUSTAINED")) { + segment = "AIRMET STG SFC WNDS" + .concat(segment); + } else if (theMatcher.group(1).equals("LLWS")) { + segment = "LLWS POTENTIAL".concat(segment); + } + } + + // process this report which starts with "AIRMET" or + // "LLWS". + AirmetReport report = AirmetParser + .processReport(segment); + if (report != null) { + // Decode and set the sequenceID + report.setSequenceID(AirmetParser + .getSequenceID(theBulletin, series)); + report.setStartTime(startTime); + report.setEndTime(endTime); + record.addAirmetReport(report); + } else { + logger.error("Error decoding segment " + + segment); + } + } + series++; + } + } + + } catch (Exception e) { + logger.error("Error postprocessing airmet", e); + record = null; + } + } + + /* + * Return the AirmetRecord record object. + */ + if (record == null) { + return new PluginDataObject[0]; + } else { + return new PluginDataObject[] { record }; + } + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetSeparator.java old mode 100755 new mode 100644 index 64c9861b3f..9633eb542d --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/AirmetSeparator.java @@ -1,144 +1,138 @@ -/** - * AirmetSeparator - * - * This class sets the raw data to an Arraylist, records, of - * String based on a uniquely identified separator. - * - *
- * L. Lin                               05/2009         Creation
- * 
- * - * This code has been developed by the SIB for use in the AWIPS system. - */ - -package gov.noaa.nws.ncep.edex.plugin.airmet.decoder; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.plugin.AbstractRecordSeparator; -import com.raytheon.edex.util.Util; - -public class AirmetSeparator extends AbstractRecordSeparator { - private final Log logger = LogFactory.getLog(getClass()); - - /** Regex used for separate the bulletins */ - private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; - - /** Regex matcher */ - private Matcher matcher; - - /** Pattern object for regex search */ - private Pattern pattern; - - /** List of records contained in file */ - private List records; - - private Iterator iterator = null; - - /** - * Constructor. - * - */ - public AirmetSeparator() { - records = new ArrayList(); - } - - public static AirmetSeparator separate(byte[] data, Headers headers) { - AirmetSeparator ds = new AirmetSeparator(); - ds.setData(data, headers); - return ds; - } - - @Override - public void setData(byte[] data, Headers headers) { - doSeparate(new String(data)); - iterator = records.iterator(); - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() - */ - @Override - public boolean hasNext() { - if (iterator == null) { - return false; - } else { - return iterator.hasNext(); - } - } - - /** - * Get record - */ - @Override - public byte[] next() { - try { - String temp = iterator.next(); - if (Util.isEmptyString(temp)) { - return null; - } else { - return temp.getBytes(); - } - } catch (NoSuchElementException e) { - return null; - } - } - - /** - * @param message - * separate bulletins - */ - private void doSeparate(String message) { - /* Regex used for separate the bulletins */ - - try { - pattern = Pattern.compile(BULLSEPARATOR); - matcher = pattern.matcher(message); - - /* - * Set number of bulletins to records only if the bulletin separator - * is not the same. At the point, only separators are stored in - * "records" - */ - while (matcher.find()) { - if (!records.contains(matcher.group())) { - records.add(matcher.group()); - } - } - - /* - * Append the raw data file to the records. - */ - for (int i = 0; i < records.size(); i++) { - if (i < records.size() - 1) { - records.set( - i, - "\n" - + message.substring( - message.indexOf(records.get(i)), - message.indexOf(records.get(i + 1)))); - } else { - records.set( - i, - "\n" - + message.substring(message.indexOf(records - .get(i)))); - } - } - } catch (Exception e) { - logger.warn("No valid records found!", e); - } - return; - } -} +/** + * AirmetSeparator + * + * This class sets the raw data to an Arraylist, records, of + * String based on a uniquely identified separator. + * + *
+ * L. Lin                               05/2009         Creation
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS system. + */ + +package gov.noaa.nws.ncep.edex.plugin.airmet.decoder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.plugin.AbstractRecordSeparator; +import com.raytheon.edex.util.Util; + +public class AirmetSeparator extends AbstractRecordSeparator { + private final Log logger = LogFactory.getLog(getClass()); + + /** Regex used for separate the bulletins */ + private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; + + /** Regex matcher */ + private Matcher matcher; + + /** Pattern object for regex search */ + private Pattern pattern; + + /** List of records contained in file */ + private List records; + + private Iterator iterator = null; + + /** + * Constructor. + * + */ + public AirmetSeparator() { + records = new ArrayList(); + } + + public static AirmetSeparator separate(byte[] data, Headers headers) { + AirmetSeparator ds = new AirmetSeparator(); + ds.setData(data, headers); + return ds; + } + + public void setData(byte[] data, Headers headers) { + doSeparate(new String(data)); + iterator = records.iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() + */ + public boolean hasNext() { + if (iterator == null) { + return false; + } else { + return iterator.hasNext(); + } + } + + /** + * Get record + */ + public byte[] next() { + try { + String temp = iterator.next(); + if (Util.isEmptyString(temp)) { + return (byte[]) null; + } else { + return temp.getBytes(); + } + } catch (NoSuchElementException e) { + return (byte[]) null; + } + } + + /** + * @param message + * separate bulletins + */ + private void doSeparate(String message) { + /* Regex used for separate the bulletins */ + + try { + pattern = Pattern.compile(BULLSEPARATOR); + matcher = pattern.matcher(message); + + /* + * Set number of bulletins to records only if the bulletin separator + * is not the same. At the point, only separators are stored in + * "records" + */ + while (matcher.find()) { + if (!records.contains(matcher.group())) { + records.add(matcher.group()); + } + } + + /* + * Append the raw data file to the records. + */ + for (int i = 0; i < records.size(); i++) { + if (i < records.size() - 1) { + records.set(i, "\n" + + message.substring( + message.indexOf(records.get(i)), message + .indexOf(records.get(i + 1)))); + } else { + records + .set(i, "\n" + + message.substring(message.indexOf(records + .get(i)))); + } + } + } catch (Exception e) { + logger.warn("No valid records found!", e); + } + return; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/package-info.java old mode 100755 new mode 100644 index 248a770b81..319b08dcd8 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains decoder.java for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.airmet.decoder;; +/** +* Contains decoder.java for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.airmet.decoder;; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/AirmetParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/AirmetParser.java old mode 100755 new mode 100644 index 990c6c035f..6ad1b03f3f --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/AirmetParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/AirmetParser.java @@ -1,682 +1,682 @@ -/** - * Airmet DecoderUtil - * - * This java class intends to serve as a decoder utility for AIRMET. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 05/2009 39 L. Lin Initial coding - * 07/2009 39 L. Lin Migration to TO11 - * 09/2009 39 L. Lin Add latitude/longitude to location table - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.airmet.util; - -import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetLocation; -import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetRecord; -import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetReport; -import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.edex.decodertools.core.LatLonPoint; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class AirmetParser { - - public static final Log logger = LogFactory.getLog(AirmetParser.class); - - /** - * Constructor - */ - public AirmetParser() { - } - - /** - * Parse the WMO line and store WMO header, OfficeID, issue time, - * designatorBBB,... - * - * @param wmoline - * The bulletin message - * - * @return an AirmetRecord - */ - public static AirmetRecord processWMO(String wmoline, Headers headers) { - - AirmetRecord record = null; - // Regular expression for WMO/ICAO, station ID, and issue date (and - // maybe designator BBB) - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; - - // Pattern used for extracting WMO header, officeID, product purge time, - // and issue date and designatorBBB - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(wmoline); - - if (theMatcher.find()) { - record = new AirmetRecord(); - - record.setWmoHeader(theMatcher.group(1)); - record.setIssueOffice(theMatcher.group(2)); - record.setDesignatorBBB(theMatcher.group(5)); - - // Decode the issue time. - Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), headers); - - record.setIssueTime(issueTime); - DataTime dataTime = new DataTime(issueTime); - record.setDataTime(dataTime); - } - return record; - } - - /** - * Obtains reportName as: SIERRA, TANGO or ZULU from a bulletin. - * - * @param bullMessage - * The bulletin message - * @return a string for report type - */ - public static String getReportName(String bullMessage) { - - // Regular expression AIRMET reportName - final String REPORTNAME_EXP = "AIRMET (SIERRA|TANGO|ZULU) "; - - // Pattern used for extracting reportName - final Pattern reportNamePattern = Pattern.compile(REPORTNAME_EXP); - Matcher theMatcher = reportNamePattern.matcher(bullMessage); - - if (theMatcher.find()) { - return theMatcher.group(1); - } else { - return " "; - } - } - - /** - * Obtains updateNumber from a bulletin. - * - * @param bullMessage - * The bulletin message - * @return an integer for update number - */ - public static Integer getUpdateNumber(String bullMessage) { - // default update number - Integer retUpdate = 0; - - // Regular expression update number - final String UPDATE_EXP = "AIRMET (SIERRA|TANGO|ZULU) UPDT ([0-9]{1}) "; - - // Pattern used for extracting update number - final Pattern updatePattern = Pattern.compile(UPDATE_EXP); - Matcher theMatcher = updatePattern.matcher(bullMessage); - - if (theMatcher.find()) { - return Integer.parseInt(theMatcher.group(2).substring(0, 1).trim()); - } else { - return retUpdate; - } - } - - /** - * Obtains correctionFlag from a report - * - * @param bullMessage - * The bulletin message - * @return an integer for correctionFlag 0 for normal, 1 for COR or CC, 2 - * for AMD, 3 for TEST, and 4 for NIL/EXPIRE report - */ - public static Integer getCorrectionFlag(String bullMessage) { - - Integer retCorrection = 0; - - // Regular expression correction - final String CORRECTION_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{2}) ([0-9]{6}) ([A-Z]{3})"; - - // Pattern used for extracting correctionFlag - final Pattern correctionPattern = Pattern.compile(CORRECTION_EXP); - Matcher theMatcher = correctionPattern.matcher(bullMessage); - - if (theMatcher.find()) { - if (theMatcher.group(5).equals("COR")) { - retCorrection = 1; - } else if (theMatcher.group(5).equals("AMD")) { - retCorrection = 2; - } else if ((theMatcher.group(5).substring(0, 2)).equals("CC")) { - retCorrection = 1; - } - } - - // Regular expression TEST message - final String TEST_EXP = " TEST "; - // Pattern used for extracting TEST message - final Pattern testPattern = Pattern.compile(TEST_EXP); - Matcher testMatcher = testPattern.matcher(bullMessage); - if (testMatcher.find()) { - retCorrection = 3; - } - - return retCorrection; - } - - /** - * Obtains cancelFlag from a report - * - * @param bullMessage - * The bulletin message - * @return an integer for cancelFlag 0 for normal and 1 for cancel - */ - public static Integer getCancelFlag(String report) { - - Integer retCancel = 0; - - // Regular expression cancelFlag - final String CANCEL_EXP = "(CANCEL|CNCL) AIRMET"; - - // Pattern used for extracting cancel - final Pattern cancelPattern = Pattern.compile(CANCEL_EXP); - Matcher theMatcher = cancelPattern.matcher(report); - - if (theMatcher.find()) { - retCancel = 1; - } - return retCancel; - } - - /** - * Obtains hazardType as: IFR (instrument flight rules), MO (mountain - * obscuration), TB (turbulence), IC (icing), SW (sustained winds), or WS - * (low level wind shear) from a report. - * - * @param theReport - * Input report message. - * @return a string for class type - */ - public static String getHazardType(String theReport) { - - String retHazardType = " "; - // Regular expression AIRMET classType - final String HAZARDTYPE_EXP = "AIRMET (IFR|MTN OBSCN|TURB|ICE|STG SFC WNDS)"; - final String TYPE2_EXP = "(LLWS POTENTIAL)"; - final String TYPE3_EXP = "(ICE|TURB|CIG BLW|VIS BLW|MTNS|LLWS|SUSTAINED)"; - final String TYPE4_EXP = "(CANCEL|CNCL)"; - - // Pattern used for extracting hazardType - final Pattern classTypePattern = Pattern.compile(HAZARDTYPE_EXP); - final Pattern type2Pattern = Pattern.compile(TYPE2_EXP); - final Pattern type3Pattern = Pattern.compile(TYPE3_EXP); - final Pattern type4Pattern = Pattern.compile(TYPE4_EXP); - - Matcher theMatcher = classTypePattern.matcher(theReport); - Matcher type2Matcher = type2Pattern.matcher(theReport); - Matcher type3Matcher = type3Pattern.matcher(theReport); - Matcher type4Matcher = type4Pattern.matcher(theReport); - - if (theMatcher.find()) { - if (theMatcher.group(1).equals("IFR")) { - retHazardType = "INSTRUMENT FLIGHT RULES"; - } else if (theMatcher.group(1).equals("MTN OBSCN")) { - retHazardType = "MOUNTAIN OBSCURATION"; - } else if (theMatcher.group(1).equals("TURB")) { - retHazardType = "TURBULENCE"; - } else if (theMatcher.group(1).equals("ICE")) { - retHazardType = "ICING"; - } else if (theMatcher.group(1).equals("STG SFC WNDS")) { - retHazardType = "SUSTAINED SFC WINDS"; - } - } else if (type2Matcher.find()) { - if (type2Matcher.group(1).equals("LLWS")) { - retHazardType = "LOW LEVEL WIND SHEAR"; - } - } else if (type3Matcher.find()) { - if (type3Matcher.group(1).equals("ICE")) { - retHazardType = "ICING"; - } else if (type3Matcher.group(1).equals("TURB")) { - retHazardType = "TURBULENCE"; - } else if (type3Matcher.group(1).equals("CIG BLW")) { - retHazardType = "INSTRUMENT FLIGHT RULES"; - } else if (type3Matcher.group(1).equals("VIS BLW")) { - retHazardType = "INSTRUMENT FLIGHT RULES"; - } else if (type3Matcher.group(1).equals("MTNS")) { - retHazardType = "MOUNTAIN OBSCURATION"; - } else if (type3Matcher.group(1).equals("LLWS")) { - retHazardType = "LOW LEVEL WIND SHEAR"; - } else if (type3Matcher.group(1).equals("SUSTAINED")) { - retHazardType = "SUSTAINED SFC WINDS"; - } - } else if (type4Matcher.find()) { - retHazardType = "CANCEL"; - } - - return retHazardType; - } - - /** - * Obtains forecast region as: S for SIERRA, T for TANGO or Z for ZULU from - * an AirmetRecord. - * - * @param record - * The AirmetRecord - * @return a string for forecast region - */ - public static String getRegion(String reportName) { - - String retRegion = null; - String forecastRegion = reportName; - - if (forecastRegion.equals("SIERRA")) { - retRegion = "S"; - } else if (forecastRegion.equals("TANGO")) { - retRegion = "T"; - } else if (forecastRegion.equals("ZULU")) { - retRegion = "Z"; - } - return retRegion; - } - - /** - * process regular section of an AIRMET report - * - * @param theReport - * The reports from bulletin message - * @return an AirmetReport table - */ - public static AirmetReport processReport(String theReport) { - - // Regular expression for flight levels - final String FLIGHT_EXP = " (BTN) (FL)?(FRZLVL|[0-9]{3})( AND |-)FL([0-9]{3})"; - final String BLW_EXP = " (BLW) FL([0-9]{3})"; - - // Pattern used for extracting flight levels - final Pattern flightPattern = Pattern.compile(FLIGHT_EXP); - final Pattern blwPattern = Pattern.compile(BLW_EXP); - - Matcher flightMatcher = flightPattern.matcher(theReport); - Matcher blwMatcher = blwPattern.matcher(theReport); - - AirmetReport currentReport = new AirmetReport(); - // Find and set the flight levels. - if (flightMatcher.find()) { - if (flightMatcher.group(1).equals("BTN")) { - if ((flightMatcher.group(3).equals("FRZLVL"))) { - currentReport.setFlightLevel1("FRZLVL"); - } else { - currentReport.setFlightLevel1(flightMatcher.group(3) - .toString()); - } - currentReport - .setFlightLevel2(flightMatcher.group(5).toString()); - } - } else if (blwMatcher.find()) { - currentReport.setFlightLevel2(blwMatcher.group(2).toString()); - } - // Get and set reportType - currentReport.setHazardType(getHazardType(theReport)); - - // Set reportIndicator - currentReport.setReportIndicator("AIRMET"); - - // Get and set cancel flag - currentReport.setCancelFlag(AirmetParser.getCancelFlag(theReport)); - - // Replace the special characters - currentReport.setSegment(theReport.replace('\r', ' ') - .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' ')); - - // Decode the locations - if (!AirmetParser.processLocation(theReport, currentReport)) { - currentReport = null; - } - - return currentReport; - } - - /** - * process the outlook of an AIRMET report. - * - * @param theOutlook - * The outlook section lines from bulletin message - * @return an AirmetReport table - */ - public static AirmetReport processOutLook(String theOutlook, - String forecastRegion) { - - AirmetReport currentOutLook = new AirmetReport(); - - currentOutLook.setSegment(theOutlook.replace('\r', ' ') - .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' ')); - - // Get and set hazard type - currentOutLook.setHazardType(getHazardType(theOutlook)); - // Set report indicator. - currentOutLook.setReportIndicator("OUTLOOK"); - - // Decode locations - if (AirmetParser.processLocation(theOutlook, currentOutLook)) { - final String SID_EXP = "AREA ([0-9]{1})"; - - // Pattern used for extracting the number of sequence ID. - final Pattern sidPattern = Pattern.compile(SID_EXP); - - Matcher theMatcher = sidPattern.matcher(theOutlook); - - // Default sequenceID as: 1S, 1T, or 1Z if locations have been - // found. - String sequenceID = "1".concat(forecastRegion); - if (theMatcher.find()) { - // Multiple areas such as: "AREA 1", "AREA 2", ...etc - sequenceID = theMatcher.group(1).concat(forecastRegion); - } - currentOutLook.setSequenceID(sequenceID); - } else { - // Default sequenceID as: 0W, 0C, or 0E if outlook section is a NIL - // report. - String sequenceID = "0".concat(forecastRegion); - currentOutLook.setSequenceID(sequenceID); - } - - // Get and set cancel flag - currentOutLook.setCancelFlag(AirmetParser.getCancelFlag(theOutlook)); - - return currentOutLook; - } - - /** - * Obtains start time from input bulletin. - * - * @param theReport - * The bulletin message - * @return a calendar for start time - */ - public static Calendar getStartTime(String theBulletin, Headers headers) { - - // Regular expression for start time - final String STARTTIME_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{2}) ([0-9]{6})( [A-Z]{3})?"; - - // Pattern used for extracting the starting time - final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); - - // Calendar mndTime = Calendar.getInstance(); - - Matcher theMatcher = starttimePattern.matcher(theBulletin); - - if (theMatcher.find()) { - // Get start time - return TimeTools.findDataTime(theMatcher.group(4), headers); - } else { - return null; - } - } - - /** - * Obtains the valid day from input bulletin. - * - * @param theBulletin - * The input bulletin - * @return a string for valid day. - */ - public static String getValidDay(String theBulletin) { - - // Regular expression for the day - final String DAY_EXP = " VALID UNTIL ([0-9]{2})([0-9]{4})"; - // Pattern used for extracting the day - final Pattern dayPattern = Pattern.compile(DAY_EXP); - Matcher theMatcher = dayPattern.matcher(theBulletin); - - String retDay; - - // Get sequence number according to 4-digit of valid time - if (theMatcher.find()) { - retDay = theMatcher.group(1); - } else { - Calendar cal = Calendar.getInstance(); - retDay = Integer.toString(cal.get(Calendar.DAY_OF_MONTH)); - } - return retDay; - } - - /** - * Obtains the sequence ID which is composed by an identifier, a sequence - * number and a series number. - * - * @param theBulletin - * The input bulletin - * @param series - * the series number of the report - * @return a string for sequence ID - */ - public static String getSequenceID(String theBulletin, Integer series) { - - // Regular expression for the sequence number - final String SEQUENCEID_EXP = " VALID UNTIL ([0-9]{2})([0-9]{4})"; - // Pattern used for extracting the sequence number - final Pattern idPattern = Pattern.compile(SEQUENCEID_EXP); - Matcher theMatcher = idPattern.matcher(theBulletin); - - Integer timeGroup; - String seqNumber; - String identifier = "???"; - // Get sequence number according to 4-digit of valid time - if (theMatcher.find()) { - timeGroup = Integer.parseInt(theMatcher.group(2)); - if (timeGroup == 800 | timeGroup == 900) { - seqNumber = "0"; - } else if (timeGroup == 1400 | timeGroup == 1500) { - seqNumber = "2"; - } else if (timeGroup == 2000 | timeGroup == 2100) { - seqNumber = "4"; - } else if (timeGroup == 200 | timeGroup == 300) { - seqNumber = "6"; - } else { - seqNumber = "8"; - } - } else { - seqNumber = "8"; - } - // System.out.println("seqNumber=" + seqNumber); - - // Regular expression for identifier - final String IDENTIFIER_EXP = "([A-Z]{3})(S|Z|T) WA ([0-9]{6})( [A-Z]{3})?"; - ; - // Pattern used for extracting the sequence number - final Pattern identifierPattern = Pattern.compile(IDENTIFIER_EXP); - Matcher idMatcher = identifierPattern.matcher(theBulletin); - // Get identifier - if (idMatcher.find()) { - identifier = idMatcher.group(1); - } - - return identifier.concat(seqNumber).concat(Integer.toString(series)); - } - - /** - * Get the end time - * - * @param theBulletin - * The bulletin which contains end time - * @return a calendar for end time - */ - public static Calendar getEndTime(String theBulletin, Headers headers) { - - // Regular expression for end time - final String ENDTIME_EXP = "VALID UNTIL ([0-9]{6})"; - - // Pattern used for extracting the end time - final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); - - // Calendar mndTime = Calendar.getInstance(); - - Matcher theMatcher = endtimePattern.matcher(theBulletin); - - if (theMatcher.find()) { - // get the end time. - return TimeTools.findDataTime(theMatcher.group(1), headers); - } else { - return null; - } - } - - /** - * Find and set valid start time and end time for outlook report. - * - * @param theReport - * The outlook section contains the valid times group - */ - public static void processValidTime(String theReport, - AirmetReport currentOutLook, String validDay, Headers headers) { - - // Regular expression for start time - final String TIMES_EXP = "OTLK VALID ([0-9]{4})-([0-9]{4})"; - - // Pattern used for extracting the starting time and end time - final Pattern starttimePattern = Pattern.compile(TIMES_EXP); - - Calendar startTime = null; - Calendar endTime = null; - - Matcher theMatcher = starttimePattern.matcher(theReport); - - if (theMatcher.find()) { - // Decode the start time and end time; then set them. - startTime = TimeTools.findDataTime(validDay.concat(theMatcher.group(1)), - headers); - - currentOutLook.setStartTime(startTime); - endTime = TimeTools.findDataTime(validDay.concat(theMatcher.group(2)), - headers); - - if (endTime.before(startTime)) { - endTime.add(Calendar.DAY_OF_MONTH, 1); - } - currentOutLook.setEndTime(endTime); - } else { - currentOutLook.setStartTime(startTime); - currentOutLook.setEndTime(endTime); - } - - } - - /** - * Parse the location lines and add location table to the report table if - * any - * - * @param theReport - * The report from bulletin message - * @param reportTable - * The report Table - * @return true if finds any location line - */ - public static Boolean processLocation(String theReport, - AirmetReport reportTable) { - - Boolean hasLocationLine = true; - String locationDelimiter = "-| TO "; - - ArrayList terminationList = new ArrayList(); - terminationList.addAll(Arrays.asList(new String[] { "CIG", "MTNS", - "ICE", "MOD", "LLWS", "SUSTAINED", "VIS", "TURB", "CANCEL", - "CNCL" })); - - Scanner scLines = new Scanner(theReport) - .useDelimiter("FROM|BOUNDED BY"); - - LatLonPoint point = null; - - // throws away the first section which is not the "FROM" location - String locationReport = scLines.next(); - - if (scLines.hasNext()) { - locationReport = scLines.next(); - - Scanner scLocationLine = new Scanner(locationReport) - .useDelimiter("\\x0d\\x0d\\x0a"); - String lines = " "; - String curLine = null; - ArrayList locationList = new ArrayList(); - locationList.clear(); - Boolean notBreak = true; - - while (scLocationLine.hasNext() && notBreak) { - // Get next location line - curLine = scLocationLine.next(); - - Scanner scLocationToken = new Scanner(curLine); - if (scLocationToken.hasNext()) { - // Check the first token from each line - String firstToken = scLocationToken.next(); - if (terminationList.contains(firstToken)) { - // terminate - notBreak = false; - break; - } - } - lines = lines.concat(" ").concat(curLine); - } - - // Clean up the leading space - lines = UtilN.removeLeadingWhiteSpaces(lines); - // Parse the location lines by a "-" or "TO" - Scanner scLocation = new Scanner(lines) - .useDelimiter(locationDelimiter); - locationList.clear(); - // Get all locations - while (scLocation.hasNext()) { - locationList.add(scLocation.next()); - } - - // set locations to data base - Integer idxLocation = 0; - if (locationList.size() > 1) { - for (String Location : locationList) { - AirmetLocation currentLocation = new AirmetLocation(); - currentLocation.setLocationLine(lines); - currentLocation.setLocation(Location); - - // Get a latLonPoint for this station ID from "vors" - // location table - point = LatLonLocTbl.getLatLonPoint(Location, "vors"); - if (point == null) { - hasLocationLine = false; - break; - } - currentLocation.setLatitude(point - .getLatitude(LatLonPoint.INDEGREES)); - currentLocation.setLongitude(point - .getLongitude(LatLonPoint.INDEGREES)); - - currentLocation.setIndex(idxLocation + 1); - idxLocation++; - - reportTable.addAirmetLocation(currentLocation); - } - } else { - hasLocationLine = false; - } - - } else { - hasLocationLine = false; - } - - return hasLocationLine; - } -} +/** + * Airmet DecoderUtil + * + * This java class intends to serve as a decoder utility for AIRMET. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 05/2009 39 L. Lin Initial coding + * 07/2009 39 L. Lin Migration to TO11 + * 09/2009 39 L. Lin Add latitude/longitude to location table + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.airmet.util; + +import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetLocation; +import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetRecord; +import gov.noaa.nws.ncep.common.dataplugin.airmet.AirmetReport; +import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class AirmetParser { + + public static final Log logger = LogFactory.getLog(AirmetParser.class); + + /** + * Constructor + */ + public AirmetParser() { + } + + /** + * Parse the WMO line and store WMO header, OfficeID, issue time, + * designatorBBB,... + * + * @param wmoline + * The bulletin message + * + * @return an AirmetRecord + */ + public static AirmetRecord processWMO(String wmoline, Headers headers) { + + AirmetRecord record = null; + // Regular expression for WMO/ICAO, station ID, and issue date (and + // maybe designator BBB) + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; + + // Pattern used for extracting WMO header, officeID, product purge time, + // and issue date and designatorBBB + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(wmoline); + + if (theMatcher.find()) { + record = new AirmetRecord(); + + record.setWmoHeader(theMatcher.group(1)); + record.setIssueOffice(theMatcher.group(2)); + record.setDesignatorBBB(theMatcher.group(5)); + + // Decode the issue time. + Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), headers); + + record.setIssueTime(issueTime); + DataTime dataTime = new DataTime(issueTime); + record.setDataTime(dataTime); + } + return record; + } + + /** + * Obtains reportName as: SIERRA, TANGO or ZULU from a bulletin. + * + * @param bullMessage + * The bulletin message + * @return a string for report type + */ + public static String getReportName(String bullMessage) { + + // Regular expression AIRMET reportName + final String REPORTNAME_EXP = "AIRMET (SIERRA|TANGO|ZULU) "; + + // Pattern used for extracting reportName + final Pattern reportNamePattern = Pattern.compile(REPORTNAME_EXP); + Matcher theMatcher = reportNamePattern.matcher(bullMessage); + + if (theMatcher.find()) { + return theMatcher.group(1); + } else { + return " "; + } + } + + /** + * Obtains updateNumber from a bulletin. + * + * @param bullMessage + * The bulletin message + * @return an integer for update number + */ + public static Integer getUpdateNumber(String bullMessage) { + // default update number + Integer retUpdate = 0; + + // Regular expression update number + final String UPDATE_EXP = "AIRMET (SIERRA|TANGO|ZULU) UPDT ([0-9]{1}) "; + + // Pattern used for extracting update number + final Pattern updatePattern = Pattern.compile(UPDATE_EXP); + Matcher theMatcher = updatePattern.matcher(bullMessage); + + if (theMatcher.find()) { + return Integer.parseInt(theMatcher.group(2).substring(0, 1).trim()); + } else { + return retUpdate; + } + } + + /** + * Obtains correctionFlag from a report + * + * @param bullMessage + * The bulletin message + * @return an integer for correctionFlag 0 for normal, 1 for COR or CC, 2 + * for AMD, 3 for TEST, and 4 for NIL/EXPIRE report + */ + public static Integer getCorrectionFlag(String bullMessage) { + + Integer retCorrection = 0; + + // Regular expression correction + final String CORRECTION_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{2}) ([0-9]{6}) ([A-Z]{3})"; + + // Pattern used for extracting correctionFlag + final Pattern correctionPattern = Pattern.compile(CORRECTION_EXP); + Matcher theMatcher = correctionPattern.matcher(bullMessage); + + if (theMatcher.find()) { + if (theMatcher.group(5).equals("COR")) { + retCorrection = 1; + } else if (theMatcher.group(5).equals("AMD")) { + retCorrection = 2; + } else if ((theMatcher.group(5).substring(0, 2)).equals("CC")) { + retCorrection = 1; + } + } + + // Regular expression TEST message + final String TEST_EXP = " TEST "; + // Pattern used for extracting TEST message + final Pattern testPattern = Pattern.compile(TEST_EXP); + Matcher testMatcher = testPattern.matcher(bullMessage); + if (testMatcher.find()) { + retCorrection = 3; + } + + return retCorrection; + } + + /** + * Obtains cancelFlag from a report + * + * @param bullMessage + * The bulletin message + * @return an integer for cancelFlag 0 for normal and 1 for cancel + */ + public static Integer getCancelFlag(String report) { + + Integer retCancel = 0; + + // Regular expression cancelFlag + final String CANCEL_EXP = "(CANCEL|CNCL) AIRMET"; + + // Pattern used for extracting cancel + final Pattern cancelPattern = Pattern.compile(CANCEL_EXP); + Matcher theMatcher = cancelPattern.matcher(report); + + if (theMatcher.find()) { + retCancel = 1; + } + return retCancel; + } + + /** + * Obtains hazardType as: IFR (instrument flight rules), MO (mountain + * obscuration), TB (turbulence), IC (icing), SW (sustained winds), or WS + * (low level wind shear) from a report. + * + * @param theReport + * Input report message. + * @return a string for class type + */ + public static String getHazardType(String theReport) { + + String retHazardType = " "; + // Regular expression AIRMET classType + final String HAZARDTYPE_EXP = "AIRMET (IFR|MTN OBSCN|TURB|ICE|STG SFC WNDS)"; + final String TYPE2_EXP = "(LLWS POTENTIAL)"; + final String TYPE3_EXP = "(ICE|TURB|CIG BLW|VIS BLW|MTNS|LLWS|SUSTAINED)"; + final String TYPE4_EXP = "(CANCEL|CNCL)"; + + // Pattern used for extracting hazardType + final Pattern classTypePattern = Pattern.compile(HAZARDTYPE_EXP); + final Pattern type2Pattern = Pattern.compile(TYPE2_EXP); + final Pattern type3Pattern = Pattern.compile(TYPE3_EXP); + final Pattern type4Pattern = Pattern.compile(TYPE4_EXP); + + Matcher theMatcher = classTypePattern.matcher(theReport); + Matcher type2Matcher = type2Pattern.matcher(theReport); + Matcher type3Matcher = type3Pattern.matcher(theReport); + Matcher type4Matcher = type4Pattern.matcher(theReport); + + if (theMatcher.find()) { + if (theMatcher.group(1).equals("IFR")) { + retHazardType = "INSTRUMENT FLIGHT RULES"; + } else if (theMatcher.group(1).equals("MTN OBSCN")) { + retHazardType = "MOUNTAIN OBSCURATION"; + } else if (theMatcher.group(1).equals("TURB")) { + retHazardType = "TURBULENCE"; + } else if (theMatcher.group(1).equals("ICE")) { + retHazardType = "ICING"; + } else if (theMatcher.group(1).equals("STG SFC WNDS")) { + retHazardType = "SUSTAINED SFC WINDS"; + } + } else if (type2Matcher.find()) { + if (type2Matcher.group(1).equals("LLWS")) { + retHazardType = "LOW LEVEL WIND SHEAR"; + } + } else if (type3Matcher.find()) { + if (type3Matcher.group(1).equals("ICE")) { + retHazardType = "ICING"; + } else if (type3Matcher.group(1).equals("TURB")) { + retHazardType = "TURBULENCE"; + } else if (type3Matcher.group(1).equals("CIG BLW")) { + retHazardType = "INSTRUMENT FLIGHT RULES"; + } else if (type3Matcher.group(1).equals("VIS BLW")) { + retHazardType = "INSTRUMENT FLIGHT RULES"; + } else if (type3Matcher.group(1).equals("MTNS")) { + retHazardType = "MOUNTAIN OBSCURATION"; + } else if (type3Matcher.group(1).equals("LLWS")) { + retHazardType = "LOW LEVEL WIND SHEAR"; + } else if (type3Matcher.group(1).equals("SUSTAINED")) { + retHazardType = "SUSTAINED SFC WINDS"; + } + } else if (type4Matcher.find()) { + retHazardType = "CANCEL"; + } + + return retHazardType; + } + + /** + * Obtains forecast region as: S for SIERRA, T for TANGO or Z for ZULU from + * an AirmetRecord. + * + * @param record + * The AirmetRecord + * @return a string for forecast region + */ + public static String getRegion(String reportName) { + + String retRegion = null; + String forecastRegion = reportName; + + if (forecastRegion.equals("SIERRA")) { + retRegion = "S"; + } else if (forecastRegion.equals("TANGO")) { + retRegion = "T"; + } else if (forecastRegion.equals("ZULU")) { + retRegion = "Z"; + } + return retRegion; + } + + /** + * process regular section of an AIRMET report + * + * @param theReport + * The reports from bulletin message + * @return an AirmetReport table + */ + public static AirmetReport processReport(String theReport) { + + // Regular expression for flight levels + final String FLIGHT_EXP = " (BTN) (FL)?(FRZLVL|[0-9]{3})( AND |-)FL([0-9]{3})"; + final String BLW_EXP = " (BLW) FL([0-9]{3})"; + + // Pattern used for extracting flight levels + final Pattern flightPattern = Pattern.compile(FLIGHT_EXP); + final Pattern blwPattern = Pattern.compile(BLW_EXP); + + Matcher flightMatcher = flightPattern.matcher(theReport); + Matcher blwMatcher = blwPattern.matcher(theReport); + + AirmetReport currentReport = new AirmetReport(); + // Find and set the flight levels. + if (flightMatcher.find()) { + if (flightMatcher.group(1).equals("BTN")) { + if ((flightMatcher.group(3).equals("FRZLVL"))) { + currentReport.setFlightLevel1("FRZLVL"); + } else { + currentReport.setFlightLevel1(flightMatcher.group(3) + .toString()); + } + currentReport + .setFlightLevel2(flightMatcher.group(5).toString()); + } + } else if (blwMatcher.find()) { + currentReport.setFlightLevel2(blwMatcher.group(2).toString()); + } + // Get and set reportType + currentReport.setHazardType(getHazardType(theReport)); + + // Set reportIndicator + currentReport.setReportIndicator("AIRMET"); + + // Get and set cancel flag + currentReport.setCancelFlag(AirmetParser.getCancelFlag(theReport)); + + // Replace the special characters + currentReport.setSegment(theReport.replace('\r', ' ') + .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' ')); + + // Decode the locations + if (!AirmetParser.processLocation(theReport, currentReport)) { + currentReport = null; + } + + return currentReport; + } + + /** + * process the outlook of an AIRMET report. + * + * @param theOutlook + * The outlook section lines from bulletin message + * @return an AirmetReport table + */ + public static AirmetReport processOutLook(String theOutlook, + String forecastRegion) { + + AirmetReport currentOutLook = new AirmetReport(); + + currentOutLook.setSegment(theOutlook.replace('\r', ' ') + .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' ')); + + // Get and set hazard type + currentOutLook.setHazardType(getHazardType(theOutlook)); + // Set report indicator. + currentOutLook.setReportIndicator("OUTLOOK"); + + // Decode locations + if (AirmetParser.processLocation(theOutlook, currentOutLook)) { + final String SID_EXP = "AREA ([0-9]{1})"; + + // Pattern used for extracting the number of sequence ID. + final Pattern sidPattern = Pattern.compile(SID_EXP); + + Matcher theMatcher = sidPattern.matcher(theOutlook); + + // Default sequenceID as: 1S, 1T, or 1Z if locations have been + // found. + String sequenceID = "1".concat(forecastRegion); + if (theMatcher.find()) { + // Multiple areas such as: "AREA 1", "AREA 2", ...etc + sequenceID = theMatcher.group(1).concat(forecastRegion); + } + currentOutLook.setSequenceID(sequenceID); + } else { + // Default sequenceID as: 0W, 0C, or 0E if outlook section is a NIL + // report. + String sequenceID = "0".concat(forecastRegion); + currentOutLook.setSequenceID(sequenceID); + } + + // Get and set cancel flag + currentOutLook.setCancelFlag(AirmetParser.getCancelFlag(theOutlook)); + + return currentOutLook; + } + + /** + * Obtains start time from input bulletin. + * + * @param theReport + * The bulletin message + * @return a calendar for start time + */ + public static Calendar getStartTime(String theBulletin, Headers headers) { + + // Regular expression for start time + final String STARTTIME_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{2}) ([0-9]{6})( [A-Z]{3})?"; + + // Pattern used for extracting the starting time + final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); + + // Calendar mndTime = Calendar.getInstance(); + + Matcher theMatcher = starttimePattern.matcher(theBulletin); + + if (theMatcher.find()) { + // Get start time + return TimeTools.findDataTime(theMatcher.group(4), headers); + } else { + return null; + } + } + + /** + * Obtains the valid day from input bulletin. + * + * @param theBulletin + * The input bulletin + * @return a string for valid day. + */ + public static String getValidDay(String theBulletin) { + + // Regular expression for the day + final String DAY_EXP = " VALID UNTIL ([0-9]{2})([0-9]{4})"; + // Pattern used for extracting the day + final Pattern dayPattern = Pattern.compile(DAY_EXP); + Matcher theMatcher = dayPattern.matcher(theBulletin); + + String retDay; + + // Get sequence number according to 4-digit of valid time + if (theMatcher.find()) { + retDay = theMatcher.group(1); + } else { + Calendar cal = Calendar.getInstance(); + retDay = Integer.toString(cal.get(Calendar.DAY_OF_MONTH)); + } + return retDay; + } + + /** + * Obtains the sequence ID which is composed by an identifier, a sequence + * number and a series number. + * + * @param theBulletin + * The input bulletin + * @param series + * the series number of the report + * @return a string for sequence ID + */ + public static String getSequenceID(String theBulletin, Integer series) { + + // Regular expression for the sequence number + final String SEQUENCEID_EXP = " VALID UNTIL ([0-9]{2})([0-9]{4})"; + // Pattern used for extracting the sequence number + final Pattern idPattern = Pattern.compile(SEQUENCEID_EXP); + Matcher theMatcher = idPattern.matcher(theBulletin); + + Integer timeGroup; + String seqNumber; + String identifier = "???"; + // Get sequence number according to 4-digit of valid time + if (theMatcher.find()) { + timeGroup = Integer.parseInt(theMatcher.group(2)); + if (timeGroup == 800 | timeGroup == 900) { + seqNumber = "0"; + } else if (timeGroup == 1400 | timeGroup == 1500) { + seqNumber = "2"; + } else if (timeGroup == 2000 | timeGroup == 2100) { + seqNumber = "4"; + } else if (timeGroup == 200 | timeGroup == 300) { + seqNumber = "6"; + } else { + seqNumber = "8"; + } + } else { + seqNumber = "8"; + } + // System.out.println("seqNumber=" + seqNumber); + + // Regular expression for identifier + final String IDENTIFIER_EXP = "([A-Z]{3})(S|Z|T) WA ([0-9]{6})( [A-Z]{3})?"; + ; + // Pattern used for extracting the sequence number + final Pattern identifierPattern = Pattern.compile(IDENTIFIER_EXP); + Matcher idMatcher = identifierPattern.matcher(theBulletin); + // Get identifier + if (idMatcher.find()) { + identifier = idMatcher.group(1); + } + + return identifier.concat(seqNumber).concat(Integer.toString(series)); + } + + /** + * Get the end time + * + * @param theBulletin + * The bulletin which contains end time + * @return a calendar for end time + */ + public static Calendar getEndTime(String theBulletin, Headers headers) { + + // Regular expression for end time + final String ENDTIME_EXP = "VALID UNTIL ([0-9]{6})"; + + // Pattern used for extracting the end time + final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); + + // Calendar mndTime = Calendar.getInstance(); + + Matcher theMatcher = endtimePattern.matcher(theBulletin); + + if (theMatcher.find()) { + // get the end time. + return TimeTools.findDataTime(theMatcher.group(1), headers); + } else { + return null; + } + } + + /** + * Find and set valid start time and end time for outlook report. + * + * @param theReport + * The outlook section contains the valid times group + */ + public static void processValidTime(String theReport, + AirmetReport currentOutLook, String validDay, Headers headers) { + + // Regular expression for start time + final String TIMES_EXP = "OTLK VALID ([0-9]{4})-([0-9]{4})"; + + // Pattern used for extracting the starting time and end time + final Pattern starttimePattern = Pattern.compile(TIMES_EXP); + + Calendar startTime = null; + Calendar endTime = null; + + Matcher theMatcher = starttimePattern.matcher(theReport); + + if (theMatcher.find()) { + // Decode the start time and end time; then set them. + startTime = TimeTools.findDataTime(validDay.concat(theMatcher.group(1)), + headers); + + currentOutLook.setStartTime(startTime); + endTime = TimeTools.findDataTime(validDay.concat(theMatcher.group(2)), + headers); + + if (endTime.before(startTime)) { + endTime.add(Calendar.DAY_OF_MONTH, 1); + } + currentOutLook.setEndTime(endTime); + } else { + currentOutLook.setStartTime(startTime); + currentOutLook.setEndTime(endTime); + } + + } + + /** + * Parse the location lines and add location table to the report table if + * any + * + * @param theReport + * The report from bulletin message + * @param reportTable + * The report Table + * @return true if finds any location line + */ + public static Boolean processLocation(String theReport, + AirmetReport reportTable) { + + Boolean hasLocationLine = true; + String locationDelimiter = "-| TO "; + + ArrayList terminationList = new ArrayList(); + terminationList.addAll(Arrays.asList(new String[] { "CIG", "MTNS", + "ICE", "MOD", "LLWS", "SUSTAINED", "VIS", "TURB", "CANCEL", + "CNCL" })); + + Scanner scLines = new Scanner(theReport) + .useDelimiter("FROM|BOUNDED BY"); + + LatLonPoint point = null; + + // throws away the first section which is not the "FROM" location + String locationReport = scLines.next(); + + if (scLines.hasNext()) { + locationReport = scLines.next(); + + Scanner scLocationLine = new Scanner(locationReport) + .useDelimiter("\\x0d\\x0d\\x0a"); + String lines = " "; + String curLine = null; + ArrayList locationList = new ArrayList(); + locationList.clear(); + Boolean notBreak = true; + + while (scLocationLine.hasNext() && notBreak) { + // Get next location line + curLine = scLocationLine.next(); + + Scanner scLocationToken = new Scanner(curLine); + if (scLocationToken.hasNext()) { + // Check the first token from each line + String firstToken = scLocationToken.next(); + if (terminationList.contains(firstToken)) { + // terminate + notBreak = false; + break; + } + } + lines = lines.concat(" ").concat(curLine); + } + + // Clean up the leading space + lines = UtilN.removeLeadingWhiteSpaces(lines); + // Parse the location lines by a "-" or "TO" + Scanner scLocation = new Scanner(lines) + .useDelimiter(locationDelimiter); + locationList.clear(); + // Get all locations + while (scLocation.hasNext()) { + locationList.add(scLocation.next()); + } + + // set locations to data base + Integer idxLocation = 0; + if (locationList.size() > 1) { + for (String Location : locationList) { + AirmetLocation currentLocation = new AirmetLocation(); + currentLocation.setLocationLine(lines); + currentLocation.setLocation(Location); + + // Get a latLonPoint for this station ID from "vors" + // location table + point = LatLonLocTbl.getLatLonPoint(Location, "vors"); + if (point == null) { + hasLocationLine = false; + break; + } + currentLocation.setLatitude(point + .getLatitude(LatLonPoint.INDEGREES)); + currentLocation.setLongitude(point + .getLongitude(LatLonPoint.INDEGREES)); + + currentLocation.setIndex(idxLocation + 1); + idxLocation++; + + reportTable.addAirmetLocation(currentLocation); + } + } else { + hasLocationLine = false; + } + + } else { + hasLocationLine = false; + } + + return hasLocationLine; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/package-info.java old mode 100755 new mode 100644 index 9e3a2d3ca7..8610c59fa0 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/src/gov/noaa/nws/ncep/edex/plugin/airmet/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.airmet.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.airmet.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/unit-test/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/2009051211.airm b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/unit-test/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/2009051211.airm index a568eb319e..ff628e4103 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/unit-test/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/2009051211.airm +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airmet/unit-test/gov/noaa/nws/ncep/edex/plugin/airmet/decoder/2009051211.airm @@ -1,30 +1,30 @@ - + -976 + -WAUS45 KKCI 121112 AAA + -WA5S + -SLCS WA 121112 AMD + -AIRMET SIERRA UPDT 2 FOR IFR AND MTN OBSCN VALID UNTIL 121500 + -. + -AIRMET IFR...ID MT + -FROM 30SW YQL TO 70SSE FCA TO 30SW MLP TO 30NE GEG TO 60WSW YXC + -TO 30SW YQL + -CIG BLW 010/VIS BLW 3SM BR. CONDS CONTG BYD 15Z ENDG 15-18Z. + -. + -AIRMET IFR...CO NM + -FROM SNY TO 50E SNY TO 50W LBL TO 30ESE TBE TO INK TO 60S CME TO + -20W CME TO 30S CIM TO TBE TO PUB TO 30W AKO TO SNY + -CIG BLW 010/VIS BLW 3SM BR. CONDS CONTG BYD 15Z ENDG 15-18Z. + -. + -AIRMET MTN OBSCN...ID MT WA OR + -FROM 50SW YQL TO 50SW HLN TO LKT TO 20WSW BKE TO 20SSE PDT TO + -90WSW YXC TO 50SW YQL + -MTNS OBSC BY CLDS/PCPN/BR. CONDS DVLPG 09-12Z. CONDS CONTG + -BYD 15Z THRU 21Z. + -. + -AIRMET MTN OBSCN...CO NM...UPDT + -FROM TBE TO CME TO 60W INK TO 50E ELP TO 50W CME TO 50ESE ABQ TO + -30SSW ALS TO TBE + -CANCEL AIRMET. CONDS HV ENDED. + -.... + - + + +976 +WAUS45 KKCI 121112 AAA +WA5S +SLCS WA 121112 AMD +AIRMET SIERRA UPDT 2 FOR IFR AND MTN OBSCN VALID UNTIL 121500 +. +AIRMET IFR...ID MT +FROM 30SW YQL TO 70SSE FCA TO 30SW MLP TO 30NE GEG TO 60WSW YXC +TO 30SW YQL +CIG BLW 010/VIS BLW 3SM BR. CONDS CONTG BYD 15Z ENDG 15-18Z. +. +AIRMET IFR...CO NM +FROM SNY TO 50E SNY TO 50W LBL TO 30ESE TBE TO INK TO 60S CME TO +20W CME TO 30S CIM TO TBE TO PUB TO 30W AKO TO SNY +CIG BLW 010/VIS BLW 3SM BR. CONDS CONTG BYD 15Z ENDG 15-18Z. +. +AIRMET MTN OBSCN...ID MT WA OR +FROM 50SW YQL TO 50SW HLN TO LKT TO 20WSW BKE TO 20SSE PDT TO +90WSW YXC TO 50SW YQL +MTNS OBSC BY CLDS/PCPN/BR. CONDS DVLPG 09-12Z. CONDS CONTG +BYD 15Z THRU 21Z. +. +AIRMET MTN OBSCN...CO NM...UPDT +FROM TBE TO CME TO 60W INK TO 50E ELP TO 50W CME TO 50ESE ABQ TO +30SSW ALS TO TBE +CANCEL AIRMET. CONDS HV ENDED. +.... +  \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/component-deploy.xml index 64294475b3..beb1bb2240 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/src/gov/noaa/nws/ncep/edex/plugin/atcf/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/src/gov/noaa/nws/ncep/edex/plugin/atcf/decoder/package-info.java index af42c2466d..8d0596b010 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/src/gov/noaa/nws/ncep/edex/plugin/atcf/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.atcf/src/gov/noaa/nws/ncep/edex/plugin/atcf/decoder/package-info.java @@ -1,7 +1,7 @@ -/** - * SGWH implementation of the plugin pattern. - * - * Package includes classes to decode the ATCF message and persist the data. - * - */ +/** + * SGWH implementation of the plugin pattern. + * + * Package includes classes to decode the ATCF message and persist the data. + * + */ package gov.noaa.nws.ncep.edex.plugin.atcf.decoder; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/META-INF/MANIFEST.MF index 1153c9740a..3ead3429c6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: com.raytheon.edex.common;bundle-version="1.10.13", com.raytheon.uf.edex.decodertools;bundle-version="1.0.0", com.raytheon.uf.common.pointdata;bundle-version="1.11.8", com.raytheon.uf.edex.pointdata;bundle-version="1.11.8", - gov.noaa.nws.ncep.common.dataplugin.aww;bundle-version="1.0.0" + gov.noaa.nws.ncep.common.dataplugin.aww;bundle-version="1.0.0", + org.geotools;bundle-version="2.6.4" Import-Package: com.raytheon.uf.edex.decodertools.core, com.raytheon.uf.edex.decodertools.time, com.raytheon.uf.edex.wmo.message, diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/component-deploy.xml index f3269fd9e5..7859107606 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java index 423e2ee1ab..f18691734f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwDecoder.java @@ -37,16 +37,22 @@ package gov.noaa.nws.ncep.edex.plugin.aww.decoder; +import gov.noaa.nws.ncep.common.dataplugin.aww.AwwLatlons; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwRecord; import gov.noaa.nws.ncep.common.dataplugin.aww.AwwUgc; +import gov.noaa.nws.ncep.common.dataplugin.aww.AwwVtec; import gov.noaa.nws.ncep.edex.plugin.aww.exception.AwwDecoderException; +import gov.noaa.nws.ncep.edex.plugin.aww.util.AwwLatLonUtil; import gov.noaa.nws.ncep.edex.plugin.aww.util.AwwParser; import gov.noaa.nws.ncep.edex.tools.decoder.MndTime; import gov.noaa.nws.ncep.edex.util.UtilN; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashSet; +import java.util.List; import java.util.Scanner; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -87,6 +93,7 @@ public class AwwDecoder extends AbstractDecoder { // Pattern used for extracting the UGC line Pattern ugcPattern = Pattern.compile(UGC_EXP, Pattern.DOTALL); + // String "&" ascii code is x26 in hex // String segmentDelim ="$$"; String segmentDelim = "\\x24\\x24"; String etx = IDecoderConstants.ETX; @@ -122,7 +129,11 @@ public class AwwDecoder extends AbstractDecoder { if (record == null) { throw new AwwDecoderException("Error on decoding Aww Record"); } - + + boolean isWtchFlag = AwwDecoder.isWtch(record);//Ticket 456 + + boolean isSevereWeatherStatusFlag = AwwDecoder.isSevereWeatherStatus(record); + // Get report type String reportType = AwwParser.getReportType(theBulletin); @@ -136,7 +147,7 @@ public class AwwDecoder extends AbstractDecoder { String segment = sc.next(); Matcher ugcMatcher = ugcPattern.matcher(segment); // discard if the segment did not have an UGC line. - if (ugcMatcher.find()) { + if (ugcMatcher.find() || isWtchFlag) { //????? not sure if this logic is correct segmentList.add(segment); } } @@ -147,9 +158,23 @@ public class AwwDecoder extends AbstractDecoder { // LATLON... for (String segment : segmentList) { Matcher ugcMatcher = ugcPattern.matcher(segment); - if (ugcMatcher.find()) { - AwwUgc ugc = AwwParser.processUgc(ugcMatcher.group(), - segment, mndTime, watchesList); + AwwUgc ugc = null; + + + if (ugcMatcher.find()) + ugc = AwwParser.processUgc(ugcMatcher.group(), segment, mndTime, watchesList); + else if(isWtchFlag) { + ugc = AwwParser.processUgcForWtch(AwwParser.WTCH_BOX_UGC_LINE, segment, mndTime, record.getIssueOffice(), watchesList); +// else if(isSevereWeatherStatusFlag) +// ugc = AwwParser.processUgcForSereveWeatherStatus(ugcMatcher.group(), segment, mndTime, record.getIssueOffice(), watchesList); + String watchNumber = AwwParser.processUgcToRetrieveWatchNumberForThunderstormOrTornado(segment); + record.setWatchNumber(watchNumber); +// } else if(isSevereWeatherStatusFlag) { +// String watchNumber = AwwParser.processUgcToRetrieveWatchNumberForStatusReport(segment); +// record.setWatchNumber(watchNumber); + } + + if(ugc != null) { record.addAwwUGC(ugc); /* @@ -160,26 +185,57 @@ public class AwwDecoder extends AbstractDecoder { * segment has one UGC line but may have multiple VTEC * lines and have more than one watch number */ - if (watchesList.size() > 0) { - String collectWatches = null; - for (int idxWatch = 0; idxWatch < watchesList - .size(); idxWatch++) { + /* + * not quite sure the following logic is correct to retrieve and then store the + * watch number. thus comment it out now. M. Gao + */ +// if (watchesList.size() > 0) { +// String collectWatches = null; +// for (int idxWatch = 0; idxWatch < watchesList.size(); idxWatch++) { +// +// if (idxWatch == 0) { +// collectWatches = watchesList.get(idxWatch); +// } else { +// collectWatches = collectWatches.concat("/") +// .concat(watchesList.get(idxWatch)); +// } +// } +// // System.out.println("==collection length=" + +// // collectWatches.length() ); +// record.setWatchNumber(collectWatches); +// } else { +// +// // The special reports may not have VTEC line; given +// // a default watch number "0000". +// record.setWatchNumber("0000"); +// } + + /* + * construct VTEC object and then add it to the current Ugc for SevereWeatherStatus aww reocrd + */ + if(isSevereWeatherStatusFlag && AwwParser.isSegmentTextValid(segment)) { + /* + * parse and then set the Watch Number for Status Report + */ + String watchNumber = AwwParser.processUgcToRetrieveWatchNumberForStatusReport(segment); + record.setWatchNumber(watchNumber); - if (idxWatch == 0) { - collectWatches = watchesList.get(idxWatch); - } else { - collectWatches = collectWatches.concat("/") - .concat(watchesList.get(idxWatch)); - } - } - // System.out.println("==collection length=" + - // collectWatches.length() ); - record.setWatchNumber(collectWatches); - } else { - - // The special reports may not have VTEC line; given - // a default watch number "0000". - record.setWatchNumber("0000"); + AwwVtec awwVtec = AwwParser.processVtectForSevereWeatherStatus(theBulletin, record.getIssueTime(), record.getIssueOffice()); + Set awwVtecSet = new HashSet(); + awwVtecSet.add(awwVtec); + ugc.setAwwVtecLine(awwVtecSet); + /* + * now calculate status latlon info and then add to ugc + */ + List pointAwwLatLonsList = AwwLatLonUtil.getAwwLatLonsListBySereveWeatherStatusPointLine(awwVtec.getVtecLine()); +// System.out.println("==========, within AwwDecoder, pointAwwLatLonsList.size="+pointAwwLatLonsList.size()); + int index=0; + for(AwwLatlons eachAwwLatlons : pointAwwLatLonsList) { +// System.out.println("===============,before adding awwLatLons to ugc, No."+(index+1)+" awwLatLons.getLat="+ +// eachAwwLatlons.getLat()+" awwLatLons.getLon="+eachAwwLatlons.getLon()); + index++; + ugc.addAwwLatLon(eachAwwLatlons); + } } } @@ -202,6 +258,8 @@ public class AwwDecoder extends AbstractDecoder { } catch (PluginException e) { throw new DecoderException("Error constructing dataURI", e); } + } else { + throw new DecoderException("Error Aww Reocrd object is NULL"); } // Decode and set attention line @@ -232,4 +290,24 @@ public class AwwDecoder extends AbstractDecoder { return new PluginDataObject[] { record }; } + + /** + * Ticket 456: for handling NO UGC lines in *.wtch2 files + * + * @param ar + * @return boolean flag whether AwwRecord is WTCH + */ + public static boolean isWtch(AwwRecord ar){ + if(ar == null) + return false; + + return "WWUS30".equalsIgnoreCase(ar.getWmoHeader()); + } + + public static boolean isSevereWeatherStatus(AwwRecord awwReocrd) { + boolean isSevereWeatherStatus = false; + if("WOUS20".equalsIgnoreCase(awwReocrd.getWmoHeader())) + isSevereWeatherStatus = true; + return isSevereWeatherStatus; + } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwSeparator.java index b51fe4ec68..3fc70aef61 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/AwwSeparator.java @@ -62,17 +62,20 @@ public class AwwSeparator extends AbstractRecordSeparator { * */ public AwwSeparator() { - records = new ArrayList(); +// System.out.println("============================== At the beginning of AwwSeparator constructor method"); + records = new ArrayList(); } public static AwwSeparator separate(byte[] data, Headers headers) { +// System.out.println("============================== At the beginning of separate method, input data[]="+new String(data)); AwwSeparator ds = new AwwSeparator(); ds.setData(data, headers); return ds; } public void setData(byte[] data, Headers headers) { - doSeparate(new String(data)); +// System.out.println("============================== At the beginning of setData method, input data[]="+new String(data)); + doSeparate(new String(data)); iterator = records.iterator(); } @@ -111,7 +114,7 @@ public class AwwSeparator extends AbstractRecordSeparator { */ private void doSeparate(String message) { /* Regex used for separate the bulletins */ - +//System.out.println("============================== At the beginning of doSeparate method, input message="+message); try { pattern = Pattern.compile(BULLSEPARATOR); matcher = pattern.matcher(message); @@ -122,7 +125,8 @@ public class AwwSeparator extends AbstractRecordSeparator { * "records" */ while (matcher.find()) { - if (!records.contains(matcher.group())) { + String matcherGroupString = matcher.group(); + if (!records.contains(matcherGroupString)) { records.add(matcher.group()); } } @@ -130,8 +134,15 @@ public class AwwSeparator extends AbstractRecordSeparator { /* * Append the raw data file to the records. */ +// System.out.println("########, before do reset on the string list, the original list content is:"); +// displayStringList(records); for (int i = 0; i < records.size(); i++) { if (i < records.size() - 1) { +// String modifiedString = "\n" +// + message.substring( +// message.indexOf(records.get(i)), +// message.indexOf(records.get(i + 1))); +// System.out.println("====, with i="+i+", the modifiedString="+modifiedString); records.set( i, "\n" @@ -139,6 +150,10 @@ public class AwwSeparator extends AbstractRecordSeparator { message.indexOf(records.get(i)), message.indexOf(records.get(i + 1)))); } else { +// String modifiedString = "\n" +// + message.substring(message.indexOf(records +// .get(i))); +// System.out.println("====*****, with i="+i+", the modifiedString="+modifiedString); records.set( i, "\n" @@ -155,4 +170,12 @@ public class AwwSeparator extends AbstractRecordSeparator { } return; } + + private void displayStringList(List stringList) { + int index = 1; + for(String eachString : stringList) { + System.out.println("=====, String Item No."+index+" ="+eachString); + index++; + } + } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/package-info.java index 41f6ec50f7..19e4ac5b2d 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/src/gov/noaa/nws/ncep/edex/plugin/aww/decoder/package-info.java @@ -1,7 +1,7 @@ -/** - * AWW implementation of the plugin pattern. - * - * Package includes classes to decode the AWW message and persist the data. - * - */ +/** + * AWW implementation of the plugin pattern. + * + * Package includes classes to decode the AWW message and persist the data. + * + */ package gov.noaa.nws.ncep.edex.plugin.aww.decoder; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/utility/edex_static/base/distribution/aww.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/utility/edex_static/base/distribution/aww.xml index 38bb4455f0..32db7f4916 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/utility/edex_static/base/distribution/aww.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/utility/edex_static/base/distribution/aww.xml @@ -1,41 +1,16 @@ ^[AFN]G.* - ^FAUS20 PANC.* - ^FAUS20 KZ.* - ^FXUS70.* - ^FXUS76 KOKC.* - ^FQUS71.* - ^FVXX2[0-4].* - ^FVCN0[0-4].* - ^FVAU0[2-4].* - ^FVAK2[1-5] PAWU.* - ^FZCA72 TJSJ.* - ^FZUS7[12346].* - ^FZUS60.* - ^RR.* - ^RWAK3[12].* - ^RWAK42.* - ^RWCA[03][13].* - ^RWCA3[1-4].* - ^RWCA[03][13].* - ^RWCA3[1-4].* - ^RW(US|CA)4[23].* - ^RWUS3[12].* + ^F(A|X|Q)US[27][016].* + ^FV(AK|AU|CN|XX)[02][0-5].* + ^FZ(CA|US)[67][012346].* + ^RW(AK|US|CA)[034][1-4].* ^WFUS.* - ^WGCA[4-7]2 TJSJ.* - ^WGUS[4-8][1-5].* - ^WGUS44.* - ^WHC[AU]31.* - ^WHUS4[1256].* - ^WOUS64 KWNS.* - ^WOHW40.* - ^WRUS01.* - ^WRCA0[12]^RR.* - ^WRAK01.* - ^WTUS8[1-2].* - ^WTHW80.* - ^WUUS5[1-5].* - ^WUUS0[1-3].* - ^WW.* + ^WG(CA|US)[4-8][1-5].* + ^WH(CA|CU|US)[34][1256].* + ^WO(HW|US)[46][04].* + ^WR(AK|CA|US)0[12].* + ^WT(HW|US)8[0-2].* + ^WUUS[05][1-5].* + ^(WW|RR).* diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/component-deploy.xml old mode 100755 new mode 100644 index d2b77ce8d9..777cd43ee3 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-common.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-common.xml old mode 100755 new mode 100644 index 296212af97..4e0c093444 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-common.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-common.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml old mode 100755 new mode 100644 index cc09493589..57168d5fda --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml @@ -1,73 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - convsigmet - - - - - - - - - - - - - java.lang.Throwable - - - - - - - java.lang.Throwable - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + convsigmet + + + + + + + + + + + + + java.lang.Throwable + + + + + + + java.lang.Throwable + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetDecoder.java old mode 100755 new mode 100644 index 40ee86d5ab..39e26d3f2c --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetDecoder.java @@ -1,224 +1,224 @@ -/** - * - * Convective Sigmet Decoder - * - * This java class decodes CONVSIGMET (convective sigmet) raw data. - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 06/2009 87/114 L. Lin Increase size of locationLine and location - * and generalize method "processLocation". - * 07/2009 87/114 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder; - -import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetRecord; -import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetSection; -import gov.noaa.nws.ncep.edex.plugin.convsigmet.util.ConvSigmetParser; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Scanner; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.exception.DecoderException; -import com.raytheon.edex.plugin.AbstractDecoder; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.PluginException; -import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; - -public class ConvSigmetDecoder extends AbstractDecoder { - - private final String pluginName; - - /** - * Constructor - * - * @throws DecoderException - */ - public ConvSigmetDecoder(String name) throws DecoderException { - pluginName = name; - } - - public PluginDataObject[] decode(byte[] data, Headers headers) - throws DecoderException { - - String traceId = ""; - if (headers != null) { - traceId = (String) headers.get("traceId"); - } - - String sectionDelim = "OUTLOOK|CONVECTIVE"; - String etx = IDecoderConstants.ETX; - String theBulletin = null; - - String region = null; - Calendar startTime = null; - byte[] messageData = null; - - ConvSigmetRecord record = null; - - ConvSigmetSeparator sep = ConvSigmetSeparator.separate(data, headers); - messageData = sep.next(); - String theMessage = new String(messageData); - - /* - * May have multiple duplicate bulletins, only get the first bulletin - * and eliminate the remaining bulletins after the first bulletin. - */ - Scanner cc = new Scanner(theMessage).useDelimiter(etx); - if (cc.hasNext()) { - theBulletin = cc.next(); - } else { - theBulletin = theMessage; - } - - // record = new ConvsigmetRecord(); - // Decode and set WMO line - record = ConvSigmetParser.processWMO(theBulletin, headers); - - // Decode the forecast region such as: W, C, or E - region = ConvSigmetParser.processFcstRegion(theBulletin); - String forecastRegion = "SIG".concat(region); - - /* - * Check the Convsigmet record object. If not, throws exception. - */ - if (record != null) { - record.setTraceId(traceId); - record.setPluginName(pluginName); - record.setReportType(pluginName); - record.setForecastRegion(forecastRegion); - try { - record.constructDataURI(); - } catch (PluginException e) { - logger.error("Error constructing dataURI", e); - record = null; - } - } - - if (record != null) { - try { - // Replace special characters to a blank so that it may be - // readable - record.setBullMessage(UtilN - .removeLeadingWhiteSpaces((theBulletin.substring(5)) - .replace('\036', ' ').replace('\r', ' ') - .replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' '))); - - // Decode the starting time - startTime = ConvSigmetParser.processStartTime(theBulletin, - headers); - - // Decode the correction flag and set - Boolean correctionFlag = ConvSigmetParser - .processCorrectionFlag(theBulletin); - Integer correction = 0; - if (correctionFlag) { - correction = 1; - } - record.setCorrectionFlag(correction); - - /* - * Break the bulletin message into sections by a "OUTLOOK" or - * "CONVECTIVE". - */ - Scanner sc = new Scanner(theBulletin) - .useDelimiter(sectionDelim); - - ArrayList segmentList = new ArrayList(); - segmentList.clear(); - while (sc.hasNext()) { - String segment = sc.next(); - segmentList.add(segment); - } - - Calendar issueTime = record.getIssueTime(); - /* - * process each section in a order of section and location line - */ - for (String segment : segmentList) { - - // starts a new section - Scanner sc2 = new Scanner(segment); - String whatSection = sc2.next(); - if (whatSection.equals("SIGMET") - || whatSection.equals("SIGMET...NONE")) { - segment = "CONVECTIVE".concat(segment); - - // process this section which starts with - // "CONVECTIVE SIGMET". - ConvSigmetSection section = ConvSigmetParser - .processSection(segment, issueTime, startTime, - region, headers); - record.addConvSigmetSection(section); - } else if (whatSection.equals("VALID")) { - segment = "OUTLOOK".concat(segment); - - // process this section which starts with - // "OUTLOOK VALID". - Scanner scOutlook = new Scanner(segment) - .useDelimiter("AREA "); - ArrayList outlookList = new ArrayList(); - outlookList.clear(); - - // Check if "OUTLOOK" section contains more than one - // "AREA". - while (scOutlook.hasNext()) { - String outlookSegment = scOutlook.next(); - outlookList.add(outlookSegment); - } - - if (outlookList.size() <= 1) { - // only one "AREA" or NIL report - ConvSigmetSection outlook = ConvSigmetParser - .processOutLook(segment, region, headers); - record.addConvSigmetSection(outlook); - } else { - /* - * Here are more than one outlook areas Store the - * header section and remove it from the outlook - * list - */ - String outlookHeader = outlookList.get(0); - outlookList.remove(outlookHeader); - // process multiple outlook sections - for (String outlookSection : outlookList) { - outlookSection = outlookHeader.concat("AREA ") - .concat(outlookSection); - ConvSigmetSection outlook = ConvSigmetParser - .processOutLook(outlookSection, region, - headers); - record.addConvSigmetSection(outlook); - } - } - } - } - } catch (Exception e) { - logger.error("Error processing decoded sigmet", e); - record = null; - } - } - - /* - * Return the ConvsigmetRecord record object. - */ - if (record == null) { - return new PluginDataObject[0]; - } else { - return new PluginDataObject[] { record }; - } - - } - -} +/** + * + * Convective Sigmet Decoder + * + * This java class decodes CONVSIGMET (convective sigmet) raw data. + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 03/2009 87/114 L. Lin Initial coding + * 06/2009 87/114 L. Lin Increase size of locationLine and location + * and generalize method "processLocation". + * 07/2009 87/114 L. Lin Migration to TO11 + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder; + +import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetRecord; +import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetSection; +import gov.noaa.nws.ncep.edex.plugin.convsigmet.util.ConvSigmetParser; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Scanner; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.exception.DecoderException; +import com.raytheon.edex.plugin.AbstractDecoder; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; + +public class ConvSigmetDecoder extends AbstractDecoder { + + private final String pluginName; + + /** + * Constructor + * + * @throws DecoderException + */ + public ConvSigmetDecoder(String name) throws DecoderException { + pluginName = name; + } + + public PluginDataObject[] decode(byte[] data, Headers headers) + throws DecoderException { + + String traceId = ""; + if (headers != null) { + traceId = (String) headers.get("traceId"); + } + + String sectionDelim = "OUTLOOK|CONVECTIVE"; + String etx = IDecoderConstants.ETX; + String theBulletin = null; + + String region = null; + Calendar startTime = null; + byte[] messageData = null; + + ConvSigmetRecord record = null; + + ConvSigmetSeparator sep = ConvSigmetSeparator.separate(data, headers); + messageData = sep.next(); + String theMessage = new String(messageData); + + /* + * May have multiple duplicate bulletins, only get the first bulletin + * and eliminate the remaining bulletins after the first bulletin. + */ + Scanner cc = new Scanner(theMessage).useDelimiter(etx); + if (cc.hasNext()) { + theBulletin = cc.next(); + } else { + theBulletin = theMessage; + } + + // record = new ConvsigmetRecord(); + // Decode and set WMO line + record = ConvSigmetParser.processWMO(theBulletin, headers); + + // Decode the forecast region such as: W, C, or E + region = ConvSigmetParser.processFcstRegion(theBulletin); + String forecastRegion = "SIG".concat(region); + + /* + * Check the Convsigmet record object. If not, throws exception. + */ + if (record != null) { + record.setTraceId(traceId); + record.setPluginName(pluginName); + record.setReportType(pluginName); + record.setForecastRegion(forecastRegion); + try { + record.constructDataURI(); + } catch (PluginException e) { + logger.error("Error constructing dataURI", e); + record = null; + } + } + + if (record != null) { + try { + // Replace special characters to a blank so that it may be + // readable + record.setBullMessage(UtilN + .removeLeadingWhiteSpaces((theBulletin.substring(5)) + .replace('\036', ' ').replace('\r', ' ') + .replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' '))); + + // Decode the starting time + startTime = ConvSigmetParser.processStartTime(theBulletin, + headers); + + // Decode the correction flag and set + Boolean correctionFlag = ConvSigmetParser + .processCorrectionFlag(theBulletin); + Integer correction = 0; + if (correctionFlag) { + correction = 1; + } + record.setCorrectionFlag(correction); + + /* + * Break the bulletin message into sections by a "OUTLOOK" or + * "CONVECTIVE". + */ + Scanner sc = new Scanner(theBulletin) + .useDelimiter(sectionDelim); + + ArrayList segmentList = new ArrayList(); + segmentList.clear(); + while (sc.hasNext()) { + String segment = sc.next(); + segmentList.add(segment); + } + + Calendar issueTime = record.getIssueTime(); + /* + * process each section in a order of section and location line + */ + for (String segment : segmentList) { + + // starts a new section + Scanner sc2 = new Scanner(segment); + String whatSection = sc2.next(); + if (whatSection.equals("SIGMET") + || whatSection.equals("SIGMET...NONE")) { + segment = "CONVECTIVE".concat(segment); + + // process this section which starts with + // "CONVECTIVE SIGMET". + ConvSigmetSection section = ConvSigmetParser + .processSection(segment, issueTime, startTime, + region, headers); + record.addConvSigmetSection(section); + } else if (whatSection.equals("VALID")) { + segment = "OUTLOOK".concat(segment); + + // process this section which starts with + // "OUTLOOK VALID". + Scanner scOutlook = new Scanner(segment) + .useDelimiter("AREA "); + ArrayList outlookList = new ArrayList(); + outlookList.clear(); + + // Check if "OUTLOOK" section contains more than one + // "AREA". + while (scOutlook.hasNext()) { + String outlookSegment = scOutlook.next(); + outlookList.add(outlookSegment); + } + + if (outlookList.size() <= 1) { + // only one "AREA" or NIL report + ConvSigmetSection outlook = ConvSigmetParser + .processOutLook(segment, region, headers); + record.addConvSigmetSection(outlook); + } else { + /* + * Here are more than one outlook areas Store the + * header section and remove it from the outlook + * list + */ + String outlookHeader = outlookList.get(0); + outlookList.remove(outlookHeader); + // process multiple outlook sections + for (String outlookSection : outlookList) { + outlookSection = outlookHeader.concat("AREA ") + .concat(outlookSection); + ConvSigmetSection outlook = ConvSigmetParser + .processOutLook(outlookSection, region, + headers); + record.addConvSigmetSection(outlook); + } + } + } + } + } catch (Exception e) { + logger.error("Error processing decoded sigmet", e); + record = null; + } + } + + /* + * Return the ConvsigmetRecord record object. + */ + if (record == null) { + return new PluginDataObject[0]; + } else { + return new PluginDataObject[] { record }; + } + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetSeparator.java old mode 100755 new mode 100644 index da0b868bd5..507e9f59cc --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/ConvSigmetSeparator.java @@ -1,145 +1,145 @@ -/** - * ConvsigmetSeparator - * - * This class sets the raw data to an Arraylist, records, of - * String based on a uniquely identified separator. - * - *
- * L. Lin                               03/2009         Creation
- * 
- * - * This code has been developed by the SIB for use in the AWIPS system. - */ - -package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.plugin.AbstractRecordSeparator; -import com.raytheon.edex.util.Util; - -public class ConvSigmetSeparator extends AbstractRecordSeparator { - private final Log logger = LogFactory.getLog(getClass()); - - /** Regex used for separate the bulletins */ - private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; - - /** Regex matcher */ - private Matcher matcher; - - /** Pattern object for regex search */ - private Pattern pattern; - - /** List of records contained in file */ - private List records; - - private Iterator iterator = null; - - /** - * Constructor. - * - */ - public ConvSigmetSeparator() { - records = new ArrayList(); - } - - public static ConvSigmetSeparator separate(byte[] data, Headers headers) { - ConvSigmetSeparator ds = new ConvSigmetSeparator(); - ds.setData(data, headers); - return ds; - } - - public void setData(byte[] data, Headers headers) { - doSeparate(new String(data)); - iterator = records.iterator(); - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() - */ - public boolean hasNext() { - if (iterator == null) { - return false; - } else { - return iterator.hasNext(); - } - } - - /** - * Get record - */ - public byte[] next() { - try { - String temp = iterator.next(); - if (Util.isEmptyString(temp)) { - return (byte[]) null; - } else { - return temp.getBytes(); - } - } catch (NoSuchElementException e) { - return (byte[]) null; - } - } - - /** - * @param message - * separate bulletins - */ - private void doSeparate(String message) { - /* Regex used for separate the bulletins */ - - try { - pattern = Pattern.compile(BULLSEPARATOR); - matcher = pattern.matcher(message); - - /* - * Set number of bulletins to records only if the bulletin separator - * is not the same. At the point, only separators are stored in - * "records" - */ - while (matcher.find()) { - if (!records.contains(matcher.group())) { - records.add(matcher.group()); - } - } - - /* - * Append the raw data file to the records. - */ - for (int i = 0; i < records.size(); i++) { - if (i < records.size() - 1) { - records.set( - i, - "\n" - + message.substring( - message.indexOf(records.get(i)), - message.indexOf(records.get(i + 1)))); - } else { - records.set( - i, - "\n" - + message.substring(message.indexOf(records - .get(i)))); - } - } - } catch (Exception e) { - e.printStackTrace(); - if (logger.isInfoEnabled()) { - logger.info("No valid records found!"); - } - logger.warn("No valid records found!"); - } - return; - } -} +/** + * ConvsigmetSeparator + * + * This class sets the raw data to an Arraylist, records, of + * String based on a uniquely identified separator. + * + *
+ * L. Lin                               03/2009         Creation
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS system. + */ + +package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.plugin.AbstractRecordSeparator; +import com.raytheon.edex.util.Util; + +public class ConvSigmetSeparator extends AbstractRecordSeparator { + private final Log logger = LogFactory.getLog(getClass()); + + /** Regex used for separate the bulletins */ + private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; + + /** Regex matcher */ + private Matcher matcher; + + /** Pattern object for regex search */ + private Pattern pattern; + + /** List of records contained in file */ + private List records; + + private Iterator iterator = null; + + /** + * Constructor. + * + */ + public ConvSigmetSeparator() { + records = new ArrayList(); + } + + public static ConvSigmetSeparator separate(byte[] data, Headers headers) { + ConvSigmetSeparator ds = new ConvSigmetSeparator(); + ds.setData(data, headers); + return ds; + } + + public void setData(byte[] data, Headers headers) { + doSeparate(new String(data)); + iterator = records.iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() + */ + public boolean hasNext() { + if (iterator == null) { + return false; + } else { + return iterator.hasNext(); + } + } + + /** + * Get record + */ + public byte[] next() { + try { + String temp = iterator.next(); + if (Util.isEmptyString(temp)) { + return (byte[]) null; + } else { + return temp.getBytes(); + } + } catch (NoSuchElementException e) { + return (byte[]) null; + } + } + + /** + * @param message + * separate bulletins + */ + private void doSeparate(String message) { + /* Regex used for separate the bulletins */ + + try { + pattern = Pattern.compile(BULLSEPARATOR); + matcher = pattern.matcher(message); + + /* + * Set number of bulletins to records only if the bulletin separator + * is not the same. At the point, only separators are stored in + * "records" + */ + while (matcher.find()) { + if (!records.contains(matcher.group())) { + records.add(matcher.group()); + } + } + + /* + * Append the raw data file to the records. + */ + for (int i = 0; i < records.size(); i++) { + if (i < records.size() - 1) { + records.set( + i, + "\n" + + message.substring( + message.indexOf(records.get(i)), + message.indexOf(records.get(i + 1)))); + } else { + records.set( + i, + "\n" + + message.substring(message.indexOf(records + .get(i)))); + } + } + } catch (Exception e) { + e.printStackTrace(); + if (logger.isInfoEnabled()) { + logger.info("No valid records found!"); + } + logger.warn("No valid records found!"); + } + return; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/package-info.java old mode 100755 new mode 100644 index 219fe9e5e6..428689393c --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains decoder.java for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder;; +/** +* Contains decoder.java for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.convsigmet.decoder;; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/ConvSigmetParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/ConvSigmetParser.java old mode 100755 new mode 100644 index 7f8718ae55..460c05d833 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/ConvSigmetParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/ConvSigmetParser.java @@ -1,644 +1,644 @@ -/** - * Convsigmet DecoderUtil - * - * This java class intends to serve as a decoder utility for Convsigmet. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 03/2009 87/114 L. Lin Initial coding - * 06/2009 87/114 L. Lin Generalize the method processLocation. - * 07/2009 87/114 L. Lin Migration to TO11 - * 09/2009 87/114 L. Lin Add latitude/longitude to location table - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.convsigmet.util; - -import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetLocation; -import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetRecord; -import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetSection; -import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.edex.decodertools.core.LatLonPoint; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class ConvSigmetParser { - - /** - * Constructor - */ - public ConvSigmetParser() { - } - - /** - * Parse the WMO line and store WMO header, OfficeID, issue time, - * designatorBBB,... - * - * @param wmoline - * The bulletin message - * - * @return a ConvsigmetRecord - */ - public static ConvSigmetRecord processWMO(String wmoline, Headers headers) { - - ConvSigmetRecord record = null; - // Regular expression for WMO/ICAO, station ID, and issue date (and - // maybe designator BBB) - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; - - // Pattern used for extracting WMO header, officeID, product purge time, - // and issue date and designatorBBB - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(wmoline); - - if (theMatcher.find()) { - record = new ConvSigmetRecord(); - - record.setWmoHeader(theMatcher.group(1)); - record.setIssueOffice(theMatcher.group(2)); - record.setDesignatorBBB(theMatcher.group(5)); - - // Decode the issue time. - Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), - headers); - record.setIssueTime(issueTime); - - DataTime dataTime = new DataTime(issueTime); - record.setDataTime(dataTime); - } - return record; - } - - /** - * Obtains forecast region as: SIGW, SIGC, or SIGE from a report - * - * @param bullMessage - * The bulletin message - * @return a string for forecast region - */ - public static String processFcstRegion(String bullMessage) { - - // Regular expression for "SIG" forecast region - final String FCSTREGION_EXP = "SIG([A-Z]{1}) ( )*"; - - // Pattern used for extracting forecast region - final Pattern fcstregionPattern = Pattern.compile(FCSTREGION_EXP); - Matcher theMatcher = fcstregionPattern.matcher(bullMessage); - - if (theMatcher.find()) { - return theMatcher.group(1); - } else { - return " "; - } - } - - /** - * process regular section of a convective sigmet report - * - * @param theSection - * The section lines from bulletin message - * @param issueTime - * The bulletin issue time - * @param startTime - * The start time for this section - * @param forecastRegion - * as "W", "C", or "E" - * @return a ConvsigmetSection table - */ - public static ConvSigmetSection processSection(String theSection, - Calendar issueTime, Calendar startTime, String forecastRegion, - Headers headers) { - - // Default equal to one hour if there is no valid time in report - final int validPeriod = 1; - - // Decode the phenomena description - ConvSigmetSection currentSection = ConvSigmetParser - .processPhenomena(theSection); - - // Replace the special characters - currentSection.setSegment(theSection.replace('\r', ' ') - .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' ')); - - // Decode the locations - ConvSigmetParser.processLocation(theSection, currentSection); - - // Decode the sequence ID - String sequenceID = ConvSigmetParser.processSequenceID(theSection); - if (sequenceID.equals(" ")) { - // Default as: 0W, 0C, or 0E if no sequenceID has been found. - sequenceID = "0".concat(forecastRegion); - } - currentSection.setSequenceID(sequenceID); - - // Set the starting time - if (startTime == null) { - currentSection.setStartTime(issueTime); - } else { - currentSection.setStartTime(startTime); - } - - // Decode the end time - Calendar endTime = ConvSigmetParser.processEndTime(theSection, - currentSection, headers); - if (endTime == null) { - /* - * if no end time available, end time will be the issue time plus a - * valid period; the default is one hour for now. - */ - endTime = TimeTools.copy(issueTime); - endTime.add(Calendar.HOUR, validPeriod); - currentSection.setEndTime(endTime); - } else { - currentSection.setEndTime(endTime); - } - - int startMonth = startTime.get(Calendar.MONTH); - int endMonth = endTime.get(Calendar.MONTH); - int startDay = startTime.get(Calendar.DAY_OF_MONTH); - int endDay = endTime.get(Calendar.DAY_OF_MONTH); - if ((startMonth == endMonth) && (startDay > endDay)) { - // In case the end time needs to advance one month - endTime.add(Calendar.MONTH, 1); - } - - return currentSection; - } - - /** - * process the outlook section of a convective sigmet report. - * - * @param theOutlook - * The outlook section lines from bulletin message - * @param forecastRegion - * as "W", "C", or "E" - * @return a ConvsigmetSection table - */ - public static ConvSigmetSection processOutLook(String theOutlook, - String forecastRegion, Headers headers) { - - ConvSigmetSection currentOutLook = new ConvSigmetSection(); - - currentOutLook.setSegment(theOutlook.replace('\r', ' ') - .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' ')); - currentOutLook.setClassType("OUTLOOK"); - - // Decode start time and end time - ConvSigmetParser.processValidTime(theOutlook, currentOutLook, headers); - - // Decode locations - if (ConvSigmetParser.processLocation(theOutlook, currentOutLook)) { - final String SID_EXP = "AREA ([0-9]{1})...FROM"; - - // Pattern used for extracting the number of sequence ID. - final Pattern sidPattern = Pattern.compile(SID_EXP); - - Matcher theMatcher = sidPattern.matcher(theOutlook); - - // Default sequenceID as: 1W, 1C, or 1E if locations have been - // found. - String sequenceID = "1".concat(forecastRegion); - if (theMatcher.find()) { - // Multiple areas such as: "AREA 1", "AREA 2", ...etc - sequenceID = theMatcher.group(1).concat(forecastRegion); - } - currentOutLook.setSequenceID(sequenceID); - } else { - // Default sequenceID as: 0W, 0C, or 0E if outlook section is a NIL - // report. - String sequenceID = "0".concat(forecastRegion); - currentOutLook.setSequenceID(sequenceID); - } - - return currentOutLook; - } - - /** - * Obtains start time from input report - * - * @param theSection - * The bulletin message - * @return a calendar for start time - */ - public static Calendar processStartTime(String theSection, Headers headers) { - - // Regular expression for start time - final String STARTTIME_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{3}) ([0-9]{6})( [A-Z]{3})?"; - - // attern used for extracting the starting time - final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); - - // Calendar mndTime = Calendar.getInstance(); - - Matcher theMatcher = starttimePattern.matcher(theSection); - - if (theMatcher.find()) { - // Get start time - Calendar mndTime = null; - return TimeTools.findDataTime(theMatcher.group(4), headers); - } else { - return null; - } - } - - /** - * Obtains correction flag - * - * @param theSection - * The bulletin message - * @return true if finds a correction flag - */ - public static Boolean processCorrectionFlag(String theSection) { - - Boolean correctionFlag = false; - - // Regular expression for the correction flag - final String CORFLAG_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{3}) ([0-9]{6})( [A-Z]{3})?"; - - // Pattern used for extracting the correction flag - final Pattern corflagPattern = Pattern.compile(CORFLAG_EXP); - - Matcher theMatcher = corflagPattern.matcher(theSection); - - if (theMatcher.find()) { - Scanner scCorrection = new Scanner(theMatcher.group(0)); - - // check if this contains a correction flag - while (scCorrection.hasNext()) { - if (scCorrection.next().equals("COR")) { - correctionFlag = true; - } - } - - } - return correctionFlag; - } - - /** - * Obtains the sequence ID - * - * @param inSegment - * The segment which contains this sequence ID - * @return a string for sequence ID - */ - public static String processSequenceID(String inSegment) { - - // Regular expression for the sequence ID - final String SEQUENCEID_EXP = "CONVECTIVE SIGMET (([0-9]{2}|[0-9]{1})[A-Z]{1})"; - - // Pattern used for extracting the sequence ID - final Pattern sequenceidPattern = Pattern.compile(SEQUENCEID_EXP); - Matcher theMatcher = sequenceidPattern.matcher(inSegment); - - if (theMatcher.find()) { - return theMatcher.group(1); - } else { - return " "; - } - } - - /** - * Get the end time - * - * @param theSegment - * The segment which contains end time - * @param section - * The section table which contains the start time - * @return a calendar for end time - */ - public static Calendar processEndTime(String theSegment, - ConvSigmetSection section, Headers headers) { - - // Regular expression for end time - final String ENDTIME_EXP = "VALID UNTIL ([0-9]{4})Z"; - - // Pattern used for extracting the end time - final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); - - // Calendar mndTime = Calendar.getInstance(); - - Matcher theMatcher = endtimePattern.matcher(theSegment); - - if (theMatcher.find()) { - Calendar startTime = section.getStartTime(); - String endTimeGroup = Integer.toString( - startTime.get(Calendar.DAY_OF_MONTH)).concat( - theMatcher.group(1)); - if (startTime.get(Calendar.DAY_OF_MONTH) < 10) { - // add a "0" if the day of month less than 10 - endTimeGroup = "0".concat(endTimeGroup); - } - // get the end time. - return TimeTools.findDataTime(endTimeGroup, headers); - } else { - return null; - } - } - - /** - * Parse the phenomena... - * - * @param theFlight - * The flight level line - * @return a section record - */ - public static ConvSigmetSection processPhenomena(String theFlight) { - - String classType = null; - - // Regular expression for the flight line - final String FL_EXP = "((DMSHG|DSIPTG|INTSFYG|DVLPG) )?(LINE|AREA|ISOL)(\\S|\\s)*FROM ([0-9]{3})?([0-9]{2})KT. ((TOP|TOPS) (TO|ABV)) FL([0-9]{3})"; - - // Pattern used for extracting the direction, speed, distance, and - // flight level - final Pattern flPattern = Pattern.compile(FL_EXP); - Matcher theMatcher = flPattern.matcher(theFlight); - - // Regular expression for the classType line - final String CLASS_EXP = "((DMSHG|DSIPTG|INTSFYG|DVLPG) )?(LINE|AREA|ISOL)(\\S|\\s)*((TOP|TOPS) (TO|ABV)) FL([0-9]{3})"; - - // Pattern used for extracting the class type and flight level - final Pattern classPattern = Pattern.compile(CLASS_EXP); - Matcher classMatcher = classPattern.matcher(theFlight); - - ConvSigmetSection currentSection = new ConvSigmetSection(); - - if (theMatcher.find()) { - classType = theMatcher.group(3); - - int direction = Integer.parseInt(theMatcher.group(5)); - int speed = Integer.parseInt(theMatcher.group(6)); - int flightLevel = Integer.parseInt(theMatcher.group(10)); - String flightLevelTop = theMatcher.group(7); - String intensity = theMatcher.group(1); - - currentSection.setFlightLevel(flightLevel); - currentSection.setDirection(direction); - currentSection.setSpeed(speed); - currentSection.setClassType(classType); - currentSection.setIntensity(intensity); - currentSection.setCloudTop(flightLevelTop); - - if (classType.equals("LINE")) { - final String DISTANCE_EXP = "LINE (EMBD )?(SEV )?TS ([0-9]{2})"; - final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); - Matcher disMatcher = distancePattern.matcher(theFlight); - if (disMatcher.find()) { - int distance = Integer.parseInt(disMatcher.group(3)); - currentSection.setDistance(distance); - } - } else if (classType.equals("ISOL")) { - final String ISOLDISTANCE_EXP = "ISOL (\\S|\\s)* TS D([0-9]{2})"; - final Pattern isoldistancePattern = Pattern - .compile(ISOLDISTANCE_EXP); - Matcher isoldisMatcher = isoldistancePattern.matcher(theFlight); - if (isoldisMatcher.find()) { - int distance = Integer.parseInt(isoldisMatcher.group(2)); - currentSection.setDistance(distance); - } - // get ISOL location table - getIsolLocation(theFlight, currentSection); - } - - } else if (classMatcher.find()) { - classType = classMatcher.group(3); - - int flightLevel = Integer.parseInt(classMatcher.group(8)); - String flightLevelTop = classMatcher.group(5); - String intensity = classMatcher.group(1); - - currentSection.setFlightLevel(flightLevel); - currentSection.setClassType(classType); - currentSection.setIntensity(intensity); - currentSection.setCloudTop(flightLevelTop); - - if (classType.equals("LINE")) { - final String DISTANCE_EXP = "LINE (EMBD )?(SEV )?TS ([0-9]{2})"; - final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); - Matcher disMatcher = distancePattern.matcher(theFlight); - if (disMatcher.find()) { - int distance = Integer.parseInt(disMatcher.group(3)); - currentSection.setDistance(distance); - } - } else if (classType.equals("ISOL")) { - final String ISOLDISTANCE_EXP = "ISOL (\\S|\\s)* TS D([0-9]{2})"; - final Pattern isoldistancePattern = Pattern - .compile(ISOLDISTANCE_EXP); - Matcher isoldisMatcher = isoldistancePattern.matcher(theFlight); - if (isoldisMatcher.find()) { - int distance = Integer.parseInt(isoldisMatcher.group(2)); - currentSection.setDistance(distance); - } - // get ISOL location table - getIsolLocation(theFlight, currentSection); - } - - } else { - // Finds no "flight level line", "CS" as default for a NIL report. - currentSection.setClassType("CS"); - currentSection.setIntensity(null); - } - - return currentSection; - } - - /** - * Obtains the start time and end time - * - * @param theSection - * The outlook section contains the valid times group - */ - public static void processValidTime(String theSection, - ConvSigmetSection currentOutLook, Headers headers) { - - // Regular expression for start time - final String TIMES_EXP = "OUTLOOK VALID ([0-9]{6})-([0-9]{6})"; - - // Pattern used for extracting the starting time and end time - final Pattern starttimePattern = Pattern.compile(TIMES_EXP); - - Calendar startTime = null; - Calendar endTime = null; - // Calendar mndTime = Calendar.getInstance(); - - Matcher theMatcher = starttimePattern.matcher(theSection); - - if (theMatcher.find()) { - // Decode the start time and end time; then set them. - startTime = TimeTools.findDataTime(theMatcher.group(1), headers); - currentOutLook.setStartTime(startTime); - endTime = TimeTools.findDataTime(theMatcher.group(2), headers); - - int startMonth = startTime.get(Calendar.MONTH); - int endMonth = endTime.get(Calendar.MONTH); - int startDay = startTime.get(Calendar.DAY_OF_MONTH); - int endDay = endTime.get(Calendar.DAY_OF_MONTH); - - if ((startMonth == endMonth) && (startDay > endDay)) { - // Roll over a month - endTime.add(Calendar.MONTH, 1); - } - - currentOutLook.setEndTime(endTime); - } else { - currentOutLook.setStartTime(startTime); - currentOutLook.setEndTime(endTime); - } - - } - - /** - * Obtains the location information for ISOL. - * - * @param theSection - * The section lines from bulletin message - * @param sectionTable - * The section Table - */ - public static void getIsolLocation(String theSection, - ConvSigmetSection sectionTable) { - - String line = null; - LatLonPoint point = null; - - final String ISOLLOCATION_EXP = "\\x0d\\x0d\\x0a(([0-9]{2}|[0-9]{3})([ENSW])* [A-Z]{3})\\x0d\\x0d\\x0a"; - final Pattern isollocationPattern = Pattern.compile(ISOLLOCATION_EXP); - Matcher isollocMatcher = isollocationPattern.matcher(theSection); - if (isollocMatcher.find()) { - line = isollocMatcher.group(1); - } - - if (line != null) { - ConvSigmetLocation currentLocation = new ConvSigmetLocation(); - currentLocation.setLocationLine(line); - currentLocation.setLocation(line); - currentLocation.setIndex(1); - // Get a latLonPoint for this station ID from "vors" location table - point = LatLonLocTbl.getLatLonPoint(line, "vors"); - currentLocation.setLatitude(point - .getLatitude(LatLonPoint.INDEGREES)); - currentLocation.setLongitude(point - .getLongitude(LatLonPoint.INDEGREES)); - sectionTable.addConvSigmetLocation(currentLocation); - } - } - - /** - * Parse the location lines and add location table to the section table if - * any - * - * @param theSection - * The section lines from bulletin message - * @param sectionTable - * The section Table - * @return true if finds a location line - */ - public static Boolean processLocation(String theSection, - ConvSigmetSection sectionTable) { - - Boolean hasLocationLine = true; - String locationDelimiter = "-"; - - ArrayList terminationList = new ArrayList(); - terminationList.addAll(Arrays - .asList(new String[] { "WST", "REF", "LINE", "AREA", "ISOL", - "DMSHG", "DVLPG", "DSIPTG", "INTSFYG" })); - - LatLonPoint point = null; - - Scanner sclocations = new Scanner(theSection).useDelimiter("FROM"); - - // throws away the first section which is not the "FROM" location - String locationSection = sclocations.next(); - - if (sclocations.hasNext()) { - locationSection = sclocations.next(); - - Scanner scLocationLine = new Scanner(locationSection) - .useDelimiter("\\x0d\\x0d\\x0a"); - String lines = " "; - String curLine = null; - ArrayList locationList = new ArrayList(); - locationList.clear(); - Boolean notBreak = true; - - while (scLocationLine.hasNext() && notBreak) { - // Get next location line - curLine = scLocationLine.next(); - - Scanner scLocationToken = new Scanner(curLine); - if (scLocationToken.hasNext()) { - // Check the first token from each line - String firstToken = scLocationToken.next(); - if (terminationList.contains(firstToken)) { - // terminate - notBreak = false; - break; - } - } - lines = lines.concat(" ").concat(curLine); - } - - // Clean up the leading space - lines = UtilN.removeLeadingWhiteSpaces(lines); - // Parse the location lines by a "-" - Scanner scLocation = new Scanner(lines) - .useDelimiter(locationDelimiter); - locationList.clear(); - // Get all locations - while (scLocation.hasNext()) { - locationList.add(scLocation.next()); - } - - // set locations to data base - if (locationList.size() > 1) { - Integer idxLocation = 0; - for (String Location : locationList) { - - ConvSigmetLocation currentLocation = new ConvSigmetLocation(); - currentLocation.setLocationLine(lines); - currentLocation.setLocation(Location); - - // Get a latLonPoint for this station ID from "vors" - // location table - point = LatLonLocTbl.getLatLonPoint(Location, "vors"); - currentLocation.setLatitude(point - .getLatitude(LatLonPoint.INDEGREES)); - currentLocation.setLongitude(point - .getLongitude(LatLonPoint.INDEGREES)); - - currentLocation.setIndex(idxLocation + 1); - idxLocation++; - - sectionTable.addConvSigmetLocation(currentLocation); - } - } else { - hasLocationLine = false; - } - - } else { - hasLocationLine = false; - } - - return hasLocationLine; - } - -} +/** + * Convsigmet DecoderUtil + * + * This java class intends to serve as a decoder utility for Convsigmet. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 03/2009 87/114 L. Lin Initial coding + * 06/2009 87/114 L. Lin Generalize the method processLocation. + * 07/2009 87/114 L. Lin Migration to TO11 + * 09/2009 87/114 L. Lin Add latitude/longitude to location table + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.convsigmet.util; + +import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetLocation; +import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetRecord; +import gov.noaa.nws.ncep.common.dataplugin.convsigmet.ConvSigmetSection; +import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class ConvSigmetParser { + + /** + * Constructor + */ + public ConvSigmetParser() { + } + + /** + * Parse the WMO line and store WMO header, OfficeID, issue time, + * designatorBBB,... + * + * @param wmoline + * The bulletin message + * + * @return a ConvsigmetRecord + */ + public static ConvSigmetRecord processWMO(String wmoline, Headers headers) { + + ConvSigmetRecord record = null; + // Regular expression for WMO/ICAO, station ID, and issue date (and + // maybe designator BBB) + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; + + // Pattern used for extracting WMO header, officeID, product purge time, + // and issue date and designatorBBB + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(wmoline); + + if (theMatcher.find()) { + record = new ConvSigmetRecord(); + + record.setWmoHeader(theMatcher.group(1)); + record.setIssueOffice(theMatcher.group(2)); + record.setDesignatorBBB(theMatcher.group(5)); + + // Decode the issue time. + Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), + headers); + record.setIssueTime(issueTime); + + DataTime dataTime = new DataTime(issueTime); + record.setDataTime(dataTime); + } + return record; + } + + /** + * Obtains forecast region as: SIGW, SIGC, or SIGE from a report + * + * @param bullMessage + * The bulletin message + * @return a string for forecast region + */ + public static String processFcstRegion(String bullMessage) { + + // Regular expression for "SIG" forecast region + final String FCSTREGION_EXP = "SIG([A-Z]{1}) ( )*"; + + // Pattern used for extracting forecast region + final Pattern fcstregionPattern = Pattern.compile(FCSTREGION_EXP); + Matcher theMatcher = fcstregionPattern.matcher(bullMessage); + + if (theMatcher.find()) { + return theMatcher.group(1); + } else { + return " "; + } + } + + /** + * process regular section of a convective sigmet report + * + * @param theSection + * The section lines from bulletin message + * @param issueTime + * The bulletin issue time + * @param startTime + * The start time for this section + * @param forecastRegion + * as "W", "C", or "E" + * @return a ConvsigmetSection table + */ + public static ConvSigmetSection processSection(String theSection, + Calendar issueTime, Calendar startTime, String forecastRegion, + Headers headers) { + + // Default equal to one hour if there is no valid time in report + final int validPeriod = 1; + + // Decode the phenomena description + ConvSigmetSection currentSection = ConvSigmetParser + .processPhenomena(theSection); + + // Replace the special characters + currentSection.setSegment(theSection.replace('\r', ' ') + .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' ')); + + // Decode the locations + ConvSigmetParser.processLocation(theSection, currentSection); + + // Decode the sequence ID + String sequenceID = ConvSigmetParser.processSequenceID(theSection); + if (sequenceID.equals(" ")) { + // Default as: 0W, 0C, or 0E if no sequenceID has been found. + sequenceID = "0".concat(forecastRegion); + } + currentSection.setSequenceID(sequenceID); + + // Set the starting time + if (startTime == null) { + currentSection.setStartTime(issueTime); + } else { + currentSection.setStartTime(startTime); + } + + // Decode the end time + Calendar endTime = ConvSigmetParser.processEndTime(theSection, + currentSection, headers); + if (endTime == null) { + /* + * if no end time available, end time will be the issue time plus a + * valid period; the default is one hour for now. + */ + endTime = TimeTools.copy(issueTime); + endTime.add(Calendar.HOUR, validPeriod); + currentSection.setEndTime(endTime); + } else { + currentSection.setEndTime(endTime); + } + + int startMonth = startTime.get(Calendar.MONTH); + int endMonth = endTime.get(Calendar.MONTH); + int startDay = startTime.get(Calendar.DAY_OF_MONTH); + int endDay = endTime.get(Calendar.DAY_OF_MONTH); + if ((startMonth == endMonth) && (startDay > endDay)) { + // In case the end time needs to advance one month + endTime.add(Calendar.MONTH, 1); + } + + return currentSection; + } + + /** + * process the outlook section of a convective sigmet report. + * + * @param theOutlook + * The outlook section lines from bulletin message + * @param forecastRegion + * as "W", "C", or "E" + * @return a ConvsigmetSection table + */ + public static ConvSigmetSection processOutLook(String theOutlook, + String forecastRegion, Headers headers) { + + ConvSigmetSection currentOutLook = new ConvSigmetSection(); + + currentOutLook.setSegment(theOutlook.replace('\r', ' ') + .replace('\036', ' ').replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' ')); + currentOutLook.setClassType("OUTLOOK"); + + // Decode start time and end time + ConvSigmetParser.processValidTime(theOutlook, currentOutLook, headers); + + // Decode locations + if (ConvSigmetParser.processLocation(theOutlook, currentOutLook)) { + final String SID_EXP = "AREA ([0-9]{1})...FROM"; + + // Pattern used for extracting the number of sequence ID. + final Pattern sidPattern = Pattern.compile(SID_EXP); + + Matcher theMatcher = sidPattern.matcher(theOutlook); + + // Default sequenceID as: 1W, 1C, or 1E if locations have been + // found. + String sequenceID = "1".concat(forecastRegion); + if (theMatcher.find()) { + // Multiple areas such as: "AREA 1", "AREA 2", ...etc + sequenceID = theMatcher.group(1).concat(forecastRegion); + } + currentOutLook.setSequenceID(sequenceID); + } else { + // Default sequenceID as: 0W, 0C, or 0E if outlook section is a NIL + // report. + String sequenceID = "0".concat(forecastRegion); + currentOutLook.setSequenceID(sequenceID); + } + + return currentOutLook; + } + + /** + * Obtains start time from input report + * + * @param theSection + * The bulletin message + * @return a calendar for start time + */ + public static Calendar processStartTime(String theSection, Headers headers) { + + // Regular expression for start time + final String STARTTIME_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{3}) ([0-9]{6})( [A-Z]{3})?"; + + // attern used for extracting the starting time + final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); + + // Calendar mndTime = Calendar.getInstance(); + + Matcher theMatcher = starttimePattern.matcher(theSection); + + if (theMatcher.find()) { + // Get start time + Calendar mndTime = null; + return TimeTools.findDataTime(theMatcher.group(4), headers); + } else { + return null; + } + } + + /** + * Obtains correction flag + * + * @param theSection + * The bulletin message + * @return true if finds a correction flag + */ + public static Boolean processCorrectionFlag(String theSection) { + + Boolean correctionFlag = false; + + // Regular expression for the correction flag + final String CORFLAG_EXP = "(\\x1e)([A-Z]{4}) ([A-Z]{3}) ([0-9]{6})( [A-Z]{3})?"; + + // Pattern used for extracting the correction flag + final Pattern corflagPattern = Pattern.compile(CORFLAG_EXP); + + Matcher theMatcher = corflagPattern.matcher(theSection); + + if (theMatcher.find()) { + Scanner scCorrection = new Scanner(theMatcher.group(0)); + + // check if this contains a correction flag + while (scCorrection.hasNext()) { + if (scCorrection.next().equals("COR")) { + correctionFlag = true; + } + } + + } + return correctionFlag; + } + + /** + * Obtains the sequence ID + * + * @param inSegment + * The segment which contains this sequence ID + * @return a string for sequence ID + */ + public static String processSequenceID(String inSegment) { + + // Regular expression for the sequence ID + final String SEQUENCEID_EXP = "CONVECTIVE SIGMET (([0-9]{2}|[0-9]{1})[A-Z]{1})"; + + // Pattern used for extracting the sequence ID + final Pattern sequenceidPattern = Pattern.compile(SEQUENCEID_EXP); + Matcher theMatcher = sequenceidPattern.matcher(inSegment); + + if (theMatcher.find()) { + return theMatcher.group(1); + } else { + return " "; + } + } + + /** + * Get the end time + * + * @param theSegment + * The segment which contains end time + * @param section + * The section table which contains the start time + * @return a calendar for end time + */ + public static Calendar processEndTime(String theSegment, + ConvSigmetSection section, Headers headers) { + + // Regular expression for end time + final String ENDTIME_EXP = "VALID UNTIL ([0-9]{4})Z"; + + // Pattern used for extracting the end time + final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); + + // Calendar mndTime = Calendar.getInstance(); + + Matcher theMatcher = endtimePattern.matcher(theSegment); + + if (theMatcher.find()) { + Calendar startTime = section.getStartTime(); + String endTimeGroup = Integer.toString( + startTime.get(Calendar.DAY_OF_MONTH)).concat( + theMatcher.group(1)); + if (startTime.get(Calendar.DAY_OF_MONTH) < 10) { + // add a "0" if the day of month less than 10 + endTimeGroup = "0".concat(endTimeGroup); + } + // get the end time. + return TimeTools.findDataTime(endTimeGroup, headers); + } else { + return null; + } + } + + /** + * Parse the phenomena... + * + * @param theFlight + * The flight level line + * @return a section record + */ + public static ConvSigmetSection processPhenomena(String theFlight) { + + String classType = null; + + // Regular expression for the flight line + final String FL_EXP = "((DMSHG|DSIPTG|INTSFYG|DVLPG) )?(LINE|AREA|ISOL)(\\S|\\s)*FROM ([0-9]{3})?([0-9]{2})KT. ((TOP|TOPS) (TO|ABV)) FL([0-9]{3})"; + + // Pattern used for extracting the direction, speed, distance, and + // flight level + final Pattern flPattern = Pattern.compile(FL_EXP); + Matcher theMatcher = flPattern.matcher(theFlight); + + // Regular expression for the classType line + final String CLASS_EXP = "((DMSHG|DSIPTG|INTSFYG|DVLPG) )?(LINE|AREA|ISOL)(\\S|\\s)*((TOP|TOPS) (TO|ABV)) FL([0-9]{3})"; + + // Pattern used for extracting the class type and flight level + final Pattern classPattern = Pattern.compile(CLASS_EXP); + Matcher classMatcher = classPattern.matcher(theFlight); + + ConvSigmetSection currentSection = new ConvSigmetSection(); + + if (theMatcher.find()) { + classType = theMatcher.group(3); + + int direction = Integer.parseInt(theMatcher.group(5)); + int speed = Integer.parseInt(theMatcher.group(6)); + int flightLevel = Integer.parseInt(theMatcher.group(10)); + String flightLevelTop = theMatcher.group(7); + String intensity = theMatcher.group(1); + + currentSection.setFlightLevel(flightLevel); + currentSection.setDirection(direction); + currentSection.setSpeed(speed); + currentSection.setClassType(classType); + currentSection.setIntensity(intensity); + currentSection.setCloudTop(flightLevelTop); + + if (classType.equals("LINE")) { + final String DISTANCE_EXP = "LINE (EMBD )?(SEV )?TS ([0-9]{2})"; + final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); + Matcher disMatcher = distancePattern.matcher(theFlight); + if (disMatcher.find()) { + int distance = Integer.parseInt(disMatcher.group(3)); + currentSection.setDistance(distance); + } + } else if (classType.equals("ISOL")) { + final String ISOLDISTANCE_EXP = "ISOL (\\S|\\s)* TS D([0-9]{2})"; + final Pattern isoldistancePattern = Pattern + .compile(ISOLDISTANCE_EXP); + Matcher isoldisMatcher = isoldistancePattern.matcher(theFlight); + if (isoldisMatcher.find()) { + int distance = Integer.parseInt(isoldisMatcher.group(2)); + currentSection.setDistance(distance); + } + // get ISOL location table + getIsolLocation(theFlight, currentSection); + } + + } else if (classMatcher.find()) { + classType = classMatcher.group(3); + + int flightLevel = Integer.parseInt(classMatcher.group(8)); + String flightLevelTop = classMatcher.group(5); + String intensity = classMatcher.group(1); + + currentSection.setFlightLevel(flightLevel); + currentSection.setClassType(classType); + currentSection.setIntensity(intensity); + currentSection.setCloudTop(flightLevelTop); + + if (classType.equals("LINE")) { + final String DISTANCE_EXP = "LINE (EMBD )?(SEV )?TS ([0-9]{2})"; + final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); + Matcher disMatcher = distancePattern.matcher(theFlight); + if (disMatcher.find()) { + int distance = Integer.parseInt(disMatcher.group(3)); + currentSection.setDistance(distance); + } + } else if (classType.equals("ISOL")) { + final String ISOLDISTANCE_EXP = "ISOL (\\S|\\s)* TS D([0-9]{2})"; + final Pattern isoldistancePattern = Pattern + .compile(ISOLDISTANCE_EXP); + Matcher isoldisMatcher = isoldistancePattern.matcher(theFlight); + if (isoldisMatcher.find()) { + int distance = Integer.parseInt(isoldisMatcher.group(2)); + currentSection.setDistance(distance); + } + // get ISOL location table + getIsolLocation(theFlight, currentSection); + } + + } else { + // Finds no "flight level line", "CS" as default for a NIL report. + currentSection.setClassType("CS"); + currentSection.setIntensity(null); + } + + return currentSection; + } + + /** + * Obtains the start time and end time + * + * @param theSection + * The outlook section contains the valid times group + */ + public static void processValidTime(String theSection, + ConvSigmetSection currentOutLook, Headers headers) { + + // Regular expression for start time + final String TIMES_EXP = "OUTLOOK VALID ([0-9]{6})-([0-9]{6})"; + + // Pattern used for extracting the starting time and end time + final Pattern starttimePattern = Pattern.compile(TIMES_EXP); + + Calendar startTime = null; + Calendar endTime = null; + // Calendar mndTime = Calendar.getInstance(); + + Matcher theMatcher = starttimePattern.matcher(theSection); + + if (theMatcher.find()) { + // Decode the start time and end time; then set them. + startTime = TimeTools.findDataTime(theMatcher.group(1), headers); + currentOutLook.setStartTime(startTime); + endTime = TimeTools.findDataTime(theMatcher.group(2), headers); + + int startMonth = startTime.get(Calendar.MONTH); + int endMonth = endTime.get(Calendar.MONTH); + int startDay = startTime.get(Calendar.DAY_OF_MONTH); + int endDay = endTime.get(Calendar.DAY_OF_MONTH); + + if ((startMonth == endMonth) && (startDay > endDay)) { + // Roll over a month + endTime.add(Calendar.MONTH, 1); + } + + currentOutLook.setEndTime(endTime); + } else { + currentOutLook.setStartTime(startTime); + currentOutLook.setEndTime(endTime); + } + + } + + /** + * Obtains the location information for ISOL. + * + * @param theSection + * The section lines from bulletin message + * @param sectionTable + * The section Table + */ + public static void getIsolLocation(String theSection, + ConvSigmetSection sectionTable) { + + String line = null; + LatLonPoint point = null; + + final String ISOLLOCATION_EXP = "\\x0d\\x0d\\x0a(([0-9]{2}|[0-9]{3})([ENSW])* [A-Z]{3})\\x0d\\x0d\\x0a"; + final Pattern isollocationPattern = Pattern.compile(ISOLLOCATION_EXP); + Matcher isollocMatcher = isollocationPattern.matcher(theSection); + if (isollocMatcher.find()) { + line = isollocMatcher.group(1); + } + + if (line != null) { + ConvSigmetLocation currentLocation = new ConvSigmetLocation(); + currentLocation.setLocationLine(line); + currentLocation.setLocation(line); + currentLocation.setIndex(1); + // Get a latLonPoint for this station ID from "vors" location table + point = LatLonLocTbl.getLatLonPoint(line, "vors"); + currentLocation.setLatitude(point + .getLatitude(LatLonPoint.INDEGREES)); + currentLocation.setLongitude(point + .getLongitude(LatLonPoint.INDEGREES)); + sectionTable.addConvSigmetLocation(currentLocation); + } + } + + /** + * Parse the location lines and add location table to the section table if + * any + * + * @param theSection + * The section lines from bulletin message + * @param sectionTable + * The section Table + * @return true if finds a location line + */ + public static Boolean processLocation(String theSection, + ConvSigmetSection sectionTable) { + + Boolean hasLocationLine = true; + String locationDelimiter = "-"; + + ArrayList terminationList = new ArrayList(); + terminationList.addAll(Arrays + .asList(new String[] { "WST", "REF", "LINE", "AREA", "ISOL", + "DMSHG", "DVLPG", "DSIPTG", "INTSFYG" })); + + LatLonPoint point = null; + + Scanner sclocations = new Scanner(theSection).useDelimiter("FROM"); + + // throws away the first section which is not the "FROM" location + String locationSection = sclocations.next(); + + if (sclocations.hasNext()) { + locationSection = sclocations.next(); + + Scanner scLocationLine = new Scanner(locationSection) + .useDelimiter("\\x0d\\x0d\\x0a"); + String lines = " "; + String curLine = null; + ArrayList locationList = new ArrayList(); + locationList.clear(); + Boolean notBreak = true; + + while (scLocationLine.hasNext() && notBreak) { + // Get next location line + curLine = scLocationLine.next(); + + Scanner scLocationToken = new Scanner(curLine); + if (scLocationToken.hasNext()) { + // Check the first token from each line + String firstToken = scLocationToken.next(); + if (terminationList.contains(firstToken)) { + // terminate + notBreak = false; + break; + } + } + lines = lines.concat(" ").concat(curLine); + } + + // Clean up the leading space + lines = UtilN.removeLeadingWhiteSpaces(lines); + // Parse the location lines by a "-" + Scanner scLocation = new Scanner(lines) + .useDelimiter(locationDelimiter); + locationList.clear(); + // Get all locations + while (scLocation.hasNext()) { + locationList.add(scLocation.next()); + } + + // set locations to data base + if (locationList.size() > 1) { + Integer idxLocation = 0; + for (String Location : locationList) { + + ConvSigmetLocation currentLocation = new ConvSigmetLocation(); + currentLocation.setLocationLine(lines); + currentLocation.setLocation(Location); + + // Get a latLonPoint for this station ID from "vors" + // location table + point = LatLonLocTbl.getLatLonPoint(Location, "vors"); + currentLocation.setLatitude(point + .getLatitude(LatLonPoint.INDEGREES)); + currentLocation.setLongitude(point + .getLongitude(LatLonPoint.INDEGREES)); + + currentLocation.setIndex(idxLocation + 1); + idxLocation++; + + sectionTable.addConvSigmetLocation(currentLocation); + } + } else { + hasLocationLine = false; + } + + } else { + hasLocationLine = false; + } + + return hasLocationLine; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/package-info.java old mode 100755 new mode 100644 index 91040f9487..4f09986546 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/src/gov/noaa/nws/ncep/edex/plugin/convsigmet/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.convsigmet.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.convsigmet.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/2009022414.conv b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/2009022414.conv index 35cd6d843e..8997344498 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/2009022414.conv +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/convsigmet/decoder/2009022414.conv @@ -1,11 +1,11 @@ - + -563 + -WSUS33 KKCI 241455 + -SIGW + -MKCW WST 241455 + -CONVECTIVE SIGMET...NONE + - + -OUTLOOK VALID 241655-242055 + -TS ARE NOT EXPD TO REQUIRE WST ISSUANCES. + - + + +563 +WSUS33 KKCI 241455 +SIGW +MKCW WST 241455 +CONVECTIVE SIGMET...NONE + +OUTLOOK VALID 241655-242055 +TS ARE NOT EXPD TO REQUIRE WST ISSUANCES. +  \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/component-deploy.xml index 5c9780191c..e4c9c2fbf5 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/res/spring/ffg-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/res/spring/ffg-ingest.xml index 9713625dc2..2a31a9d668 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/res/spring/ffg-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ffg/res/spring/ffg-ingest.xml @@ -1,65 +1,73 @@ - + + + + + - - - - - - - - + - - - - - ffg - - - - - - - ffg - - - - - - - - - - - - - java.lang.Throwable - - + + + + + + + + + ffg + + + + + + + + + + + + + java.lang.Throwable + + - - - java.lang.Throwable - - - - + + + java.lang.Throwable + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/component-deploy.xml index fde43408f0..6afefb4e3c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/src/gov/noaa/nws/ncep/edex/plugin/idft/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/src/gov/noaa/nws/ncep/edex/plugin/idft/decoder/package-info.java index ac808192ab..6be47d815c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/src/gov/noaa/nws/ncep/edex/plugin/idft/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/src/gov/noaa/nws/ncep/edex/plugin/idft/decoder/package-info.java @@ -1,7 +1,7 @@ -/** - * IDFT implementation of the plugin pattern. - * - * Package includes classes to decode the IDFT message and persist the data. - * - */ +/** + * IDFT implementation of the plugin pattern. + * + * Package includes classes to decode the IDFT message and persist the data. + * + */ package gov.noaa.nws.ncep.edex.plugin.idft.decoder; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/component-deploy.xml old mode 100755 new mode 100644 index 63c677d45d..2f4a294d8b --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-common.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-common.xml old mode 100755 new mode 100644 index b88e96a48d..6acee491a6 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-common.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-common.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml old mode 100755 new mode 100644 index 8c04e35c3d..79ce6b0e5c --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml @@ -1,72 +1,72 @@ - - - - - - - - - - - - - - - - - - - - - - - - intlsigmet - - - - - - - - - - - - - java.lang.Throwable - - - - - - - java.lang.Throwable - - - - - + + + + + + + + + + + + + + + + + + + + + + + + intlsigmet + + + + + + + + + + + + + java.lang.Throwable + + + + + + + java.lang.Throwable + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetDecoder.java old mode 100755 new mode 100644 index a36686b891..39648fbe79 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetDecoder.java @@ -1,198 +1,197 @@ -/** - * - * IntlSigmet Decoder - * - * This java class decodes INTLSIGMET raw data. - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 113 L. Lin Initial creation - * 07/2009 113 L. Lin Migration to TO11 - * 05/2010 113 L. Lin Migration to TO11DR11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder; - -import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetRecord; -import gov.noaa.nws.ncep.edex.plugin.intlsigmet.util.IntlSigmetParser; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.Calendar; -import java.util.Scanner; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.exception.DecoderException; -import com.raytheon.edex.plugin.AbstractDecoder; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.PluginException; -import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class IntlSigmetDecoder extends AbstractDecoder { - - private final String pluginName; - - /** - * Constructor - * - * @throws DecoderException - */ - public IntlSigmetDecoder(String name) throws DecoderException { - pluginName = name; - } - - public PluginDataObject[] decode(byte[] data, Headers headers) - throws DecoderException { - - String traceId = ""; - if (headers != null) { - traceId = (String) headers.get("traceId"); - } - - String etx = IDecoderConstants.ETX; - String theBulletin = null; - - Calendar startTime = null; - byte[] messageData = null; - - IntlSigmetRecord record = null; - // Default equal to four hours from start time if there is no valid time - // in report - final int validPeriod = 4; - - IntlSigmetSeparator sep = IntlSigmetSeparator.separate(data, headers); - messageData = sep.next(); - String theMessage = new String(messageData); - - /* - * May have multiple duplicate bulletins, only get the first bulletin - * and eliminate the remaining bulletins after the first bulletin. - */ - Scanner cc = new Scanner(theMessage).useDelimiter(etx); - if (cc.hasNext()) { - theBulletin = cc.next(); - } else { - theBulletin = theMessage; - } - - // Decode and set WMO line - record = IntlSigmetParser.processWMO(theBulletin, headers); - - /* - * Check the IntlSigmet record object. If not, throws exception. - */ - if (record != null) { - record.setTraceId(traceId); - record.setPluginName(pluginName); - record.setReportType(pluginName); - record.setHazardType(IntlSigmetParser.getHazardType(theBulletin)); - // Decode and set the messageID - record.setMessageID(IntlSigmetParser.getMessageID(theBulletin)); - // Decode and set the sequence number - record.setSequenceNumber(IntlSigmetParser - .getSequenceNumber(theBulletin)); - try { - record.constructDataURI(); - } catch (PluginException e) { - logger.error("Error constructing dataURI", e); - record = null; - } - } - if (record != null) { - try { - // Replace special characters to a blank so that it may be - // readable - record.setBullMessage(UtilN - .removeLeadingWhiteSpaces((theBulletin.substring(5)) - .replace('\036', ' ').replace('\r', ' ') - .replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' '))); - - if (!record.getHazardType().equals("NIL")) { - - // Decode the issue time - Calendar issueTime = record.getIssueTime(); - - // Decode the starting time - startTime = IntlSigmetParser.getStartTime(theBulletin, - headers); - if (startTime == null) { - startTime = issueTime; - } - - // Decode the end time - Calendar endTime = IntlSigmetParser.getEndTime(theBulletin, - headers); - if (endTime == null) { - /* - * if no end time available, end time will be the start - * time plus a valid period; the default is four hours - * for now. - */ - endTime = TimeTools.copy(startTime); - endTime.add(Calendar.HOUR, validPeriod); - } - - // Set start time and end time - record.setStartTime(startTime); - record.setEndTime(endTime); - - // Decode and set the atsu - record.setAtsu(IntlSigmetParser.getAtsu(theBulletin)); - - // Decode and set the intensity - record.setIntensity(IntlSigmetParser - .getIntensity(theBulletin)); - - // Decode and set the flight levels - IntlSigmetParser.processFlightLevels(theBulletin, record); - - // Decode and set the omwo - record.setOmwo(IntlSigmetParser.getOmwo(theBulletin)); - - // Decode and set the direction - record.setDirection(IntlSigmetParser - .getDirection(theBulletin)); - - // Decode and set the speed - record.setSpeed(IntlSigmetParser.getSpeed(theBulletin)); - - // Decode and set distance - record.setDistance(IntlSigmetParser - .getDistance(theBulletin)); - - // Decode and set nameLocation - record.setNameLocation(IntlSigmetParser - .getNameLocation(theBulletin)); - - // Decode and set the remarks - record.setRemarks(IntlSigmetParser.getRemarks(theBulletin)); - - // Decode and set polyGonExtend - record.setPolygonExtent(IntlSigmetParser - .getPolygonExtent(theBulletin)); - } - } catch (Exception e) { - logger.error("Error postprocessing " + pluginName, e); - record = null; - } - } - - /* - * Return the IntlSigmetRecord record object. - */ - if (record == null) { - return new PluginDataObject[0]; - } else { - return new PluginDataObject[] { record }; - } - - } - -} +/** + * + * IntlSigmet Decoder + * + * This java class decodes INTLSIGMET raw data. + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 113 L. Lin Initial creation + * 07/2009 113 L. Lin Migration to TO11 + * 05/2010 113 L. Lin Migration to TO11DR11 + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder; + +import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetRecord; +import gov.noaa.nws.ncep.edex.plugin.intlsigmet.util.IntlSigmetParser; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.Calendar; +import java.util.Scanner; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.exception.DecoderException; +import com.raytheon.edex.plugin.AbstractDecoder; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class IntlSigmetDecoder extends AbstractDecoder { + + private final String pluginName; + + /** + * Constructor + * + * @throws DecoderException + */ + public IntlSigmetDecoder(String name) throws DecoderException { + pluginName = name; + } + + public PluginDataObject[] decode(byte[] data, Headers headers) + throws DecoderException { + + String traceId = ""; + if (headers != null) { + traceId = (String) headers.get("traceId"); + } + + String etx = IDecoderConstants.ETX; + String theBulletin = null; + + Calendar startTime = null; + byte[] messageData = null; + + IntlSigmetRecord record = null; + // Default equal to four hours from start time if there is no valid time + // in report + final int validPeriod = 4; + + IntlSigmetSeparator sep = IntlSigmetSeparator.separate(data, headers); + messageData = sep.next(); + String theMessage = new String(messageData); + + /* + * May have multiple duplicate bulletins, only get the first bulletin + * and eliminate the remaining bulletins after the first bulletin. + */ + Scanner cc = new Scanner(theMessage).useDelimiter(etx); + if (cc.hasNext()) { + theBulletin = cc.next(); + } else { + theBulletin = theMessage; + } + + // Decode and set WMO line + record = IntlSigmetParser.processWMO(theBulletin, headers); + + /* + * Check the IntlSigmet record object. If not, throws exception. + */ + if (record != null) { + record.setTraceId(traceId); + record.setPluginName(pluginName); + record.setReportType(pluginName); + record.setHazardType(IntlSigmetParser.getHazardType(theBulletin)); + // Decode and set the messageID + record.setMessageID(IntlSigmetParser.getMessageID(theBulletin)); + // Decode and set the sequence number + record.setSequenceNumber(IntlSigmetParser + .getSequenceNumber(theBulletin)); + try { + record.constructDataURI(); + } catch (PluginException e) { + logger.error("Error constructing dataURI", e); + record = null; + } + } + if (record != null) { + try { + // Replace special characters to a blank so that it may be + // readable + record.setBullMessage(UtilN + .removeLeadingWhiteSpaces((theBulletin.substring(5)) + .replace('\036', ' ').replace('\r', ' ') + .replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' '))); + + if (!record.getHazardType().equals("NIL")) { + + // Decode the issue time + Calendar issueTime = record.getIssueTime(); + + // Decode the starting time + startTime = IntlSigmetParser.getStartTime(theBulletin, + headers); + if (startTime == null) { + startTime = issueTime; + } + + // Decode the end time + Calendar endTime = IntlSigmetParser.getEndTime(theBulletin, + headers); + if (endTime == null) { + /* + * if no end time available, end time will be the start + * time plus a valid period; the default is four hours + * for now. + */ + endTime = TimeTools.copy(startTime); + endTime.add(Calendar.HOUR, validPeriod); + } + + // Set start time and end time + record.setStartTime(startTime); + record.setEndTime(endTime); + + // Decode and set the atsu + record.setAtsu(IntlSigmetParser.getAtsu(theBulletin)); + + // Decode and set the intensity + record.setIntensity(IntlSigmetParser + .getIntensity(theBulletin)); + + // Decode and set the flight levels + IntlSigmetParser.processFlightLevels(theBulletin, record); + + // Decode and set the omwo + record.setOmwo(IntlSigmetParser.getOmwo(theBulletin)); + + // Decode and set the direction + record.setDirection(IntlSigmetParser + .getDirection(theBulletin)); + + // Decode and set the speed + record.setSpeed(IntlSigmetParser.getSpeed(theBulletin)); + + // Decode and set distance + record.setDistance(IntlSigmetParser + .getDistance(theBulletin)); + + // Decode and set nameLocation + record.setNameLocation(IntlSigmetParser + .getNameLocation(theBulletin)); + + // Decode and set the remarks + record.setRemarks(IntlSigmetParser.getRemarks(theBulletin)); + + // Decode and set polyGonExtend + record.setPolygonExtent(IntlSigmetParser.getPolygonExtent(theBulletin)); + } + } catch (Exception e) { + logger.error("Error postprocessing " + pluginName, e); + record = null; + } + } + + /* + * Return the IntlSigmetRecord record object. + */ + if (record == null) { + return new PluginDataObject[0]; + } else { + return new PluginDataObject[] { record }; + } + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetSeparator.java old mode 100755 new mode 100644 index ccb86b4310..9586140291 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/IntlSigmetSeparator.java @@ -1,147 +1,147 @@ -/** - * IntlsigmetSeparator - * - * This class sets the raw data to an Arraylist, records, of - * String based on a uniquely identified separator. - * - * HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 113 L. Lin Initial creation - * 07/2009 113 L. Lin Migration to TO11 - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.plugin.AbstractRecordSeparator; -import com.raytheon.edex.util.Util; - -public class IntlSigmetSeparator extends AbstractRecordSeparator { - private final Log logger = LogFactory.getLog(getClass()); - - /** Regex used for separate the bulletins */ - private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; - - /** Regex matcher */ - private Matcher matcher; - - /** Pattern object for regex search */ - private Pattern pattern; - - /** List of records contained in file */ - private List records; - - private Iterator iterator = null; - - /** - * Constructor. - * - */ - public IntlSigmetSeparator() { - records = new ArrayList(); - } - - public static IntlSigmetSeparator separate(byte[] data, Headers headers) { - IntlSigmetSeparator ds = new IntlSigmetSeparator(); - ds.setData(data, headers); - return ds; - } - - public void setData(byte[] data, Headers headers) { - doSeparate(new String(data)); - iterator = records.iterator(); - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() - */ - public boolean hasNext() { - if (iterator == null) { - return false; - } else { - return iterator.hasNext(); - } - } - - /** - * Get record - */ - public byte[] next() { - try { - String temp = iterator.next(); - if (Util.isEmptyString(temp)) { - return (byte[]) null; - } else { - return temp.getBytes(); - } - } catch (NoSuchElementException e) { - return (byte[]) null; - } - } - - /** - * @param message - * separate bulletins - */ - private void doSeparate(String message) { - /* Regex used for separate the bulletins */ - - try { - pattern = Pattern.compile(BULLSEPARATOR); - matcher = pattern.matcher(message); - - /* - * Set number of bulletins to records only if the bulletin separator - * is not the same. At the point, only separators are stored in - * "records" - */ - while (matcher.find()) { - if (!records.contains(matcher.group())) { - records.add(matcher.group()); - } - } - - /* - * Append the raw data file to the records. - */ - for (int i = 0; i < records.size(); i++) { - if (i < records.size() - 1) { - records.set( - i, - "\n" - + message.substring( - message.indexOf(records.get(i)), - message.indexOf(records.get(i + 1)))); - } else { - records.set( - i, - "\n" - + message.substring(message.indexOf(records - .get(i)))); - } - } - } catch (Exception e) { - logger.warn("No valid records found!", e); - } - return; - } -} +/** + * IntlsigmetSeparator + * + * This class sets the raw data to an Arraylist, records, of + * String based on a uniquely identified separator. + * + * HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 113 L. Lin Initial creation + * 07/2009 113 L. Lin Migration to TO11 + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.plugin.AbstractRecordSeparator; +import com.raytheon.edex.util.Util; + +public class IntlSigmetSeparator extends AbstractRecordSeparator { + private final Log logger = LogFactory.getLog(getClass()); + + /** Regex used for separate the bulletins */ + private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; + + /** Regex matcher */ + private Matcher matcher; + + /** Pattern object for regex search */ + private Pattern pattern; + + /** List of records contained in file */ + private List records; + + private Iterator iterator = null; + + /** + * Constructor. + * + */ + public IntlSigmetSeparator() { + records = new ArrayList(); + } + + public static IntlSigmetSeparator separate(byte[] data, Headers headers) { + IntlSigmetSeparator ds = new IntlSigmetSeparator(); + ds.setData(data, headers); + return ds; + } + + public void setData(byte[] data, Headers headers) { + doSeparate(new String(data)); + iterator = records.iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() + */ + public boolean hasNext() { + if (iterator == null) { + return false; + } else { + return iterator.hasNext(); + } + } + + /** + * Get record + */ + public byte[] next() { + try { + String temp = iterator.next(); + if (Util.isEmptyString(temp)) { + return (byte[]) null; + } else { + return temp.getBytes(); + } + } catch (NoSuchElementException e) { + return (byte[]) null; + } + } + + /** + * @param message + * separate bulletins + */ + private void doSeparate(String message) { + /* Regex used for separate the bulletins */ + + try { + pattern = Pattern.compile(BULLSEPARATOR); + matcher = pattern.matcher(message); + + /* + * Set number of bulletins to records only if the bulletin separator + * is not the same. At the point, only separators are stored in + * "records" + */ + while (matcher.find()) { + if (!records.contains(matcher.group())) { + records.add(matcher.group()); + } + } + + /* + * Append the raw data file to the records. + */ + for (int i = 0; i < records.size(); i++) { + if (i < records.size() - 1) { + records.set( + i, + "\n" + + message.substring( + message.indexOf(records.get(i)), + message.indexOf(records.get(i + 1)))); + } else { + records.set( + i, + "\n" + + message.substring(message.indexOf(records + .get(i)))); + } + } + } catch (Exception e) { + logger.warn("No valid records found!", e); + } + return; + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/package-info.java old mode 100755 new mode 100644 index cf944c8b08..9b5e68be59 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains decoder.java for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder;; +/** +* Contains decoder.java for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.intlsigmet.decoder;; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/IntlSigmetParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/IntlSigmetParser.java old mode 100755 new mode 100644 index c4b058b7b2..b87da1056d --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/IntlSigmetParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/IntlSigmetParser.java @@ -1,1684 +1,1688 @@ -/** - * IntlSigmet DecoderUtil - * - * This java class intends to serve as a decoder utility for INTLSIGMET. - * - * HISTORY - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 113 L. Lin Initial coding - * 07/2009 113 L. Lin Migration to TO11 - * 09/2009 113 L. Lin Convert station ID to lat/lon - * if any exists. - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.intlsigmet.util; - -import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetLocation; -import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetRecord; -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; -import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.edex.decodertools.core.LatLonPoint; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class IntlSigmetParser { - - private static final String CONUS_EXP = "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|HOTEL|" - + "INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|TANGO|" - + "UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; - - /** - * Constructor - */ - public IntlSigmetParser() { - } - - /** - * Parse the WMO line and store WMO header, OfficeID, issue time, ... - * - * @param wmoline - * The bulletin message - * - * @return an IntlSigmetRecord - */ - public static IntlSigmetRecord processWMO(String wmoline, Headers headers) { - - IntlSigmetRecord record = null; - // Regular expression for WMO/ICAO, station ID, and issue date. - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})"; - - // Pattern used for extracting WMO header, officeID, and issue date. - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(wmoline); - - if (theMatcher.find()) { - record = new IntlSigmetRecord(); - - record.setWmoHeader(theMatcher.group(1)); - record.setIssueOffice(theMatcher.group(2)); - - // Decode the issue time. - Calendar mndTime = null; - Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), - headers); - record.setIssueTime(issueTime); - - DataTime dataTime = new DataTime(issueTime); - record.setDataTime(dataTime); - } - return record; - } - - /** - * Obtains hazardType as: TS (thunderstorm), TB (turbulence), HU - * (hurricane), TR (tropical storm), TD (tropical depression), VA (volcanic - * ash cloud), MW (marked mountain waves), TC (tropical cyclone), SQ (squall - * line), CT (CAT), IC (icing), GR (hail), DS (duststorm), SS (sandstorm), - * CB (cumulonimbus), WS (low level wind shear), TEST, or CN (cancel), - * etc... - * - * @param theReport - * Input report message. - * @return a string for hazard type - */ - public static String getHazardType(String theReport) { - - String retHazardType = " "; - // Regular expression for hazardType - final String HAZARDTYPE_EXP = "(HURRICANE|HURCN |TROPICAL STORM|TROPICAL DEPRESSION|" - + " TD | SQL | TS | TS/|FRQ TS| TS| SH/TS |TURB| CB | VA | MTW |" - + " ICE | TR | GR | TC | CT | CAT | DS | SS | WS | TSGR |VOLCANIC ASH|HVYSS|" - + " ICG|ICING|LLWS|WATERSPOUTS|THUNDERSTORMS|WIND|TS OBS|CB/TS|TORNADO)"; - final String NIL_EXP = "(NIL)"; - final String MIS_EXP = "(TAF |METAR )"; - final String CNL_EXP = "(CANCEL| CNL | CNCL |:CNL| CNL|INVALID|DISCARDED|" - + "CNL SIGMET| CLN SIGMET|CNCLD)"; - final String TEST_EXP = "(TEST |DISREGARD)"; - - // Pattern used for extracting hazardType - final Pattern hazardTypePattern = Pattern.compile(HAZARDTYPE_EXP); - final Pattern nilPattern = Pattern.compile(NIL_EXP); - final Pattern cnlPattern = Pattern.compile(CNL_EXP); - final Pattern misPattern = Pattern.compile(MIS_EXP); - final Pattern testPattern = Pattern.compile(TEST_EXP); - - Matcher theMatcher = hazardTypePattern.matcher(theReport); - Matcher nilMatcher = nilPattern.matcher(theReport); - Matcher cnlMatcher = cnlPattern.matcher(theReport); - Matcher misMatcher = misPattern.matcher(theReport); - Matcher testMatcher = testPattern.matcher(theReport); - - if (cnlMatcher.find()) { - retHazardType = "CANCEL"; - } else if (testMatcher.find()) { - retHazardType = "TEST"; - } else if (theMatcher.find()) { - if (theMatcher.group(1).equals("HURRICANE")) { - retHazardType = "HURRICANE"; - } else if (theMatcher.group(1).equals("HURCN ")) { - retHazardType = "HURRICANE"; - } else if (theMatcher.group(1).equals(" TD ")) { - retHazardType = "TROPICAL DEPRESSION"; - } else if (theMatcher.group(1).equals("TROPICAL STORM")) { - retHazardType = "TROPICAL STORM"; - } else if (theMatcher.group(1).equals("TROPICAL DEPRESSION")) { - retHazardType = "TROPICAL DEPRESSION"; - } else if (theMatcher.group(1).equals(" SQL ")) { - retHazardType = "SQUALL LINE"; - } else if (theMatcher.group(1).equals("TURB")) { - retHazardType = "TURBULENCE"; - } else if (theMatcher.group(1).equals(" ICE ")) { - retHazardType = "ICING"; - } else if (theMatcher.group(1).equals(" ICG")) { - retHazardType = "ICING"; - } else if (theMatcher.group(1).equals("ICING")) { - retHazardType = "ICING"; - } else if (theMatcher.group(1).equals(" TS ")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals("FRQ TS")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals(" TS/")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals(" SH/TS ")) { - retHazardType = "THUNDERSTORM WIND SHEAR"; - } else if (theMatcher.group(1).equals(" CB ")) { - retHazardType = "CUMULONIMBUS"; - } else if (theMatcher.group(1).equals(" VA ")) { - retHazardType = "VOLCANIC ASH CLOUD"; - } else if (theMatcher.group(1).equals(" MTW ")) { - retHazardType = "MARKED MOUNTAIN WAVES"; - } else if (theMatcher.group(1).equals(" TR ")) { - retHazardType = "TROPICAL STORM"; - } else if (theMatcher.group(1).equals(" GR ")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals(" TC ")) { - retHazardType = "TROPICAL CYCLONE"; - } else if (theMatcher.group(1).equals(" CT ")) { - retHazardType = "CAT"; - } else if (theMatcher.group(1).equals(" CAT ")) { - retHazardType = "CAT"; - } else if (theMatcher.group(1).equals(" DS ")) { - retHazardType = "DUSTSTORM"; - } else if (theMatcher.group(1).equals(" SS ")) { - retHazardType = "SANDSTORM"; - } else if (theMatcher.group(1).equals(" WS ")) { - retHazardType = "LOW LEVEL WIND SHEAR"; - } else if (theMatcher.group(1).equals("LLWS")) { - retHazardType = "LOW LEVEL WIND SHEAR"; - } else if (theMatcher.group(1).equals(" TSGR ")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals("VOLCANIC ASH")) { - retHazardType = "VOLCANIC ASH CLOUD"; - } else if (theMatcher.group(1).equals("TS ")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals("HVYSS ")) { - retHazardType = "HEAVY SANDSTORM"; - } else if (theMatcher.group(1).equals("WATERSPOUTS")) { - retHazardType = "WATERSPOUTS"; - } else if (theMatcher.group(1).equals("THUNDERSTORMS")) { - retHazardType = "THUNDERSTORMS"; - } else if (theMatcher.group(1).equals("WIND")) { - retHazardType = "WINDS"; - } else if (theMatcher.group(1).equals("TS OBS")) { - retHazardType = "THUNDERSTORMS"; - } else if (theMatcher.group(1).equals(" TS")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals("CB/TS")) { - retHazardType = getThunderStorm(theReport); - } else if (theMatcher.group(1).equals("TORNADO")) { - retHazardType = "TORNADO"; - } - } else if (nilMatcher.find()) { - retHazardType = "NIL"; - } else if (misMatcher.find()) { - retHazardType = "NIL"; - } else { - retHazardType = "UNKNOWN ???"; - } - return retHazardType; - } - - /** - * Obtains the message ID. - * - * @param theBulletin - * The input bulletin - * @return a string for messageID - */ - public static String getMessageID(String theBulletin) { - - String messageID = " "; - - // // Regular expression for CONUS message ID - // final String CONUS_EXP = - // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|" + - // "GOLF|HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|" - // + - // "ROMEO|SIERRA|TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) " + - // "([0-9]{1}|[0-9]{2}) VALID"; - - // Pattern used for extracting the message ID - final Pattern conusPattern = Pattern.compile(CONUS_EXP); - Matcher idconusMatcher = conusPattern.matcher(theBulletin); - - // Regular expression for CANADA message ID - final String CANADA_EXP = "SIGMET ([A-Z]{1})([0-9]{1}|[0-9]{2}) (VALID " - + "([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the message ID - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher idcanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK message ID - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) (VALID )?" - + "([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the message ID - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher idjapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER1_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); - Matcher idother1Matcher = other1Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER2_EXP = "(SIGMET) ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}|[A-Z]{1}[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})"; - // Pattern used for extracting the message ID - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher idother2Matcher = other2Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER3_EXP = "([A-Z]{4}) SIGMET ([A-Z]* )?([0-9]{1}|[0-9]{2}) VALID ([0-9]{6})/([0-9]{6}) " - + "([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); - Matcher idother3Matcher = other3Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); - Matcher idother4Matcher = other4Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); - Matcher idother5Matcher = other5Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER6_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); - Matcher idother6Matcher = other6Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER7_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other7Pattern = Pattern.compile(OTHER7_EXP); - Matcher idother7Matcher = other7Pattern.matcher(theBulletin); - - // Regular expression for others' message ID - final String OTHER8_EXP = "([A-Z]{4}) SIGMET( |\\W)*VALID( |\\W)*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message ID - final Pattern other8Pattern = Pattern.compile(OTHER8_EXP); - Matcher idother8Matcher = other8Pattern.matcher(theBulletin); - - // Get messageID - if (idconusMatcher.find()) { - messageID = idconusMatcher.group(2); - } else if (idcanadaMatcher.find()) { - messageID = idcanadaMatcher.group(6); - } else if (idother1Matcher.find()) { - messageID = idother1Matcher.group(6); - } else if (idjapanMatcher.find()) { - messageID = idjapanMatcher.group(7); - } else if (idother2Matcher.find()) { - messageID = idother2Matcher.group(1); - } else if (idother3Matcher.find()) { - messageID = idother3Matcher.group(6); - } else if (idother4Matcher.find()) { - messageID = idother4Matcher.group(8); - } else if (idother5Matcher.find()) { - messageID = idother5Matcher.group(7); - } else if (idother6Matcher.find()) { - messageID = idother6Matcher.group(8); - } else if (idother7Matcher.find()) { - messageID = idother7Matcher.group(8); - } else if (idother8Matcher.find()) { - messageID = idother8Matcher.group(7); - } - - return messageID; - } - - /** - * Obtains the sequence number. - * - * @param theBulletin - * The input bulletin - * @return a string for sequenceNumber - */ - public static String getSequenceNumber(String theBulletin) { - - String sequenceNumber = " "; - - // // Regular expression for CONUS sequence number - // final String CONUS_EXP = - // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|HOTEL|" - // + - // "INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|TANGO|" - // + - // "UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; - - // Pattern used for extracting the sequence number - final Pattern conusPattern = Pattern.compile(CONUS_EXP); - Matcher seqnoconusMatcher = conusPattern.matcher(theBulletin); - - // Regular expression for CANADA sequence number - final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " - + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the sequence number - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher seqnocanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK sequence number - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " - + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the sequence number - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher seqnojapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; - // Pattern used for extracting the sequence number - final Pattern otherPattern = Pattern.compile(OTHER_EXP); - Matcher seqnootherMatcher = otherPattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER2_EXP = "SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}|A-Z]{1}[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})"; - // Pattern used for extracting the sequence number - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher seqnoother2Matcher = other2Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER3_EXP = "([A-Z]{4}) SIGMET (([A-Z]* )?([0-9]{1}|[0-9]{2})) " - + "VALID ([0-9]{6})/([0-9]{6}) ([A-Z]{4})(-)?"; - // Pattern used for extracting the sequence number - final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); - Matcher seqnoother3Matcher = other3Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the sequence number - final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); - Matcher seqnoother4Matcher = other4Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the sequence number - final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); - Matcher seqnoother5Matcher = other5Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER6_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message sequence number - final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); - Matcher seqnoother6Matcher = other6Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER7_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the sequence number - final Pattern other7Pattern = Pattern.compile(OTHER7_EXP); - Matcher seqnoother7Matcher = other7Pattern.matcher(theBulletin); - - // Regular expression for others' sequence number - final String OTHER8_EXP = "([A-Z]{4}) SIGMET( |\\W)*([0-9]{1})( |\\W)*VALID"; - // Pattern used for extracting the sequence number - final Pattern other8Pattern = Pattern.compile(OTHER8_EXP); - Matcher seqnoother8Matcher = other8Pattern.matcher(theBulletin); - - // Get sequenceNumber - if (seqnoconusMatcher.find()) { - sequenceNumber = seqnoconusMatcher.group(3); - } else if (seqnocanadaMatcher.find()) { - sequenceNumber = seqnocanadaMatcher.group(1); - } else if (seqnootherMatcher.find()) { - sequenceNumber = seqnootherMatcher.group(2); - } else if (seqnojapanMatcher.find()) { - sequenceNumber = seqnojapanMatcher.group(2); - } else if (seqnoother2Matcher.find()) { - sequenceNumber = seqnoother2Matcher.group(1); - } else if (seqnoother3Matcher.find()) { - sequenceNumber = seqnoother3Matcher.group(2); - } else if (seqnoother4Matcher.find()) { - sequenceNumber = seqnoother4Matcher.group(3); - } else if (seqnoother5Matcher.find()) { - // lacking sequence number; default 0 - sequenceNumber = "0"; - } else if (seqnoother6Matcher.find()) { - sequenceNumber = seqnoother6Matcher.group(3); - } else if (seqnoother7Matcher.find()) { - sequenceNumber = seqnoother7Matcher.group(3); - } else if (seqnoother8Matcher.find()) { - sequenceNumber = seqnoother8Matcher.group(3); - } - - return sequenceNumber; - } - - /** - * Obtains the Air Traffic Service Unit. - * - * @param theBulletin - * The input bulletin - * @return a string for atsu. - */ - public static String getAtsu(String theBulletin) { - - String atsu = null; - - // // Regular expression for CONUS ATSU - // final String CONUS_EXP = - // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|" + - // "HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|" - // + - // "TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; - - // Pattern used for extracting the ATSU - final Pattern conusPattern = Pattern.compile(CONUS_EXP); - Matcher atsuconusMatcher = conusPattern.matcher(theBulletin); - - // Regular expression for CANADA ATSU - final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " - + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the ATSU - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher atsucanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK ATSU - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " - + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the ATSU - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher atsujapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for others' ATSU - final String OTHER1_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2})" - + "( )*VALID"; - // Pattern used for extracting the ATSU - final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); - Matcher atsuother1Matcher = other1Pattern.matcher(theBulletin); - - // Regular expression for CONUS ATSU - final String CONUS2_EXP = "([A-Z]{4} ([A-Z]{4} )*)SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|" - + "GOLF|HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|" - + "TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; - // Pattern used for extracting the ATSU - final Pattern conus2Pattern = Pattern.compile(CONUS2_EXP); - Matcher atsuconus2Matcher = conus2Pattern.matcher(theBulletin); - - final String OTHER2_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the ATSU - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher atsuother2Matcher = other2Pattern.matcher(theBulletin); - - // Regular expression for others' ATSU - final String OTHER3_EXP = "([A-Z]{4}) SIGMET ([0-9]{1})( |\\W)*VALID( |\\W)*" - + "([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the ATSU - final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); - Matcher atsuother3Matcher = other3Pattern.matcher(theBulletin); - - // Get atsu - if (atsuconus2Matcher.find()) { - atsu = atsuconus2Matcher.group(1); - } else if (atsuconusMatcher.find()) { - atsu = atsuconusMatcher.group(1); - } else if (atsucanadaMatcher.find()) { - atsu = atsucanadaMatcher.group(5); - } else if (atsuother1Matcher.find()) { - atsu = atsuother1Matcher.group(1); - } else if (atsujapanMatcher.find()) { - atsu = atsujapanMatcher.group(1); - } else if (atsuother2Matcher.find()) { - atsu = atsuother2Matcher.group(1); - } else if (atsuother3Matcher.find()) { - atsu = atsuother3Matcher.group(1); - } - - return atsu; - } - - /** - * Obtains the location indicator of the meteorological watch office - * originating the message. - * - * @param theBulletin - * The input bulletin - * @return a string for omwo. - */ - public static String getOmwo(String theBulletin) { - - String omwo = " "; - - // Regular expression for CONUS OMWO - final String CONUS_EXP = "([A-Z]{4}) ([A-Z]{4} )?SIGMET ([A-Z])* ([0-9]{1}|[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the OMWO - final Pattern conusPattern = Pattern.compile(CONUS_EXP); - Matcher omwoconusMatcher = conusPattern.matcher(theBulletin); - - // Regular expression for CANADA OMWO - final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " - + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the OMWO - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher omwocanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK OMWO - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " - + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the OMWO - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher omwojapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for other OMWO - final String OTHER_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; - // Pattern used for extracting the OMWO - final Pattern otherPattern = Pattern.compile(OTHER_EXP); - Matcher omwootherMatcher = otherPattern.matcher(theBulletin); - - // Regular expression for others' OMWO - final String OTHER2_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|" - + "[A-Z]{2}[0-9]{2}|[A-Z]{1}[0-9]{2}) " - + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message OMWO - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher omwoother2Matcher = other2Pattern.matcher(theBulletin); - - // Regular expression for others' OMWO - final String OTHER3_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})" - + "( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message OMWO - final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); - Matcher omwoother3Matcher = other3Pattern.matcher(theBulletin); - - // Regular expression for others' OMWO - final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message OMWO - final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); - Matcher omwoother4Matcher = other4Pattern.matcher(theBulletin); - - // Regular expression for others' OMWO - final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " - + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the message OMWO - final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); - Matcher omwoother5Matcher = other5Pattern.matcher(theBulletin); - - // Regular expression for others' OMWO - final String OTHER6_EXP = "([A-Z]{4}) SIGMET ([0-9]{1})( |\\W)*" - + "VALID( |\\W)*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; - // Pattern used for extracting the OMWO - final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); - Matcher omwoother6Matcher = other6Pattern.matcher(theBulletin); - - // Get omwo - if (omwoconusMatcher.find()) { - omwo = omwoconusMatcher.group(8); - } else if (omwocanadaMatcher.find()) { - omwo = omwocanadaMatcher.group(5); - } else if (omwootherMatcher.find()) { - omwo = omwootherMatcher.group(6); - } else if (omwojapanMatcher.find()) { - omwo = omwojapanMatcher.group(7); - } else if (omwoother2Matcher.find()) { - omwo = omwoother2Matcher.group(8); - } else if (omwoother3Matcher.find()) { - omwo = omwoother3Matcher.group(7); - } else if (omwoother4Matcher.find()) { - omwo = omwoother4Matcher.group(8); - } else if (omwoother5Matcher.find()) { - omwo = omwoother5Matcher.group(8); - } else if (omwoother6Matcher.find()) { - omwo = omwoother6Matcher.group(8); - } - - return omwo; - } - - /** - * Obtains start time from input bulletin. - * - * @param theReport - * The bulletin message - * @return a calendar for start time - */ - public static Calendar getStartTime(String theBulletin, Headers headers) { - - String time = "???"; - - // Regular expression for general start time group - final String START_EXP = " VALID( )*([0-9]{6})/([0-9]{6})"; - // Pattern used for extracting the start time group - final Pattern startPattern = Pattern.compile(START_EXP); - Matcher timestartMatcher = startPattern.matcher(theBulletin); - - // Regular expression for CANADA start time group - final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}) VALID ([0-9]{6})/([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the start time group - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher timecanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK start time group - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " - + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the start time group - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher timejapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for others' start time - final String OTHER1_EXP = " VALID( )*([0-9]{6})(Z)?/([0-9]{6})(Z)?"; - // Pattern used for extracting the start time - final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); - Matcher time1Matcher = other1Pattern.matcher(theBulletin); - - // Regular expression for others' start time - final String OTHER2_EXP = " VALID( )*([0-9]{4})/([0-9]{4})"; - // Pattern used for extracting the start time - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher time2Matcher = other2Pattern.matcher(theBulletin); - - // Get time group - if (timestartMatcher.find()) { - time = timestartMatcher.group(2); - } else if (timejapanMatcher.find()) { - time = timejapanMatcher.group(4); - } else if (time1Matcher.find()) { - time = time1Matcher.group(2); - } else if (timecanadaMatcher.find()) { - time = timecanadaMatcher.group(2); - } else if (time2Matcher.find()) { - // Handle start time in special case without day - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{2})([0-9]{4})"; - // Pattern used for extracting WMO header, officeID, and issue date - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(theBulletin); - if (theMatcher.find()) { - time = time2Matcher.group(2).concat(theMatcher.group(3)); - } - } - if (time != "???") { - // Get start time - return TimeTools.findDataTime(time, headers); - } else { - return null; - } - } - - /** - * Get the end time - * - * @param theBulletin - * The bulletin which contains end time - * @return a calendar for end time - */ - public static Calendar getEndTime(String theBulletin, Headers headers) { - - String time = "???"; - - // Regular expression for CONUS end time group - final String ENDTIME_EXP = " VALID( )*([0-9]{6})/([0-9]{6})"; - // Pattern used for extracting the end time group - final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); - Matcher endtimeMatcher = endtimePattern.matcher(theBulletin); - - // Regular expression for CANADA end time group - final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}) " - + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; - // Pattern used for extracting the end time group - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher timecanadaMatcher = canadaPattern.matcher(theBulletin); - - // Regular expression for JAPAN and UK end time group - final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " - + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; - // Pattern used for extracting the end time group - final Pattern japanPattern = Pattern.compile(JAPAN_EXP); - Matcher timejapanMatcher = japanPattern.matcher(theBulletin); - - // Regular expression for others' end time - final String OTHER1_EXP = " VALID( )*([0-9]{6})(Z)?/([0-9]{6})(Z)?"; - // Pattern used for extracting the end time - final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); - Matcher time1Matcher = other1Pattern.matcher(theBulletin); - - // Regular expression for others' end time - final String OTHER2_EXP = " VALID( )*([0-9]{4})/([0-9]{4})"; - // Pattern used for extracting the end time - final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); - Matcher time2Matcher = other2Pattern.matcher(theBulletin); - - // Get time group - if (endtimeMatcher.find()) { - time = endtimeMatcher.group(3); - } else if (timejapanMatcher.find()) { - time = timejapanMatcher.group(4); - } else if (timecanadaMatcher.find()) { - time = timecanadaMatcher.group(4); - } else if (timecanadaMatcher.find()) { - time = timecanadaMatcher.group(6); - } else if (time1Matcher.find()) { - time = time1Matcher.group(4); - } else if (time2Matcher.find()) { - // Handle end time special case without day - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{2})([0-9]{4})"; - // Pattern used for extracting WMO header, officeID and issue time - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(theBulletin); - if (theMatcher.find()) { - time = time2Matcher.group(3).concat(theMatcher.group(3)); - } - } - - if (time != "???") { - // Get end time - Calendar mndTime = null; - return TimeTools.findDataTime(time, headers); - } else { - return null; - } - } - - /** - * Parse the bulletin and store flight level 1 or level 2 if any. - * - * @param theBulletin - * The bulletin message - * @param record - * The main table - */ - public static void processFlightLevels(String theBulletin, - IntlSigmetRecord record) { - - String flevel1 = " "; - String flevel2 = " "; - - // Regular expression for general one flight level - final String FLEVEL1_EXP = "(TOP|TOPS|TOPS TO) FL( )?([0-9]{3})"; - // Pattern used for extracting the flight level - final Pattern flevel1Pattern = Pattern.compile(FLEVEL1_EXP); - Matcher flevel1Matcher = flevel1Pattern.matcher(theBulletin); - - // Regular expression for flight levels in format "BETWEEN ... AND ...." - final String BETWEEN_EXP = "(BETWEEN|BTN) (FL)?([0-9]{3}|[0-9]{2}) AND " - + "(FL)?([0-9]{3}|[0-9]{2})"; - // Pattern used for extracting the flight levels - final Pattern betweenPattern = Pattern.compile(BETWEEN_EXP); - Matcher betweenMatcher = betweenPattern.matcher(theBulletin); - - // Regular expression for flight levels in format - // "TOPS ... MAX TOPS ...." for Canada - final String MAXTOPS_EXP = "TOPS( |\\x0d\\x0d\\x0a)([0-9]{3}|[0-9]{2}) " - + "MAX TOPS ([0-9]{3}|[0-9]{2})"; - // Pattern used for extracting the flight levels - final Pattern maxtopsPattern = Pattern.compile(MAXTOPS_EXP); - Matcher maxtopsMatcher = maxtopsPattern.matcher(theBulletin); - - // Regular expression for general two flight levels in "360-440" or - // "360/440" format - final String FLEVEL2_EXP = "FL([0-9]{3}|[0-9]{2})(-|/)([0-9]{3}|[0-9]{2})"; - // Pattern used for extracting the flight levels - final Pattern flevel2Pattern = Pattern.compile(FLEVEL2_EXP); - Matcher flevel2Matcher = flevel2Pattern.matcher(theBulletin); - - // Regular expression for general one flight level - final String FLEVEL3_EXP = "(TOP|TOPS|TOPS TO) (FL )?([0-9]{3})"; - // Pattern used for extracting the flight level - final Pattern flevel3Pattern = Pattern.compile(FLEVEL3_EXP); - Matcher flevel3Matcher = flevel3Pattern.matcher(theBulletin); - - final String FLEVEL4_EXP = "FL([0-9]{3})"; - // Pattern used for extracting the flight level - final Pattern flevel4Pattern = Pattern.compile(FLEVEL4_EXP); - Matcher flevel4Matcher = flevel4Pattern.matcher(theBulletin); - - // Get flight levels group - if (maxtopsMatcher.find()) { - flevel1 = maxtopsMatcher.group(3); - } else if (flevel2Matcher.find()) { - flevel1 = flevel2Matcher.group(1); - flevel2 = flevel2Matcher.group(3); - } else if (betweenMatcher.find()) { - flevel1 = betweenMatcher.group(3); - flevel2 = betweenMatcher.group(5); - } else if (flevel1Matcher.find()) { - flevel1 = flevel1Matcher.group(3); - } else if (flevel3Matcher.find()) { - flevel1 = flevel3Matcher.group(3); - } else if (flevel4Matcher.find()) { - flevel1 = flevel4Matcher.group(1); - } - - // Set flight levels to database - if (flevel1 != " ") { - record.setFlightlevel1(Integer.parseInt(flevel1)); - } - if (flevel2 != " ") { - record.setFlightlevel2(Integer.parseInt(flevel2)); - } - - // Parse the locations - processLocation(theBulletin, record); - - } - - /** - * Obtains remarks from a bulletin - * - * @param bullMessage - * The bulletin message - * @return a string for remarks - */ - public static String getRemarks(String bullMessage) { - - String retRemarks = " "; - - // Regular expression correction - final String CORR_EXP = "(COR | (CC[A-Z]{1}))"; - - // Pattern used for extracting correction - final Pattern corrPattern = Pattern.compile(CORR_EXP); - Matcher corrMatcher = corrPattern.matcher(bullMessage); - - // Regular expression amendment - final String AMD_EXP = "(AMD )"; - // Pattern used for extracting amendment - final Pattern amdPattern = Pattern.compile(AMD_EXP); - Matcher amdMatcher = amdPattern.matcher(bullMessage); - - // Regular expression for TEST - final String TEST_EXP = "TEST "; - // Pattern used for extracting test - final Pattern testPattern = Pattern.compile(TEST_EXP); - Matcher testMatcher = testPattern.matcher(bullMessage); - - if (corrMatcher.find()) { - retRemarks = corrMatcher.group(1); - } else if (amdMatcher.find()) { - retRemarks = amdMatcher.group(); - } else if (testMatcher.find()) { - retRemarks = "TEST"; - } - - return retRemarks; - } - - /** - * Obtains speed from a bulletin - * - * @param bullMessage - * The bulletin message - * @return an integer for speed - */ - public static Integer getSpeed(String bullMessage) { - - Integer retSpeed = IDecoderConstantsN.INTEGER_MISSING; - - final String SPEED_EXP = "(MOVE|MOV|MOVG) (|E|N|S|W|\006|\012)* " - + "([0-9]{1}|[0-9]{2})(-[0-9]{2})?( )?(KT)"; - // Pattern used for extracting speed for general - final Pattern speedPattern = Pattern.compile(SPEED_EXP); - Matcher theMatcher = speedPattern.matcher(bullMessage); - - final String CANADA1_EXP = "(MOVE |MOV |MOVG )?([ENSW]{1})WD " - + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; - // Pattern used for extracting speed for Canada - final Pattern canada1Pattern = Pattern.compile(CANADA1_EXP); - Matcher canada1Matcher = canada1Pattern.matcher(bullMessage); - - final String CANADA2_EXP = "(MOVE |MOV |MOVG )?([ENSW]{2})WD " - + "([0-9]{2}|[0-9]{1})(\\x0d\\x0d\\x0a| )?KT"; - // Pattern used for extracting speed for Canada - final Pattern canada2Pattern = Pattern.compile(CANADA2_EXP); - Matcher canada2Matcher = canada2Pattern.matcher(bullMessage); - - final String KMH_EXP = "([0-9]{2}|[0-9]{3})(( )*|( )?\\x0d\\x0d\\x0a)KMH"; - // Pattern used for extracting speed for KMH - final Pattern kmhPattern = Pattern.compile(KMH_EXP); - Matcher kmhMatcher = kmhPattern.matcher(bullMessage); - - if (theMatcher.find()) { - retSpeed = Integer.parseInt(theMatcher.group(3)); - } else if (canada1Matcher.find()) { - retSpeed = Integer.parseInt(canada1Matcher.group(3)); - } else if (canada2Matcher.find()) { - retSpeed = Integer.parseInt(canada2Matcher.group(3)); - } else if (kmhMatcher.find()) { - Integer kmhSpeed = Integer.parseInt(kmhMatcher.group(1)); - // Convert KMH to Knots - float speed = (float) (((double) kmhSpeed * 1000.0 / 3600.0) * 1.9425); - retSpeed = (int) speed; - } - - return retSpeed; - } - - /** - * Obtains intensity from a bulletin - * - * @param bullMessage - * The bulletin message - * @return a string for intensity - */ - public static String getIntensity(String bullMessage) { - - String intensity = null; - - // Regular expression for intensity - final String INTENSITY_EXP = "( NC | INTSF| WKN | NC=|WKN=|NC.|WKNG )"; - // Pattern used for extracting intensityFlag - final Pattern intensityPattern = Pattern.compile(INTENSITY_EXP); - Matcher theMatcher = intensityPattern.matcher(bullMessage); - - if (theMatcher.find()) { - intensity = theMatcher.group(1); - intensity = UtilN.removeLeadingWhiteSpaces(intensity); - if (intensity.substring(0, 2).equals("NC")) { - intensity = "NC"; - } else if (intensity.substring(0, 3).equals("WKN")) { - intensity = "WKN"; - } - } - - return intensity; - } - - /** - * Obtains direction from a bulletin - * - * @param bullMessage - * The bulletin message - * @return a string for direction - */ - public static String getDirection(String bullMessage) { - - String direction = null; - - final String CANADA1_EXP = "(MOVE |MOV |MOVG )?([ENSW]{1})WD " - + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; - // Pattern used for extracting direction for Canada - final Pattern canada1Pattern = Pattern.compile(CANADA1_EXP); - Matcher canada1Matcher = canada1Pattern.matcher(bullMessage); - - final String CANADA2_EXP = "(MOVE |MOV |MOVG )?([ENSW]{2})WD " - + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; - // Pattern used for extracting direction for Canada - final Pattern canada2Pattern = Pattern.compile(CANADA2_EXP); - Matcher canada2Matcher = canada2Pattern.matcher(bullMessage); - - // Regular expression for direction - final String DIRECTION_EXP = "(MOVE|MOV|MOVG) ([ENSW]{3}|[ENSW]{2}|[ENSW]{1})"; - // Pattern used for extracting direction for general - final Pattern directionPattern = Pattern.compile(DIRECTION_EXP); - Matcher theMatcher = directionPattern.matcher(bullMessage); - - final String DIR2_EXP = "(MOVE|MOV|MOVG)(\\D)*([ENSW]{3}|[ENSW]{2}|[ENSW]{1}) "; - // Pattern used for extracting direction for Canada - final Pattern dir2Pattern = Pattern.compile(DIR2_EXP); - Matcher dir2Matcher = dir2Pattern.matcher(bullMessage); - - final String DIR3_EXP = "(MOVE|MOV|MOVG) (SOUTH|NORTH|WEST|EAST) "; - // Pattern used for extracting direction for Canada - final Pattern dir3Pattern = Pattern.compile(DIR3_EXP); - Matcher dir3Matcher = dir3Pattern.matcher(bullMessage); - - if (canada2Matcher.find()) { - direction = canada2Matcher.group(2); - } else if (canada1Matcher.find()) { - direction = canada1Matcher.group(2); - } else if (theMatcher.find()) { - direction = theMatcher.group(2); - } else if (dir2Matcher.find()) { - direction = dir2Matcher.group(3); - } else if (dir3Matcher.find()) { - direction = dir3Matcher.group(2); - if (direction.equals("SOUTH")) { - direction = "S"; - } else if (direction.equals("NORTH")) { - direction = "N"; - } else if (direction.equals("WEST")) { - direction = "W"; - } else if (direction.equals("EAST")) { - direction = "E"; - } - } - return direction; - } - - /** - * Parse the location to set Lat/Lon or location name - * - * @param theLocation - * The location with lat/lon or location name - * @param locTb - * The location table - */ - public static void processLatLon(String theLocation, - IntlSigmetLocation locTb, Integer index, IntlSigmetRecord record) { - - double flat, flon; - - final String LATLON1_EXP = "(N|S)([0-9]{2})([0-9]{2}) (E|W)([0-9]{3})([0-9]{2})"; - // Pattern used for extracting latlon - CONUS - final Pattern latlon1Pattern = Pattern.compile(LATLON1_EXP); - Matcher latlon1Matcher = latlon1Pattern.matcher(theLocation); - - final String LATLON2_EXP = "/([0-9]{2})([0-9]{2})(N|S)([0-9]{3})" - + "([0-9]{2})(E|W)/((\\S|\\s|\\D)*)"; - // Pattern used for extracting latlon - Canada - final Pattern latlon2Pattern = Pattern.compile(LATLON2_EXP); - Matcher latlon2Matcher = latlon2Pattern.matcher(theLocation); - - final String LATLON3_EXP = "(N|S)([0-9]{2})([0-9]{2})(E|W)([0-9]{3})([0-9]{2})"; - // Pattern used for extracting latlon - final Pattern latlon3Pattern = Pattern.compile(LATLON3_EXP); - Matcher latlon3Matcher = latlon3Pattern.matcher(theLocation); - - final String LATLON4_EXP = "(N|S)([0-9]{2})(E|W)([0-9]{3}|[0-9]{2})"; - // Pattern used for extracting latlon - final Pattern latlon4Pattern = Pattern.compile(LATLON4_EXP); - Matcher latlon4Matcher = latlon4Pattern.matcher(theLocation); - - final String LATLON5_EXP = "([0-9]{2})(N|S)([0-9]{3}|[0-9]{2})(E|W)"; - // Pattern used for extracting latlon - Japan - final Pattern latlon5Pattern = Pattern.compile(LATLON5_EXP); - Matcher latlon5Matcher = latlon5Pattern.matcher(theLocation); - - final String LATLON6_EXP = "([0-9]{2})([0-9]{2})(N|S)([0-9]{3})([0-9]{2})(E|W)"; - // Pattern used for extracting latlon - final Pattern latlon6Pattern = Pattern.compile(LATLON6_EXP); - Matcher latlon6Matcher = latlon6Pattern.matcher(theLocation); - - final String LATLON7_EXP = "(N|S)([0-9]{2})([0-9]{2})[\\W| ]*(E|W)" - + "([0-9]{3})([0-9]{2})"; - // Pattern used for extracting latlon - final Pattern latlon7Pattern = Pattern.compile(LATLON7_EXP); - Matcher latlon7Matcher = latlon7Pattern.matcher(theLocation); - - final String LATLON8_EXP = "(N|S)([0-9]{2})( )*(E|W)([0-9]{3}|[0-9]{2})"; - // Pattern used for extracting latlon - final Pattern latlon8Pattern = Pattern.compile(LATLON8_EXP); - Matcher latlon8Matcher = latlon8Pattern.matcher(theLocation); - - double NSFlag = 1.0; - double EWFlag = 1.0; - double seconds = 60.0; - LatLonPoint point = null; - - if (record.getWmoHeader().equals("WSMC31")) { - // WSMC31 issues lat/lon in decimals. - seconds = 100.0; - } - - if (latlon1Matcher.find()) { - // latlon format for CONUS - if (latlon1Matcher.group(1).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag - * (Integer.parseInt(latlon1Matcher.group(2)) + (Integer - .parseInt(latlon1Matcher.group(3)) / seconds)); - if (latlon1Matcher.group(4).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag - * (Integer.parseInt(latlon1Matcher.group(5)) + (Integer - .parseInt(latlon1Matcher.group(6)) / seconds)); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon1Matcher.group()); - } else if (latlon2Matcher.find()) { - // latlon format for Canada - if (latlon2Matcher.group(3).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag - * (Integer.parseInt(latlon2Matcher.group(1)) + (Integer - .parseInt(latlon2Matcher.group(2)) / seconds)); - if (latlon2Matcher.group(6).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag - * (Integer.parseInt(latlon2Matcher.group(4)) + (Integer - .parseInt(latlon2Matcher.group(5)) / seconds)); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon2Matcher.group(7)); - } else if (latlon3Matcher.find()) { - if (latlon3Matcher.group(1).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag - * (Integer.parseInt(latlon3Matcher.group(2)) + (Integer - .parseInt(latlon3Matcher.group(3)) / seconds)); - if (latlon3Matcher.group(4).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag - * (Integer.parseInt(latlon3Matcher.group(5)) + (Integer - .parseInt(latlon3Matcher.group(6)) / seconds)); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon3Matcher.group()); - } else if (latlon4Matcher.find()) { - if (latlon4Matcher.group(1).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag * (Integer.parseInt(latlon4Matcher.group(2))); - if (latlon4Matcher.group(3).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag * (Integer.parseInt(latlon4Matcher.group(4))); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon4Matcher.group()); - } else if (latlon5Matcher.find()) { - if (latlon5Matcher.group(2).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag * (Integer.parseInt(latlon5Matcher.group(1))); - if (latlon5Matcher.group(4).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag * (Integer.parseInt(latlon5Matcher.group(3))); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon5Matcher.group()); - } else if (latlon6Matcher.find()) { - // latlon6 format - if (latlon6Matcher.group(3).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag - * (Integer.parseInt(latlon6Matcher.group(1)) + (Integer - .parseInt(latlon6Matcher.group(2)) / seconds)); - if (latlon6Matcher.group(6).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag - * (Integer.parseInt(latlon6Matcher.group(4)) + (Integer - .parseInt(latlon6Matcher.group(5)) / seconds)); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon6Matcher.group()); - } else if (latlon7Matcher.find()) { - // latlon format - if (latlon7Matcher.group(1).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag - * (Integer.parseInt(latlon7Matcher.group(2)) + (Integer - .parseInt(latlon7Matcher.group(3)) / seconds)); - if (latlon7Matcher.group(4).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag - * (Integer.parseInt(latlon7Matcher.group(5)) + (Integer - .parseInt(latlon7Matcher.group(6)) / seconds)); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon7Matcher.group()); - } else if (latlon8Matcher.find()) { - if (latlon8Matcher.group(1).equals("S")) { - NSFlag = -1.0; - } - flat = NSFlag * (Integer.parseInt(latlon8Matcher.group(2))); - if (latlon8Matcher.group(4).equals("W")) { - EWFlag = -1.0; - } - flon = EWFlag * (Integer.parseInt(latlon8Matcher.group(5))); - locTb.setLatitude(flat); - locTb.setLongitude(flon); - locTb.setLocationName(latlon8Matcher.group()); - } else { - System.out.println("theLocation=" + theLocation); - if ((index == 0) - && ((theLocation.substring(0, 3).equals("IN ")) || theLocation - .substring(0, 3).equals("OF "))) { - // handle special case with "IN " or "OF " and location - String retLoc = theLocation.substring(3); - locTb.setLocationName(retLoc); - // Get a latLonPoint for this station ID from "vors" location - // table - point = LatLonLocTbl.getLatLonPoint(retLoc, "vors"); - locTb.setLatitude(point.getLatitude(LatLonPoint.INDEGREES)); - locTb.setLongitude(point.getLongitude(LatLonPoint.INDEGREES)); - } else { - locTb.setLocationName(theLocation); - // Get a latLonPoint for this station ID from "vors" location - // table - point = LatLonLocTbl.getLatLonPoint(theLocation, "vors"); - locTb.setLatitude(point.getLatitude(LatLonPoint.INDEGREES)); - locTb.setLongitude(point.getLongitude(LatLonPoint.INDEGREES)); - - } - } - } - - /** - * Obtains distance or radius from a bulletin for a "LINE" type - * - * @param bullMessage - * The bulletin message - * @return an integer of distance - */ - public static Integer getDistance(String bullMessage) { - - Integer retDistance = IDecoderConstantsN.INTEGER_MISSING; - - // Regular expression for distance - final String DISTANCE_EXP = "(WI )?([0-9]{2}|[0-9]{3})( )?NM "; - // Pattern used for extracting distance - final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); - Matcher theMatcher = distancePattern.matcher(bullMessage); - - // Regular expression distance for Canada - final String CANADA_EXP = "WTN ([0-9]{2}|[0-9]{3}) NM OF LN "; - // Pattern used for extracting distance for CANADA sigmet - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher canadaMatcher = canadaPattern.matcher(bullMessage); - - if (theMatcher.find()) { - retDistance = Integer.parseInt(theMatcher.group(2)); - } else if (canadaMatcher.find()) { - retDistance = Integer.parseInt(canadaMatcher.group(1)); - } - return retDistance; - } - - /** - * Get name location for the VA, TC, or HU.... - * - * @param bullMessage - * The bulletin message - * @return a string for nameLocation - */ - public static String getNameLocation(String bullMessage) { - - String retLocation = " "; - - final String VA_EXP = "MT (\\S)*-PEAK LOC ([NS][0-9]{4} [EW][0-9]{5}) "; - // Pattern used for extracting VA nameLocation - final Pattern vaPattern = Pattern.compile(VA_EXP); - Matcher vaMatcher = vaPattern.matcher(bullMessage); - - final String TC_EXP = " TC ((\\S)* FCST (\\S)* (\\S)*) "; - // Pattern used for extracting TC nameLocation - final Pattern tcPattern = Pattern.compile(TC_EXP); - Matcher tcMatcher = tcPattern.matcher(bullMessage); - - // final String HUR1_EXP = "(HURRICANE IRENE LOCATED AT )"; - final String HUR1_EXP = "(HURRICANE ([A-Z])* LOCATED AT ([\\w|.])* ([\\w|.])*) MOVG"; - // Pattern used for extracting Hurricane nameLocation - final Pattern hur1Pattern = Pattern.compile(HUR1_EXP); - Matcher hur1Matcher = hur1Pattern.matcher(bullMessage); - - final String HUR2_EXP = "(HURCN ([A-Z])* NEAR ([\\w|.])* ([\\w|.])*) "; - // Pattern used for extracting Hurricane nameLocation - final Pattern hur2Pattern = Pattern.compile(HUR2_EXP); - Matcher hur2Matcher = hur2Pattern.matcher(bullMessage); - - final String TS_EXP = "(TROPICAL STORM ([A-Z])* (\\w)*)"; - // Pattern used for extracting Tropical Storm nameLocation - final Pattern tsPattern = Pattern.compile(TS_EXP); - Matcher tsMatcher = tsPattern.matcher(bullMessage); - - final String TD_EXP = "(TROPICAL (DEPRESSION )?([A-Z])* (\\w)*)"; - // Pattern used for extracting Tropical Depression nameLocation - final Pattern tdPattern = Pattern.compile(TD_EXP); - Matcher tdMatcher = tdPattern.matcher(bullMessage); - - if (vaMatcher.find()) { - retLocation = vaMatcher.group(); - } else if (tcMatcher.find()) { - retLocation = tcMatcher.group(1); - } else if (hur1Matcher.find()) { - retLocation = hur1Matcher.group(1); - } else if (hur2Matcher.find()) { - retLocation = hur2Matcher.group(1); - } else if (tsMatcher.find()) { - retLocation = tsMatcher.group(1); - } else if (tdMatcher.find()) { - retLocation = tdMatcher.group(1); - } - - return retLocation; - } - - /** - * Obtains polygon extent from a bulletin for a "LINE" type or a polygon - * type - * - * @param bullMessage - * The bulletin message - * @return a string - */ - public static String getPolygonExtent(String bullMessage) { - - String retStr = ""; - - // Regular expression for distance - final String DISTANCE_EXP = "(WI )?([0-9]{2}|[0-9]{3})( )?NM "; - // Pattern used for extracting distance - final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); - Matcher theMatcher = distancePattern.matcher(bullMessage); - - // Regular expression for line - final String LINE_EXP = " ([0-9]{2}|[0-9]{3})( )?NM (EITHER SIDE OF)"; - // Pattern used for extracting line information - final Pattern linePattern = Pattern.compile(LINE_EXP); - Matcher lineMatcher = linePattern.matcher(bullMessage); - - // Regular expression distance for Canada - final String CANADA_EXP = "(WTN|WITHIN) ([0-9]{2}|[0-9]{3})( )?NM OF (LN|LINE)"; - // Pattern used for extracting distance for CANADA sigmet - final Pattern canadaPattern = Pattern.compile(CANADA_EXP); - Matcher canadaMatcher = canadaPattern.matcher(bullMessage); - - // Regular expression for POLYGON - final String POLYGON_EXP = " ([0-9]{2}|[0-9]{3})( )?NM ([EWSN]|[EWSN]{2}|[EWSN]{3}) OF"; - // Pattern used for extracting POLYGON information - final Pattern polygonPattern = Pattern.compile(POLYGON_EXP); - Matcher polygonMatcher = polygonPattern.matcher(bullMessage); - - if (canadaMatcher.find()) { - retStr = canadaMatcher.group(1); - } else if (lineMatcher.find()) { - retStr = lineMatcher.group(3); - } else if (polygonMatcher.find()) { - retStr = polygonMatcher.group(3).concat(" OF"); - } else if (theMatcher.find()) { - retStr = theMatcher.group(1); - } - - return retStr; - } - - /** - * Parse the location lines and add location table to the main record table - * if any - * - * @param theBulletin - * The report from bulletin message - * @param record - * The main table - * @return a boolean true if any location exists. - */ - public static boolean processLocation(String theBulletin, - IntlSigmetRecord record) { - - boolean ret = false; - - String locationDelimiter = "-"; - String retLocation = "?"; - int locPositionIndex = -1; - - ArrayList terminationList = new ArrayList(); - // Locations ends with these key words - terminationList.addAll(Arrays - .asList(new String[] { "TOP", "SEV", "BKN", "STNR", "ISOL", - "MOV", "SOLID", "TOPS", "AREA", "BTN", "STG", "SEVERE", - "INTSF=", "MAINLY", "SIGMET", "OCNL", "WKN", "PL", - "FZRA", "LLWS", "TURB", "STR", "FCST", "VA", "MDT", - "STRONG", "LN", "AT", "BASED", "OF", "SVR", "OVER", - "TS", "AND", "OBL", "TURBUL", "BLW", "TOP", "TORNADO", - "CORRECTION" })); - - final String LATLON1_EXP = "(N|S)([0-9]{4}) (E|W)([0-9]{5}) -"; - // Pattern used for extracting latlon - final Pattern latlon1Pattern = Pattern.compile(LATLON1_EXP); - Matcher latlon1Matcher = latlon1Pattern.matcher(theBulletin); - - final String LATLON2_EXP = "/([0-9]{4})(N|S)([0-9]{5})(E|W)/"; - // Pattern used for extracting latlon - final Pattern latlon2Pattern = Pattern.compile(LATLON2_EXP); - Matcher latlon2Matcher = latlon2Pattern.matcher(theBulletin); - - final String LATLON3_EXP = "(N|S)([0-9]{4})(E|W)([0-9]{5})-"; - // Pattern used for extracting latlon - final Pattern latlon3Pattern = Pattern.compile(LATLON3_EXP); - Matcher latlon3Matcher = latlon3Pattern.matcher(theBulletin); - - final String LATLON4_EXP = "(N|S)([0-9]{2})(E|W)([0-9]{3})"; - // Pattern used for extracting latlon - final Pattern latlon4Pattern = Pattern.compile(LATLON4_EXP); - Matcher latlon4Matcher = latlon4Pattern.matcher(theBulletin); - - final String LATLON5_EXP = "([0-9]{2})(N|S)([0-9]{3}|[0-9]{2})(E|W)"; - // Pattern used for extracting latlon - final Pattern latlon5Pattern = Pattern.compile(LATLON5_EXP); - Matcher latlon5Matcher = latlon5Pattern.matcher(theBulletin); - - final String LATLON6_EXP = "([0-9]{4})(N|S)([0-9]{5})(E|W)"; - // Pattern used for extracting latlon - final Pattern latlon6Pattern = Pattern.compile(LATLON6_EXP); - Matcher latlon6Matcher = latlon6Pattern.matcher(theBulletin); - - final String LATLON7_EXP = " [A-Z]*( )?-( )?[A-Z]*( )?-"; - // Pattern used for extracting latlon - final Pattern latlon7Pattern = Pattern.compile(LATLON7_EXP); - Matcher latlon7Matcher = latlon7Pattern.matcher(theBulletin); - - final String LATLON9_EXP = " [A-Z]* [A-Z]*/(\\w| )*/"; - // Pattern used for extracting latlon - final Pattern latlon9Pattern = Pattern.compile(LATLON9_EXP); - Matcher latlon9Matcher = latlon9Pattern.matcher(theBulletin); - - // Find the position of first location - if (latlon7Matcher.find()) { - retLocation = latlon7Matcher.group(); - } else if (latlon1Matcher.find()) { - retLocation = latlon1Matcher.group(); - } else if (latlon2Matcher.find()) { - retLocation = latlon2Matcher.group(); - } else if (latlon3Matcher.find()) { - retLocation = latlon3Matcher.group(); - } else if (latlon4Matcher.find()) { - retLocation = latlon4Matcher.group(); - } else if (latlon5Matcher.find()) { - retLocation = latlon5Matcher.group(); - } else if (latlon6Matcher.find()) { - retLocation = latlon6Matcher.group(); - } else if (latlon9Matcher.find()) { - retLocation = latlon9Matcher.group(); - int sigmetIndex = retLocation.indexOf("SIGMET"); - int fcstIndex = retLocation.indexOf("FCST "); - int innIndex = retLocation.indexOf("IN N/"); - int sfcIndex = retLocation.indexOf(" SFC"); - int obsIndex = retLocation.indexOf(" OBS"); - // Handle special cases and throw them away - if (sigmetIndex != -1) { - retLocation = "?"; - } else if (fcstIndex != -1) { - retLocation = "?"; - } else if (innIndex != -1) { - retLocation = "?"; - } else if (sfcIndex != -1) { - retLocation = "?"; - } else if (obsIndex != -1) { - retLocation = "?"; - } - - } - - locPositionIndex = theBulletin.indexOf(retLocation); - - if (locPositionIndex > 0) { - String secondHalf = theBulletin.substring(locPositionIndex); - Scanner scLocationLine = new Scanner(secondHalf) - .useDelimiter("\\x0d\\x0d\\x0a"); - String lines = " "; - String curLine = null; - ArrayList locationList = new ArrayList(); - locationList.clear(); - Boolean notBreak = true; - - while (scLocationLine.hasNext() && notBreak) { - // Get next location line - curLine = scLocationLine.next(); - - Scanner scLocationToken = new Scanner(curLine); - while (scLocationToken.hasNext() && notBreak) { - // Check the token from each line - String token = scLocationToken.next(); - if (terminationList.contains(token)) { - // terminate and get the locations in this line - int token_pos = curLine.indexOf(token); - lines = lines.concat(" ").concat( - curLine.substring(0, token_pos)); - notBreak = false; - break; - } - } - if (notBreak) { - lines = lines.concat(" ").concat(curLine); - } - } - - // Clean up the leading space - lines = UtilN.removeLeadingWhiteSpaces(lines); - lines = removeChar(lines, '\r'); - lines = removeChar(lines, '\n'); - - // Decide the location delimiter. - Boolean whiteDel = false; - int dashPos = lines.indexOf("-"); - int slashPos = lines.indexOf("/"); - if (dashPos != -1) { - locationDelimiter = "-"; - } else if (slashPos != -1) { - locationDelimiter = "/"; - } else { - locationDelimiter = " "; - whiteDel = true; - } - // Parse the location lines by a "-", "/", or " ". - Scanner scLocation = new Scanner(lines) - .useDelimiter(locationDelimiter); - - locationList.clear(); - // Get all locations - while (scLocation.hasNext()) { - // Clean up the leading space - String location = UtilN.removeLeadingWhiteSpaces(scLocation - .next()); - if (whiteDel) { - // white space as delimiter - int lengthOfLocation = location.length(); - if (lengthOfLocation > 2) { - if (Character.isDigit(location.toCharArray()[0]) - && (lengthOfLocation > 2)) { - locationList.add(location); - } else if (Character.isDigit(location.toCharArray()[1]) - && (lengthOfLocation > 2)) { - locationList.add(location); - } - } - } else if ((location.length() > 0) - && (!location.substring(0, 2).equals("FL"))) { - // exception handle for a "FL" false location - locationList.add(location); - } - } - - // set locations to data base - Integer idxLocation = 0; - if (locationList.size() > 1) { - for (String Location : locationList) { - IntlSigmetLocation currentLocation = new IntlSigmetLocation(); - currentLocation.setLocationLine(lines); - // currentLocation.setLocationName(Location); - processLatLon(Location, currentLocation, idxLocation, - record); - currentLocation.setIndex(idxLocation + 1); - idxLocation++; - - record.addIntlSigmetLocation(currentLocation); - } - ret = true; - } - } - return ret; - } - - /** - * Get detail information for Thunderstorm. - * - * @param theReport - * the input bulletin - * @return a string for Thunderstorm - */ - public static String getThunderStorm(String theReport) { - - String retTS = "THUNDERSTORM"; - // Regular expression for tsType - final String TSTYPE_EXP = "(SQL EMBD TS |ISOL EMBD TS |EMBD TS GR |ISOL TS |EMBD TS |" - + "FRQ TS|SQL TS |TS GR |OBSC TS|FRQ TSGR |OCNL TS |EMBD TSGR | TSGR | GR |" - + "TS/CB|CB/TS)"; - // Pattern used for extracting hazardType - final Pattern tsTypePattern = Pattern.compile(TSTYPE_EXP); - Matcher tsMatcher = tsTypePattern.matcher(theReport); - - if (tsMatcher.find()) { - if (tsMatcher.group(1).equals("EMBD TS GR ")) { - retTS = "EMBEDED THUNDERSTORMS HAIL"; - } else if (tsMatcher.group(1).equals("SQL EMBD TS ")) { - retTS = "SQUALL EMBEDED THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("ISOL EMBD TS ")) { - retTS = "ISOLATED EMBEDED THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("ISOL TS ")) { - retTS = "ISOLATED THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("EMBD TS ")) { - retTS = "EMBEDED THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("FRQ TS")) { - retTS = "FREQUENT THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("SQL TS ")) { - retTS = "SQUALL THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("TS GR ")) { - retTS = "THUNDERSTORMS HAIL"; - } else if (tsMatcher.group(1).equals("OBSC TS")) { - retTS = "OBSCURE THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("FRQ TSGR ")) { - retTS = "FREQUENT THUNDERSTORMS HAIL"; - } else if (tsMatcher.group(1).equals("OCNL TS ")) { - retTS = "OCCASIONAL THUNDERSTORMS"; - } else if (tsMatcher.group(1).equals("EMBD TSGR ")) { - retTS = "EMBEDED THUNDERSTORMS HAIL"; - } else if (tsMatcher.group(1).equals(" TSGR ")) { - retTS = "THUNDERSTORMS HAIL"; - } else if (tsMatcher.group(1).equals(" GR ")) { - retTS = "HAIL"; - } else if (tsMatcher.group(1).equals("TS/CB")) { - retTS = "THUNDERSTORMS CUMULONIMBUS"; - } else if (tsMatcher.group(1).equals("CB/TS")) { - retTS = "THUNDERSTORMS CUMULONIMBUS"; - } - } - - return retTS; - } - - /** - * Remove a character from a string and return the result. - * - * @param s - * the string - * @param c - * the character to be removed - * @return a string. - */ - public static String removeChar(String s, char c) { - - String ret = ""; - - for (int i = 0; i < s.length(); i++) { - if (s.charAt(i) != c) - ret += s.charAt(i); - } - - return ret; - } - -} +/** + * IntlSigmet DecoderUtil + * + * This java class intends to serve as a decoder utility for INTLSIGMET. + * + * HISTORY + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 113 L. Lin Initial coding + * 07/2009 113 L. Lin Migration to TO11 + * 09/2009 113 L. Lin Convert station ID to lat/lon + * if any exists. + * 11/2011 512 S. Gurung Fixed NullPointerException bug while processing lat/lon (from vors) + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.intlsigmet.util; + +import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetLocation; +import gov.noaa.nws.ncep.common.dataplugin.intlsigmet.IntlSigmetRecord; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; +import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class IntlSigmetParser { + + private static final String CONUS_EXP = "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|HOTEL|" + + "INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|TANGO|" + + "UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; + + /** + * Constructor + */ + public IntlSigmetParser() { + } + + /** + * Parse the WMO line and store WMO header, OfficeID, issue time, ... + * + * @param wmoline + * The bulletin message + * + * @return an IntlSigmetRecord + */ + public static IntlSigmetRecord processWMO(String wmoline, Headers headers) { + + IntlSigmetRecord record = null; + // Regular expression for WMO/ICAO, station ID, and issue date. + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})"; + + // Pattern used for extracting WMO header, officeID, and issue date. + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(wmoline); + + if (theMatcher.find()) { + record = new IntlSigmetRecord(); + + record.setWmoHeader(theMatcher.group(1)); + record.setIssueOffice(theMatcher.group(2)); + + // Decode the issue time. + Calendar mndTime = null; + Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), + headers); + record.setIssueTime(issueTime); + + DataTime dataTime = new DataTime(issueTime); + record.setDataTime(dataTime); + } + return record; + } + + /** + * Obtains hazardType as: TS (thunderstorm), TB (turbulence), HU + * (hurricane), TR (tropical storm), TD (tropical depression), VA (volcanic + * ash cloud), MW (marked mountain waves), TC (tropical cyclone), SQ (squall + * line), CT (CAT), IC (icing), GR (hail), DS (duststorm), SS (sandstorm), + * CB (cumulonimbus), WS (low level wind shear), TEST, or CN (cancel), + * etc... + * + * @param theReport + * Input report message. + * @return a string for hazard type + */ + public static String getHazardType(String theReport) { + + String retHazardType = " "; + // Regular expression for hazardType + final String HAZARDTYPE_EXP = "(HURRICANE|HURCN |TROPICAL STORM|TROPICAL DEPRESSION|" + + " TD | SQL | TS | TS/|FRQ TS| TS| SH/TS |TURB| CB | VA | MTW |" + + " ICE | TR | GR | TC | CT | CAT | DS | SS | WS | TSGR |VOLCANIC ASH|HVYSS|" + + " ICG|ICING|LLWS|WATERSPOUTS|THUNDERSTORMS|WIND|TS OBS|CB/TS|TORNADO)"; + final String NIL_EXP = "(NIL)"; + final String MIS_EXP = "(TAF |METAR )"; + final String CNL_EXP = "(CANCEL| CNL | CNCL |:CNL| CNL|INVALID|DISCARDED|" + + "CNL SIGMET| CLN SIGMET|CNCLD)"; + final String TEST_EXP = "(TEST |DISREGARD)"; + + // Pattern used for extracting hazardType + final Pattern hazardTypePattern = Pattern.compile(HAZARDTYPE_EXP); + final Pattern nilPattern = Pattern.compile(NIL_EXP); + final Pattern cnlPattern = Pattern.compile(CNL_EXP); + final Pattern misPattern = Pattern.compile(MIS_EXP); + final Pattern testPattern = Pattern.compile(TEST_EXP); + + Matcher theMatcher = hazardTypePattern.matcher(theReport); + Matcher nilMatcher = nilPattern.matcher(theReport); + Matcher cnlMatcher = cnlPattern.matcher(theReport); + Matcher misMatcher = misPattern.matcher(theReport); + Matcher testMatcher = testPattern.matcher(theReport); + + if (cnlMatcher.find()) { + retHazardType = "CANCEL"; + } else if (testMatcher.find()) { + retHazardType = "TEST"; + } else if (theMatcher.find()) { + if (theMatcher.group(1).equals("HURRICANE")) { + retHazardType = "HURRICANE"; + } else if (theMatcher.group(1).equals("HURCN ")) { + retHazardType = "HURRICANE"; + } else if (theMatcher.group(1).equals(" TD ")) { + retHazardType = "TROPICAL DEPRESSION"; + } else if (theMatcher.group(1).equals("TROPICAL STORM")) { + retHazardType = "TROPICAL STORM"; + } else if (theMatcher.group(1).equals("TROPICAL DEPRESSION")) { + retHazardType = "TROPICAL DEPRESSION"; + } else if (theMatcher.group(1).equals(" SQL ")) { + retHazardType = "SQUALL LINE"; + } else if (theMatcher.group(1).equals("TURB")) { + retHazardType = "TURBULENCE"; + } else if (theMatcher.group(1).equals(" ICE ")) { + retHazardType = "ICING"; + } else if (theMatcher.group(1).equals(" ICG")) { + retHazardType = "ICING"; + } else if (theMatcher.group(1).equals("ICING")) { + retHazardType = "ICING"; + } else if (theMatcher.group(1).equals(" TS ")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals("FRQ TS")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals(" TS/")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals(" SH/TS ")) { + retHazardType = "THUNDERSTORM WIND SHEAR"; + } else if (theMatcher.group(1).equals(" CB ")) { + retHazardType = "CUMULONIMBUS"; + } else if (theMatcher.group(1).equals(" VA ")) { + retHazardType = "VOLCANIC ASH CLOUD"; + } else if (theMatcher.group(1).equals(" MTW ")) { + retHazardType = "MARKED MOUNTAIN WAVES"; + } else if (theMatcher.group(1).equals(" TR ")) { + retHazardType = "TROPICAL STORM"; + } else if (theMatcher.group(1).equals(" GR ")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals(" TC ")) { + retHazardType = "TROPICAL CYCLONE"; + } else if (theMatcher.group(1).equals(" CT ")) { + retHazardType = "CAT"; + } else if (theMatcher.group(1).equals(" CAT ")) { + retHazardType = "CAT"; + } else if (theMatcher.group(1).equals(" DS ")) { + retHazardType = "DUSTSTORM"; + } else if (theMatcher.group(1).equals(" SS ")) { + retHazardType = "SANDSTORM"; + } else if (theMatcher.group(1).equals(" WS ")) { + retHazardType = "LOW LEVEL WIND SHEAR"; + } else if (theMatcher.group(1).equals("LLWS")) { + retHazardType = "LOW LEVEL WIND SHEAR"; + } else if (theMatcher.group(1).equals(" TSGR ")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals("VOLCANIC ASH")) { + retHazardType = "VOLCANIC ASH CLOUD"; + } else if (theMatcher.group(1).equals("TS ")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals("HVYSS ")) { + retHazardType = "HEAVY SANDSTORM"; + } else if (theMatcher.group(1).equals("WATERSPOUTS")) { + retHazardType = "WATERSPOUTS"; + } else if (theMatcher.group(1).equals("THUNDERSTORMS")) { + retHazardType = "THUNDERSTORMS"; + } else if (theMatcher.group(1).equals("WIND")) { + retHazardType = "WINDS"; + } else if (theMatcher.group(1).equals("TS OBS")) { + retHazardType = "THUNDERSTORMS"; + } else if (theMatcher.group(1).equals(" TS")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals("CB/TS")) { + retHazardType = getThunderStorm(theReport); + } else if (theMatcher.group(1).equals("TORNADO")) { + retHazardType = "TORNADO"; + } + } else if (nilMatcher.find()) { + retHazardType = "NIL"; + } else if (misMatcher.find()) { + retHazardType = "NIL"; + } else { + retHazardType = "UNKNOWN ???"; + } + return retHazardType; + } + + /** + * Obtains the message ID. + * + * @param theBulletin + * The input bulletin + * @return a string for messageID + */ + public static String getMessageID(String theBulletin) { + + String messageID = " "; + + // // Regular expression for CONUS message ID + // final String CONUS_EXP = + // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|" + + // "GOLF|HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|" + // + + // "ROMEO|SIERRA|TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) " + + // "([0-9]{1}|[0-9]{2}) VALID"; + + // Pattern used for extracting the message ID + final Pattern conusPattern = Pattern.compile(CONUS_EXP); + Matcher idconusMatcher = conusPattern.matcher(theBulletin); + + // Regular expression for CANADA message ID + final String CANADA_EXP = "SIGMET ([A-Z]{1})([0-9]{1}|[0-9]{2}) (VALID " + + "([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the message ID + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher idcanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK message ID + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) (VALID )?" + + "([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the message ID + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher idjapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER1_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); + Matcher idother1Matcher = other1Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER2_EXP = "(SIGMET) ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}|[A-Z]{1}[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})"; + // Pattern used for extracting the message ID + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher idother2Matcher = other2Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER3_EXP = "([A-Z]{4}) SIGMET ([A-Z]* )?([0-9]{1}|[0-9]{2}) VALID ([0-9]{6})/([0-9]{6}) " + + "([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); + Matcher idother3Matcher = other3Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); + Matcher idother4Matcher = other4Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); + Matcher idother5Matcher = other5Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER6_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); + Matcher idother6Matcher = other6Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER7_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other7Pattern = Pattern.compile(OTHER7_EXP); + Matcher idother7Matcher = other7Pattern.matcher(theBulletin); + + // Regular expression for others' message ID + final String OTHER8_EXP = "([A-Z]{4}) SIGMET( |\\W)*VALID( |\\W)*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message ID + final Pattern other8Pattern = Pattern.compile(OTHER8_EXP); + Matcher idother8Matcher = other8Pattern.matcher(theBulletin); + + // Get messageID + if (idconusMatcher.find()) { + messageID = idconusMatcher.group(2); + } else if (idcanadaMatcher.find()) { + messageID = idcanadaMatcher.group(6); + } else if (idother1Matcher.find()) { + messageID = idother1Matcher.group(6); + } else if (idjapanMatcher.find()) { + messageID = idjapanMatcher.group(7); + } else if (idother2Matcher.find()) { + messageID = idother2Matcher.group(1); + } else if (idother3Matcher.find()) { + messageID = idother3Matcher.group(6); + } else if (idother4Matcher.find()) { + messageID = idother4Matcher.group(8); + } else if (idother5Matcher.find()) { + messageID = idother5Matcher.group(7); + } else if (idother6Matcher.find()) { + messageID = idother6Matcher.group(8); + } else if (idother7Matcher.find()) { + messageID = idother7Matcher.group(8); + } else if (idother8Matcher.find()) { + messageID = idother8Matcher.group(7); + } + + return messageID; + } + + /** + * Obtains the sequence number. + * + * @param theBulletin + * The input bulletin + * @return a string for sequenceNumber + */ + public static String getSequenceNumber(String theBulletin) { + + String sequenceNumber = " "; + + // // Regular expression for CONUS sequence number + // final String CONUS_EXP = + // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|HOTEL|" + // + + // "INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|TANGO|" + // + + // "UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; + + // Pattern used for extracting the sequence number + final Pattern conusPattern = Pattern.compile(CONUS_EXP); + Matcher seqnoconusMatcher = conusPattern.matcher(theBulletin); + + // Regular expression for CANADA sequence number + final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " + + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the sequence number + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher seqnocanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK sequence number + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " + + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the sequence number + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher seqnojapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; + // Pattern used for extracting the sequence number + final Pattern otherPattern = Pattern.compile(OTHER_EXP); + Matcher seqnootherMatcher = otherPattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER2_EXP = "SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}|A-Z]{1}[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})"; + // Pattern used for extracting the sequence number + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher seqnoother2Matcher = other2Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER3_EXP = "([A-Z]{4}) SIGMET (([A-Z]* )?([0-9]{1}|[0-9]{2})) " + + "VALID ([0-9]{6})/([0-9]{6}) ([A-Z]{4})(-)?"; + // Pattern used for extracting the sequence number + final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); + Matcher seqnoother3Matcher = other3Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the sequence number + final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); + Matcher seqnoother4Matcher = other4Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the sequence number + final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); + Matcher seqnoother5Matcher = other5Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER6_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message sequence number + final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); + Matcher seqnoother6Matcher = other6Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER7_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the sequence number + final Pattern other7Pattern = Pattern.compile(OTHER7_EXP); + Matcher seqnoother7Matcher = other7Pattern.matcher(theBulletin); + + // Regular expression for others' sequence number + final String OTHER8_EXP = "([A-Z]{4}) SIGMET( |\\W)*([0-9]{1})( |\\W)*VALID"; + // Pattern used for extracting the sequence number + final Pattern other8Pattern = Pattern.compile(OTHER8_EXP); + Matcher seqnoother8Matcher = other8Pattern.matcher(theBulletin); + + // Get sequenceNumber + if (seqnoconusMatcher.find()) { + sequenceNumber = seqnoconusMatcher.group(3); + } else if (seqnocanadaMatcher.find()) { + sequenceNumber = seqnocanadaMatcher.group(1); + } else if (seqnootherMatcher.find()) { + sequenceNumber = seqnootherMatcher.group(2); + } else if (seqnojapanMatcher.find()) { + sequenceNumber = seqnojapanMatcher.group(2); + } else if (seqnoother2Matcher.find()) { + sequenceNumber = seqnoother2Matcher.group(1); + } else if (seqnoother3Matcher.find()) { + sequenceNumber = seqnoother3Matcher.group(2); + } else if (seqnoother4Matcher.find()) { + sequenceNumber = seqnoother4Matcher.group(3); + } else if (seqnoother5Matcher.find()) { + // lacking sequence number; default 0 + sequenceNumber = "0"; + } else if (seqnoother6Matcher.find()) { + sequenceNumber = seqnoother6Matcher.group(3); + } else if (seqnoother7Matcher.find()) { + sequenceNumber = seqnoother7Matcher.group(3); + } else if (seqnoother8Matcher.find()) { + sequenceNumber = seqnoother8Matcher.group(3); + } + + return sequenceNumber; + } + + /** + * Obtains the Air Traffic Service Unit. + * + * @param theBulletin + * The input bulletin + * @return a string for atsu. + */ + public static String getAtsu(String theBulletin) { + + String atsu = null; + + // // Regular expression for CONUS ATSU + // final String CONUS_EXP = + // "([A-Z]{4}) SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|GOLF|" + + // "HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|" + // + + // "TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; + + // Pattern used for extracting the ATSU + final Pattern conusPattern = Pattern.compile(CONUS_EXP); + Matcher atsuconusMatcher = conusPattern.matcher(theBulletin); + + // Regular expression for CANADA ATSU + final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " + + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the ATSU + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher atsucanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK ATSU + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " + + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the ATSU + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher atsujapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for others' ATSU + final String OTHER1_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2})" + + "( )*VALID"; + // Pattern used for extracting the ATSU + final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); + Matcher atsuother1Matcher = other1Pattern.matcher(theBulletin); + + // Regular expression for CONUS ATSU + final String CONUS2_EXP = "([A-Z]{4} ([A-Z]{4} )*)SIGMET (ALFA|BRAVO|CHARLIE|DELTA|ECHO|FOXTROT|" + + "GOLF|HOTEL|INDIA|JULIETT|JULIET|KILO|LIMA|MIKE|NOVEMBER|OSCAR|PAPA|QUEBEC|ROMEO|SIERRA|" + + "TANGO|UNIFORM|VICTOR|WHISKEY|XRAY|YANKEE|ZULU) ([0-9]{1}|[0-9]{2}) VALID"; + // Pattern used for extracting the ATSU + final Pattern conus2Pattern = Pattern.compile(CONUS2_EXP); + Matcher atsuconus2Matcher = conus2Pattern.matcher(theBulletin); + + final String OTHER2_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the ATSU + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher atsuother2Matcher = other2Pattern.matcher(theBulletin); + + // Regular expression for others' ATSU + final String OTHER3_EXP = "([A-Z]{4}) SIGMET ([0-9]{1})( |\\W)*VALID( |\\W)*" + + "([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the ATSU + final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); + Matcher atsuother3Matcher = other3Pattern.matcher(theBulletin); + + // Get atsu + if (atsuconus2Matcher.find()) { + atsu = atsuconus2Matcher.group(1); + } else if (atsuconusMatcher.find()) { + atsu = atsuconusMatcher.group(1); + } else if (atsucanadaMatcher.find()) { + atsu = atsucanadaMatcher.group(5); + } else if (atsuother1Matcher.find()) { + atsu = atsuother1Matcher.group(1); + } else if (atsujapanMatcher.find()) { + atsu = atsujapanMatcher.group(1); + } else if (atsuother2Matcher.find()) { + atsu = atsuother2Matcher.group(1); + } else if (atsuother3Matcher.find()) { + atsu = atsuother3Matcher.group(1); + } + + return atsu; + } + + /** + * Obtains the location indicator of the meteorological watch office + * originating the message. + * + * @param theBulletin + * The input bulletin + * @return a string for omwo. + */ + public static String getOmwo(String theBulletin) { + + String omwo = " "; + + // Regular expression for CONUS OMWO + final String CONUS_EXP = "([A-Z]{4}) ([A-Z]{4} )?SIGMET ([A-Z])* ([0-9]{1}|[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the OMWO + final Pattern conusPattern = Pattern.compile(CONUS_EXP); + Matcher omwoconusMatcher = conusPattern.matcher(theBulletin); + + // Regular expression for CANADA OMWO + final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}|[A-Z]{1}[0-9]{2}) " + + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the OMWO + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher omwocanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK OMWO + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " + + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the OMWO + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher omwojapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for other OMWO + final String OTHER_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID ([0-9]{6})/([0-9]{6})( UTC)? ([A-Z]{4})(-)?"; + // Pattern used for extracting the OMWO + final Pattern otherPattern = Pattern.compile(OTHER_EXP); + Matcher omwootherMatcher = otherPattern.matcher(theBulletin); + + // Regular expression for others' OMWO + final String OTHER2_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|" + + "[A-Z]{2}[0-9]{2}|[A-Z]{1}[0-9]{2}) " + + "VALID( )*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message OMWO + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher omwoother2Matcher = other2Pattern.matcher(theBulletin); + + // Regular expression for others' OMWO + final String OTHER3_EXP = "([A-Z]{4}) SIGMET( )*VALID( )*([0-9]{6})/([0-9]{6})" + + "( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message OMWO + final Pattern other3Pattern = Pattern.compile(OTHER3_EXP); + Matcher omwoother3Matcher = other3Pattern.matcher(theBulletin); + + // Regular expression for others' OMWO + final String OTHER4_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{4})/([0-9]{4})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message OMWO + final Pattern other4Pattern = Pattern.compile(OTHER4_EXP); + Matcher omwoother4Matcher = other4Pattern.matcher(theBulletin); + + // Regular expression for others' OMWO + final String OTHER5_EXP = "([A-Z]{4}) SIGMET( )*([0-9]{1}|[0-9]{2}|[A-Z]{1}[0-9]{1}|[A-Z]{2}[0-9]{2}) " + + "VALID( )*([0-9]{6})Z/([0-9]{6})Z( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the message OMWO + final Pattern other5Pattern = Pattern.compile(OTHER5_EXP); + Matcher omwoother5Matcher = other5Pattern.matcher(theBulletin); + + // Regular expression for others' OMWO + final String OTHER6_EXP = "([A-Z]{4}) SIGMET ([0-9]{1})( |\\W)*" + + "VALID( |\\W)*([0-9]{6})/([0-9]{6})( )*([A-Z]{4})(-)?"; + // Pattern used for extracting the OMWO + final Pattern other6Pattern = Pattern.compile(OTHER6_EXP); + Matcher omwoother6Matcher = other6Pattern.matcher(theBulletin); + + // Get omwo + if (omwoconusMatcher.find()) { + omwo = omwoconusMatcher.group(8); + } else if (omwocanadaMatcher.find()) { + omwo = omwocanadaMatcher.group(5); + } else if (omwootherMatcher.find()) { + omwo = omwootherMatcher.group(6); + } else if (omwojapanMatcher.find()) { + omwo = omwojapanMatcher.group(7); + } else if (omwoother2Matcher.find()) { + omwo = omwoother2Matcher.group(8); + } else if (omwoother3Matcher.find()) { + omwo = omwoother3Matcher.group(7); + } else if (omwoother4Matcher.find()) { + omwo = omwoother4Matcher.group(8); + } else if (omwoother5Matcher.find()) { + omwo = omwoother5Matcher.group(8); + } else if (omwoother6Matcher.find()) { + omwo = omwoother6Matcher.group(8); + } + + return omwo; + } + + /** + * Obtains start time from input bulletin. + * + * @param theReport + * The bulletin message + * @return a calendar for start time + */ + public static Calendar getStartTime(String theBulletin, Headers headers) { + + String time = "???"; + + // Regular expression for general start time group + final String START_EXP = " VALID( )*([0-9]{6})/([0-9]{6})"; + // Pattern used for extracting the start time group + final Pattern startPattern = Pattern.compile(START_EXP); + Matcher timestartMatcher = startPattern.matcher(theBulletin); + + // Regular expression for CANADA start time group + final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}) VALID ([0-9]{6})/([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the start time group + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher timecanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK start time group + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " + + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the start time group + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher timejapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for others' start time + final String OTHER1_EXP = " VALID( )*([0-9]{6})(Z)?/([0-9]{6})(Z)?"; + // Pattern used for extracting the start time + final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); + Matcher time1Matcher = other1Pattern.matcher(theBulletin); + + // Regular expression for others' start time + final String OTHER2_EXP = " VALID( )*([0-9]{4})/([0-9]{4})"; + // Pattern used for extracting the start time + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher time2Matcher = other2Pattern.matcher(theBulletin); + + // Get time group + if (timestartMatcher.find()) { + time = timestartMatcher.group(2); + } else if (timejapanMatcher.find()) { + time = timejapanMatcher.group(4); + } else if (time1Matcher.find()) { + time = time1Matcher.group(2); + } else if (timecanadaMatcher.find()) { + time = timecanadaMatcher.group(2); + } else if (time2Matcher.find()) { + // Handle start time in special case without day + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{2})([0-9]{4})"; + // Pattern used for extracting WMO header, officeID, and issue date + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(theBulletin); + if (theMatcher.find()) { + time = time2Matcher.group(2).concat(theMatcher.group(3)); + } + } + if (time != "???") { + // Get start time + return TimeTools.findDataTime(time, headers); + } else { + return null; + } + } + + /** + * Get the end time + * + * @param theBulletin + * The bulletin which contains end time + * @return a calendar for end time + */ + public static Calendar getEndTime(String theBulletin, Headers headers) { + + String time = "???"; + + // Regular expression for CONUS end time group + final String ENDTIME_EXP = " VALID( )*([0-9]{6})/([0-9]{6})"; + // Pattern used for extracting the end time group + final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); + Matcher endtimeMatcher = endtimePattern.matcher(theBulletin); + + // Regular expression for CANADA end time group + final String CANADA_EXP = "SIGMET ([A-Z]{1}[0-9]{1}) " + + "(VALID ([0-9]{6})/|CANCELLED AT )([0-9]{6}) ([A-Z]{4})-"; + // Pattern used for extracting the end time group + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher timecanadaMatcher = canadaPattern.matcher(theBulletin); + + // Regular expression for JAPAN and UK end time group + final String JAPAN_EXP = "([A-Z]{4}) SIGMET ([0-9]{1}|[0-9]{2}) " + + "(VALID )?([0-9]{6})/([0-9]{6})(UTC)? ([A-Z]{4})-"; + // Pattern used for extracting the end time group + final Pattern japanPattern = Pattern.compile(JAPAN_EXP); + Matcher timejapanMatcher = japanPattern.matcher(theBulletin); + + // Regular expression for others' end time + final String OTHER1_EXP = " VALID( )*([0-9]{6})(Z)?/([0-9]{6})(Z)?"; + // Pattern used for extracting the end time + final Pattern other1Pattern = Pattern.compile(OTHER1_EXP); + Matcher time1Matcher = other1Pattern.matcher(theBulletin); + + // Regular expression for others' end time + final String OTHER2_EXP = " VALID( )*([0-9]{4})/([0-9]{4})"; + // Pattern used for extracting the end time + final Pattern other2Pattern = Pattern.compile(OTHER2_EXP); + Matcher time2Matcher = other2Pattern.matcher(theBulletin); + + // Get time group + if (endtimeMatcher.find()) { + time = endtimeMatcher.group(3); + } else if (timejapanMatcher.find()) { + time = timejapanMatcher.group(4); + } else if (timecanadaMatcher.find()) { + time = timecanadaMatcher.group(4); + } else if (timecanadaMatcher.find()) { + time = timecanadaMatcher.group(6); + } else if (time1Matcher.find()) { + time = time1Matcher.group(4); + } else if (time2Matcher.find()) { + // Handle end time special case without day + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{2})([0-9]{4})"; + // Pattern used for extracting WMO header, officeID and issue time + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(theBulletin); + if (theMatcher.find()) { + time = time2Matcher.group(3).concat(theMatcher.group(3)); + } + } + + if (time != "???") { + // Get end time + Calendar mndTime = null; + return TimeTools.findDataTime(time, headers); + } else { + return null; + } + } + + /** + * Parse the bulletin and store flight level 1 or level 2 if any. + * + * @param theBulletin + * The bulletin message + * @param record + * The main table + */ + public static void processFlightLevels(String theBulletin, + IntlSigmetRecord record) { + + String flevel1 = " "; + String flevel2 = " "; + + // Regular expression for general one flight level + final String FLEVEL1_EXP = "(TOP|TOPS|TOPS TO) FL( )?([0-9]{3})"; + // Pattern used for extracting the flight level + final Pattern flevel1Pattern = Pattern.compile(FLEVEL1_EXP); + Matcher flevel1Matcher = flevel1Pattern.matcher(theBulletin); + + // Regular expression for flight levels in format "BETWEEN ... AND ...." + final String BETWEEN_EXP = "(BETWEEN|BTN) (FL)?([0-9]{3}|[0-9]{2}) AND " + + "(FL)?([0-9]{3}|[0-9]{2})"; + // Pattern used for extracting the flight levels + final Pattern betweenPattern = Pattern.compile(BETWEEN_EXP); + Matcher betweenMatcher = betweenPattern.matcher(theBulletin); + + // Regular expression for flight levels in format + // "TOPS ... MAX TOPS ...." for Canada + final String MAXTOPS_EXP = "TOPS( |\\x0d\\x0d\\x0a)([0-9]{3}|[0-9]{2}) " + + "MAX TOPS ([0-9]{3}|[0-9]{2})"; + // Pattern used for extracting the flight levels + final Pattern maxtopsPattern = Pattern.compile(MAXTOPS_EXP); + Matcher maxtopsMatcher = maxtopsPattern.matcher(theBulletin); + + // Regular expression for general two flight levels in "360-440" or + // "360/440" format + final String FLEVEL2_EXP = "FL([0-9]{3}|[0-9]{2})(-|/)([0-9]{3}|[0-9]{2})"; + // Pattern used for extracting the flight levels + final Pattern flevel2Pattern = Pattern.compile(FLEVEL2_EXP); + Matcher flevel2Matcher = flevel2Pattern.matcher(theBulletin); + + // Regular expression for general one flight level + final String FLEVEL3_EXP = "(TOP|TOPS|TOPS TO) (FL )?([0-9]{3})"; + // Pattern used for extracting the flight level + final Pattern flevel3Pattern = Pattern.compile(FLEVEL3_EXP); + Matcher flevel3Matcher = flevel3Pattern.matcher(theBulletin); + + final String FLEVEL4_EXP = "FL([0-9]{3})"; + // Pattern used for extracting the flight level + final Pattern flevel4Pattern = Pattern.compile(FLEVEL4_EXP); + Matcher flevel4Matcher = flevel4Pattern.matcher(theBulletin); + + // Get flight levels group + if (maxtopsMatcher.find()) { + flevel1 = maxtopsMatcher.group(3); + } else if (flevel2Matcher.find()) { + flevel1 = flevel2Matcher.group(1); + flevel2 = flevel2Matcher.group(3); + } else if (betweenMatcher.find()) { + flevel1 = betweenMatcher.group(3); + flevel2 = betweenMatcher.group(5); + } else if (flevel1Matcher.find()) { + flevel1 = flevel1Matcher.group(3); + } else if (flevel3Matcher.find()) { + flevel1 = flevel3Matcher.group(3); + } else if (flevel4Matcher.find()) { + flevel1 = flevel4Matcher.group(1); + } + + // Set flight levels to database + if (flevel1 != " ") { + record.setFlightlevel1(Integer.parseInt(flevel1)); + } + if (flevel2 != " ") { + record.setFlightlevel2(Integer.parseInt(flevel2)); + } + + // Parse the locations + processLocation(theBulletin, record); + + } + + /** + * Obtains remarks from a bulletin + * + * @param bullMessage + * The bulletin message + * @return a string for remarks + */ + public static String getRemarks(String bullMessage) { + + String retRemarks = " "; + + // Regular expression correction + final String CORR_EXP = "(COR | (CC[A-Z]{1}))"; + + // Pattern used for extracting correction + final Pattern corrPattern = Pattern.compile(CORR_EXP); + Matcher corrMatcher = corrPattern.matcher(bullMessage); + + // Regular expression amendment + final String AMD_EXP = "(AMD )"; + // Pattern used for extracting amendment + final Pattern amdPattern = Pattern.compile(AMD_EXP); + Matcher amdMatcher = amdPattern.matcher(bullMessage); + + // Regular expression for TEST + final String TEST_EXP = "TEST "; + // Pattern used for extracting test + final Pattern testPattern = Pattern.compile(TEST_EXP); + Matcher testMatcher = testPattern.matcher(bullMessage); + + if (corrMatcher.find()) { + retRemarks = corrMatcher.group(1); + } else if (amdMatcher.find()) { + retRemarks = amdMatcher.group(); + } else if (testMatcher.find()) { + retRemarks = "TEST"; + } + + return retRemarks; + } + + /** + * Obtains speed from a bulletin + * + * @param bullMessage + * The bulletin message + * @return an integer for speed + */ + public static Integer getSpeed(String bullMessage) { + + Integer retSpeed = IDecoderConstantsN.INTEGER_MISSING; + + final String SPEED_EXP = "(MOVE|MOV|MOVG) (|E|N|S|W|\006|\012)* " + + "([0-9]{1}|[0-9]{2})(-[0-9]{2})?( )?(KT)"; + // Pattern used for extracting speed for general + final Pattern speedPattern = Pattern.compile(SPEED_EXP); + Matcher theMatcher = speedPattern.matcher(bullMessage); + + final String CANADA1_EXP = "(MOVE |MOV |MOVG )?([ENSW]{1})WD " + + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; + // Pattern used for extracting speed for Canada + final Pattern canada1Pattern = Pattern.compile(CANADA1_EXP); + Matcher canada1Matcher = canada1Pattern.matcher(bullMessage); + + final String CANADA2_EXP = "(MOVE |MOV |MOVG )?([ENSW]{2})WD " + + "([0-9]{2}|[0-9]{1})(\\x0d\\x0d\\x0a| )?KT"; + // Pattern used for extracting speed for Canada + final Pattern canada2Pattern = Pattern.compile(CANADA2_EXP); + Matcher canada2Matcher = canada2Pattern.matcher(bullMessage); + + final String KMH_EXP = "([0-9]{2}|[0-9]{3})(( )*|( )?\\x0d\\x0d\\x0a)KMH"; + // Pattern used for extracting speed for KMH + final Pattern kmhPattern = Pattern.compile(KMH_EXP); + Matcher kmhMatcher = kmhPattern.matcher(bullMessage); + + if (theMatcher.find()) { + retSpeed = Integer.parseInt(theMatcher.group(3)); + } else if (canada1Matcher.find()) { + retSpeed = Integer.parseInt(canada1Matcher.group(3)); + } else if (canada2Matcher.find()) { + retSpeed = Integer.parseInt(canada2Matcher.group(3)); + } else if (kmhMatcher.find()) { + Integer kmhSpeed = Integer.parseInt(kmhMatcher.group(1)); + // Convert KMH to Knots + float speed = (float) (((double) kmhSpeed * 1000.0 / 3600.0) * 1.9425); + retSpeed = (int) speed; + } + + return retSpeed; + } + + /** + * Obtains intensity from a bulletin + * + * @param bullMessage + * The bulletin message + * @return a string for intensity + */ + public static String getIntensity(String bullMessage) { + + String intensity = null; + + // Regular expression for intensity + final String INTENSITY_EXP = "( NC | INTSF| WKN | NC=|WKN=|NC.|WKNG )"; + // Pattern used for extracting intensityFlag + final Pattern intensityPattern = Pattern.compile(INTENSITY_EXP); + Matcher theMatcher = intensityPattern.matcher(bullMessage); + + if (theMatcher.find()) { + intensity = theMatcher.group(1); + intensity = UtilN.removeLeadingWhiteSpaces(intensity); + if (intensity.substring(0, 2).equals("NC")) { + intensity = "NC"; + } else if (intensity.substring(0, 3).equals("WKN")) { + intensity = "WKN"; + } + } + + return intensity; + } + + /** + * Obtains direction from a bulletin + * + * @param bullMessage + * The bulletin message + * @return a string for direction + */ + public static String getDirection(String bullMessage) { + + String direction = null; + + final String CANADA1_EXP = "(MOVE |MOV |MOVG )?([ENSW]{1})WD " + + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; + // Pattern used for extracting direction for Canada + final Pattern canada1Pattern = Pattern.compile(CANADA1_EXP); + Matcher canada1Matcher = canada1Pattern.matcher(bullMessage); + + final String CANADA2_EXP = "(MOVE |MOV |MOVG )?([ENSW]{2})WD " + + "([0-9]{2}|[0-9]{1})( |\\x0d\\x0d\\x0a)?KT"; + // Pattern used for extracting direction for Canada + final Pattern canada2Pattern = Pattern.compile(CANADA2_EXP); + Matcher canada2Matcher = canada2Pattern.matcher(bullMessage); + + // Regular expression for direction + final String DIRECTION_EXP = "(MOVE|MOV|MOVG) ([ENSW]{3}|[ENSW]{2}|[ENSW]{1})"; + // Pattern used for extracting direction for general + final Pattern directionPattern = Pattern.compile(DIRECTION_EXP); + Matcher theMatcher = directionPattern.matcher(bullMessage); + + final String DIR2_EXP = "(MOVE|MOV|MOVG)(\\D)*([ENSW]{3}|[ENSW]{2}|[ENSW]{1}) "; + // Pattern used for extracting direction for Canada + final Pattern dir2Pattern = Pattern.compile(DIR2_EXP); + Matcher dir2Matcher = dir2Pattern.matcher(bullMessage); + + final String DIR3_EXP = "(MOVE|MOV|MOVG) (SOUTH|NORTH|WEST|EAST) "; + // Pattern used for extracting direction for Canada + final Pattern dir3Pattern = Pattern.compile(DIR3_EXP); + Matcher dir3Matcher = dir3Pattern.matcher(bullMessage); + + if (canada2Matcher.find()) { + direction = canada2Matcher.group(2); + } else if (canada1Matcher.find()) { + direction = canada1Matcher.group(2); + } else if (theMatcher.find()) { + direction = theMatcher.group(2); + } else if (dir2Matcher.find()) { + direction = dir2Matcher.group(3); + } else if (dir3Matcher.find()) { + direction = dir3Matcher.group(2); + if (direction.equals("SOUTH")) { + direction = "S"; + } else if (direction.equals("NORTH")) { + direction = "N"; + } else if (direction.equals("WEST")) { + direction = "W"; + } else if (direction.equals("EAST")) { + direction = "E"; + } + } + return direction; + } + + /** + * Parse the location to set Lat/Lon or location name + * + * @param theLocation + * The location with lat/lon or location name + * @param locTb + * The location table + */ + public static void processLatLon(String theLocation, + IntlSigmetLocation locTb, Integer index, IntlSigmetRecord record) { + + double flat, flon; + + final String LATLON1_EXP = "(N|S)([0-9]{2})([0-9]{2}) (E|W)([0-9]{3})([0-9]{2})"; + // Pattern used for extracting latlon - CONUS + final Pattern latlon1Pattern = Pattern.compile(LATLON1_EXP); + Matcher latlon1Matcher = latlon1Pattern.matcher(theLocation); + + final String LATLON2_EXP = "/([0-9]{2})([0-9]{2})(N|S)([0-9]{3})" + + "([0-9]{2})(E|W)/((\\S|\\s|\\D)*)"; + // Pattern used for extracting latlon - Canada + final Pattern latlon2Pattern = Pattern.compile(LATLON2_EXP); + Matcher latlon2Matcher = latlon2Pattern.matcher(theLocation); + + final String LATLON3_EXP = "(N|S)([0-9]{2})([0-9]{2})(E|W)([0-9]{3})([0-9]{2})"; + // Pattern used for extracting latlon + final Pattern latlon3Pattern = Pattern.compile(LATLON3_EXP); + Matcher latlon3Matcher = latlon3Pattern.matcher(theLocation); + + final String LATLON4_EXP = "(N|S)([0-9]{2})(E|W)([0-9]{3}|[0-9]{2})"; + // Pattern used for extracting latlon + final Pattern latlon4Pattern = Pattern.compile(LATLON4_EXP); + Matcher latlon4Matcher = latlon4Pattern.matcher(theLocation); + + final String LATLON5_EXP = "([0-9]{2})(N|S)([0-9]{3}|[0-9]{2})(E|W)"; + // Pattern used for extracting latlon - Japan + final Pattern latlon5Pattern = Pattern.compile(LATLON5_EXP); + Matcher latlon5Matcher = latlon5Pattern.matcher(theLocation); + + final String LATLON6_EXP = "([0-9]{2})([0-9]{2})(N|S)([0-9]{3})([0-9]{2})(E|W)"; + // Pattern used for extracting latlon + final Pattern latlon6Pattern = Pattern.compile(LATLON6_EXP); + Matcher latlon6Matcher = latlon6Pattern.matcher(theLocation); + + final String LATLON7_EXP = "(N|S)([0-9]{2})([0-9]{2})[\\W| ]*(E|W)" + + "([0-9]{3})([0-9]{2})"; + // Pattern used for extracting latlon + final Pattern latlon7Pattern = Pattern.compile(LATLON7_EXP); + Matcher latlon7Matcher = latlon7Pattern.matcher(theLocation); + + final String LATLON8_EXP = "(N|S)([0-9]{2})( )*(E|W)([0-9]{3}|[0-9]{2})"; + // Pattern used for extracting latlon + final Pattern latlon8Pattern = Pattern.compile(LATLON8_EXP); + Matcher latlon8Matcher = latlon8Pattern.matcher(theLocation); + + double NSFlag = 1.0; + double EWFlag = 1.0; + double seconds = 60.0; + LatLonPoint point = null; + + if (record.getWmoHeader().equals("WSMC31")) { + // WSMC31 issues lat/lon in decimals. + seconds = 100.0; + } + + if (latlon1Matcher.find()) { + // latlon format for CONUS + if (latlon1Matcher.group(1).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag + * (Integer.parseInt(latlon1Matcher.group(2)) + (Integer + .parseInt(latlon1Matcher.group(3)) / seconds)); + if (latlon1Matcher.group(4).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag + * (Integer.parseInt(latlon1Matcher.group(5)) + (Integer + .parseInt(latlon1Matcher.group(6)) / seconds)); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon1Matcher.group()); + } else if (latlon2Matcher.find()) { + // latlon format for Canada + if (latlon2Matcher.group(3).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag + * (Integer.parseInt(latlon2Matcher.group(1)) + (Integer + .parseInt(latlon2Matcher.group(2)) / seconds)); + if (latlon2Matcher.group(6).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag + * (Integer.parseInt(latlon2Matcher.group(4)) + (Integer + .parseInt(latlon2Matcher.group(5)) / seconds)); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon2Matcher.group(7)); + } else if (latlon3Matcher.find()) { + if (latlon3Matcher.group(1).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag + * (Integer.parseInt(latlon3Matcher.group(2)) + (Integer + .parseInt(latlon3Matcher.group(3)) / seconds)); + if (latlon3Matcher.group(4).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag + * (Integer.parseInt(latlon3Matcher.group(5)) + (Integer + .parseInt(latlon3Matcher.group(6)) / seconds)); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon3Matcher.group()); + } else if (latlon4Matcher.find()) { + if (latlon4Matcher.group(1).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag * (Integer.parseInt(latlon4Matcher.group(2))); + if (latlon4Matcher.group(3).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag * (Integer.parseInt(latlon4Matcher.group(4))); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon4Matcher.group()); + } else if (latlon5Matcher.find()) { + if (latlon5Matcher.group(2).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag * (Integer.parseInt(latlon5Matcher.group(1))); + if (latlon5Matcher.group(4).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag * (Integer.parseInt(latlon5Matcher.group(3))); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon5Matcher.group()); + } else if (latlon6Matcher.find()) { + // latlon6 format + if (latlon6Matcher.group(3).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag + * (Integer.parseInt(latlon6Matcher.group(1)) + (Integer + .parseInt(latlon6Matcher.group(2)) / seconds)); + if (latlon6Matcher.group(6).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag + * (Integer.parseInt(latlon6Matcher.group(4)) + (Integer + .parseInt(latlon6Matcher.group(5)) / seconds)); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon6Matcher.group()); + } else if (latlon7Matcher.find()) { + // latlon format + if (latlon7Matcher.group(1).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag + * (Integer.parseInt(latlon7Matcher.group(2)) + (Integer + .parseInt(latlon7Matcher.group(3)) / seconds)); + if (latlon7Matcher.group(4).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag + * (Integer.parseInt(latlon7Matcher.group(5)) + (Integer + .parseInt(latlon7Matcher.group(6)) / seconds)); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon7Matcher.group()); + } else if (latlon8Matcher.find()) { + if (latlon8Matcher.group(1).equals("S")) { + NSFlag = -1.0; + } + flat = NSFlag * (Integer.parseInt(latlon8Matcher.group(2))); + if (latlon8Matcher.group(4).equals("W")) { + EWFlag = -1.0; + } + flon = EWFlag * (Integer.parseInt(latlon8Matcher.group(5))); + locTb.setLatitude(flat); + locTb.setLongitude(flon); + locTb.setLocationName(latlon8Matcher.group()); + } else { + System.out.println("theLocation=" + theLocation); + if ((index == 0) + && ((theLocation.substring(0, 3).equals("IN ")) || theLocation + .substring(0, 3).equals("OF "))) { + // handle special case with "IN " or "OF " and location + String retLoc = theLocation.substring(3); + locTb.setLocationName(retLoc); + // Get a latLonPoint for this station ID from "vors" location + // table + point = LatLonLocTbl.getLatLonPoint(retLoc, "vors"); + if (point != null) { + locTb.setLatitude(point.getLatitude(LatLonPoint.INDEGREES)); + locTb.setLongitude(point.getLongitude(LatLonPoint.INDEGREES)); + } + } else { + locTb.setLocationName(theLocation); + // Get a latLonPoint for this station ID from "vors" location + // table + point = LatLonLocTbl.getLatLonPoint(theLocation, "vors"); + if (point != null) { + locTb.setLatitude(point.getLatitude(LatLonPoint.INDEGREES)); + locTb.setLongitude(point.getLongitude(LatLonPoint.INDEGREES)); + } + + } + } + } + + /** + * Obtains distance or radius from a bulletin for a "LINE" type + * + * @param bullMessage + * The bulletin message + * @return an integer of distance + */ + public static Integer getDistance(String bullMessage) { + + Integer retDistance = IDecoderConstantsN.INTEGER_MISSING; + + // Regular expression for distance + final String DISTANCE_EXP = "(WI )?([0-9]{2}|[0-9]{3})( )?NM "; + // Pattern used for extracting distance + final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); + Matcher theMatcher = distancePattern.matcher(bullMessage); + + // Regular expression distance for Canada + final String CANADA_EXP = "WTN ([0-9]{2}|[0-9]{3}) NM OF LN "; + // Pattern used for extracting distance for CANADA sigmet + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher canadaMatcher = canadaPattern.matcher(bullMessage); + + if (theMatcher.find()) { + retDistance = Integer.parseInt(theMatcher.group(2)); + } else if (canadaMatcher.find()) { + retDistance = Integer.parseInt(canadaMatcher.group(1)); + } + return retDistance; + } + + /** + * Get name location for the VA, TC, or HU.... + * + * @param bullMessage + * The bulletin message + * @return a string for nameLocation + */ + public static String getNameLocation(String bullMessage) { + + String retLocation = " "; + + final String VA_EXP = "MT (\\S)*-PEAK LOC ([NS][0-9]{4} [EW][0-9]{5}) "; + // Pattern used for extracting VA nameLocation + final Pattern vaPattern = Pattern.compile(VA_EXP); + Matcher vaMatcher = vaPattern.matcher(bullMessage); + + final String TC_EXP = " TC ((\\S)* FCST (\\S)* (\\S)*) "; + // Pattern used for extracting TC nameLocation + final Pattern tcPattern = Pattern.compile(TC_EXP); + Matcher tcMatcher = tcPattern.matcher(bullMessage); + + // final String HUR1_EXP = "(HURRICANE IRENE LOCATED AT )"; + final String HUR1_EXP = "(HURRICANE ([A-Z])* LOCATED AT ([\\w|.])* ([\\w|.])*) MOVG"; + // Pattern used for extracting Hurricane nameLocation + final Pattern hur1Pattern = Pattern.compile(HUR1_EXP); + Matcher hur1Matcher = hur1Pattern.matcher(bullMessage); + + final String HUR2_EXP = "(HURCN ([A-Z])* NEAR ([\\w|.])* ([\\w|.])*) "; + // Pattern used for extracting Hurricane nameLocation + final Pattern hur2Pattern = Pattern.compile(HUR2_EXP); + Matcher hur2Matcher = hur2Pattern.matcher(bullMessage); + + final String TS_EXP = "(TROPICAL STORM ([A-Z])* (\\w)*)"; + // Pattern used for extracting Tropical Storm nameLocation + final Pattern tsPattern = Pattern.compile(TS_EXP); + Matcher tsMatcher = tsPattern.matcher(bullMessage); + + final String TD_EXP = "(TROPICAL (DEPRESSION )?([A-Z])* (\\w)*)"; + // Pattern used for extracting Tropical Depression nameLocation + final Pattern tdPattern = Pattern.compile(TD_EXP); + Matcher tdMatcher = tdPattern.matcher(bullMessage); + + if (vaMatcher.find()) { + retLocation = vaMatcher.group(); + } else if (tcMatcher.find()) { + retLocation = tcMatcher.group(1); + } else if (hur1Matcher.find()) { + retLocation = hur1Matcher.group(1); + } else if (hur2Matcher.find()) { + retLocation = hur2Matcher.group(1); + } else if (tsMatcher.find()) { + retLocation = tsMatcher.group(1); + } else if (tdMatcher.find()) { + retLocation = tdMatcher.group(1); + } + + return retLocation; + } + + /** + * Obtains polygon extent from a bulletin for a "LINE" type + * or a polygon type + * + * @param bullMessage The bulletin message + * @return a string + */ + public static String getPolygonExtent(String bullMessage) { + + String retStr = ""; + + // Regular expression for distance + final String DISTANCE_EXP = "(WI )?([0-9]{2}|[0-9]{3})( )?NM "; + // Pattern used for extracting distance + final Pattern distancePattern = Pattern.compile(DISTANCE_EXP); + Matcher theMatcher = distancePattern.matcher( bullMessage ); + + // Regular expression for line + final String LINE_EXP = " ([0-9]{2}|[0-9]{3})( )?NM (EITHER SIDE OF)"; + // Pattern used for extracting line information + final Pattern linePattern = Pattern.compile(LINE_EXP); + Matcher lineMatcher = linePattern.matcher( bullMessage ); + + // Regular expression distance for Canada + final String CANADA_EXP = "(WTN|WITHIN) ([0-9]{2}|[0-9]{3})( )?NM OF (LN|LINE)"; + // Pattern used for extracting distance for CANADA sigmet + final Pattern canadaPattern = Pattern.compile(CANADA_EXP); + Matcher canadaMatcher = canadaPattern.matcher( bullMessage ); + + // Regular expression for POLYGON + final String POLYGON_EXP = " ([0-9]{2}|[0-9]{3})( )?NM ([EWSN]|[EWSN]{2}|[EWSN]{3}) OF"; + // Pattern used for extracting POLYGON information + final Pattern polygonPattern = Pattern.compile(POLYGON_EXP); + Matcher polygonMatcher = polygonPattern.matcher( bullMessage ); + + if (canadaMatcher.find()) { + retStr = canadaMatcher.group(1); + } else if (lineMatcher.find()) { + retStr = lineMatcher.group(3); + } else if (polygonMatcher.find()) { + retStr = polygonMatcher.group(3).concat(" OF"); + } else if (theMatcher.find()) { + retStr = theMatcher.group(1); + } + + return retStr; + } + + /** + * Parse the location lines and add location table to the main record table + * if any + * + * @param theBulletin + * The report from bulletin message + * @param record + * The main table + * @return a boolean true if any location exists. + */ + public static boolean processLocation(String theBulletin, + IntlSigmetRecord record) { + + boolean ret = false; + + String locationDelimiter = "-"; + String retLocation = "?"; + int locPositionIndex = -1; + + ArrayList terminationList = new ArrayList(); + // Locations ends with these key words + terminationList.addAll(Arrays + .asList(new String[] { "TOP", "SEV", "BKN", "STNR", "ISOL", + "MOV", "SOLID", "TOPS", "AREA", "BTN", "STG", "SEVERE", + "INTSF=", "MAINLY", "SIGMET", "OCNL", "WKN", "PL", + "FZRA", "LLWS", "TURB", "STR", "FCST", "VA", "MDT", + "STRONG", "LN", "AT", "BASED", "OF", "SVR", "OVER", + "TS", "AND", "OBL", "TURBUL", "BLW", "TOP", "TORNADO", + "CORRECTION" })); + + final String LATLON1_EXP = "(N|S)([0-9]{4}) (E|W)([0-9]{5}) -"; + // Pattern used for extracting latlon + final Pattern latlon1Pattern = Pattern.compile(LATLON1_EXP); + Matcher latlon1Matcher = latlon1Pattern.matcher(theBulletin); + + final String LATLON2_EXP = "/([0-9]{4})(N|S)([0-9]{5})(E|W)/"; + // Pattern used for extracting latlon + final Pattern latlon2Pattern = Pattern.compile(LATLON2_EXP); + Matcher latlon2Matcher = latlon2Pattern.matcher(theBulletin); + + final String LATLON3_EXP = "(N|S)([0-9]{4})(E|W)([0-9]{5})-"; + // Pattern used for extracting latlon + final Pattern latlon3Pattern = Pattern.compile(LATLON3_EXP); + Matcher latlon3Matcher = latlon3Pattern.matcher(theBulletin); + + final String LATLON4_EXP = "(N|S)([0-9]{2})(E|W)([0-9]{3})"; + // Pattern used for extracting latlon + final Pattern latlon4Pattern = Pattern.compile(LATLON4_EXP); + Matcher latlon4Matcher = latlon4Pattern.matcher(theBulletin); + + final String LATLON5_EXP = "([0-9]{2})(N|S)([0-9]{3}|[0-9]{2})(E|W)"; + // Pattern used for extracting latlon + final Pattern latlon5Pattern = Pattern.compile(LATLON5_EXP); + Matcher latlon5Matcher = latlon5Pattern.matcher(theBulletin); + + final String LATLON6_EXP = "([0-9]{4})(N|S)([0-9]{5})(E|W)"; + // Pattern used for extracting latlon + final Pattern latlon6Pattern = Pattern.compile(LATLON6_EXP); + Matcher latlon6Matcher = latlon6Pattern.matcher(theBulletin); + + final String LATLON7_EXP = " [A-Z]*( )?-( )?[A-Z]*( )?-"; + // Pattern used for extracting latlon + final Pattern latlon7Pattern = Pattern.compile(LATLON7_EXP); + Matcher latlon7Matcher = latlon7Pattern.matcher(theBulletin); + + final String LATLON9_EXP = " [A-Z]* [A-Z]*/(\\w| )*/"; + // Pattern used for extracting latlon + final Pattern latlon9Pattern = Pattern.compile(LATLON9_EXP); + Matcher latlon9Matcher = latlon9Pattern.matcher(theBulletin); + + // Find the position of first location + if (latlon7Matcher.find()) { + retLocation = latlon7Matcher.group(); + } else if (latlon1Matcher.find()) { + retLocation = latlon1Matcher.group(); + } else if (latlon2Matcher.find()) { + retLocation = latlon2Matcher.group(); + } else if (latlon3Matcher.find()) { + retLocation = latlon3Matcher.group(); + } else if (latlon4Matcher.find()) { + retLocation = latlon4Matcher.group(); + } else if (latlon5Matcher.find()) { + retLocation = latlon5Matcher.group(); + } else if (latlon6Matcher.find()) { + retLocation = latlon6Matcher.group(); + } else if (latlon9Matcher.find()) { + retLocation = latlon9Matcher.group(); + int sigmetIndex = retLocation.indexOf("SIGMET"); + int fcstIndex = retLocation.indexOf("FCST "); + int innIndex = retLocation.indexOf("IN N/"); + int sfcIndex = retLocation.indexOf(" SFC"); + int obsIndex = retLocation.indexOf(" OBS"); + // Handle special cases and throw them away + if (sigmetIndex != -1) { + retLocation = "?"; + } else if (fcstIndex != -1) { + retLocation = "?"; + } else if (innIndex != -1) { + retLocation = "?"; + } else if (sfcIndex != -1) { + retLocation = "?"; + } else if (obsIndex != -1) { + retLocation = "?"; + } + + } + + locPositionIndex = theBulletin.indexOf(retLocation); + + if (locPositionIndex > 0) { + String secondHalf = theBulletin.substring(locPositionIndex); + Scanner scLocationLine = new Scanner(secondHalf) + .useDelimiter("\\x0d\\x0d\\x0a"); + String lines = " "; + String curLine = null; + ArrayList locationList = new ArrayList(); + locationList.clear(); + Boolean notBreak = true; + + while (scLocationLine.hasNext() && notBreak) { + // Get next location line + curLine = scLocationLine.next(); + + Scanner scLocationToken = new Scanner(curLine); + while (scLocationToken.hasNext() && notBreak) { + // Check the token from each line + String token = scLocationToken.next(); + if (terminationList.contains(token)) { + // terminate and get the locations in this line + int token_pos = curLine.indexOf(token); + lines = lines.concat(" ").concat( + curLine.substring(0, token_pos)); + notBreak = false; + break; + } + } + if (notBreak) { + lines = lines.concat(" ").concat(curLine); + } + } + + // Clean up the leading space + lines = UtilN.removeLeadingWhiteSpaces(lines); + lines = removeChar(lines, '\r'); + lines = removeChar(lines, '\n'); + + // Decide the location delimiter. + Boolean whiteDel = false; + int dashPos = lines.indexOf("-"); + int slashPos = lines.indexOf("/"); + if (dashPos != -1) { + locationDelimiter = "-"; + } else if (slashPos != -1) { + locationDelimiter = "/"; + } else { + locationDelimiter = " "; + whiteDel = true; + } + // Parse the location lines by a "-", "/", or " ". + Scanner scLocation = new Scanner(lines) + .useDelimiter(locationDelimiter); + + locationList.clear(); + // Get all locations + while (scLocation.hasNext()) { + // Clean up the leading space + String location = UtilN.removeLeadingWhiteSpaces(scLocation + .next()); + if (whiteDel) { + // white space as delimiter + int lengthOfLocation = location.length(); + if (lengthOfLocation > 2) { + if (Character.isDigit(location.toCharArray()[0]) + && (lengthOfLocation > 2)) { + locationList.add(location); + } else if (Character.isDigit(location.toCharArray()[1]) + && (lengthOfLocation > 2)) { + locationList.add(location); + } + } + } else if ((location.length() > 0) + && (!location.substring(0, 2).equals("FL"))) { + // exception handle for a "FL" false location + locationList.add(location); + } + } + + // set locations to data base + Integer idxLocation = 0; + if (locationList.size() > 1) { + for (String Location : locationList) { + IntlSigmetLocation currentLocation = new IntlSigmetLocation(); + currentLocation.setLocationLine(lines); + // currentLocation.setLocationName(Location); + processLatLon(Location, currentLocation, idxLocation, + record); + currentLocation.setIndex(idxLocation + 1); + idxLocation++; + + record.addIntlSigmetLocation(currentLocation); + } + ret = true; + } + } + return ret; + } + + /** + * Get detail information for Thunderstorm. + * + * @param theReport + * the input bulletin + * @return a string for Thunderstorm + */ + public static String getThunderStorm(String theReport) { + + String retTS = "THUNDERSTORM"; + // Regular expression for tsType + final String TSTYPE_EXP = "(SQL EMBD TS |ISOL EMBD TS |EMBD TS GR |ISOL TS |EMBD TS |" + + "FRQ TS|SQL TS |TS GR |OBSC TS|FRQ TSGR |OCNL TS |EMBD TSGR | TSGR | GR |" + + "TS/CB|CB/TS)"; + // Pattern used for extracting hazardType + final Pattern tsTypePattern = Pattern.compile(TSTYPE_EXP); + Matcher tsMatcher = tsTypePattern.matcher(theReport); + + if (tsMatcher.find()) { + if (tsMatcher.group(1).equals("EMBD TS GR ")) { + retTS = "EMBEDED THUNDERSTORMS HAIL"; + } else if (tsMatcher.group(1).equals("SQL EMBD TS ")) { + retTS = "SQUALL EMBEDED THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("ISOL EMBD TS ")) { + retTS = "ISOLATED EMBEDED THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("ISOL TS ")) { + retTS = "ISOLATED THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("EMBD TS ")) { + retTS = "EMBEDED THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("FRQ TS")) { + retTS = "FREQUENT THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("SQL TS ")) { + retTS = "SQUALL THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("TS GR ")) { + retTS = "THUNDERSTORMS HAIL"; + } else if (tsMatcher.group(1).equals("OBSC TS")) { + retTS = "OBSCURE THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("FRQ TSGR ")) { + retTS = "FREQUENT THUNDERSTORMS HAIL"; + } else if (tsMatcher.group(1).equals("OCNL TS ")) { + retTS = "OCCASIONAL THUNDERSTORMS"; + } else if (tsMatcher.group(1).equals("EMBD TSGR ")) { + retTS = "EMBEDED THUNDERSTORMS HAIL"; + } else if (tsMatcher.group(1).equals(" TSGR ")) { + retTS = "THUNDERSTORMS HAIL"; + } else if (tsMatcher.group(1).equals(" GR ")) { + retTS = "HAIL"; + } else if (tsMatcher.group(1).equals("TS/CB")) { + retTS = "THUNDERSTORMS CUMULONIMBUS"; + } else if (tsMatcher.group(1).equals("CB/TS")) { + retTS = "THUNDERSTORMS CUMULONIMBUS"; + } + } + + return retTS; + } + + /** + * Remove a character from a string and return the result. + * + * @param s + * the string + * @param c + * the character to be removed + * @return a string. + */ + public static String removeChar(String s, char c) { + + String ret = ""; + + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) != c) + ret += s.charAt(i); + } + + return ret; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/package-info.java old mode 100755 new mode 100644 index 91e3452c24..d6c1a45bcd --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/src/gov/noaa/nws/ncep/edex/plugin/intlsigmet/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.intlsigmet.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.intlsigmet.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/2009060816.isig b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/2009060816.isig index 1929d5e6ad..1f1cfd584e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/2009060816.isig +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/unit-test/gov/noaa/nws/ncep/edex/plugin/intlsigmet/decoder/2009060816.isig @@ -1,9 +1,9 @@ - + -345 + -WSNT08 KKCI 081620 + -SIGA0H + -KZMA SIGMET HOTEL 1 VALID 081620/082020 KKCI- + -MIAMI OCEANIC FIR FRQ TS OBS AT 1620Z WI N2500 W07400 - N2145 + -W07445 - N2315 W07715 - N2500 W07400. TOP FL460. STNR. INTSF. + - + + +345 +WSNT08 KKCI 081620 +SIGA0H +KZMA SIGMET HOTEL 1 VALID 081620/082020 KKCI- +MIAMI OCEANIC FIR FRQ TS OBS AT 1620Z WI N2500 W07400 - N2145 +W07445 - N2315 W07715 - N2500 W07400. TOP FL460. STNR. INTSF. +  diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/utility/edex_static/base/distribution/intlsigmet.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/utility/edex_static/base/distribution/intlsigmet.xml index 8b840209d5..19c3c50588 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/utility/edex_static/base/distribution/intlsigmet.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/utility/edex_static/base/distribution/intlsigmet.xml @@ -1,7 +1,34 @@ - ^W[CSV]PA(0[1-9]|1[1-3]) PHFO.* - ^W[CSV]NT(0[1-9]|1[1-3]) KKCI.* - ^WAAK4[789] PAWU.* - ^W[CSV]PN0[1-6] KKCI.* + ^WSAK0[12] PAWU.* + ^WSA[LG]31 .* + ^WSAU21 .* + ^WSBZ[23]1 .* + ^WSBW20 .* + ^WSC[AH]31 .* + ^WSCD20 .* + ^WSCI3[14579] .* + ^WSCN(3[12356]|02) .* + ^WSE[EW]3[1-3] .* + ^WSF(I31|G20|J01|R3[245]) .* + ^WS(G[LR]|L[JV])31 .* + ^WSIE31 .* + ^WSIY3[1-3] .* + ^WSIN(31|90) .* + ^WSM[CAGVOP]31 .* + ^WSN(L31|U20|O3[2456]) .* + ^WSP[RM]31 .* + ^WSR[ASH]3[126] .* + ^WSS(([MQG]31)|(G32)|([CRSD]20)) .* + ^WSTS(40|31) .* + ^WSU(K32|R34) .* + ^WSZA21 .* + ^W[CSV](PA|NT)(0[1-9]|1[1-3]) .* + ^W[CSV]PN0[1-6] .* + ^W[SCV]HO31 .* + ^W[SV]JP31 .* + ^WV(AG|EQ)31 .* + ^WV(IY32|RS37) .* + ^W[CSV](NT|PN|PA|AK)[01][0-9] (KKCI|PHFO|PAWU) ([0-3][0-9])([0-2][0-9]).* + ^W[CSV].... [^KP]... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/component-deploy.xml index 798fc4fd44..70460b4c5e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/src/gov/noaa/nws/ncep/edex/plugin/mcidas/decoder/McidasDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/src/gov/noaa/nws/ncep/edex/plugin/mcidas/decoder/McidasDecoder.java index 421936749a..c5739461f6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/src/gov/noaa/nws/ncep/edex/plugin/mcidas/decoder/McidasDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mcidas/src/gov/noaa/nws/ncep/edex/plugin/mcidas/decoder/McidasDecoder.java @@ -15,6 +15,7 @@ * 12/2009 144 T. Lee Renamed proj type for resource * rendering * 05/2010 144 L. Lin Migration to TO11DR11. + * 11/2011 T. Lee Enhanced for ntbn * * * @author tlee @@ -30,9 +31,11 @@ import java.io.InputStream; import java.util.Calendar; import java.util.TimeZone; +import com.raytheon.edex.esb.Headers; import com.raytheon.edex.exception.DecoderException; import com.raytheon.edex.plugin.AbstractDecoder; import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.edex.decodertools.time.TimeTools; import gov.noaa.nws.ncep.common.dataplugin.mcidas.McidasMapCoverage; @@ -52,7 +55,7 @@ public class McidasDecoder extends AbstractDecoder { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); private McidasRecord mr = new McidasRecord(); - public PluginDataObject[] decode(byte[] data) throws Exception { + public PluginDataObject[] decode(byte[] data, Headers headers) throws Exception { int endian = 0; byte[] area = null; byte[] nonAreaBlock = new byte[data.length - SIZE_OF_AREA]; @@ -63,13 +66,10 @@ public class McidasDecoder extends AbstractDecoder { * Separate area file and non-area block. */ record.setSizeRecords(data.length); - if (area == null) { - area = new byte[SIZE_OF_AREA]; - System.arraycopy(data, 0, area, 0, SIZE_OF_AREA); - System.arraycopy(data, SIZE_OF_AREA, nonAreaBlock, 0, nonAreaBlock.length); - } else { - nonAreaBlock = data; - } + + area = new byte[SIZE_OF_AREA]; + System.arraycopy(data, 0, area, 0, SIZE_OF_AREA); + System.arraycopy(data, SIZE_OF_AREA, nonAreaBlock, 0, nonAreaBlock.length); /* * First word contains all zero for a valid record @@ -238,16 +238,25 @@ public class McidasDecoder extends AbstractDecoder { } } record.setAreaName(areaName); - String filename = mr.getInputFileName(); - record.setInputFileName(filename); - + String fileName = ""; + if ( headers != null ) { + fileName = (String) headers.get("traceId"); + } + record.setInputFileName(fileName); + /* * Acquire image type from input file name if needed. */ - if (imageType.equals("UNKNOWN") || satelliteName.equals("VAAC")) { - int index = filename.indexOf("_2"); - imageType = filename.substring(0,index); - } + if (imageType.equals("UNKNOWN") || satelliteName.equals("VAAC")) { + if ( fileName.contains("_20") ) { + int index = fileName.indexOf("_20");; + imageType = fileName.substring(0,index); + if ( imageType.contains("_") ) { + index = imageType.lastIndexOf("_"); + imageType = imageType.substring (index + 1, imageType.length()); + } + } + } record.setImageType(imageType); /* @@ -710,15 +719,13 @@ public class McidasDecoder extends AbstractDecoder { record.setCoverage(mapCoverage); record.setPersistenceTime(TimeTools.getSystemCalendar()); record.setPluginName("mcidas"); - record.constructDataURI(); - } - if (record == null) { - System.out.println (" Not a valid image record"); - return new PluginDataObject[0]; - } - else { - return new PluginDataObject[] {record}; + try { + record.constructDataURI(); + } catch (PluginException e) { + e.printStackTrace(); + } } + return new PluginDataObject[] {record}; } else { return new PluginDataObject[0]; @@ -888,7 +895,7 @@ public class McidasDecoder extends AbstractDecoder { } } } - return decode(fileData); + return decode(fileData, null); } /* diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/component-deploy.xml index c307947f59..e88aa871f4 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/component-deploy.xml @@ -1,10 +1,9 @@ - - + + + + + + - \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/endpoints/mosaic-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/endpoints/mosaic-ingest.xml index e89c4f1a52..ac42373d24 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/endpoints/mosaic-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/endpoints/mosaic-ingest.xml @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -43,25 +43,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java index 9ad33f3ebb..772af358c4 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/MosaicRecord.java @@ -1,6 +1,6 @@ -package gov.noaa.nws.ncep.edex.plugin.mosaic.common; - +package gov.noaa.nws.ncep.edex.plugin.mosaic.common; + import gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3.DataLevelThreshold; import gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3.SymbologyBlock; import gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3.SymbologyPacket; @@ -45,7 +45,7 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.operation.MathTransform; - + //import com.raytheon.edex.map.MapUtil; import com.raytheon.uf.common.dataplugin.IDecoderGettable; import com.raytheon.uf.common.dataplugin.annotations.DataURI; @@ -83,7 +83,7 @@ import com.vividsolutions.jts.geom.Envelope; * This code has been developed by the SIB for use in the AWIPS2 system. * @author L. Lin * @version 1.0 - */ + */ @Entity @@ -94,41 +94,41 @@ import com.vividsolutions.jts.geom.Envelope; @DynamicSerialize public class MosaicRecord extends PersistablePluginDataObject implements IPersistable, ISpatialEnabled, IMosaicRecord { - - private static final long serialVersionUID = 1L; - - @Column - @DataURI(position = 2) - @DynamicSerializeElement - @XmlElement(nillable = false) - private Integer productCode; - + + private static final long serialVersionUID = 1L; + + @Column + @DataURI(position = 2) + @DynamicSerializeElement + @XmlElement(nillable = false) + private Integer productCode; + @Column - @DataURI(position=3) - @DynamicSerializeElement - @XmlElement(nillable = false) - private Integer resolution; - - @Column(length = 16) - @DataURI(position = 1) - @DynamicSerializeElement - @XmlElement(nillable = false) - private String prodName; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Float latitude; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Float longitude; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Float elevation; + @DataURI(position=3) + @DynamicSerializeElement + @XmlElement(nillable = false) + private Integer resolution; + + @Column(length = 16) + @DataURI(position = 1) + @DynamicSerializeElement + @XmlElement(nillable = false) + private String prodName; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Float latitude; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Float longitude; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Float elevation; @Column @DynamicSerializeElement @@ -140,12 +140,12 @@ public class MosaicRecord extends PersistablePluginDataObject implements @DynamicSerializeElement @XmlElement(nillable = false) private Integer sourceId; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) private Integer volumeCoveragePattern; - + @Column @DynamicSerializeElement @XmlElement(nillable = false) @@ -160,150 +160,150 @@ public class MosaicRecord extends PersistablePluginDataObject implements @DynamicSerializeElement @XmlElement(nillable = false) private Calendar generationTime; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Integer numLevels; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Integer nx; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private Integer ny; - - @Column - @DynamicSerializeElement - @XmlElement(nillable = false) - private String format; - - @Column(length = 16) - @DynamicSerializeElement - @XmlElement(nillable = false) - private String unit; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Integer numLevels; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Integer nx; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private Integer ny; + + @Column + @DynamicSerializeElement + @XmlElement(nillable = false) + private String format; + + @Column(length = 16) + @DynamicSerializeElement + @XmlElement(nillable = false) + private String unit; + + @Transient + private byte[] rawData; @Transient - private byte[] rawData; - - @Transient - private byte[] headerBlock; - - @Transient - private short[] thresholds; - - @Transient - private short[] productDependentValues; - - @Transient - private Object[] decodedThresholds; - - @Transient - private SymbologyBlock symbologyBlock; - - @Transient - private HashMap>> productVals = new HashMap>>(); - - @Transient - private HashMap> recordVals = new HashMap>(); - - @Transient - private Map symbologyData = new HashMap(); - - public MosaicRecord() { - super(); - this.nx = 0; - this.ny = 0; - rawData = null; - thresholds = new short[16]; - decodedThresholds = new Object[16]; - } - - public MosaicRecord(int rows, int columns) { - this(); - this.nx = rows; - this.ny = columns; - rawData = new byte[rows * columns]; - thresholds = new short[16]; - decodedThresholds = new Object[16]; - } - - /** - * Constructs a mosaic record from a dataURI - * - * @param uri - * The dataURI - * @param tableDef - * The table definition associated with this class - */ - public MosaicRecord(String uri) { - super(uri); - } - - /** - * @param dataStore - * @throws StorageException - */ - public void retrieveFromDataStore(IDataStore dataStore) - throws StorageException, FileNotFoundException { - - if ("Radial".equals(format) || "Raster".equals(format)) { - //ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( + private byte[] headerBlock; + + @Transient + private short[] thresholds; + + @Transient + private short[] productDependentValues; + + @Transient + private Object[] decodedThresholds; + + @Transient + private SymbologyBlock symbologyBlock; + + @Transient + private HashMap>> productVals = new HashMap>>(); + + @Transient + private HashMap> recordVals = new HashMap>(); + + @Transient + private Map symbologyData = new HashMap(); + + public MosaicRecord() { + super(); + this.nx = 0; + this.ny = 0; + rawData = null; + thresholds = new short[16]; + decodedThresholds = new Object[16]; + } + + public MosaicRecord(int rows, int columns) { + this(); + this.nx = rows; + this.ny = columns; + rawData = new byte[rows * columns]; + thresholds = new short[16]; + decodedThresholds = new Object[16]; + } + + /** + * Constructs a mosaic record from a dataURI + * + * @param uri + * The dataURI + * @param tableDef + * The table definition associated with this class + */ + public MosaicRecord(String uri) { + super(uri); + } + + /** + * @param dataStore + * @throws StorageException + */ + public void retrieveFromDataStore(IDataStore dataStore) + throws StorageException, FileNotFoundException { + + if ("Radial".equals(format) || "Raster".equals(format)) { + //ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( // getDataURI(), "Data"); ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( - getDataURI(), "Data", Request.ALL); - setRawData(byteData.getByteData()); - } - - if ("Graphic".equals(format) || "XY".equals(format) - || "Graph".equals(format)) { - - try { - //ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( + getDataURI(), "Data", Request.ALL); + setRawData(byteData.getByteData()); + } + + if ("Graphic".equals(format) || "XY".equals(format) + || "Graph".equals(format)) { + + try { + //ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( // getDataURI(), "Symbology"); ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( - getDataURI(), "Symbology", Request.ALL); - ByteArrayInputStream bais = new ByteArrayInputStream(byteData - .getByteData()); - Object o = DynamicSerializationManager.getManager( - SerializationType.Thrift).deserialize(bais); - setSymbologyBlock((SymbologyBlock) o); - } catch (Throwable e) { - setSymbologyBlock(null); - } - - try { - ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( - getDataURI(), "ProductVals", Request.ALL); - ByteArrayInputStream bais = new ByteArrayInputStream(byteData - .getByteData()); - Object o = DynamicSerializationManager.getManager( - SerializationType.Thrift).deserialize(bais); - setProductVals((HashMap>>) o); - } catch (Throwable e) { - setProductVals(null); - } - - } - try { - ShortDataRecord shortData = (ShortDataRecord) dataStore.retrieve( - getDataURI(), "Thresholds", Request.ALL); - setThresholds(shortData.getShortData()); - } catch (Exception e) { - setThresholds(null); - } - - try { - ShortDataRecord depValData = (ShortDataRecord) dataStore.retrieve( - getDataURI(), "DependentValues", Request.ALL); - setProductDependentValues(depValData.getShortData()); - } catch (Throwable e) { - setProductDependentValues(null); - } - } + getDataURI(), "Symbology", Request.ALL); + ByteArrayInputStream bais = new ByteArrayInputStream(byteData + .getByteData()); + Object o = DynamicSerializationManager.getManager( + SerializationType.Thrift).deserialize(bais); + setSymbologyBlock((SymbologyBlock) o); + } catch (Throwable e) { + setSymbologyBlock(null); + } + + try { + ByteDataRecord byteData = (ByteDataRecord) dataStore.retrieve( + getDataURI(), "ProductVals", Request.ALL); + ByteArrayInputStream bais = new ByteArrayInputStream(byteData + .getByteData()); + Object o = DynamicSerializationManager.getManager( + SerializationType.Thrift).deserialize(bais); + setProductVals((HashMap>>) o); + } catch (Throwable e) { + setProductVals(null); + } + + } + try { + ShortDataRecord shortData = (ShortDataRecord) dataStore.retrieve( + getDataURI(), "Thresholds", Request.ALL); + setThresholds(shortData.getShortData()); + } catch (Exception e) { + setThresholds(null); + } + + try { + ShortDataRecord depValData = (ShortDataRecord) dataStore.retrieve( + getDataURI(), "DependentValues", Request.ALL); + setProductDependentValues(depValData.getShortData()); + } catch (Throwable e) { + setProductDependentValues(null); + } + } /** * Get the time to use for persisting this data. @@ -317,16 +317,16 @@ public class MosaicRecord extends PersistablePluginDataObject implements return null; return c.getTime(); - } - - /** - * Set the time to be used for the persistence time for this object. - * - * @param persistTime - * The persistence time to be used. - */ - public void setPersistenceTime(Calendar persistTime) { - setInsertTime(persistTime); + } + + /** + * Set the time to be used for the persistence time for this object. + * + * @param persistTime + * The persistence time to be used. + */ + public void setPersistenceTime(Calendar persistTime) { + setInsertTime(persistTime); } public String getProdName() { @@ -337,21 +337,21 @@ public class MosaicRecord extends PersistablePluginDataObject implements this.prodName = prodName; } - /** - * @return the productCode - */ - public Integer getProductCode() { - return productCode; - } - - /** - * @param productCode - * the productCode to set - */ - public void setProductCode(Integer productCode) { - this.productCode = productCode; - } - + /** + * @return the productCode + */ + public Integer getProductCode() { + return productCode; + } + + /** + * @param productCode + * the productCode to set + */ + public void setProductCode(Integer productCode) { + this.productCode = productCode; + } + public Integer getNx() { return nx; } @@ -366,16 +366,16 @@ public class MosaicRecord extends PersistablePluginDataObject implements public void setNy(Integer ny) { this.ny = ny; - } - + } + public Integer getResolution() { return resolution; } public void setResolution(Integer resolution) { this.resolution = resolution; - } - + } + public Integer getSourceId() { return sourceId; } @@ -384,22 +384,22 @@ public class MosaicRecord extends PersistablePluginDataObject implements this.sourceId = sourceId; } - public Float getLatitude() { - return latitude; - } - - public void setLatitude(Float latitude) { - this.latitude = latitude; - } - - public Float getLongitude() { - return longitude; - } - - public void setLongitude(Float longitude) { - this.longitude = longitude; - } - + public Float getLatitude() { + return latitude; + } + + public void setLatitude(Float latitude) { + this.latitude = latitude; + } + + public Float getLongitude() { + return longitude; + } + + public void setLongitude(Float longitude) { + this.longitude = longitude; + } + public Float getTrueElevationAngle() { return trueElevationAngle; } @@ -416,71 +416,71 @@ public class MosaicRecord extends PersistablePluginDataObject implements this.headerBlock = headerBlock; } - public byte[] getRawData() { - return rawData; - } - - public void setRawData(byte[] mosaicData) { - this.rawData = mosaicData; - } - - public int getOpMode() { - return 1; - } - - public void setRawDataValue(int radial, int bin, byte value) { - if ((radial < nx) && (bin < ny)) { - rawData[radial * ny + bin] = value; - } - } - - public byte getRawDataValue(int radial, int bin) { - return rawData[radial * ny + bin]; - } - - public short getThreshold(int i) { - return thresholds[i]; - } - - public Object getDecodedThreshold(int i) { - return decodedThresholds[i]; - } - - public void setThreshold(int i, short threshold) { - this.thresholds[i] = threshold; - this.decodedThresholds[i] = new DataLevelThreshold(threshold).decode(); - } - - public short[] getThresholds() { - return thresholds; - } - - public Object[] getDecodedThresholds() { - return decodedThresholds; - } - - public void setThresholds(short[] thresholds) { - this.thresholds = thresholds; - this.decodedThresholds = null; - if (thresholds != null) { - this.decodedThresholds = new Object[thresholds.length]; - int i = 0; - DataLevelThreshold dl = new DataLevelThreshold(); - for (short threshold : thresholds) { - dl.set(threshold); - this.decodedThresholds[i++] = dl.decode(); - } - } - } - - public Integer getNumLevels() { - return numLevels; - } - - public void setNumLevels(Integer numLevels) { - this.numLevels = numLevels; - } - + public byte[] getRawData() { + return rawData; + } + + public void setRawData(byte[] mosaicData) { + this.rawData = mosaicData; + } + + public int getOpMode() { + return 1; + } + + public void setRawDataValue(int radial, int bin, byte value) { + if ((radial < nx) && (bin < ny)) { + rawData[radial * ny + bin] = value; + } + } + + public byte getRawDataValue(int radial, int bin) { + return rawData[radial * ny + bin]; + } + + public short getThreshold(int i) { + return thresholds[i]; + } + + public Object getDecodedThreshold(int i) { + return decodedThresholds[i]; + } + + public void setThreshold(int i, short threshold) { + this.thresholds[i] = threshold; + this.decodedThresholds[i] = new DataLevelThreshold(threshold).decode(); + } + + public short[] getThresholds() { + return thresholds; + } + + public Object[] getDecodedThresholds() { + return decodedThresholds; + } + + public void setThresholds(short[] thresholds) { + this.thresholds = thresholds; + this.decodedThresholds = null; + if (thresholds != null) { + this.decodedThresholds = new Object[thresholds.length]; + int i = 0; + DataLevelThreshold dl = new DataLevelThreshold(); + for (short threshold : thresholds) { + dl.set(threshold); + this.decodedThresholds[i++] = dl.decode(); + } + } + } + + public Integer getNumLevels() { + return numLevels; + } + + public void setNumLevels(Integer numLevels) { + this.numLevels = numLevels; + } + public Calendar getIssueTime() { return issueTime; } @@ -504,284 +504,284 @@ public class MosaicRecord extends PersistablePluginDataObject implements public void setGenerationTime(Calendar generationTime) { this.generationTime = generationTime; } - - public String getFormat() { - return format; + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public Integer getVolumeCoveragePattern() { + return volumeCoveragePattern; + } + + public void setVolumeCoveragePattern(Integer volumeCoveragePattern) { + this.volumeCoveragePattern = volumeCoveragePattern; + } + + /** + * @return the unit + */ + public String getUnit() { + return unit; + } + + /** + * @param unit + * the unit to set + */ + public void setUnit(String unit) { + this.unit = unit; + } + + public Float getElevation() { + return elevation; + } + + public void setElevation(Float elevation) { + this.elevation = elevation; + } + + /** + * Get the IDecoderGettable reference for this record. + * + * @return The IDecoderGettable reference for this record. Null for this + * class. + */ + @Override + public IDecoderGettable getDecoderGettable() { + return null; } - - public void setFormat(String format) { - this.format = format; - } - - public Integer getVolumeCoveragePattern() { - return volumeCoveragePattern; - } - - public void setVolumeCoveragePattern(Integer volumeCoveragePattern) { - this.volumeCoveragePattern = volumeCoveragePattern; - } - - /** - * @return the unit - */ - public String getUnit() { - return unit; - } - - /** - * @param unit - * the unit to set - */ - public void setUnit(String unit) { - this.unit = unit; - } - - public Float getElevation() { - return elevation; - } - - public void setElevation(Float elevation) { - this.elevation = elevation; - } - - /** - * Get the IDecoderGettable reference for this record. - * - * @return The IDecoderGettable reference for this record. Null for this - * class. - */ - @Override - public IDecoderGettable getDecoderGettable() { - return null; - } - - /** - * @return the symbologyBlock - */ - public SymbologyBlock getSymbologyBlock() { - return symbologyBlock; - } - - /** - * @param symbologyBlock - * the symbologyBlock to set - */ - public void setSymbologyBlock(SymbologyBlock symbologyBlock) { - this.symbologyBlock = symbologyBlock; - } - - public short getProductDependentValue(int value) { - return productDependentValues[value]; - } - - /** - * @return the productDependentValues - */ - public short[] getProductDependentValues() { - return productDependentValues; - } - - /** - * @param productDependentValues - * the productDependentValues to set - */ - public void setProductDependentValues(short[] productDependentValues) { - this.productDependentValues = productDependentValues; - } - - public ProjectedCRS getCRS() { - return MapUtil.constructStereographic(MapUtil.AWIPS_EARTH_RADIUS, - MapUtil.AWIPS_EARTH_RADIUS, this.latitude, this.longitude); - } - - /** - * @return the symbologyData - */ - public Map getSymbologyData() { - return symbologyData; - } - - /** - * @param symbologyData - * the symbologyData to set - */ - public void setSymbologyData(Map symbologyData) { - this.symbologyData = symbologyData; - } - - public Integer getDataValue(Coordinate latLon) { - double[] input = { latLon.x, latLon.y }; - double[] output = new double[2]; - try { - MathTransform mt = MapUtil.getTransformFromLatLon(getCRS()); - - mt.transform(input, 0, output, 0, 1); - } catch (Exception e) { - return null; - } - - int dataValue = 0; - - // ********************************** - // Raster case - // ********************************** - if ("Raster".equals(this.getFormat())) { - - int col = (int) (output[0] / this.getResolution() + (this - .getNy() / 2)); - - int row = (int) (output[1] / this.getResolution() + (this - .getNy() / 2)); - - row = this.getNy() - row - 1; - - if ((row >= 0) && (row < this.getNy()) && (col >= 0) - && (col < this.getNy())) { - dataValue = this.getRawDataValue(row, col); - } - } - - return dataValue; - } - - /** - * @param productVals - * the productVals to set - */ - public void setProductVals( - HashMap>> map) { - this.productVals = map; - } - - public void printSymbologyData() { - System.out - .println("******************************************************************************"); - System.out.println("*** START Symbology Data Contents"); - System.out - .println("******************************************************************************"); - - for (MosaicDataKey key : symbologyData.keySet()) { - System.out.println("Key: " + key); - MosaicDataPoint data = symbologyData.get(key); - HashMap> displayPointData = data - .getDisplayPointData(); - for (Integer pktType : displayPointData.keySet()) { - System.out.println("\tPt Type: " + pktType); - for (SymbologyPoint currPt : displayPointData.get(pktType)) { - System.out.println("\t\t" + currPt); - } - } - - HashMap> displayPacketData = data - .getDisplayPacketData(); - for (Integer pktType : displayPacketData.keySet()) { - System.out.println("\tPkt Type: " + pktType); - for (SymbologyPacket currPkt : displayPacketData.get(pktType)) { - System.out.println("\t\t" + currPkt); - } - } - } - - System.out - .println("******************************************************************************"); - System.out.println("*** END Symbology Data Contents"); - System.out - .println("******************************************************************************"); - } - - /* - * Return the product values map for a type, a storm id, and the desired - * value type - * - * (non-Javadoc) - * - * @see - * com.raytheon.edex.plugin.mosaic.IMosaicRecord#getProductVals(com.raytheon - * .edex.util.mosaic.MosaicConstants.MapValues) - */ - @Override - public String getProductVals(MosaicConstants.MapValues type, String id, - MapValues valueName) { - return productVals.get(type).get(id).get(valueName); - } - - /** - * Return the product values map for the product type and for a certain - * storm id - * - * @param type - * @param id - * @return - */ - public Map getProductValsPerStorm( - MosaicConstants.MapValues type, String id) { - return productVals.get(type).get(id); - } - - /** - * Return the product values map for a certain product type - * - * @param type - * @return - */ - public Map> getProductValsPerType( - MosaicConstants.MapValues type) { - return productVals.get(type); - } - - /** - * Return the entire product values map - * - * @return - */ - public Map>> getProductValsMap() { - return productVals; - } - - /** - * @return the recordVals - */ - public String getProductValsPerRecord(MosaicConstants.MapValues type, - MosaicConstants.MapValues val) { - return recordVals.get(type).get(val); - } - - /** - * @return the recordVals - */ - public HashMap> getRecordVals() { - return recordVals; - } - - /** - * @param recordVals - * the recordVals to set - */ - public void setRecordVals( - HashMap> recordVals) { - this.recordVals = recordVals; - } - - /** - * Search in the map for the storm id and send back the feature if that is - * the case - * - * @param type - * @param id - * @return - */ - public List getFeatures(MosaicConstants.MapValues type, String id) { - List list = new ArrayList(); - for (Map.Entry> entry : productVals - .get(type).entrySet()) { - if (id.trim().equals( - entry.getValue() - .get(MosaicConstants.MapValues.MESO_STORM_ID) - .toString().trim())) { - list.add(entry.getKey()); - } - } - return list; + + /** + * @return the symbologyBlock + */ + public SymbologyBlock getSymbologyBlock() { + return symbologyBlock; + } + + /** + * @param symbologyBlock + * the symbologyBlock to set + */ + public void setSymbologyBlock(SymbologyBlock symbologyBlock) { + this.symbologyBlock = symbologyBlock; + } + + public short getProductDependentValue(int value) { + return productDependentValues[value]; + } + + /** + * @return the productDependentValues + */ + public short[] getProductDependentValues() { + return productDependentValues; + } + + /** + * @param productDependentValues + * the productDependentValues to set + */ + public void setProductDependentValues(short[] productDependentValues) { + this.productDependentValues = productDependentValues; + } + + public ProjectedCRS getCRS() { + return MapUtil.constructStereographic(MapUtil.AWIPS_EARTH_RADIUS, + MapUtil.AWIPS_EARTH_RADIUS, this.latitude, this.longitude); + } + + /** + * @return the symbologyData + */ + public Map getSymbologyData() { + return symbologyData; + } + + /** + * @param symbologyData + * the symbologyData to set + */ + public void setSymbologyData(Map symbologyData) { + this.symbologyData = symbologyData; + } + + public Integer getDataValue(Coordinate latLon) { + double[] input = { latLon.x, latLon.y }; + double[] output = new double[2]; + try { + MathTransform mt = MapUtil.getTransformFromLatLon(getCRS()); + + mt.transform(input, 0, output, 0, 1); + } catch (Exception e) { + return null; + } + + int dataValue = 0; + + // ********************************** + // Raster case + // ********************************** + if ("Raster".equals(this.getFormat())) { + + int col = (int) (output[0] / this.getResolution() + (this + .getNy() / 2)); + + int row = (int) (output[1] / this.getResolution() + (this + .getNy() / 2)); + + row = this.getNy() - row - 1; + + if ((row >= 0) && (row < this.getNy()) && (col >= 0) + && (col < this.getNy())) { + dataValue = this.getRawDataValue(row, col); + } + } + + return dataValue; + } + + /** + * @param productVals + * the productVals to set + */ + public void setProductVals( + HashMap>> map) { + this.productVals = map; + } + + public void printSymbologyData() { + System.out + .println("******************************************************************************"); + System.out.println("*** START Symbology Data Contents"); + System.out + .println("******************************************************************************"); + + for (MosaicDataKey key : symbologyData.keySet()) { + System.out.println("Key: " + key); + MosaicDataPoint data = symbologyData.get(key); + HashMap> displayPointData = data + .getDisplayPointData(); + for (Integer pktType : displayPointData.keySet()) { + System.out.println("\tPt Type: " + pktType); + for (SymbologyPoint currPt : displayPointData.get(pktType)) { + System.out.println("\t\t" + currPt); + } + } + + HashMap> displayPacketData = data + .getDisplayPacketData(); + for (Integer pktType : displayPacketData.keySet()) { + System.out.println("\tPkt Type: " + pktType); + for (SymbologyPacket currPkt : displayPacketData.get(pktType)) { + System.out.println("\t\t" + currPkt); + } + } + } + + System.out + .println("******************************************************************************"); + System.out.println("*** END Symbology Data Contents"); + System.out + .println("******************************************************************************"); + } + + /* + * Return the product values map for a type, a storm id, and the desired + * value type + * + * (non-Javadoc) + * + * @see + * com.raytheon.edex.plugin.mosaic.IMosaicRecord#getProductVals(com.raytheon + * .edex.util.mosaic.MosaicConstants.MapValues) + */ + @Override + public String getProductVals(MosaicConstants.MapValues type, String id, + MapValues valueName) { + return productVals.get(type).get(id).get(valueName); + } + + /** + * Return the product values map for the product type and for a certain + * storm id + * + * @param type + * @param id + * @return + */ + public Map getProductValsPerStorm( + MosaicConstants.MapValues type, String id) { + return productVals.get(type).get(id); + } + + /** + * Return the product values map for a certain product type + * + * @param type + * @return + */ + public Map> getProductValsPerType( + MosaicConstants.MapValues type) { + return productVals.get(type); + } + + /** + * Return the entire product values map + * + * @return + */ + public Map>> getProductValsMap() { + return productVals; + } + + /** + * @return the recordVals + */ + public String getProductValsPerRecord(MosaicConstants.MapValues type, + MosaicConstants.MapValues val) { + return recordVals.get(type).get(val); + } + + /** + * @return the recordVals + */ + public HashMap> getRecordVals() { + return recordVals; + } + + /** + * @param recordVals + * the recordVals to set + */ + public void setRecordVals( + HashMap> recordVals) { + this.recordVals = recordVals; + } + + /** + * Search in the map for the storm id and send back the feature if that is + * the case + * + * @param type + * @param id + * @return + */ + public List getFeatures(MosaicConstants.MapValues type, String id) { + List list = new ArrayList(); + for (Map.Entry> entry : productVals + .get(type).entrySet()) { + if (id.trim().equals( + entry.getValue() + .get(MosaicConstants.MapValues.MESO_STORM_ID) + .toString().trim())) { + list.add(entry.getKey()); + } + } + return list; } @Override @@ -794,5 +794,5 @@ public class MosaicRecord extends PersistablePluginDataObject implements public ISpatialObject getSpatialObject() { // TODO Auto-generated method stub return null; - } -} + } +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/package-info.java index 41a4d5fb8e..c6d66da4ab 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/common/package-info.java @@ -1,4 +1,4 @@ -/** - * Core classes for radar plugin. Core files include the decoder, record, separator, and writer implementations - */ +/** + * Core classes for radar plugin. Core files include the decoder, record, separator, and writer implementations + */ package gov.noaa.nws.ncep.edex.plugin.mosaic.common; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/decoder/package-info.java index 605caf019e..5d85283f76 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/decoder/package-info.java @@ -1,4 +1,4 @@ -/** - * Core classes for radar plugin. Core files include the decoder, record, separator, and writer implementations - */ +/** + * Core classes for radar plugin. Core files include the decoder, record, separator, and writer implementations + */ package gov.noaa.nws.ncep.edex.plugin.mosaic.decoder; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/package-info.java index 65aaf17643..1d3d23fe73 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/uengine/package-info.java @@ -1,5 +1,5 @@ -/** - * Contains JavaScript oriented μEngine tasks specific to mosaic - * - */ +/** + * Contains JavaScript oriented μEngine tasks specific to mosaic + * + */ package gov.noaa.nws.ncep.edex.plugin.mosaic.uengine; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/Level3Parser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/Level3Parser.java index 9ad37f9859..944dedae95 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/Level3Parser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/Level3Parser.java @@ -1,21 +1,21 @@ -package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; - +package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; + import gov.noaa.nws.ncep.edex.plugin.mosaic.util.MosaicUtil; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Calendar; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Calendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Level3Parser is a class that will allow the user to do the following: @@ -32,147 +32,147 @@ import org.apache.commons.logging.LogFactory; * This code has been developed by the SIB for use in the AWIPS2 system. * @author L. Lin * @version 1.0 - */ - -public class Level3Parser { - - private static final int Z_DEFLATED = 8; - - private static final int DEF_WBITS = 15; - - private static final Pattern WMO_PATTERN = Pattern - .compile("([A-Z]{4}[0-9]{2} [A-Z]{4} [0-9]{6})\\x0D\\x0D\\x0A(\\w{6})\\x0D\\x0D\\x0A"); - - /** The logger */ - private final transient Log logger = LogFactory.getLog(getClass()); - - protected DataInputStream theMosaicData = null; - - private ByteArrayInputStream theRawMosaicData = null; - - protected byte[] theRawMosaicByteArray = null; - - // message header - private int theMessageCode; - - private Calendar theMsgTimestamp; - - private int theMsgLength; - - private int theSourceId; - - private int theDestinationId; - - private int numberOfBlocks; - - // product description block - private double theLatitude; - - private double theLongitude; - - private int theHeight; - - private int theProductCode; - - private int theOperationalMode; - - private int theVolumeCoveragePattern; - - private int theSequenceNumber; - - private int theVolumeScanNumber; - - private Calendar theVolScanTime; - - private Calendar theProdGenTime; - - private static short[] productDependentValues; - - private int elevationNumber; - + */ + +public class Level3Parser { + + private static final int Z_DEFLATED = 8; + + private static final int DEF_WBITS = 15; + + private static final Pattern WMO_PATTERN = Pattern + .compile("([A-Z]{4}[0-9]{2} [A-Z]{4} [0-9]{6})\\x0D\\x0D\\x0A(\\w{6})\\x0D\\x0D\\x0A"); + + /** The logger */ + private final transient Log logger = LogFactory.getLog(getClass()); + + protected DataInputStream theMosaicData = null; + + private ByteArrayInputStream theRawMosaicData = null; + + protected byte[] theRawMosaicByteArray = null; + + // message header + private int theMessageCode; + + private Calendar theMsgTimestamp; + + private int theMsgLength; + + private int theSourceId; + + private int theDestinationId; + + private int numberOfBlocks; + + // product description block + private double theLatitude; + + private double theLongitude; + + private int theHeight; + + private int theProductCode; + + private int theOperationalMode; + + private int theVolumeCoveragePattern; + + private int theSequenceNumber; + + private int theVolumeScanNumber; + + private Calendar theVolScanTime; + + private Calendar theProdGenTime; + + private static short[] productDependentValues; + + private int elevationNumber; + private short[] dataLevelThresholds; private int maximumDataLevel; // Use for raster display! - private static int numberOfColumns; - - private SymbologyBlock symbologyBlock; - - private int numberOfMaps; - - /** - * This level3Parser constructor accepts a mosaic file contained within a - * java.io.File object. - * - * @param aMosaic - * A java.io.File object containing a raw mosaic file - * @throws IOException - * If the mosaic head parsing fails, an IO exception is thrown - */ - public Level3Parser(File aMosaic) throws IOException { - int fileSize = (int) aMosaic.length(); - byte[] tempRawMosaicByteArray = new byte[fileSize]; - - FileInputStream mosaicFile = null; - - try { - mosaicFile = new FileInputStream(aMosaic); + private static int numberOfColumns; + + private SymbologyBlock symbologyBlock; + + private int numberOfMaps; + + /** + * This level3Parser constructor accepts a mosaic file contained within a + * java.io.File object. + * + * @param aMosaic + * A java.io.File object containing a raw mosaic file + * @throws IOException + * If the mosaic head parsing fails, an IO exception is thrown + */ + public Level3Parser(File aMosaic) throws IOException { + int fileSize = (int) aMosaic.length(); + byte[] tempRawMosaicByteArray = new byte[fileSize]; + + FileInputStream mosaicFile = null; + + try { + mosaicFile = new FileInputStream(aMosaic); mosaicFile.read(tempRawMosaicByteArray); - } finally { - if (mosaicFile != null) { - mosaicFile.close(); - } - } - init(tempRawMosaicByteArray); - } - - /** - * This level3Parser constructor accepts a mosaic file already converted to a - * byte array. - * - * @param aMosaic - * A byte array containing a raw mosaic file - * @throws IOException - * If the mosaic head parsing fails, an IO exception is thrown - */ + } finally { + if (mosaicFile != null) { + mosaicFile.close(); + } + } + init(tempRawMosaicByteArray); + } + + /** + * This level3Parser constructor accepts a mosaic file already converted to a + * byte array. + * + * @param aMosaic + * A byte array containing a raw mosaic file + * @throws IOException + * If the mosaic head parsing fails, an IO exception is thrown + */ public Level3Parser(byte[] aMosaic) throws IOException { - init(aMosaic); - } - - /** - * @param aMosaic - * @throws IOException - */ - private void init(byte[] aMosaic) throws IOException { - // skip the WMO header if any + init(aMosaic); + } + + /** + * @param aMosaic + * @throws IOException + */ + private void init(byte[] aMosaic) throws IOException { + // skip the WMO header if any String headerSearch = new String(aMosaic, 0, 80); - // decide where the mosaic starts + // decide where the mosaic starts int wmoHeaderSize = findStartMosaicData(headerSearch); - //check if mosaic file compressed or not compressed + //check if mosaic file compressed or not compressed if (isCompressed(aMosaic, wmoHeaderSize)) { - theRawMosaicByteArray = decompressMosaic(aMosaic, wmoHeaderSize); + theRawMosaicByteArray = decompressMosaic(aMosaic, wmoHeaderSize); } else { - theRawMosaicByteArray = new byte[aMosaic.length - wmoHeaderSize]; - System.arraycopy(aMosaic, wmoHeaderSize, theRawMosaicByteArray, 0, - theRawMosaicByteArray.length); - } + theRawMosaicByteArray = new byte[aMosaic.length - wmoHeaderSize]; + System.arraycopy(aMosaic, wmoHeaderSize, theRawMosaicByteArray, 0, + theRawMosaicByteArray.length); + } - //allocate the same length of buf + //allocate the same length of buf theRawMosaicData = new ByteArrayInputStream(theRawMosaicByteArray); //create DataInputStream so that it may be accessible - //to read by the object "theMosaicData" in parseMosaicHeader - theMosaicData = new DataInputStream(theRawMosaicData); - - // parse the header to get constants in message header block - this.parseMosaicHeader(); - if (this.theMessageCode != 2) { - this.parseMosaicMessage(); + //to read by the object "theMosaicData" in parseMosaicHeader + theMosaicData = new DataInputStream(theRawMosaicData); + + // parse the header to get constants in message header block + this.parseMosaicHeader(); + if (this.theMessageCode != 2) { + this.parseMosaicMessage(); } - } - + } + public int getNumberOfMaps() { return numberOfMaps; } @@ -181,433 +181,433 @@ public class Level3Parser { this.numberOfMaps = numberOfMaps; } - /** - * Returns the NEXRAD message code from the level 3 header - * - * @return An integer that can range from -131 to -16 and 0 to 211 - */ - public int getMessageCode() { - return theMessageCode; - } - - /** - * Returns a Date object which represents the time of the message. This is - * for the time of the message only and does not reflect the time of the - * scan or the time the product was generated. - * - * @return A Date object for the time the NEXRAD message was generated - */ - public Calendar getMessageTimestamp() { - return theMsgTimestamp; - } - - /** - * Returns the total length of the message. This is the number of bytes for - * the entire message including this header information being parsed right - * now. - * - * @return A long which will be from 18 to 409586 - */ - public long getMessageLength() { - return theMsgLength; - } - - /** - * Returns an integer reflecting the the sender of the message. - * - * @return A number from 0 to 999 - */ - public int getSourceId() { - return theSourceId; - } - - /** - * Returns an integer reflecting the the destination of the message. - * - * @return A number from 0 to 999 - */ - public int getDestinationId() { - return theDestinationId; - } - - /** - * Returns the latitude of the mosaic site. Positive indicates north, - * negative will indicate south. - * - * @return A latitude in decimal degree between -90.0 to 90.0 - */ - public double getLatitude() { - return theLatitude; - } - - /** - * Returns the longitude of the mosaic site. Positive indicates east, - * negative will indicate west. - * - * @return A longitude in decimal degrees between -180.0 to 180.0 - */ - public double getLongitude() { - return theLongitude; - } - - /** - * Returns the height of the mosaic. This will be in the units feet. - * - * @return An integer from -100 to 11,000 - */ - public int getHeight() { - return theHeight; - } - - /** - * Returns the internal NEXRAD product code of the weather product being - * transmitted. - * - * @return A product code from -131 to -16 and 16 to 131 - */ - public int getProductCode() { - return theProductCode; - } - - /** - * Returns the operational mode the mosaic is currently running in. - * - * @return A operational mode number from 0 to 2 - */ - public int getOperationalMode() { - return theOperationalMode; - } - - /** - * Returns the RDA volum coverage pattern. This indicates the scan strategy - * being used. Not entirely sure what this means in an operational setting. - * - * @return A number 1 to 767 for the volume coverage pattern - */ - public int getVolumeCoveragePattern() { - return theVolumeCoveragePattern; - } - - /** - * Returns the sequence number of the request that generated the NEXRAD - * product. In case the product was requested by an alert condition, it will - * return a -13. - * - * @return A sequence number either -13 or 0 to 32767 - */ - public int getSequenceNumber() { - return theSequenceNumber; - } - - /** - * Returns the mosaic site's internal counter entry. This will start at 1 and - * go to 80. - * - * @return A counter number 1 to 80 - */ - public int getVolumeScanNumber() { - return theVolumeScanNumber; - } - - /** - * Returns a Date object which represents the time the scan was done. This - * is for the time of the volume scan only and does not reflect the time of - * the message or the time the product was generated. - * - * @return A Date object for the time of the volume scan - */ - public Calendar getVolumeScanTime() { - return theVolScanTime; - } - - /** - * Returns a Date object which represents the time the product was - * generated. This is for the time of product generation only and does not - * reflect the time of the message or the time the scan was done. - * - * @return A Date object for the time the product was generated - */ - public Calendar getProductGenerationTime() { - return theProdGenTime; - } - - /** - * Returns the entire raw mosaic message. - * - * @return The mosaic message - */ - public byte[] getRawMosaicData() { - return theRawMosaicByteArray; - } - - public static short getProductDependentValue(int value) { - return productDependentValues[value]; - } - - public short[] getProductDependentValue() { - return productDependentValues; - } - - public short getDataLevelThreshold(int code) { - return dataLevelThresholds[code]; - } - + /** + * Returns the NEXRAD message code from the level 3 header + * + * @return An integer that can range from -131 to -16 and 0 to 211 + */ + public int getMessageCode() { + return theMessageCode; + } + + /** + * Returns a Date object which represents the time of the message. This is + * for the time of the message only and does not reflect the time of the + * scan or the time the product was generated. + * + * @return A Date object for the time the NEXRAD message was generated + */ + public Calendar getMessageTimestamp() { + return theMsgTimestamp; + } + + /** + * Returns the total length of the message. This is the number of bytes for + * the entire message including this header information being parsed right + * now. + * + * @return A long which will be from 18 to 409586 + */ + public long getMessageLength() { + return theMsgLength; + } + + /** + * Returns an integer reflecting the the sender of the message. + * + * @return A number from 0 to 999 + */ + public int getSourceId() { + return theSourceId; + } + + /** + * Returns an integer reflecting the the destination of the message. + * + * @return A number from 0 to 999 + */ + public int getDestinationId() { + return theDestinationId; + } + + /** + * Returns the latitude of the mosaic site. Positive indicates north, + * negative will indicate south. + * + * @return A latitude in decimal degree between -90.0 to 90.0 + */ + public double getLatitude() { + return theLatitude; + } + + /** + * Returns the longitude of the mosaic site. Positive indicates east, + * negative will indicate west. + * + * @return A longitude in decimal degrees between -180.0 to 180.0 + */ + public double getLongitude() { + return theLongitude; + } + + /** + * Returns the height of the mosaic. This will be in the units feet. + * + * @return An integer from -100 to 11,000 + */ + public int getHeight() { + return theHeight; + } + + /** + * Returns the internal NEXRAD product code of the weather product being + * transmitted. + * + * @return A product code from -131 to -16 and 16 to 131 + */ + public int getProductCode() { + return theProductCode; + } + + /** + * Returns the operational mode the mosaic is currently running in. + * + * @return A operational mode number from 0 to 2 + */ + public int getOperationalMode() { + return theOperationalMode; + } + + /** + * Returns the RDA volum coverage pattern. This indicates the scan strategy + * being used. Not entirely sure what this means in an operational setting. + * + * @return A number 1 to 767 for the volume coverage pattern + */ + public int getVolumeCoveragePattern() { + return theVolumeCoveragePattern; + } + + /** + * Returns the sequence number of the request that generated the NEXRAD + * product. In case the product was requested by an alert condition, it will + * return a -13. + * + * @return A sequence number either -13 or 0 to 32767 + */ + public int getSequenceNumber() { + return theSequenceNumber; + } + + /** + * Returns the mosaic site's internal counter entry. This will start at 1 and + * go to 80. + * + * @return A counter number 1 to 80 + */ + public int getVolumeScanNumber() { + return theVolumeScanNumber; + } + + /** + * Returns a Date object which represents the time the scan was done. This + * is for the time of the volume scan only and does not reflect the time of + * the message or the time the product was generated. + * + * @return A Date object for the time of the volume scan + */ + public Calendar getVolumeScanTime() { + return theVolScanTime; + } + + /** + * Returns a Date object which represents the time the product was + * generated. This is for the time of product generation only and does not + * reflect the time of the message or the time the scan was done. + * + * @return A Date object for the time the product was generated + */ + public Calendar getProductGenerationTime() { + return theProdGenTime; + } + + /** + * Returns the entire raw mosaic message. + * + * @return The mosaic message + */ + public byte[] getRawMosaicData() { + return theRawMosaicByteArray; + } + + public static short getProductDependentValue(int value) { + return productDependentValues[value]; + } + + public short[] getProductDependentValue() { + return productDependentValues; + } + + public short getDataLevelThreshold(int code) { + return dataLevelThresholds[code]; + } + private SymbologyBlock readSymbologyBlock(int offset) throws IOException { - - SymbologyBlock symBlock = null; - if (offset != 0) { + + SymbologyBlock symBlock = null; + if (offset != 0) { theMosaicData.reset(); - theMosaicData.skip(offset); + theMosaicData.skip(offset); int divider = theMosaicData.readShort(); int blockId = theMosaicData.readUnsignedShort(); - if ((divider != -1) || (blockId != SymbologyBlock.getBlockId())) { - throw new IOException( - "This does not appear to be a symbology block"); - } + if ((divider != -1) || (blockId != SymbologyBlock.getBlockId())) { + throw new IOException( + "This does not appear to be a symbology block"); + } int blockLen = theMosaicData.readInt(); - byte[] buf = MosaicUtil.subArray(theRawMosaicByteArray, offset, - blockLen); - DataInputStream in = new DataInputStream(new ByteArrayInputStream( - buf)); - - // Skipping the number of layers, layer divider, - // and data layer length + byte[] buf = MosaicUtil.subArray(theRawMosaicByteArray, offset, + blockLen); + DataInputStream in = new DataInputStream(new ByteArrayInputStream( + buf)); + + // Skipping the number of layers, layer divider, + // and data layer length in.skip(8); - symBlock = new SymbologyBlock(in); - } - return symBlock; - } - - /** - * Goes through the mosaic header and reads in all the important fields. - * - * @throws IOException - */ + symBlock = new SymbologyBlock(in); + } + return symBlock; + } + + /** + * Goes through the mosaic header and reads in all the important fields. + * + * @throws IOException + */ private void parseMosaicHeader() throws IOException { - - // Message Header Block + + // Message Header Block theMessageCode = theMosaicData.readUnsignedShort(); - - theMsgTimestamp = Calendar.getInstance(); - theMsgTimestamp.setTimeInMillis(this.createTimestamp(theMosaicData + + theMsgTimestamp = Calendar.getInstance(); + theMsgTimestamp.setTimeInMillis(this.createTimestamp(theMosaicData .readUnsignedShort(), theMosaicData.readInt())); - + theMsgLength = theMosaicData.readInt(); - - // TODO: validate message length here and not everywhere else - + + // TODO: validate message length here and not everywhere else + theSourceId = theMosaicData.readShort(); - + theDestinationId = theMosaicData.readShort(); - + numberOfBlocks = theMosaicData.readShort(); - } - + } + private void parseMosaicMessage() throws IOException { - + // Product Description Block - // skip two bytes for the "BLock Divider" - always equals to -1 + // skip two bytes for the "BLock Divider" - always equals to -1 theMosaicData.skip(2); - - theLatitude = theMosaicData.readInt() * 0.001; + + theLatitude = theMosaicData.readInt() * 0.001; theLongitude = theMosaicData.readInt() * 0.001; - - theHeight = theMosaicData.readShort(); + + theHeight = theMosaicData.readShort(); theProductCode = theMosaicData.readShort(); - - theOperationalMode = theMosaicData.readUnsignedShort(); - theVolumeCoveragePattern = theMosaicData.readUnsignedShort(); - theSequenceNumber = theMosaicData.readShort(); - theVolumeScanNumber = theMosaicData.readUnsignedShort(); - theVolScanTime = Calendar.getInstance(); - theVolScanTime.setTimeInMillis(this.createTimestamp(theMosaicData - .readUnsignedShort(), theMosaicData.readInt())); - theProdGenTime = Calendar.getInstance(); - theProdGenTime.setTimeInMillis(this.createTimestamp(theMosaicData - .readUnsignedShort(), theMosaicData.readInt())); - - productDependentValues = new short[10]; - productDependentValues[0] = theMosaicData.readShort(); + + theOperationalMode = theMosaicData.readUnsignedShort(); + theVolumeCoveragePattern = theMosaicData.readUnsignedShort(); + theSequenceNumber = theMosaicData.readShort(); + theVolumeScanNumber = theMosaicData.readUnsignedShort(); + theVolScanTime = Calendar.getInstance(); + theVolScanTime.setTimeInMillis(this.createTimestamp(theMosaicData + .readUnsignedShort(), theMosaicData.readInt())); + theProdGenTime = Calendar.getInstance(); + theProdGenTime.setTimeInMillis(this.createTimestamp(theMosaicData + .readUnsignedShort(), theMosaicData.readInt())); + + productDependentValues = new short[10]; + productDependentValues[0] = theMosaicData.readShort(); productDependentValues[1] = theMosaicData.readShort(); - - elevationNumber = theMosaicData.readUnsignedShort(); + + elevationNumber = theMosaicData.readUnsignedShort(); productDependentValues[2] = theMosaicData.readShort(); - - dataLevelThresholds = new short[16]; - for (int i = 0; i < dataLevelThresholds.length; i++) { + + dataLevelThresholds = new short[16]; + for (int i = 0; i < dataLevelThresholds.length; i++) { dataLevelThresholds[i] = theMosaicData.readShort(); - } + } maximumDataLevel = theMosaicData.readShort(); - + //for (int i = 3; i < productDependentValues.length; i++) { //In Mosaic, there are only 8 product dependent values - for (int i = 3; i < productDependentValues.length -2; i++) { + for (int i = 3; i < productDependentValues.length -2; i++) { productDependentValues[i] = theMosaicData.readShort(); } - //Use for raster display! + //Use for raster display! numberOfColumns = theMosaicData.readShort(); //Use for raster display! numberOfMaps = theMosaicData.readShort(); - int symbologyBlockOffset = theMosaicData.readInt() * 2; - symbologyBlock = readSymbologyBlock(symbologyBlockOffset); - } - - /** - * Takes the various time and date fields from the mosaic data and creates - * and Date object. - * - * @param aDayCount - * @param aSecondCount - * @return - */ - private long createTimestamp(long aDayCount, long aSecondCount) { - aDayCount--; - long timeStamp = ((aDayCount * 60 * 60 * 24) + aSecondCount) * 1000; - return timeStamp; - } - - /** - * Takes a string from the beginning of the file and determines if the WMO - * header is there. - * - * @param headerInfo - * The string from the beginning of the file that might contain a - * wmo header - * @return The count from the beginning of the file to the actual mosaic data - */ - private int findStartMosaicData(String headerInfo) { - int startOfMosaicData = 0; - Matcher matcher = WMO_PATTERN.matcher(headerInfo); - boolean foundHeader = matcher.find(); - String wmoHeader = ""; + int symbologyBlockOffset = theMosaicData.readInt() * 2; + symbologyBlock = readSymbologyBlock(symbologyBlockOffset); + } + + /** + * Takes the various time and date fields from the mosaic data and creates + * and Date object. + * + * @param aDayCount + * @param aSecondCount + * @return + */ + private long createTimestamp(long aDayCount, long aSecondCount) { + aDayCount--; + long timeStamp = ((aDayCount * 60 * 60 * 24) + aSecondCount) * 1000; + return timeStamp; + } + + /** + * Takes a string from the beginning of the file and determines if the WMO + * header is there. + * + * @param headerInfo + * The string from the beginning of the file that might contain a + * wmo header + * @return The count from the beginning of the file to the actual mosaic data + */ + private int findStartMosaicData(String headerInfo) { + int startOfMosaicData = 0; + Matcher matcher = WMO_PATTERN.matcher(headerInfo); + boolean foundHeader = matcher.find(); + String wmoHeader = ""; String awipsID = ""; - - if (foundHeader) { - wmoHeader = matcher.group(1); - awipsID = matcher.group(2); - startOfMosaicData = matcher.end(); - } - - return startOfMosaicData; - } - - /** - * Checks to see if data at the specified offset of the buffer is the start - * of a compressed block - * - * @param inBuf - * the data buffer - * @param inOff - * the offset into the buffer - * @return true if data is compressed - */ - private boolean isCompressed(byte[] inBuf, int inOff) { - int b0 = inBuf[inOff] & 0xFF; - int b1 = inBuf[inOff + 1] & 0xFF; - if ((b0 & 0xf) == Z_DEFLATED) { - if ((b0 >> 4) + 8 <= DEF_WBITS) { - if ((((b0 << 8) + b1) % 31) == 0) { - return true; - } - } - } - - return false; - } - - /** - * Method to handle compressed mosaic data. If data is not compressed it is - * just copied to the output buffer. - * - * @return The decompressed byte array for the mosaic data - */ - private byte[] decompressMosaic(byte[] inBuf, int offset) { - byte[] outBuf = new byte[4000]; - int inOff = offset; - int outOff = 0; - Inflater decompressor = new Inflater(); + + if (foundHeader) { + wmoHeader = matcher.group(1); + awipsID = matcher.group(2); + startOfMosaicData = matcher.end(); + } + + return startOfMosaicData; + } + + /** + * Checks to see if data at the specified offset of the buffer is the start + * of a compressed block + * + * @param inBuf + * the data buffer + * @param inOff + * the offset into the buffer + * @return true if data is compressed + */ + private boolean isCompressed(byte[] inBuf, int inOff) { + int b0 = inBuf[inOff] & 0xFF; + int b1 = inBuf[inOff + 1] & 0xFF; + if ((b0 & 0xf) == Z_DEFLATED) { + if ((b0 >> 4) + 8 <= DEF_WBITS) { + if ((((b0 << 8) + b1) % 31) == 0) { + return true; + } + } + } + + return false; + } + + /** + * Method to handle compressed mosaic data. If data is not compressed it is + * just copied to the output buffer. + * + * @return The decompressed byte array for the mosaic data + */ + private byte[] decompressMosaic(byte[] inBuf, int offset) { + byte[] outBuf = new byte[4000]; + int inOff = offset; + int outOff = 0; + Inflater decompressor = new Inflater(); int decompressedLen = 0; - - try { - do { - if (inBuf.length - inOff <= 0) { - logger - .error("An error occurred. Apparently, the mosaic product expects more data. Aborting decompress."); - break; - } - - // if compressed then decompress this block - if (isCompressed(inBuf, inOff)) { - decompressor.reset(); - decompressor.setInput(inBuf, inOff, inBuf.length - inOff); - decompressor - .inflate(outBuf, outOff, outBuf.length - outOff); - - inOff += decompressor.getTotalIn(); - outOff += decompressor.getTotalOut(); - - // else just copy the remainder of the data - } else { - int len = inBuf.length - inOff; - len = Math.min(len, outBuf.length - outOff); - System.arraycopy(inBuf, inOff, outBuf, outOff, len); - inOff += len; - outOff += len; - } - - if (decompressedLen == 0) { - decompressedLen = (outBuf[62] << 24 & 0xFF000000) - | (outBuf[63] << 16 & 0x00FF0000) - | (outBuf[64] << 8 & 0x0000FF00) - | (outBuf[65] & 0x000000FF); - - byte[] tmpBuf = outBuf; - outBuf = new byte[decompressedLen]; - outOff = Math.min(decompressedLen, outOff - 54); - System.arraycopy(tmpBuf, 54, outBuf, 0, outOff); - } - - } while (outOff < outBuf.length); - - } catch (DataFormatException e) { - logger - .error("Invalid data format encountered during decompression"); - } finally { - decompressor.end(); - } - - return outBuf; - } - - public int getNumberOfBlocks() { - return numberOfBlocks; - } - - public int getElevationNumber() { - return elevationNumber; - } - - public int getTheSourceId() { - return theSourceId; - } - - public void setTheSourceId(int theSourceId) { - this.theSourceId = theSourceId; - } - - public int getTheDestinationId() { - return theDestinationId; - } - - public void setTheDestinationId(int theDestinationId) { - this.theDestinationId = theDestinationId; - } - - public SymbologyBlock getSymbologyBlock() { - return symbologyBlock; + + try { + do { + if (inBuf.length - inOff <= 0) { + logger + .error("An error occurred. Apparently, the mosaic product expects more data. Aborting decompress."); + break; + } + + // if compressed then decompress this block + if (isCompressed(inBuf, inOff)) { + decompressor.reset(); + decompressor.setInput(inBuf, inOff, inBuf.length - inOff); + decompressor + .inflate(outBuf, outOff, outBuf.length - outOff); + + inOff += decompressor.getTotalIn(); + outOff += decompressor.getTotalOut(); + + // else just copy the remainder of the data + } else { + int len = inBuf.length - inOff; + len = Math.min(len, outBuf.length - outOff); + System.arraycopy(inBuf, inOff, outBuf, outOff, len); + inOff += len; + outOff += len; + } + + if (decompressedLen == 0) { + decompressedLen = (outBuf[62] << 24 & 0xFF000000) + | (outBuf[63] << 16 & 0x00FF0000) + | (outBuf[64] << 8 & 0x0000FF00) + | (outBuf[65] & 0x000000FF); + + byte[] tmpBuf = outBuf; + outBuf = new byte[decompressedLen]; + outOff = Math.min(decompressedLen, outOff - 54); + System.arraycopy(tmpBuf, 54, outBuf, 0, outOff); + } + + } while (outOff < outBuf.length); + + } catch (DataFormatException e) { + logger + .error("Invalid data format encountered during decompression"); + } finally { + decompressor.end(); + } + + return outBuf; + } + + public int getNumberOfBlocks() { + return numberOfBlocks; + } + + public int getElevationNumber() { + return elevationNumber; + } + + public int getTheSourceId() { + return theSourceId; + } + + public void setTheSourceId(int theSourceId) { + this.theSourceId = theSourceId; + } + + public int getTheDestinationId() { + return theDestinationId; + } + + public void setTheDestinationId(int theDestinationId) { + this.theDestinationId = theDestinationId; + } + + public SymbologyBlock getSymbologyBlock() { + return symbologyBlock; } public int getMaximumDataLevel() { @@ -625,6 +625,6 @@ public class Level3Parser { @SuppressWarnings("static-access") public void setNumberOfColumns(int numberOfColumns) { this.numberOfColumns = numberOfColumns; - } - -} + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyBlock.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyBlock.java index 0ef60ba2fc..55782faa69 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyBlock.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyBlock.java @@ -1,14 +1,14 @@ -package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * SymbologyBlock creates an object that will allow the iteration over 1 to 15 @@ -22,160 +22,160 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * This code has been developed by the SIB for use in the AWIPS2 system. * @author L. Lin * @version 1.0 - */ - -@DynamicSerialize -public class SymbologyBlock extends AbstractBlock implements - ISerializableObject { - - private static final int BLOCK_ID = 1; - - public static int getBlockId() { - return BLOCK_ID; - } - - @DynamicSerializeElement - private Layer[] layers; - - /** - * @param in - * @throws IOException - */ - public SymbologyBlock(DataInputStream in) throws IOException { - super(in); - } - - public SymbologyBlock() { - - } - - /** - * @return the layers - */ - public Layer[] getLayers() { - return layers; - } - - /** - * @param layers - * the layers to set - */ - public void setLayers(Layer[] layers) { - this.layers = layers; - } - - /** - * Parses the symbology block header for all the important information. - * - * @throws IOException - */ - @Override + */ + +@DynamicSerialize +public class SymbologyBlock extends AbstractBlock implements + ISerializableObject { + + private static final int BLOCK_ID = 1; + + public static int getBlockId() { + return BLOCK_ID; + } + + @DynamicSerializeElement + private Layer[] layers; + + /** + * @param in + * @throws IOException + */ + public SymbologyBlock(DataInputStream in) throws IOException { + super(in); + } + + public SymbologyBlock() { + + } + + /** + * @return the layers + */ + public Layer[] getLayers() { + return layers; + } + + /** + * @param layers + * the layers to set + */ + public void setLayers(Layer[] layers) { + this.layers = layers; + } + + /** + * Parses the symbology block header for all the important information. + * + * @throws IOException + */ + @Override protected void init(DataInputStream in) throws IOException { - //numLayers starts at 65th half-word + //numLayers starts at 65th half-word int numLayers = in.readShort(); - List layerList = new ArrayList(); - + List layerList = new ArrayList(); + in.skip(2); // skip first layer divider - NEXT_LAYER: for (int i = 0; i < 1; i++) { - Layer layer = new Layer(); - layer.setLayerId(i); + NEXT_LAYER: for (int i = 0; i < 1; i++) { + Layer layer = new Layer(); + layer.setLayerId(i); List packet = new ArrayList(); int layerSize = in.readInt(); - in.mark(layerSize); - - int packetId; + in.mark(layerSize); + + int packetId; do { - //Raster Opcode at 69th half-word - packetId is the Opcode + //Raster Opcode at 69th half-word - packetId is the Opcode packetId = in.readUnsignedShort(); - if (packetId == 0xFFFF || packetId == 0x0000) { - break; // found layer divider break out of packet loop + if (packetId == 0xFFFF || packetId == 0x0000) { + break; // found layer divider break out of packet loop } - - SymbologyPacket symPacket = PacketFactory.createPacket( - packetId, in); - + + SymbologyPacket symPacket = PacketFactory.createPacket( + packetId, in); + if (symPacket != null) { - packet.add(symPacket); - } else { - in.reset(); - in.skip(layerSize); - if (in.available() >= 2) { - in.skip(2); // skip next layer divider - } - continue NEXT_LAYER; - } + packet.add(symPacket); + } else { + in.reset(); + in.skip(layerSize); + if (in.available() >= 2) { + in.skip(2); // skip next layer divider + } + continue NEXT_LAYER; + } } while (in.available() >= 2); - - layer.setPackets(packet.toArray(new SymbologyPacket[packet - .size()])); - layerList.add(layer); - } - - this.layers = layerList.toArray(new Layer[layerList.size()]); - } - - /** - * This method will return an object representing the layer number passed - * in. This method will examine the layer and create and instance of its - * actual type (i.e. Radial) and return that layer.
- *
- * Important Presently, only radial data is supported. All others - * will return null. - * - * @return An object for that layer - * @throws IOException - */ - public SymbologyPacket getSymbologyLayerContent(int layerNumber) - throws IOException { - SymbologyPacket symLayer = null; - return symLayer; - } - - /** - * Returns the number of symbology layers contained with the block. Most - * likely, this will be 1, but in case a file contains more, they can be - * iterated through. - * - * @return An integer of the number of layers, 1 to 15 - */ - public int getNumLayers() { - if (layers != null) { - return layers.length; - } - return 0; - } - - public int getNumPackets(int l) { - if (layers != null) { - SymbologyPacket[] layer = layers[l].packets; - if (layer != null) { - return layer.length; - } - } - return 0; - } - - public SymbologyPacket[] getPackets(int layer) { - return layers[layer].packets; - } - - public SymbologyPacket getPacket(int layer, int packet) { - return layers[layer].packets[packet]; - } - - @Override - public String toString() { - String s = ""; - if (layers != null) { - for (int l = 0; l < layers.length; l++) { - s += "\nLayer " + (l + 1); - for (SymbologyPacket packet : layers[l].packets) { - s += "\n" + packet; - } - } - } - return s; - } - -} + + layer.setPackets(packet.toArray(new SymbologyPacket[packet + .size()])); + layerList.add(layer); + } + + this.layers = layerList.toArray(new Layer[layerList.size()]); + } + + /** + * This method will return an object representing the layer number passed + * in. This method will examine the layer and create and instance of its + * actual type (i.e. Radial) and return that layer.
+ *
+ * Important Presently, only radial data is supported. All others + * will return null. + * + * @return An object for that layer + * @throws IOException + */ + public SymbologyPacket getSymbologyLayerContent(int layerNumber) + throws IOException { + SymbologyPacket symLayer = null; + return symLayer; + } + + /** + * Returns the number of symbology layers contained with the block. Most + * likely, this will be 1, but in case a file contains more, they can be + * iterated through. + * + * @return An integer of the number of layers, 1 to 15 + */ + public int getNumLayers() { + if (layers != null) { + return layers.length; + } + return 0; + } + + public int getNumPackets(int l) { + if (layers != null) { + SymbologyPacket[] layer = layers[l].packets; + if (layer != null) { + return layer.length; + } + } + return 0; + } + + public SymbologyPacket[] getPackets(int layer) { + return layers[layer].packets; + } + + public SymbologyPacket getPacket(int layer, int packet) { + return layers[layer].packets[packet]; + } + + @Override + public String toString() { + String s = ""; + if (layers != null) { + for (int l = 0; l < layers.length; l++) { + s += "\nLayer " + (l + 1); + for (SymbologyPacket packet : layers[l].packets) { + s += "\n" + packet; + } + } + } + return s; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyPacket.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyPacket.java index e9b9a65959..0e141a523e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyPacket.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/level3/SymbologyPacket.java @@ -1,10 +1,10 @@ -package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; - -import java.io.DataInputStream; -import java.io.IOException; - -import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +package gov.noaa.nws.ncep.edex.plugin.mosaic.util.level3; + +import java.io.DataInputStream; +import java.io.IOException; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** * Abstract class that defines the binary values for the various symbology @@ -18,43 +18,43 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * This code has been developed by the SIB for use in the AWIPS2 system. * @author L. Lin * @version 1.0 - */ - -public abstract class SymbologyPacket { - - @DynamicSerializeElement - protected int packetId; - - public SymbologyPacket(int packetId, DataInputStream in) throws IOException { - this.packetId = packetId; - init(in); - } - - protected SymbologyPacket() { - - } - - protected abstract void init(DataInputStream in) throws IOException; - - /** - * @return the packetId - */ - public int getPacketId() { - return packetId; - } - - /** - * @param packetId - * the packetId to set - */ - public void setPacketId(int packetId) { - this.packetId = packetId; - } - - @Override - public String toString() { - String s = String.format("\tPacket ID: 0x%04X", packetId); - return s; - } - -} + */ + +public abstract class SymbologyPacket { + + @DynamicSerializeElement + protected int packetId; + + public SymbologyPacket(int packetId, DataInputStream in) throws IOException { + this.packetId = packetId; + init(in); + } + + protected SymbologyPacket() { + + } + + protected abstract void init(DataInputStream in) throws IOException; + + /** + * @return the packetId + */ + public int getPacketId() { + return packetId; + } + + /** + * @param packetId + * the packetId to set + */ + public void setPacketId(int packetId) { + this.packetId = packetId; + } + + @Override + public String toString() { + String s = String.format("\tPacket ID: 0x%04X", packetId); + return s; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/package-info.java index f45b2ee224..fa41f0fba5 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/src/gov/noaa/nws/ncep/edex/plugin/mosaic/util/package-info.java @@ -1,4 +1,4 @@ -/** - * Contains utility classes for the mosaic plugin. - */ -package gov.noaa.nws.ncep.edex.plugin.mosaic.util; +/** + * Contains utility classes for the mosaic plugin. + */ +package gov.noaa.nws.ncep.edex.plugin.mosaic.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncccfp/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncccfp/component-deploy.xml index fe17cba4e4..e9187d5653 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncccfp/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncccfp/component-deploy.xml @@ -1,10 +1,10 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/NcgribDecoder.py b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/NcgribDecoder.py index 735441ba8f..0249543fb6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/NcgribDecoder.py +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/NcgribDecoder.py @@ -131,6 +131,12 @@ THINNED_GRID_VALUES = THINNED_GRID_PT_MAP.values() # 06/28/11 xguo Added codes to get correct VAR/VCD # 07/12/11 xguo Changed Grib1Decoder() to Ncgrib1Decoder() # 07/26/11 xguo Added codes to handle Derived Ensemble Data +# 09/08/11 xguo Added one column grib data +# 09/21/11 xguo Check derived ensemble data +# 10/04/11 xguo Remove '_' from model name +# 11/02/11 xguo Added codes to decode firewx +# 11/08/11 xguo Adjusted glevel1/glevel2 for PRES/PDLY/POTV +# 11/22/11 xguo Updated Level infor in model # class NcgribDecoder(): @@ -147,8 +153,10 @@ class NcgribDecoder(): self.inputFile = None self.abbr = None self.derived = None - self.VCD = -1 - + self.VCD = -1 + self.count = 1 + self.AddColumn = -1 + ## # Decodes the ncgrib file # @@ -208,7 +216,7 @@ class NcgribDecoder(): if record != None: self._addRecord(records, record) - if self.abbr == "uW" or self.abbr == "uWmean" or self.abbr == "uWsprd": + if self.abbr == "uW" or self.abbr == "uWmean" or self.abbr == "uWsprd" or self.abbr == "uWprob": #Extract a second field if it exists metadataResults = grib2.getMetadata(gribFile, recordIndex, fieldIndex + 1, 0) numFields = metadataResults['numFields'] @@ -339,6 +347,9 @@ class NcgribDecoder(): nx = gdsSectionValues['coverage'].getNx().intValue() ny = gdsSectionValues['coverage'].getNy().intValue() + + if self.AddColumn == 1: + nx = nx - 1 # Correct the data according to the scan mode found in the gds section. scanMode = gdsSectionValues['scanMode'] @@ -383,8 +394,8 @@ class NcgribDecoder(): self._createModelName(pdsSectionValues['model'], self.inputFile) modelName = pdsSectionValues['model'].getModelName() - if modelName == "GHMNEST" : - pdsSectionValues['model'].generateId(self.inputFile) + if modelName == "GHMNEST" or modelName == "GHM6TH" or modelName == "HWRFNEST" or modelName == "GFS" or modelName == "NAMFIREWX": + pdsSectionValues['model'].generateId(self.inputFile) else: pdsSectionValues['model'].generateId() @@ -463,7 +474,10 @@ class NcgribDecoder(): record.setModelName(model.getModelName()) record.setFileName(self.inputFile) tokens = self.inputFile.split(".") - record.setEventName(tokens[0]) + if len(tokens) >= 3 and tokens[2] == "firewxnest": + record.setEventName(tokens[2]); + else : + record.setEventName(tokens[0]) record.setModelInfo(model) record.setResCompFlags(Integer(gdsSectionValues['resCompFlags'])) @@ -483,13 +497,32 @@ class NcgribDecoder(): discipline = record.getDiscipline() # pdt = record.getPdt() g2scale = Grib2VarsTableLookup.getG2varsScale(discipline, category, parameterId, pdsTemplateNumber) + if g2scale != 0: scale = pow(10,g2scale ) missscale = -999999 * scale for i in range(0,len(numpyDataArray)): numpyDataArray[i] = numpyDataArray[i] * scale numpyDataArray = numpy.where(numpyDataArray == missscale, -999999, numpyDataArray) - record.setMessageData(numpyDataArray) + + if self.AddColumn == 1: + self.AddColumn = -1 + numpyDataArray1 = None + nx1 = nx + 1 + metadata[4] = nx1 * ny + numpyDataArray1 = numpy.zeros((ny, nx1), numpy.float32) + numpyDataArray = numpy.resize(numpyDataArray, (ny, nx)) + + for i in range(ny): + for j in range(nx): + numpyDataArray1[i,j] = numpyDataArray[i,j] + numpyDataArray1[i,nx] = numpyDataArray[i,0] + + numpyDataArray1 = numpy.resize(numpyDataArray1, (1, metadata[4])) + + record.setMessageData(numpyDataArray1) + else: + record.setMessageData(numpyDataArray) if pdsTemplateNumber == 8 : if lenPds > 27 : @@ -499,10 +532,10 @@ class NcgribDecoder(): record.setProcessType(int(pdsSectionValues['processedDataType'])) record.setVcrdId1(int(pdsSectionValues['verticalCoordinate1'])) record.setVcrdId2(int(pdsSectionValues['verticalCoordinate2'])) - record.setGlevel1(int(pdsSectionValues['level1'])) + record.setDecodedLevel1( pdsSectionValues['level1'] ) record.setGridVersion(2) if pdsSectionValues['level2'] is not None: - record.setGlevel2(int(pdsSectionValues['level2'])) + record.setDecodedLevel2( pdsSectionValues['level2'] ) # Special case handling for ffg grids if(model.getCenterid() == 9): @@ -688,7 +721,10 @@ class NcgribDecoder(): elif (derivedForecast >= 2 and derivedForecast <= 5 ): parameterAbbreviation= parameterAbbreviation+"sprd" self.derived = 'sprd' - + elif (derivedForecast >= 193 and derivedForecast <= 195 ): + parameterAbbreviation= parameterAbbreviation+"prob" + self.derived = 'prob' + model.setTypeEnsemble(Integer(pdsTemplate[15])) model.setNumForecasts(Integer(pdsTemplate[16])) @@ -751,7 +787,10 @@ class NcgribDecoder(): model.setParameterUnit(parameterUnit) tokens = self.inputFile.split(".") - model.setEventName(tokens[0]) + if len(tokens) >= 3 and tokens[2] == "firewxnest": + model.setEventName(tokens[2]) + else: + model.setEventName(tokens[0]) # Constructing the Level object level = LevelFactory.getInstance().getLevel(levelName, levelOneValue, levelTwoValue, levelUnit) @@ -825,8 +864,8 @@ class NcgribDecoder(): pdsFields['endTime'] = endTime pdsFields['model'] = model - pdsFields['level1'] = pdsTemplate[11] - pdsFields['level2'] = pdsTemplate[14] + pdsFields['level1'] = levelOneValue #pdsTemplate[11] + pdsFields['level2'] = levelTwoValue #pdsTemplate[14] pdsFields['category'] = pdsTemplate[0] pdsFields['parameterId'] = pdsTemplate[1] pdsFields['processedDataType'] = pdsTemplate[2] @@ -883,7 +922,13 @@ class NcgribDecoder(): ny = gdsTemplate[8] dx = self._divideBy10e6(gdsTemplate[16]) dy = self._divideBy10e6(gdsTemplate[17]) - + Lon1 = lo1 + lo2 + Lon2 = lo2 + dx + if Lon1 == 360.0 or Lon2 == 360.0: + nx = nx + 1 + lo2 = lo2 + dx + self.AddColumn = 1 + coverage.setSpacingUnit(DEFAULT_SPACING_UNIT2) coverage.setNx(Integer(nx)) coverage.setNy(Integer(ny)) @@ -925,7 +970,14 @@ class NcgribDecoder(): dy = self._divideBy10e6(gdsTemplate[18]) scanMode = gdsTemplate[15] resCompFlags = gdsTemplate[11] - + + Lon1 = lo1 + lo2 + Lon2 = lo2 + dx + if Lon1 == 360.0 or Lon2 == 360.0: + nx = nx + 1 + lo2 = lo2 + dx + self.AddColumn = 1 + coverage.setSpacingUnit(DEFAULT_SPACING_UNIT) coverage.setMajorAxis(majorAxis) coverage.setMinorAxis(minorAxis) @@ -1100,6 +1152,13 @@ class NcgribDecoder(): dx = self._divideBy10e6(gdsTemplate[16]) dy = self._divideBy10e6(gdsTemplate[17]) + Lon1 = lo1 + lo2 + Lon2 = lo2 + dx + if Lon1 == 360.0 or Lon2 == 360.0: + nx = nx + 1 + lo2 = lo2 + dx + self.AddColumn = 1 + coverage.setSpacingUnit(DEFAULT_SPACING_UNIT2) coverage.setNx(Integer(nx)) coverage.setNy(Integer(ny)) @@ -1194,7 +1253,7 @@ class NcgribDecoder(): def _correctLat(self, lat): if lat < 0: - lat = lat % 180 + lat = lat % -180 else: lat = lat % 180 @@ -1354,27 +1413,40 @@ class NcgribDecoder(): gridid = model.getGridid() process = model.getGenprocess() gridModel = NcgribModelLookup.getInstance().getModel(center, subcenter, gridid, process) - + if gridModel is None: - name = "UnknownModel:" + str(center) + ":" + str(subcenter) + ":" + str(process) + ":" + gridid + name = "NewGrid:" + str(center) + ":" + str(subcenter) + ":" + str(process) + ":" + gridid tokens = fileName.split(".") hurricane = tokens[0] basin = hurricane[-1] trackno = hurricane[-3:-1] - if trackno.isdigit() : - basins = "lewcs" - if basin in basins: + if trackno.isdigit() or tokens[2] =="firewxnest": + if trackno.isdigit(): + basins = "lewcs" + if basin in basins: #name = "GHM:" + str(center) + ":" + str(subcenter) + ":" + str(process) + ":" + gridid #hurricaneName = hurricane[:len(hurricane)-3] - if tokens[2] == "gribn3": - name = "GHMNEST" - else: - name = "GHM" - NcgribModelLookup.getInstance().setModel(center, subcenter, str(gridid), process, name) - gridModel = NcgribModelLookup.getInstance().getModel(center, subcenter, gridid, process) + name = "GHM" + if tokens[2] == "gribn3": + name = "GHMNEST" + elif tokens[2] == "grib6th": + name = "GHM6TH" + elif tokens[2] == "hwrfprs_n": + name = "HWRFNEST" + elif tokens[2] == "hwrfprs_p": + name = "HWRF" + else: + name = "NAMFIREWX" + NcgribModelLookup.getInstance().setModel(center, subcenter, gridid, process, name) + gridModel = NcgribModelLookup.getInstance().getModel(center, subcenter, gridid, process) #name = gridModel.getName() else: name = gridModel.getName() + if name == "GEFS" : + tokens = fileName.split(".") + gefc = tokens[0] + if gefc[:3] == "gec": + name = "GEFC" model.setModelName(name) @@ -1418,36 +1490,63 @@ class NcgribDecoder(): # get and set vcord and scale vcord = Grib2VcrdTableLookup.getGnamByVcrdId(vcrd1, vcrd2) record.setVcord(vcord) - scale = Grib2VcrdTableLookup.getScaleByVcrdId(vcrd1, vcrd2) - record.setScale(scale) + scale = float( Grib2VcrdTableLookup.getScaleByVcrdId(vcrd1, vcrd2) ) + scale = pow ( 10, scale) + #record.setScale(scale) + glevel1 = record.getDecodedLevel1() + if (glevel1 != 0 and scale != 1 ) : + record.setGlevel1(int(round(glevel1 * scale))) + else : + record.setGlevel1(int(round(glevel1))) + + if vcrd2 == 255 : + record.setGlevel2(-9999) + else : + glevel2 = record.getDecodedLevel2() + if (glevel2 != 0 and scale != 1 ) : + record.setGlevel2(int(round(glevel2 * scale))) + else : + record.setGlevel2( int(round(glevel2) )) + levelName = record.getModelInfo().getLevelName() + levelOneValue = 1.0*record.getGlevel1() + levelTwoValue = 1.0*record.getGlevel2() + levelUnit = record.getModelInfo().getLevelUnit() + level = LevelFactory.getInstance().getLevel(levelName, levelOneValue, levelTwoValue, levelUnit) + record.getModelInfo().setLevel(level) else : + record.setGlevel1( int(record.getDecodedLevel1) ) + record.setGlevel2( int(record.getDecodedLevel2) ) LogStream.logEvent("No vertical coordinate ID for first fixed surfaced level" + str(vcrd1) + "], and second fixed surfaced [" + str(vcrd2) + "]"); - # Change glevl1 and glevel2 - glevel1 = record.getGlevel1() - if vcrd2 == 255 : - record.setGlevel2(-9999) - if vcord == 'PRES' : - record.setGlevel1(int(glevel1 /100)) - elif vcord == 'POTV' : - record.setGlevel1(int(glevel1 /1000)) - + if str(g2vcrdId).isdigit() : g2varsId = Grib2VarsTableLookup.getG2varsId(discipline, category, parameterId, pdt) # print ("5=", discipline, category, parameterId, pdt,g2varsId, parm) if g2varsId > 0 : parm = Grib2VarsTableLookup.getVarGnam(discipline, category, parameterId, pdt) + modelName = record.getModelName() if self.derived == 'mean': parm = parm + "ENMW" + if modelName.find('MEAN') == -1: + modelName = modelName +"MEAN" elif self.derived == 'sprd': parm = parm + "ENSA" + if modelName.find('SPREAD') == -1 : + modelName = modelName +"SPREAD" + elif self.derived == 'prob': + parm = parm + "PROB" + if modelName.find ('PROB') == -1: + modelName = modelName +"PROB" + record.setModelName(modelName) + record.getModelInfo().setModelName(modelName) + if pdt == 8 : record.setParm(parm.replace("--", charHour)) else : record.setParm(parm) - + record.setProcessType(self.count) if g2varsId > 0 : # the parameter ID is in the table so append the record records.append(record) @@ -1455,4 +1554,5 @@ class NcgribDecoder(): if discipline != 255: LogStream.logEvent("No variable ID for discipline:", discipline, "category =",category, "parameterId =", parameterId, "pdt=", pdt); self.derived = None - + self.count = self.count + 1 + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/component-deploy.xml index 9b2a74680d..716459972f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-ingest.xml index 1c552aeb4e..a5868c86b1 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-ingest.xml @@ -19,8 +19,6 @@
- - diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/Ncgrib1Decoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/Ncgrib1Decoder.java index 2cf90c3708..4db902642f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/Ncgrib1Decoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/Ncgrib1Decoder.java @@ -27,6 +27,7 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; +import java.util.List; import java.util.Set; import ucar.grib.GribNumbers; @@ -71,6 +72,13 @@ import com.raytheon.edex.plugin.AbstractDecoder; import com.raytheon.uf.common.dataplugin.level.Level; import com.raytheon.uf.common.dataplugin.level.LevelFactory; import com.raytheon.uf.common.dataquery.db.QueryResult; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.edex.database.DataAccessLayerException; @@ -86,6 +94,8 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 3/11/10 4758 bphillip Initial Creation + * 9/08/10 X. Guo Add new column + * 11/02/11 X. Guo Check octet size for isEnsmble() * * * @@ -93,7 +103,9 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory; * @version 1 */ public class Ncgrib1Decoder extends AbstractDecoder { - + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(Ncgrib1Decoder.class); + /** Missing value string */ private static final String MISSING = "Missing"; @@ -105,11 +117,36 @@ public class Ncgrib1Decoder extends AbstractDecoder { private String fileName=""; + private boolean addCol = false; + + private static final int[] fourtyOne = new int[] { 1, 1, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3 }; + + private static final int[] fourtyTwo = new int[] { 1, 2, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5 }; + + private static final int[] perturbation = new int[] { 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12 }; + static { AVG_ACCUM_LIST.add(3); AVG_ACCUM_LIST.add(4); AVG_ACCUM_LIST.add(6); AVG_ACCUM_LIST.add(7); + + IPathManager pm = PathManagerFactory.getPathManager(); + String ucarUserFile = pm.getFile( + pm.getContext(LocalizationType.EDEX_STATIC, + LocalizationLevel.BASE), "/ncgrib/ucar/userTables.lst") + .getPath(); + try { + GribPDSParamTable.addParameterUserLookup(ucarUserFile); + } catch (IOException e) { + statusHandler + .handle(Priority.PROBLEM, + "Error reading user parameter tables for ucar grib decoder", + e); + } } /** @@ -160,11 +197,15 @@ public class Ncgrib1Decoder extends AbstractDecoder { + gribFile + "]"); } ArrayList records = g1i.getRecords(); - NcgribRecord[] gribRecords = new NcgribRecord[records.size()]; +// NcgribRecord[] gribRecords = new NcgribRecord[records.size()]; + List gribRecords = new ArrayList(); for (int i = 0; i < records.size(); i++) { - gribRecords[i] = decodeRecord((Grib1Record) records.get(i), raf); + NcgribRecord rec = decodeRecord((Grib1Record) records.get(i), raf); + if ( rec != null ) { + gribRecords.add(rec); + } } - return gribRecords; + return gribRecords.toArray(new NcgribRecord[] {}); } finally { if (raf != null) { try { @@ -210,12 +251,13 @@ public class Ncgrib1Decoder extends AbstractDecoder { // Some centers use other center's parameter tables so we need to check // for that +// System.out.println ("==centerid:" + centerid + " subcenterid:" + subcenterid + " pdsVars.getTableVersion():" + pdsVars.getTableVersion()); int[] tableValue = Ncgrib1TableMap.getInstance().getTableAlias(centerid, subcenterid, pdsVars.getParameterTableVersion()); int centerAlias = tableValue[0]; int subcenterAlias = tableValue[1]; int tableAlias = tableValue[2]; - int vcrdid = pdsVars.getLevelType1(); + int vcrdid = pdsVars.getLevelType1(); /* * Decodes the parameter information from the record. An attempt is @@ -277,10 +319,24 @@ public class Ncgrib1Decoder extends AbstractDecoder { model.setParameterName(parameterName); model.setParameterAbbreviation(parameterAbbreviation); model.setParameterUnit(parameterUnit); - if (pdsVars.isEnsemble()) { + + // unidata does not handle isEnsemble call when + // octet size is less than 40. + if (pdsVars.getLength() > 40 && pdsVars.isEnsemble()) { model.setNumForecasts(pdsVars.getNumberForecasts()); model.setTypeEnsemble(pdsVars.getType()); - model.setPerturbationNumber(pdsVars.getPerturbationNumber()); + // rcg: added code to get perturbation + int pos41 = pdsVars.getOctet(41); + int pos42 = pdsVars.getOctet(42); + int pert = pdsVars.getID(); + for (int i = 0; i < perturbation.length; i++) { + if (pos41 == fourtyOne[i] && pos42 == fourtyTwo[i]) { + pert = perturbation[i]; + break; + } + } + model.setPerturbationNumber(pert); +// model.setPerturbationNumber(pdsVars.getPerturbationNumber()); } else { model.setNumForecasts(null); model.setTypeEnsemble(null); @@ -316,6 +372,7 @@ public class Ncgrib1Decoder extends AbstractDecoder { */ Grib1Data gd = new Grib1Data(raf); float[] data = null; + try { boolean bmsPresent = pdsVars.bmsExists(); int scanMode = gdsVars.getScanMode(); @@ -332,7 +389,12 @@ public class Ncgrib1Decoder extends AbstractDecoder { } correctForScanMode(data, gdsVars.getNx(), gdsVars.getNy(), bmsPresent, scanMode); - retVal.setMessageData(data); + if ( getAddCol()) { + float []dataArry = this.addOneColumnDataTo1D(data, gdsVars.getNx(),gdsVars.getNy() ); + retVal.setMessageData(dataArry); + } + else + retVal.setMessageData(data); } catch (IOException e) { throw new GribException("Error getting data from grib file", e); } @@ -345,16 +407,26 @@ public class Ncgrib1Decoder extends AbstractDecoder { if (subCoverage != null) { SubNcgrid subGrid = NcgribSpatialCache.getInstance().getSubGrid( modelName); + int nx = gridCoverage.getNx(); + if ( getAddCol()) { + nx = nx - 1; + } // resize the data array - float[][] dataArray = this.resizeDataTo2D(data, gridCoverage - .getNx(), gridCoverage.getNy()); + float[][] dataArray = this.resizeDataTo2D(data, nx, + gridCoverage.getNy()); dataArray = this.subGrid(dataArray, subGrid.getStartX(), subGrid .getStartY(), subGrid.getNX(), subGrid.getNY()); data = this.resizeDataTo1D(dataArray, subGrid.getNY(), subGrid .getNX()); - retVal.setMessageData(data); + if (getAddCol()) { + float [] dataArray1 = this.addOneColumnDataTo1D(data, subGrid.getNX(), subGrid.getNY()); + retVal.setMessageData(dataArray1); + } + else + retVal.setMessageData(data); model.setLocation(subCoverage); } + setAddCol(false); String newAbbr = NcgribParamTranslator.getInstance().translateParameter( 1, model, dataTime); @@ -369,8 +441,11 @@ public class Ncgrib1Decoder extends AbstractDecoder { } else { model.setParameterAbbreviation(newAbbr); } - + if (!model.getParameterName().equals(MISSING)) { + if ( modelName.toUpperCase().equals("GFS")) { + model.generateId(fileName); + } try { model = NcgribModelCache.getInstance().getModel(model); } catch (DataAccessLayerException e) { @@ -402,24 +477,54 @@ public class Ncgrib1Decoder extends AbstractDecoder { retVal.setCategory(category); retVal.setParameterId(pid); retVal.setProcessedDataType(pdsVars.getGenProcessId()); - retVal.setGlevel1((int)model.getLevel().getLevelonevalue()); - retVal.setGlevel2((int)model.getLevel().getLeveltwovalue()); + retVal.setDecodedLevel1( (float)model.getLevel().getLevelonevalue()); + retVal.setDecodedLevel2((float)model.getLevel().getLeveltwovalue()); retVal.setVcrdId1(vcrdid); retVal.setVcrdId2(vcrdid); retVal.setGridVersion(1); String vcord = "NONE"; String scale = ""; + //TODO need to change this call to read the GRIB1 version of the vcrd table + // instead of the GRIB2 version... Grib2Vcrd grib2Vcrd = Grib2VcrdTableLookup.getGrib2VcrdByGrib1VcrdId (vcrdid); if ( grib2Vcrd != null ) { vcord = grib2Vcrd.getGnam(); scale = grib2Vcrd.getScale(); + + float dscale = (float)Math.pow ( 10, Double.parseDouble(scale)); + float glevel1 = retVal.getDecodedLevel1(); + if (glevel1 != 0 && dscale != 1 ) { + retVal.setGlevel1(Math.round(glevel1 * dscale)); + } + else { + retVal.setGlevel1(Math.round(glevel1)); + } + + float glevel2 = retVal.getDecodedLevel2(); + if ( glevel2 == -999999. ) { + retVal.setGlevel2(-9999); + } + else { + if (glevel2 != 0 && dscale != 1 ) { + retVal.setGlevel2(Math.round(glevel2 * dscale)); + } + else { + retVal.setGlevel2( Math.round(glevel2) ); + } + } + } + else { + retVal.setGlevel1((int)model.getLevel().getLevelonevalue()); + retVal.setGlevel2((int)model.getLevel().getLeveltwovalue()); } retVal.setVcord(vcord); - retVal.setScale(scale); + //retVal.setScale(scale); String parm = Grib2VarsTableLookup.getVarGnam4Grib1 (discipline,category,pid); retVal.setParm(parm); + + // Special case handling for ffg grids try { if (model.getCenterid() == 9) { @@ -474,6 +579,31 @@ public class Ncgrib1Decoder extends AbstractDecoder { return newGrid; } + /** + * Resizes a 1-D data array into a 2-D array based on the provided row and + * column count and add one column for each row, then convert to 1-D array. + * + * @param data + * The 1-D array of data + * @param columnCount + * The number of columns to map the data to + * @param rowCount + * The number of rows to map the data to + * @return The 1-D array of data + */ + private float[] addOneColumnDataTo1D(float[] data, int columnCount, int rowCount) { + float[][] newGrid = new float[rowCount][columnCount+1]; + + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + newGrid[row][column] = data[row * columnCount + column]; + } + newGrid[row][columnCount] = newGrid[row][0]; + } + + return resizeDataTo1D(newGrid,rowCount,columnCount+1); + } + /** * Resizes a 2-D array of data to a 1-D array * @@ -620,15 +750,26 @@ public class Ncgrib1Decoder extends AbstractDecoder { NcgridCoverage coverage = null; int gridType = gdsVars.getGdtn(); + int nx; + float Lon1, Lon2,lo2; switch (gridType) { case 0: LatLonNcgridCoverage latLonCoverage = new LatLonNcgridCoverage(); - latLonCoverage.setNx(gdsVars.getNx()); + nx = gdsVars.getNx(); + lo2 = gdsVars.getLo2()+360.0F; + Lon1 = gdsVars.getLo1() + lo2; + Lon2 = lo2 + gdsVars.getDx(); + if ( Lon1 == 360.0 || Lon2 == 360.0 ) { + nx = nx + 1; + lo2 = Lon2; + setAddCol (true); + } + latLonCoverage.setNx(nx); latLonCoverage.setNy(gdsVars.getNy()); latLonCoverage.setLa1(gdsVars.getLa1()); latLonCoverage.setLo1(gdsVars.getLo1()); latLonCoverage.setLa2(gdsVars.getLa2()); - latLonCoverage.setLo2(gdsVars.getLo2()); + latLonCoverage.setLo2(lo2); if (gdsVars.getGridUnits().equals("degrees")) { latLonCoverage.setSpacingUnit("degree"); latLonCoverage.setDx(gdsVars.getDx()); @@ -648,12 +789,24 @@ public class Ncgrib1Decoder extends AbstractDecoder { MercatorNcgridCoverage mercator = new MercatorNcgridCoverage(); mercator.setMajorAxis(gdsVars.getMajorAxis() * 1000); mercator.setMinorAxis(gdsVars.getMinorAxis() * 1000); - mercator.setNx(gdsVars.getNx()); + nx = gdsVars.getNx(); + lo2 = gdsVars.getLo2()+360.0F; + Lon1 = gdsVars.getLo1() + lo2; + Lon2 = lo2 + gdsVars.getDx(); + if ( Lon1 == 360.0 || Lon2 == 360.0 ) { + nx = nx + 1; + lo2 = Lon2; + setAddCol (true); + } + else { + lo2 = correctLon(lo2); + } + mercator.setNx(nx); mercator.setNy(gdsVars.getNy()); mercator.setLa1(correctLat(gdsVars.getLa1())); mercator.setLo1(correctLon(gdsVars.getLo1())); mercator.setLa2(correctLat(gdsVars.getLa2())); - mercator.setLo2(correctLon(gdsVars.getLo2())); + mercator.setLo2(lo2); mercator.setLatin(correctLat(gdsVars.getLatin1())); if (gdsVars.getGridUnits().equals("degrees")) { mercator.setSpacingUnit("degree"); @@ -1145,4 +1298,11 @@ public class Ncgrib1Decoder extends AbstractDecoder { return lat; } + private void setAddCol ( boolean addCol ) { + this.addCol = addCol; + } + + private boolean getAddCol ( ) { + return this.addCol; + } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcMercatorDao.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcMercatorDao.java index 4377d6d5cc..c06d742572 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcMercatorDao.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcMercatorDao.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcPolarStereoDao.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcPolarStereoDao.java index 4c92e5c75c..a344c3a679 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcPolarStereoDao.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcPolarStereoDao.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcgribDao.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcgribDao.java index 5f6ecb6401..048078a59b 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcgribDao.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/dao/NcgribDao.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/handler/GetNcCoverageHandler.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/handler/GetNcCoverageHandler.java index 433a72e364..59d2349d4f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/handler/GetNcCoverageHandler.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/handler/GetNcCoverageHandler.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/notify/NcgribNotifyTransform.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/notify/NcgribNotifyTransform.java index b228e65bfe..25f39e1908 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/notify/NcgribNotifyTransform.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/notify/NcgribNotifyTransform.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/spatial/NcgribSpatialCache.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/spatial/NcgribSpatialCache.java index 0b417ebc06..989e19ea7d 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/spatial/NcgribSpatialCache.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/spatial/NcgribSpatialCache.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/NcgribModelCache.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/NcgribModelCache.java index 286d5e836d..329c43375b 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/NcgribModelCache.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/NcgribModelCache.java @@ -1,19 +1,19 @@ /** * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA * This software product contains export-restricted data whose * export/transfer/disclosure is restricted by U.S. law. Dissemination * to non-U.S. persons whether in the United States or abroad requires * an export license or other authorization. * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/TableTimeStamp.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/TableTimeStamp.java index 98bb3d41f6..9a25c2c05c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/TableTimeStamp.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/plugin/ncgrib/util/TableTimeStamp.java @@ -1,166 +1,166 @@ -/** - * TableTimeStamp - A Java class to update some known - * ncep grib2 vars.xml and vcrd.xml and ncgribmodel.xml. - * - * SOFTWARE HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 10/2010 276 L. Lin Initial creation - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ - -package gov.noaa.nws.ncep.edex.plugin.ncgrib.util; - -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; -import gov.noaa.nws.ncep.edex.util.grib2vars.Grib2VarsTableLookup; -import gov.noaa.nws.ncep.edex.util.grib2vcrd.Grib2VcrdTableLookup; -import gov.noaa.nws.ncep.edex.util.ncgrib.NcgribModelLookup; - -import java.io.File; - -import com.raytheon.uf.common.localization.IPathManager; -import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.PathManagerFactory; - -public class TableTimeStamp { - - private static long ncepVarsTimeStamp; - - private static long ncepVcrdTimeStamp; - - private static long ncepNcgribModelTimeStamp; - - public TableTimeStamp() { - } - - public static synchronized void updateXmlTables() throws GribException { - - long ncepVarsFileTime = 0; - long ncepVcrdFileTime = 0; - long ncepGribModelFileTime = 0; - - /* - * Gets all predefined found in the utility directory - */ - IPathManager pathMgr = PathManagerFactory.getPathManager(); - LocalizationContext commonStaticBase = pathMgr.getContext( - LocalizationContext.LocalizationType.COMMON_STATIC, - LocalizationContext.LocalizationLevel.BASE); - - /* check NCEP VARS control file */ - String ncepVarsPath = ""; - - try { - ncepVarsPath = pathMgr.getFile(commonStaticBase, - "ncgrid" + File.separator + "grib2vars.xml") - .getCanonicalPath(); - - } catch (Exception e) { - throw new GribException( - "Unable to unmarshal ncep grib2vars.xml file"); - } - - File ncepVarsTable = new File(ncepVarsPath); - try { - if (ncepVarsTable.exists()) { - ncepVarsFileTime = ncepVarsTable.lastModified(); - if (ncepVarsFileTime != getNcepVarsTimeStamp()) { - System.out - .println("NCEP grib2vars.xml has been modified or the first time, so load it ..."); - Grib2VarsTableLookup.readG2varsTable(); - setNcepVarsTimeStamp(ncepVarsFileTime); - } - } - } catch (Exception e) { - throw new GribException("Unable to read ncep grib2vars file"); - } - - /* check NCEP VCRD control file */ - String ncepVcrdPath = ""; - - try { - ncepVcrdPath = pathMgr.getFile(commonStaticBase, - "ncgrid" + File.separator + "grib2vcrd.xml") - .getCanonicalPath(); - - } catch (Exception e) { - throw new GribException( - "Unable to unmarshal ncep grib2vcrd.xml file"); - } - - File ncepVcrdTable = new File(ncepVcrdPath); - try { - if (ncepVcrdTable.exists()) { - ncepVcrdFileTime = ncepVcrdTable.lastModified(); - if (ncepVcrdFileTime != getNcepVcrdTimeStamp()) { - System.out - .println("NCEP grib2vcrd.xml has been modified or the first time, so load it ..."); - Grib2VcrdTableLookup.readG2vcrdTable(); - setNcepVcrdTimeStamp(ncepVcrdFileTime); - } - } - } catch (Exception e) { - throw new GribException("Unable to read ncep grib2vcrd file"); - } - - /* check NCEP Grib Model control file */ - String ncepGridModelPath = ""; - - try { - ncepGridModelPath = pathMgr.getFile(commonStaticBase, - "ncgrid" + File.separator + "ncgribModels.xml") - .getCanonicalPath(); - - } catch (Exception e) { - throw new GribException( - "Unable to unmarshal ncep ncgribModels.xml file"); - } - - File ncepGribModelTable = new File(ncepGridModelPath); - try { - if (ncepGribModelTable.exists()) { - ncepGribModelFileTime = ncepGribModelTable.lastModified(); - if (ncepGribModelFileTime != getNcepNcgribModelTimeStamp()) { - System.out - .println("NCEP ncgribModels.xml has been modified or the first time, so load it ..."); - NcgribModelLookup.ReloadInstance(); - setNcepNcgribModelTimeStamp(ncepGribModelFileTime); - } - } - } catch (Exception e) { - throw new GribException("Unable to read ncep grib2vcrd file"); - } - - } - - public static long getNcepVarsTimeStamp() { - return ncepVarsTimeStamp; - } - - public static void setNcepVarsTimeStamp(long ncepVarsTimeStamp) { - TableTimeStamp.ncepVarsTimeStamp = ncepVarsTimeStamp; - } - - public static long getNcepVcrdTimeStamp() { - return ncepVcrdTimeStamp; - } - - public static void setNcepVcrdTimeStamp(long ncepVcrdTimeStamp) { - TableTimeStamp.ncepVcrdTimeStamp = ncepVcrdTimeStamp; - } - - public static long getNcepNcgribModelTimeStamp() { - return ncepNcgribModelTimeStamp; - } - - public static void setNcepNcgribModelTimeStamp(long ncepNcgribModelTimeStamp) { - TableTimeStamp.ncepNcgribModelTimeStamp = ncepNcgribModelTimeStamp; - } - -} +/** + * TableTimeStamp - A Java class to update some known + * ncep grib2 vars.xml and vcrd.xml and ncgribmodel.xml. + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 10/2010 276 L. Lin Initial creation + * + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ + +package gov.noaa.nws.ncep.edex.plugin.ncgrib.util; + +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; +import gov.noaa.nws.ncep.edex.util.grib2vars.Grib2VarsTableLookup; +import gov.noaa.nws.ncep.edex.util.grib2vcrd.Grib2VcrdTableLookup; +import gov.noaa.nws.ncep.edex.util.ncgrib.NcgribModelLookup; + +import java.io.File; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.PathManagerFactory; + +public class TableTimeStamp { + + private static long ncepVarsTimeStamp; + + private static long ncepVcrdTimeStamp; + + private static long ncepNcgribModelTimeStamp; + + public TableTimeStamp() { + } + + public static synchronized void updateXmlTables() throws GribException { + + long ncepVarsFileTime = 0; + long ncepVcrdFileTime = 0; + long ncepGribModelFileTime = 0; + + /* + * Gets all predefined found in the utility directory + */ + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext commonStaticBase = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.BASE); + + /* check NCEP VARS control file */ + String ncepVarsPath = ""; + + try { + ncepVarsPath = pathMgr.getFile(commonStaticBase, + "ncgrid" + File.separator + "grib2vars.xml") + .getCanonicalPath(); + + } catch (Exception e) { + throw new GribException( + "Unable to unmarshal ncep grib2vars.xml file"); + } + + File ncepVarsTable = new File(ncepVarsPath); + try { + if (ncepVarsTable.exists()) { + ncepVarsFileTime = ncepVarsTable.lastModified(); + if (ncepVarsFileTime != getNcepVarsTimeStamp()) { + System.out + .println("NCEP grib2vars.xml has been modified or the first time, so load it ..."); + Grib2VarsTableLookup.readG2varsTable(); + setNcepVarsTimeStamp(ncepVarsFileTime); + } + } + } catch (Exception e) { + throw new GribException("Unable to read ncep grib2vars file"); + } + + /* check NCEP VCRD control file */ + String ncepVcrdPath = ""; + + try { + ncepVcrdPath = pathMgr.getFile(commonStaticBase, + "ncgrid" + File.separator + "grib2vcrd.xml") + .getCanonicalPath(); + + } catch (Exception e) { + throw new GribException( + "Unable to unmarshal ncep grib2vcrd.xml file"); + } + + File ncepVcrdTable = new File(ncepVcrdPath); + try { + if (ncepVcrdTable.exists()) { + ncepVcrdFileTime = ncepVcrdTable.lastModified(); + if (ncepVcrdFileTime != getNcepVcrdTimeStamp()) { + System.out + .println("NCEP grib2vcrd.xml has been modified or the first time, so load it ..."); + Grib2VcrdTableLookup.readG2vcrdTable(); + setNcepVcrdTimeStamp(ncepVcrdFileTime); + } + } + } catch (Exception e) { + throw new GribException("Unable to read ncep grib2vcrd file"); + } + + /* check NCEP Grib Model control file */ + String ncepGridModelPath = ""; + + try { + ncepGridModelPath = pathMgr.getFile(commonStaticBase, + "ncgrid" + File.separator + "ncgribModels.xml") + .getCanonicalPath(); + + } catch (Exception e) { + throw new GribException( + "Unable to unmarshal ncep ncgribModels.xml file"); + } + + File ncepGribModelTable = new File(ncepGridModelPath); + try { + if (ncepGribModelTable.exists()) { + ncepGribModelFileTime = ncepGribModelTable.lastModified(); + if (ncepGribModelFileTime != getNcepNcgribModelTimeStamp()) { + System.out + .println("NCEP ncgribModels.xml has been modified or the first time, so load it ..."); + NcgribModelLookup.ReloadInstance(); + setNcepNcgribModelTimeStamp(ncepGribModelFileTime); + } + } + } catch (Exception e) { + throw new GribException("Unable to read ncep grib2vcrd file"); + } + + } + + public static long getNcepVarsTimeStamp() { + return ncepVarsTimeStamp; + } + + public static void setNcepVarsTimeStamp(long ncepVarsTimeStamp) { + TableTimeStamp.ncepVarsTimeStamp = ncepVarsTimeStamp; + } + + public static long getNcepVcrdTimeStamp() { + return ncepVcrdTimeStamp; + } + + public static void setNcepVcrdTimeStamp(long ncepVcrdTimeStamp) { + TableTimeStamp.ncepVcrdTimeStamp = ncepVcrdTimeStamp; + } + + public static long getNcepNcgribModelTimeStamp() { + return ncepNcgribModelTimeStamp; + } + + public static void setNcepNcgribModelTimeStamp(long ncepNcgribModelTimeStamp) { + TableTimeStamp.ncepNcgribModelTimeStamp = ncepNcgribModelTimeStamp; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/NcgridCatalog.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/NcgridCatalog.java index c061333c10..796df18a46 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/NcgridCatalog.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/NcgridCatalog.java @@ -21,24 +21,23 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.ncgrib; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; +import java.util.HashMap; import java.util.List; -import java.util.TimeZone; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.raytheon.edex.uengine.tasks.ScriptTask; -import com.raytheon.uf.common.derivparam.tree.DataTree; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.edex.database.dao.CoreDao; import com.raytheon.uf.edex.database.dao.DaoConfig; import com.raytheon.uf.edex.database.query.DatabaseQuery; -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.NcgribModel; -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.util.NcgribModelLookup; -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.util.NcgridModel; +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.NcgribRecord; +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.ncdatatree.NcDataTree; /** * The NcgridCatalog script task is used to retrieve the necessary elements needed @@ -65,10 +64,23 @@ public class NcgridCatalog extends ScriptTask { .getLog(NcgridCatalog.class); private static final String[] GRIDFIELDS = { "modelName", - "parameterAbbreviation", "parameterName", "parameterUnit", - "level.id" }; + "eventName", "parm", "vcord", + "glevel1", "glevel2" }; + + public static final String PLUGIN_NAME_QUERY = "pluginName"; + + public static final String MODEL_NAME_QUERY = "modelName"; + + public static final String EVENT_NAME_QUERY = "eventName"; + + public static final String PARAMETER_QUERY = "parm"; + + public static final String LEVEL_ID_QUERY = "vcord"; + + public static final String LEVEL_ONE_QUERY = "glevel1"; + + public static final String LEVEL_TWO_QUERY = "glevel2"; - private Long insertTime; /* * (non-Javadoc) @@ -77,19 +89,15 @@ public class NcgridCatalog extends ScriptTask { */ @Override public Object execute() throws EdexException { - DataTree ncgridTree = null; + NcDataTree ncgridTree = null; CoreDao ncgribDao = null; List queryResults = null; - ncgribDao = new CoreDao(DaoConfig.forClass(NcgribModel.class)); + ncgribDao = new CoreDao(DaoConfig.forClass(NcgribRecord.class)); // if we do not get a table back, just return an empty list - ncgridTree = new DataTree(); - DatabaseQuery query = new DatabaseQuery(NcgribModel.class.getName()); - if (insertTime != null) { - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - time.setTimeInMillis(insertTime); - query.addQueryParam("insertTime", time, ">"); - } + ncgridTree = new NcDataTree(); + DatabaseQuery query = new DatabaseQuery(NcgribRecord.class.getName()); + List distinctFields = Arrays.asList(GRIDFIELDS); query.addOrder(distinctFields.get(0), true); @@ -101,33 +109,34 @@ public class NcgridCatalog extends ScriptTask { ArrayList gridFields = new ArrayList(Arrays .asList((Object[]) gridField)); String model = gridFields.get(0).toString(); - ncgridTree.addBranch(model, getDt(model), gridFields.get(1) + String event = gridFields.get(1).toString(); + String parm = gridFields.get(2).toString(); + String vcord = gridFields.get(3).toString(); + String level1 = gridFields.get(4).toString(); + String level2 = gridFields.get(5).toString(); + + Map rcMap = new HashMap(); + rcMap.put(PLUGIN_NAME_QUERY, new RequestConstraint("ncgrib")); + rcMap.put(MODEL_NAME_QUERY, + new RequestConstraint(model)); + rcMap.put(EVENT_NAME_QUERY, + new RequestConstraint(event)); + rcMap.put(PARAMETER_QUERY, + new RequestConstraint(parm)); + rcMap.put(LEVEL_ID_QUERY, + new RequestConstraint(vcord)); + rcMap.put(LEVEL_ONE_QUERY, + new RequestConstraint(level1)); + rcMap.put(LEVEL_TWO_QUERY, + new RequestConstraint(level2)); + ncgridTree.addBranch(model, gridFields.get(1) .toString(), gridFields.get(2).toString(), gridFields.get(3).toString(), gridFields.get(4) - .toString()); + .toString(), gridFields.get(5).toString(), rcMap); } } } return ncgridTree; } - private int getDt(String modelName) { - NcgridModel model = NcgribModelLookup.getInstance().getModelByName( - modelName); - if (model != null && model.getDt() != null) { - int dTinSeconds = model.getDt(); - - // dT <= 24 is in hours, need to convert to seconds - if (Math.abs(dTinSeconds) <= 24) { - dTinSeconds *= 3600; - } - return dTinSeconds; - } - return -1; - } - - public void setInsertTime(long time) { - insertTime = new Long(time); - } - } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/package-info.java index 41b91513e7..c80ab35d77 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/uengine/tasks/ncgrib/package-info.java @@ -1,4 +1,4 @@ -/** - * Contains JavaScript oriented μEngine tasks specific to gribs - */ +/** + * Contains JavaScript oriented μEngine tasks specific to gribs + */ package gov.noaa.nws.ncep.edex.uengine.tasks.ncgrib; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsComparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsComparator.java index 7d495a6552..24b49ef02e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsComparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsComparator.java @@ -1,56 +1,56 @@ -package gov.noaa.nws.ncep.edex.util.grib2vars; - -import java.util.Comparator; - -/** - * Comparator for Grib2Vars fields. - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 10/10		276  		L. Lin	   Initial Creation
- *                       
- * 
- * - * @author llin - * @version 1 - */ - -public class Grib2VarsComparator implements Comparator, IGrib2VarsField { - - private Grib2VarsField field; - - public Grib2VarsComparator(Grib2VarsField f) { - this.field = f; - } - - public int compare(Grib2Vars o1, Grib2Vars o2) { - switch (field) { - case G2VARSID: - return o1.getG2Varsid() - o2.getG2Varsid(); - case DISCIPLINE: - return o1.getDiscipline() - o2.getDiscipline(); - case CATEGORY: - return o1.getCategory() - o2.getCategory(); - case PID: - return o1.getPid() - o2.getPid(); - case PDT: - return o1.getPdt() - o2.getPdt(); - case NAME: - return o1.getName().compareToIgnoreCase(o2.getName()); - case UNITS: - return o1.getUnits().compareToIgnoreCase(o2.getUnits()); - case GNAM: - return o1.getGnam().compareToIgnoreCase(o2.getGnam()); - case SCALE: - return o1.getScale() - o2.getScale(); - case MISSING: - return o1.getMissing().compareTo(o2.getMissing()); - default: - return 0; - } - - } +package gov.noaa.nws.ncep.edex.util.grib2vars; + +import java.util.Comparator; + +/** + * Comparator for Grib2Vars fields. + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 10/10		276  		L. Lin	   Initial Creation
+ *                       
+ * 
+ * + * @author llin + * @version 1 + */ + +public class Grib2VarsComparator implements Comparator, IGrib2VarsField { + + private Grib2VarsField field; + + public Grib2VarsComparator(Grib2VarsField f) { + this.field = f; + } + + public int compare(Grib2Vars o1, Grib2Vars o2) { + switch (field) { + case G2VARSID: + return o1.getG2Varsid() - o2.getG2Varsid(); + case DISCIPLINE: + return o1.getDiscipline() - o2.getDiscipline(); + case CATEGORY: + return o1.getCategory() - o2.getCategory(); + case PID: + return o1.getPid() - o2.getPid(); + case PDT: + return o1.getPdt() - o2.getPdt(); + case NAME: + return o1.getName().compareToIgnoreCase(o2.getName()); + case UNITS: + return o1.getUnits().compareToIgnoreCase(o2.getUnits()); + case GNAM: + return o1.getGnam().compareToIgnoreCase(o2.getGnam()); + case SCALE: + return o1.getScale() - o2.getScale(); + case MISSING: + return o1.getMissing().compareTo(o2.getMissing()); + default: + return 0; + } + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTable.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTable.java index 87d0c0bcd5..77827218d6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTable.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTable.java @@ -1,185 +1,185 @@ -package gov.noaa.nws.ncep.edex.util.grib2vars; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -/** - * This class reads a g2Vars table from an xml file and contains a list of g2Varss. - * This class also provide general g2Vars search functions given g2Vars field, and - * field value. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 10/10  		276   	   	L. Lin	   Initial Creation
- * 07/11                    X. Guo     Added getGrib2Vars4Grib1()
- *                       
- * 
- * - * @author llin - * @version 1 - */ - -public class Grib2VarsTable implements IGrib2VarsField { - - private final String PACKAGE = "gov.noaa.nws.ncep.edex.util.grib2vars"; - - private List g2VarsList; - - private static Grib2VarsField last = null; - - /** - * Constructor. - * @param tableFileName - full path of the xml table file - */ - public Grib2VarsTable( String tableFileName ) { - - try{ - g2VarsList = readGrib2VarsTable( tableFileName ); - } - catch ( JAXBException exp ){ - g2VarsList = null; - exp.printStackTrace(); - } - - } - - /** - * Reads the contents of the input g2Vars table file - * @param xmlFilename - full path of the xml table name - * @return - a list of g2Varss - * @throws JAXBException - */ - private List readGrib2VarsTable( String xmlFilename ) throws JAXBException{ - - File xmlFile = new File(xmlFilename); - - JAXBContext context = JAXBContext.newInstance( - PACKAGE); - Unmarshaller unmarshaller = context.createUnmarshaller(); - Grib2VarsList g2Varslist = null; - - try { - g2Varslist = (Grib2VarsList)unmarshaller.unmarshal( - new FileReader(xmlFile)); - List listOfItems = g2Varslist.getGrib2Vars(); - return listOfItems; - - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - - } catch (NullPointerException e2) { - e2.printStackTrace(); - } - - return null; - - } - - /** - * Gets the list of the g2Varss - * @return - the list of g2Varss - */ - public List getGrib2VarsList(){ - - return g2VarsList; - - } - - /** - * Search a g2Vars given a field, and search key value. - * - * @param sf - * @param key - * @return Grib2Vars - */ - public Grib2Vars getGrib2Vars(int discipline, int category, int pid, int pdt) { - - if (g2VarsList == null || g2VarsList.isEmpty()) return null; - - for (Grib2Vars g2Vars : g2VarsList) { - if (g2Vars.discipline == discipline && - g2Vars.category == category && - g2Vars.pid == pid && - g2Vars.pdt == pdt ) { - return g2Vars; - } - } - return null; - } - - public Grib2Vars getGrib2Vars4Grib1(int discipline, int category, int pid) { - - if (g2VarsList == null || g2VarsList.isEmpty()) return null; - - for (Grib2Vars g2Vars : g2VarsList) { - if (g2Vars.discipline == discipline && - g2Vars.category == category && - g2Vars.pid == pid ) { - return g2Vars; - } - } - return null; - } - /** - * Search g2Vars list given a field, and search key value. - * - * @param sf - * @param key - * @return Grib2Vars - */ - public List getGrib2Varss(Grib2VarsField sf, Integer key) { - if (g2VarsList == null || g2VarsList.isEmpty()) return null; - - Grib2VarsComparator comparator = new Grib2VarsComparator(sf); - if (last == null || (last != null && last != sf )) { - Collections.sort(g2VarsList, comparator); - last = sf; - } - - List list = new ArrayList(); - - Grib2Vars s = getComparedGrib2Vars(sf, key); - int index; - while ((index = Collections.binarySearch(g2VarsList, s, comparator)) >= 0) { - list.add(g2VarsList.get(index)); - g2VarsList.remove(index); - } - - if (list.size() > 0) { - for (Grib2Vars st : list) { - g2VarsList.add(st); - } - - last = null; - return list; - } - else { - return null; - } - } - - - private Grib2Vars getComparedGrib2Vars(Grib2VarsField sf, Integer key){ - Grib2Vars g2Vars = new Grib2Vars(); - switch (sf) { - case G2VARSID: - g2Vars.setG2Varsid((Integer)key); - break; - } - - return g2Vars; - } - +package gov.noaa.nws.ncep.edex.util.grib2vars; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +/** + * This class reads a g2Vars table from an xml file and contains a list of g2Varss. + * This class also provide general g2Vars search functions given g2Vars field, and + * field value. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 10/10  		276   	   	L. Lin	   Initial Creation
+ * 07/11                    X. Guo     Added getGrib2Vars4Grib1()
+ *                       
+ * 
+ * + * @author llin + * @version 1 + */ + +public class Grib2VarsTable implements IGrib2VarsField { + + private final String PACKAGE = "gov.noaa.nws.ncep.edex.util.grib2vars"; + + private List g2VarsList; + + private static Grib2VarsField last = null; + + /** + * Constructor. + * @param tableFileName - full path of the xml table file + */ + public Grib2VarsTable( String tableFileName ) { + + try{ + g2VarsList = readGrib2VarsTable( tableFileName ); + } + catch ( JAXBException exp ){ + g2VarsList = null; + exp.printStackTrace(); + } + + } + + /** + * Reads the contents of the input g2Vars table file + * @param xmlFilename - full path of the xml table name + * @return - a list of g2Varss + * @throws JAXBException + */ + private List readGrib2VarsTable( String xmlFilename ) throws JAXBException{ + + File xmlFile = new File(xmlFilename); + + JAXBContext context = JAXBContext.newInstance( + PACKAGE); + Unmarshaller unmarshaller = context.createUnmarshaller(); + Grib2VarsList g2Varslist = null; + + try { + g2Varslist = (Grib2VarsList)unmarshaller.unmarshal( + new FileReader(xmlFile)); + List listOfItems = g2Varslist.getGrib2Vars(); + return listOfItems; + + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + + } catch (NullPointerException e2) { + e2.printStackTrace(); + } + + return null; + + } + + /** + * Gets the list of the g2Varss + * @return - the list of g2Varss + */ + public List getGrib2VarsList(){ + + return g2VarsList; + + } + + /** + * Search a g2Vars given a field, and search key value. + * + * @param sf + * @param key + * @return Grib2Vars + */ + public Grib2Vars getGrib2Vars(int discipline, int category, int pid, int pdt) { + + if (g2VarsList == null || g2VarsList.isEmpty()) return null; + + for (Grib2Vars g2Vars : g2VarsList) { + if (g2Vars.discipline == discipline && + g2Vars.category == category && + g2Vars.pid == pid && + g2Vars.pdt == pdt ) { + return g2Vars; + } + } + return null; + } + + public Grib2Vars getGrib2Vars4Grib1(int discipline, int category, int pid) { + + if (g2VarsList == null || g2VarsList.isEmpty()) return null; + + for (Grib2Vars g2Vars : g2VarsList) { + if (g2Vars.discipline == discipline && + g2Vars.category == category && + g2Vars.pid == pid ) { + return g2Vars; + } + } + return null; + } + /** + * Search g2Vars list given a field, and search key value. + * + * @param sf + * @param key + * @return Grib2Vars + */ + public List getGrib2Varss(Grib2VarsField sf, Integer key) { + if (g2VarsList == null || g2VarsList.isEmpty()) return null; + + Grib2VarsComparator comparator = new Grib2VarsComparator(sf); + if (last == null || (last != null && last != sf )) { + Collections.sort(g2VarsList, comparator); + last = sf; + } + + List list = new ArrayList(); + + Grib2Vars s = getComparedGrib2Vars(sf, key); + int index; + while ((index = Collections.binarySearch(g2VarsList, s, comparator)) >= 0) { + list.add(g2VarsList.get(index)); + g2VarsList.remove(index); + } + + if (list.size() > 0) { + for (Grib2Vars st : list) { + g2VarsList.add(st); + } + + last = null; + return list; + } + else { + return null; + } + } + + + private Grib2Vars getComparedGrib2Vars(Grib2VarsField sf, Integer key){ + Grib2Vars g2Vars = new Grib2Vars(); + switch (sf) { + case G2VARSID: + g2Vars.setG2Varsid((Integer)key); + break; + } + + return g2Vars; + } + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTableLookup.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTableLookup.java index cb0ac3d252..15a9b47fe5 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTableLookup.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/Grib2VarsTableLookup.java @@ -1,282 +1,282 @@ -/** - * Grib2varsTableLookup - A Java class to define some known - * both g2varsncep1.tbl and g2varswmo2.tbl. - * - * SOFTWARE HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 10/2010 276 L. Lin Initial creation - * 06/2011 X. Guo Added getVarGnam() - * 07/2011 X. Guo Added getVarGnam4Grib1() - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ -package gov.noaa.nws.ncep.edex.util.grib2vars; - -import java.io.File; - -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; - -import com.raytheon.uf.common.localization.IPathManager; -import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.PathManagerFactory; - -public class Grib2VarsTableLookup { - - private static Grib2VarsTable grib2varsTbl = null; - private static String name; - private static String units; - private static Integer scale; - private static String gnam; - private static float missing; - - public Grib2VarsTableLookup() { - } - - public static synchronized String readG2varsTable() throws GribException { - - Grib2VarsTable myTbl = null; - - /* - * Gets all predefined found in the utility directory - */ - IPathManager pathMgr = PathManagerFactory.getPathManager(); - LocalizationContext commonStaticBase = pathMgr.getContext( - LocalizationContext.LocalizationType.COMMON_STATIC, - LocalizationContext.LocalizationLevel.BASE); - - String path = ""; - - try { - path = pathMgr.getFile(commonStaticBase, - "ncgrid" + File.separator + "grib2vars.xml") - .getCanonicalPath(); - - // System.out.println (" grib2 vars table lookup path=" + path); - } catch (Exception e) { - throw new GribException( - "Unable to unmarshal ncep grib2vars.xml file"); - } - - File varsFile = new File(path); - try { - if (varsFile.exists()) { - myTbl = new Grib2VarsTable(path); - setG2varsTable(myTbl); - // System.out.println("Grib2varsTableLookup- read grib2vars.xml file=" - // + path); - } - } catch (Exception e) { - throw new GribException("Unable to read ncep grib2vars file"); - } - return path; - } - - /** - * Given discipline, category, pid, and pdt, find g2vars entry in - * "grib2vars.xml" and set g2varsid, name, units, scale, gnam, and missing - * fields. . - * - * @param discipline - * , category, pid and pdt are integers. - * @return - * @throws GribException - * - */ - public static int getG2varsId(int discipline, int category, int pid, int pdt) - throws GribException { - Grib2Vars g2vars = null; - int g2varsid = -1; - // Wrap decoding in a try block, in case of exception on xml. - try { - // Read in the stationNumber table XML if not exists - if (grib2varsTbl == null) { - readG2varsTable(); - } - - // Search station ID and return whole station record - if (grib2varsTbl != null) { - g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, - pdt); - } - - if (g2vars != null) { - g2varsid = g2vars.g2Varsid; - name = g2vars.name; - units = g2vars.units; - gnam = g2vars.gnam; - scale = g2vars.scale; - missing = g2vars.missing; - } - } catch (Exception e) { - // TODO: Use central error logging if this code is kept - throw new GribException( - "Error occurs while finding g2vars entry from g2vars.xml table"); - } - - return g2varsid; - } - - /** - * Given discipline, category, pid, and pdt, find g2vars entry in - * "grib2vars.xml" and set g2varsid, name, units, g2varsscale, gnam, and - * missing fields. . - * - * @param discipline - * , category, pid and pdt are integers. - * @return - * @throws GribException - * - */ - public static int getG2varsScale(int discipline, int category, int pid, - int pdt) throws GribException { - Grib2Vars g2vars = null; - int g2scale = 0; - // Wrap decoding in a try block, in case of exception on xml. - try { - // Read in the stationNumber table XML if not exists - if (grib2varsTbl == null) { - readG2varsTable(); - } - - // Search station ID and return whole station record - if (grib2varsTbl != null) { - g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, - pdt); - } - - if (g2vars != null) { - // g2Varsid = g2vars.g2Varsid; - name = g2vars.name; - units = g2vars.units; - gnam = g2vars.gnam; - g2scale = g2vars.scale; - missing = g2vars.missing; - } - } catch (Exception e) { - // TODO: Use central error logging if this code is kept - throw new GribException( - "Error occurs while finding g2vars entry from g2vars.xml table"); - } - - return g2scale; - } - - /** - * @return the grib2varsTbl - */ - public static Grib2VarsTable getG2varsTable() { - return grib2varsTbl; - } - - /** - * @param Grib2VarsTable - * the grib2varsTbl to set - */ - public static void setG2varsTable(Grib2VarsTable grib2varsTbl) { - Grib2VarsTableLookup.grib2varsTbl = grib2varsTbl; - } - - public static String getName() { - return name; - } - - public static void setName(String name) { - Grib2VarsTableLookup.name = name; - } - - public static String getVarGnam( int discipline, int category, int pid, int pdt) throws GribException { - Grib2Vars g2vars = null; - String varName="NONE"; - // Wrap decoding in a try block, in case of exception on xml. - try { - // Read in the stationNumber table XML if not exists - if (grib2varsTbl == null) { - readG2varsTable(); - } - - // Search station ID and return whole station record - if (grib2varsTbl != null) { - g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, - pdt); - } - - if (g2vars != null) { - // g2Varsid = g2vars.g2Varsid; - varName = g2vars.gnam; - } - } catch (Exception e) { - // TODO: Use central error logging if this code is kept - throw new GribException( - "Error occurs while finding g2vars entry from g2vars.xml table"); - } - - return varName; - } - - public static String getVarGnam4Grib1( int discipline, int category, int pid) throws GribException { - Grib2Vars g2vars = null; - String varName="NONE"; - // Wrap decoding in a try block, in case of exception on xml. - try { - // Read in the stationNumber table XML if not exists - if (grib2varsTbl == null) { - readG2varsTable(); - } - - // Search station ID and return whole station record - if (grib2varsTbl != null) { - g2vars = grib2varsTbl.getGrib2Vars4Grib1(discipline, category, pid ); - } - - if (g2vars != null) { - // g2Varsid = g2vars.g2Varsid; - varName = g2vars.gnam; - } - } catch (Exception e) { - // TODO: Use central error logging if this code is kept - throw new GribException( - "Error occurs while finding g2vars entry from g2vars.xml table"); - } - - return varName; - } - - public static String getUnits() { - return units; - } - - public static void setUnits(String units) { - Grib2VarsTableLookup.units = units; - } - - public static Integer getScale() { - return scale; - } - - public static void setScale(Integer scale) { - Grib2VarsTableLookup.scale = scale; - } - - public static String getGnam() { - return gnam; - } - - public static void setGnam(String gnam) { - Grib2VarsTableLookup.gnam = gnam; - } - - public static float getMissing() { - return missing; - } - - public static void setMissing(float missing) { - Grib2VarsTableLookup.missing = missing; - } - -} +/** + * Grib2varsTableLookup - A Java class to define some known + * both g2varsncep1.tbl and g2varswmo2.tbl. + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 10/2010 276 L. Lin Initial creation + * 06/2011 X. Guo Added getVarGnam() + * 07/2011 X. Guo Added getVarGnam4Grib1() + * + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ +package gov.noaa.nws.ncep.edex.util.grib2vars; + +import java.io.File; + +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.PathManagerFactory; + +public class Grib2VarsTableLookup { + + private static Grib2VarsTable grib2varsTbl = null; + private static String name; + private static String units; + private static Integer scale; + private static String gnam; + private static float missing; + + public Grib2VarsTableLookup() { + } + + public static synchronized String readG2varsTable() throws GribException { + + Grib2VarsTable myTbl = null; + + /* + * Gets all predefined found in the utility directory + */ + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext commonStaticBase = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.BASE); + + String path = ""; + + try { + path = pathMgr.getFile(commonStaticBase, + "ncgrid" + File.separator + "grib2vars.xml") + .getCanonicalPath(); + + // System.out.println (" grib2 vars table lookup path=" + path); + } catch (Exception e) { + throw new GribException( + "Unable to unmarshal ncep grib2vars.xml file"); + } + + File varsFile = new File(path); + try { + if (varsFile.exists()) { + myTbl = new Grib2VarsTable(path); + setG2varsTable(myTbl); + // System.out.println("Grib2varsTableLookup- read grib2vars.xml file=" + // + path); + } + } catch (Exception e) { + throw new GribException("Unable to read ncep grib2vars file"); + } + return path; + } + + /** + * Given discipline, category, pid, and pdt, find g2vars entry in + * "grib2vars.xml" and set g2varsid, name, units, scale, gnam, and missing + * fields. . + * + * @param discipline + * , category, pid and pdt are integers. + * @return + * @throws GribException + * + */ + public static int getG2varsId(int discipline, int category, int pid, int pdt) + throws GribException { + Grib2Vars g2vars = null; + int g2varsid = -1; + // Wrap decoding in a try block, in case of exception on xml. + try { + // Read in the stationNumber table XML if not exists + if (grib2varsTbl == null) { + readG2varsTable(); + } + + // Search station ID and return whole station record + if (grib2varsTbl != null) { + g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, + pdt); + } + + if (g2vars != null) { + g2varsid = g2vars.g2Varsid; + name = g2vars.name; + units = g2vars.units; + gnam = g2vars.gnam; + scale = g2vars.scale; + missing = g2vars.missing; + } + } catch (Exception e) { + // TODO: Use central error logging if this code is kept + throw new GribException( + "Error occurs while finding g2vars entry from g2vars.xml table"); + } + + return g2varsid; + } + + /** + * Given discipline, category, pid, and pdt, find g2vars entry in + * "grib2vars.xml" and set g2varsid, name, units, g2varsscale, gnam, and + * missing fields. . + * + * @param discipline + * , category, pid and pdt are integers. + * @return + * @throws GribException + * + */ + public static int getG2varsScale(int discipline, int category, int pid, + int pdt) throws GribException { + Grib2Vars g2vars = null; + int g2scale = 0; + // Wrap decoding in a try block, in case of exception on xml. + try { + // Read in the stationNumber table XML if not exists + if (grib2varsTbl == null) { + readG2varsTable(); + } + + // Search station ID and return whole station record + if (grib2varsTbl != null) { + g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, + pdt); + } + + if (g2vars != null) { + // g2Varsid = g2vars.g2Varsid; + name = g2vars.name; + units = g2vars.units; + gnam = g2vars.gnam; + g2scale = g2vars.scale; + missing = g2vars.missing; + } + } catch (Exception e) { + // TODO: Use central error logging if this code is kept + throw new GribException( + "Error occurs while finding g2vars entry from g2vars.xml table"); + } + + return g2scale; + } + + /** + * @return the grib2varsTbl + */ + public static Grib2VarsTable getG2varsTable() { + return grib2varsTbl; + } + + /** + * @param Grib2VarsTable + * the grib2varsTbl to set + */ + public static void setG2varsTable(Grib2VarsTable grib2varsTbl) { + Grib2VarsTableLookup.grib2varsTbl = grib2varsTbl; + } + + public static String getName() { + return name; + } + + public static void setName(String name) { + Grib2VarsTableLookup.name = name; + } + + public static String getVarGnam( int discipline, int category, int pid, int pdt) throws GribException { + Grib2Vars g2vars = null; + String varName="NONE"; + // Wrap decoding in a try block, in case of exception on xml. + try { + // Read in the stationNumber table XML if not exists + if (grib2varsTbl == null) { + readG2varsTable(); + } + + // Search station ID and return whole station record + if (grib2varsTbl != null) { + g2vars = grib2varsTbl.getGrib2Vars(discipline, category, pid, + pdt); + } + + if (g2vars != null) { + // g2Varsid = g2vars.g2Varsid; + varName = g2vars.gnam; + } + } catch (Exception e) { + // TODO: Use central error logging if this code is kept + throw new GribException( + "Error occurs while finding g2vars entry from g2vars.xml table"); + } + + return varName; + } + + public static String getVarGnam4Grib1( int discipline, int category, int pid) throws GribException { + Grib2Vars g2vars = null; + String varName="NONE"; + // Wrap decoding in a try block, in case of exception on xml. + try { + // Read in the stationNumber table XML if not exists + if (grib2varsTbl == null) { + readG2varsTable(); + } + + // Search station ID and return whole station record + if (grib2varsTbl != null) { + g2vars = grib2varsTbl.getGrib2Vars4Grib1(discipline, category, pid ); + } + + if (g2vars != null) { + // g2Varsid = g2vars.g2Varsid; + varName = g2vars.gnam; + } + } catch (Exception e) { + // TODO: Use central error logging if this code is kept + throw new GribException( + "Error occurs while finding g2vars entry from g2vars.xml table"); + } + + return varName; + } + + public static String getUnits() { + return units; + } + + public static void setUnits(String units) { + Grib2VarsTableLookup.units = units; + } + + public static Integer getScale() { + return scale; + } + + public static void setScale(Integer scale) { + Grib2VarsTableLookup.scale = scale; + } + + public static String getGnam() { + return gnam; + } + + public static void setGnam(String gnam) { + Grib2VarsTableLookup.gnam = gnam; + } + + public static float getMissing() { + return missing; + } + + public static void setMissing(float missing) { + Grib2VarsTableLookup.missing = missing; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/IGrib2VarsField.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/IGrib2VarsField.java index 54803378a7..8f20bfac2e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/IGrib2VarsField.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vars/IGrib2VarsField.java @@ -1,18 +1,18 @@ -package gov.noaa.nws.ncep.edex.util.grib2vars; - -public interface IGrib2VarsField { - - public static enum Grib2VarsField { - G2VARSID, // g2vars id - DISCIPLINE, // The discipline - CATEGORY, // The category - PID, // The parameter id - PDT, // The product definition template - NAME, // description of this g2vars - UNITS, // units - GNAM, // gnam - SCALE, // scale - MISSING // The missing value - } - -} +package gov.noaa.nws.ncep.edex.util.grib2vars; + +public interface IGrib2VarsField { + + public static enum Grib2VarsField { + G2VARSID, // g2vars id + DISCIPLINE, // The discipline + CATEGORY, // The category + PID, // The parameter id + PDT, // The product definition template + NAME, // description of this g2vars + UNITS, // units + GNAM, // gnam + SCALE, // scale + MISSING // The missing value + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdComparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdComparator.java index e541ee6b73..e81e58c04f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdComparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdComparator.java @@ -1,50 +1,50 @@ -package gov.noaa.nws.ncep.edex.util.grib2vcrd; - -import java.util.Comparator; - -/** - * Comparator for Grib2Vcrd fields. - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 10/10		276  		L. Lin	   Initial Creation
- *                       
- * 
- * - * @author llin - * @version 1 - */ - -public class Grib2VcrdComparator implements Comparator, IGrib2VcrdField { - - private Grib2VcrdField field; - - public Grib2VcrdComparator(Grib2VcrdField f) { - this.field = f; - } - - public int compare(Grib2Vcrd o1, Grib2Vcrd o2) { - switch (field) { - case G2VCRDID: - return o1.getG2Vcrdid() - o2.getG2Vcrdid(); - case VCRDID1: - return o1.getVcrdid1() - o2.getVcrdid1(); - case VCRDID2: - return o1.getVcrdid2() - o2.getVcrdid2(); - case NAME: - return o1.getName().compareToIgnoreCase(o2.getName()); - case UNITS: - return o1.getUnits().compareToIgnoreCase(o2.getUnits()); - case GNAM: - return o1.getGnam().compareToIgnoreCase(o2.getGnam()); - case SCALE: - return o1.getScale().compareToIgnoreCase(o2.getScale()); - default: - return 0; - } - - } +package gov.noaa.nws.ncep.edex.util.grib2vcrd; + +import java.util.Comparator; + +/** + * Comparator for Grib2Vcrd fields. + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 10/10		276  		L. Lin	   Initial Creation
+ *                       
+ * 
+ * + * @author llin + * @version 1 + */ + +public class Grib2VcrdComparator implements Comparator, IGrib2VcrdField { + + private Grib2VcrdField field; + + public Grib2VcrdComparator(Grib2VcrdField f) { + this.field = f; + } + + public int compare(Grib2Vcrd o1, Grib2Vcrd o2) { + switch (field) { + case G2VCRDID: + return o1.getG2Vcrdid() - o2.getG2Vcrdid(); + case VCRDID1: + return o1.getVcrdid1() - o2.getVcrdid1(); + case VCRDID2: + return o1.getVcrdid2() - o2.getVcrdid2(); + case NAME: + return o1.getName().compareToIgnoreCase(o2.getName()); + case UNITS: + return o1.getUnits().compareToIgnoreCase(o2.getUnits()); + case GNAM: + return o1.getGnam().compareToIgnoreCase(o2.getGnam()); + case SCALE: + return o1.getScale().compareToIgnoreCase(o2.getScale()); + default: + return 0; + } + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTable.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTable.java index eebe6743ab..b040812981 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTable.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTable.java @@ -1,189 +1,189 @@ -package gov.noaa.nws.ncep.edex.util.grib2vcrd; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -/** - * This class reads a g2Vcrd table from an xml file and contains a list of g2Vcrds. - * This class also provide general g2Vcrd search functions given g2Vcrd field, and - * field value. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 10/10  		276   	   	L. Lin	   Initial Creation
- * 07/11                    X. Guo     Added getGrib2VcrdByVcrd1()
- *                       
- * 
- * - * @author llin - * @version 1 - */ - -public class Grib2VcrdTable implements IGrib2VcrdField { - - private final String PACKAGE = "gov.noaa.nws.ncep.edex.util.grib2vcrd"; - - private List g2VcrdList; - - private static Grib2VcrdField last = null; - - /** - * Constructor. - * @param tableFileName - full path of the xml table file - */ - public Grib2VcrdTable( String tableFileName ) { - - try{ - g2VcrdList = readGrib2VcrdTable( tableFileName ); - } - catch ( JAXBException exp ){ - g2VcrdList = null; - exp.printStackTrace(); - } - - } - - /** - * Reads the contents of the input g2Vcrd table file - * @param xmlFilename - full path of the xml table name - * @return - a list of g2Vcrds - * @throws JAXBException - */ - private List readGrib2VcrdTable( String xmlFilename ) throws JAXBException{ - - File xmlFile = new File(xmlFilename); - - JAXBContext context = JAXBContext.newInstance( - PACKAGE); - Unmarshaller unmarshaller = context.createUnmarshaller(); - Grib2VcrdList g2Vcrdlist = null; - - try { - g2Vcrdlist = (Grib2VcrdList)unmarshaller.unmarshal( - new FileReader(xmlFile)); - List listOfItems = g2Vcrdlist.getGrib2Vcrd(); - return listOfItems; - - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - - } catch (NullPointerException e2) { - e2.printStackTrace(); - } - - return null; - - } - - /** - * Gets the list of the g2Vcrds - * @return - the list of g2Vcrds - */ - public List getGrib2VcrdList(){ - - return g2VcrdList; - - } - - /** - * Search a g2Vcrd given a field, and search key value. - * - * @param sf - * @param key - * @return Grib2Vcrd - */ - public Grib2Vcrd getGrib2Vcrd(int vcrdid1, int vcrdid2) { - - if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; - - for (Grib2Vcrd g2Vcrd : g2VcrdList) { - if (g2Vcrd.vcrdid1 == vcrdid1 && - g2Vcrd.vcrdid2 == vcrdid2 ) { - return g2Vcrd; - } - } - return null; - } - - /** - * Search a g2Vcrd given a field, and search key value. - * - * @param sf - * @param key - * @return Grib2Vcrd - */ - public Grib2Vcrd getGrib2VcrdByVcrd1 (int vcrdid1 ) { - - if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; - - for (Grib2Vcrd g2Vcrd : g2VcrdList) { - if (g2Vcrd.vcrdid1 == vcrdid1 ) { - return g2Vcrd; - } - } - return null; - } - - /** - * Search g2Vcrd list given a field, and search key value. - * - * @param sf - * @param key - * @return Grib2Vcrd - */ - public List getGrib2Vcrds(Grib2VcrdField sf, Integer key) { - if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; - - Grib2VcrdComparator comparator = new Grib2VcrdComparator(sf); - if (last == null || (last != null && last != sf )) { - Collections.sort(g2VcrdList, comparator); - last = sf; - } - - List list = new ArrayList(); - - Grib2Vcrd s = getComparedGrib2Vcrd(sf, key); - int index; - while ((index = Collections.binarySearch(g2VcrdList, s, comparator)) >= 0) { - list.add(g2VcrdList.get(index)); - g2VcrdList.remove(index); - } - - if (list.size() > 0) { - for (Grib2Vcrd st : list) { - g2VcrdList.add(st); - } - - last = null; - return list; - } - else { - return null; - } - } - - - private Grib2Vcrd getComparedGrib2Vcrd(Grib2VcrdField sf, Integer key){ - Grib2Vcrd g2Vcrd = new Grib2Vcrd(); - switch (sf) { - case G2VCRDID: - g2Vcrd.setG2Vcrdid((Integer)key); - break; - } - - return g2Vcrd; - } - +package gov.noaa.nws.ncep.edex.util.grib2vcrd; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +/** + * This class reads a g2Vcrd table from an xml file and contains a list of g2Vcrds. + * This class also provide general g2Vcrd search functions given g2Vcrd field, and + * field value. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 10/10  		276   	   	L. Lin	   Initial Creation
+ * 07/11                    X. Guo     Added getGrib2VcrdByVcrd1()
+ *                       
+ * 
+ * + * @author llin + * @version 1 + */ + +public class Grib2VcrdTable implements IGrib2VcrdField { + + private final String PACKAGE = "gov.noaa.nws.ncep.edex.util.grib2vcrd"; + + private List g2VcrdList; + + private static Grib2VcrdField last = null; + + /** + * Constructor. + * @param tableFileName - full path of the xml table file + */ + public Grib2VcrdTable( String tableFileName ) { + + try{ + g2VcrdList = readGrib2VcrdTable( tableFileName ); + } + catch ( JAXBException exp ){ + g2VcrdList = null; + exp.printStackTrace(); + } + + } + + /** + * Reads the contents of the input g2Vcrd table file + * @param xmlFilename - full path of the xml table name + * @return - a list of g2Vcrds + * @throws JAXBException + */ + private List readGrib2VcrdTable( String xmlFilename ) throws JAXBException{ + + File xmlFile = new File(xmlFilename); + + JAXBContext context = JAXBContext.newInstance( + PACKAGE); + Unmarshaller unmarshaller = context.createUnmarshaller(); + Grib2VcrdList g2Vcrdlist = null; + + try { + g2Vcrdlist = (Grib2VcrdList)unmarshaller.unmarshal( + new FileReader(xmlFile)); + List listOfItems = g2Vcrdlist.getGrib2Vcrd(); + return listOfItems; + + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + + } catch (NullPointerException e2) { + e2.printStackTrace(); + } + + return null; + + } + + /** + * Gets the list of the g2Vcrds + * @return - the list of g2Vcrds + */ + public List getGrib2VcrdList(){ + + return g2VcrdList; + + } + + /** + * Search a g2Vcrd given a field, and search key value. + * + * @param sf + * @param key + * @return Grib2Vcrd + */ + public Grib2Vcrd getGrib2Vcrd(int vcrdid1, int vcrdid2) { + + if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; + + for (Grib2Vcrd g2Vcrd : g2VcrdList) { + if (g2Vcrd.vcrdid1 == vcrdid1 && + g2Vcrd.vcrdid2 == vcrdid2 ) { + return g2Vcrd; + } + } + return null; + } + + /** + * Search a g2Vcrd given a field, and search key value. + * + * @param sf + * @param key + * @return Grib2Vcrd + */ + public Grib2Vcrd getGrib2VcrdByVcrd1 (int vcrdid1 ) { + + if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; + + for (Grib2Vcrd g2Vcrd : g2VcrdList) { + if (g2Vcrd.vcrdid1 == vcrdid1 ) { + return g2Vcrd; + } + } + return null; + } + + /** + * Search g2Vcrd list given a field, and search key value. + * + * @param sf + * @param key + * @return Grib2Vcrd + */ + public List getGrib2Vcrds(Grib2VcrdField sf, Integer key) { + if (g2VcrdList == null || g2VcrdList.isEmpty()) return null; + + Grib2VcrdComparator comparator = new Grib2VcrdComparator(sf); + if (last == null || (last != null && last != sf )) { + Collections.sort(g2VcrdList, comparator); + last = sf; + } + + List list = new ArrayList(); + + Grib2Vcrd s = getComparedGrib2Vcrd(sf, key); + int index; + while ((index = Collections.binarySearch(g2VcrdList, s, comparator)) >= 0) { + list.add(g2VcrdList.get(index)); + g2VcrdList.remove(index); + } + + if (list.size() > 0) { + for (Grib2Vcrd st : list) { + g2VcrdList.add(st); + } + + last = null; + return list; + } + else { + return null; + } + } + + + private Grib2Vcrd getComparedGrib2Vcrd(Grib2VcrdField sf, Integer key){ + Grib2Vcrd g2Vcrd = new Grib2Vcrd(); + switch (sf) { + case G2VCRDID: + g2Vcrd.setG2Vcrdid((Integer)key); + break; + } + + return g2Vcrd; + } + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTableLookup.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTableLookup.java index d7993d15c9..30c293f20f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTableLookup.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/Grib2VcrdTableLookup.java @@ -1,260 +1,260 @@ -/** - * Grib2vcrdTableLookup - A Java class to define some known - * both g2vcrdncep1.tbl and g2vcrdwmo2.tbl. - * - * SOFTWARE HISTORY - * - * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 10/2010 276 L. Lin Initial creation - * 06/2011 X. Guo Added getGnamByVcrdId(() - * getScaleByVcrdId() - * 07/2011 X. Guo Added getGrib2VcrdByGrib1VcrdId() - * - * - * - * This code has been developed by the SIB for use in the AWIPS2 system. - * @author L. Lin - * @version 1.0 - */ -package gov.noaa.nws.ncep.edex.util.grib2vcrd; - -import java.io.File; - -import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; - -import com.raytheon.uf.common.localization.IPathManager; -import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.PathManagerFactory; -import com.raytheon.uf.edex.core.props.PropertiesFactory; - -public class Grib2VcrdTableLookup { - - private static Grib2VcrdTable grib2vcrdTbl=null; - private static String name; - private static String units; - private static String scale; - private static String gnam; - - public static synchronized String readG2vcrdTable () throws GribException{ - - Grib2VcrdTable myTbl = null; - - /* - * Gets all predefined found in the utility directory - */ - IPathManager pathMgr = PathManagerFactory.getPathManager(); - LocalizationContext commonStaticBase = pathMgr.getContext( - LocalizationContext.LocalizationType.COMMON_STATIC, - LocalizationContext.LocalizationLevel.BASE); - - LocalizationContext commonStaticSite = pathMgr.getContext( - LocalizationContext.LocalizationType.COMMON_STATIC, - LocalizationContext.LocalizationLevel.SITE); - - String path = ""; - String sitePath = ""; - - try { - path = pathMgr.getFile( - commonStaticBase, - "ncgrid" + File.separator + "grib2vcrd.xml") - .getCanonicalPath(); - - //System.out.println (" grib2 vcrd table lookup path=" + path); - - sitePath = pathMgr.getFile( - commonStaticSite, - PropertiesFactory.getInstance().getEnvProperties() - .getEnvValue("SITENAME") - + File.separator - + "ncgrid" - + File.separator - + "g2vcrd.xml").getCanonicalPath(); - //System.out.println (" grib2 vcrd table lookup sitepath=" + sitePath); - } catch (Exception e) { - throw new GribException("Unable to unmarshal ncep grib2vcrd.xml file"); - } - - File modelFile = new File(path); - try { - if (modelFile.exists()) { - myTbl = new Grib2VcrdTable(path); - setG2vcrdTable(myTbl); - //System.out.println("Grib2varsTableLookup- read grib2vars.xml file=" + path); - } - } catch (Exception e) { - throw new GribException("Unable to read ncep grib2vcrd file"); - } - return path; - } - - /** - * Given discipline, category, pid, and pdt, find g2vcrd entry in "grib2vcrd.xml" - * and set g2vcrdid, name, units, scale, gnam, and missing fields. - * . - * - * @param discipline, category, pid and pdt are integers. - * @return - * @throws GribException - * - */ - public static int getG2vcrdId(int vcrdid1, int vcrdid2) throws GribException { - Grib2Vcrd g2vcrd=null; - int g2vcrdid = -1; - // Wrap decoding in a try block, in case of exception on xml. - try { - - - // Read in the stationNumber table XML if not exists - if (grib2vcrdTbl == null) { - readG2vcrdTable(); - } - // Search station ID and return whole station record - if (grib2vcrdTbl != null) { - g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); - } - - if ( g2vcrd != null) { - g2vcrdid = g2vcrd.g2Vcrdid; - name = g2vcrd.name; - units = g2vcrd.units; - gnam = g2vcrd.gnam; - scale = g2vcrd.scale; - } - } - catch (Exception e) { - //TODO: Use central error logging if this code is kept - throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); - } - - return g2vcrdid; - } - - /** - * @return the grib2vcrdTbl - */ - public static Grib2VcrdTable getG2vcrdTable() { - return grib2vcrdTbl; - } - - /** - * @param Grib2VcrdTable - * the grib2vcrdTbl to set - */ - public static void setG2vcrdTable(Grib2VcrdTable grib2vcrdTbl) { - Grib2VcrdTableLookup.grib2vcrdTbl = grib2vcrdTbl; - } - - public static String getName() { - return name; - } - - public static void setName(String name) { - Grib2VcrdTableLookup.name = name; - } - - public static String getGnamByVcrdId ( int vcrdid1, int vcrdid2) throws GribException { - Grib2Vcrd g2vcrd=null; - String gvrdName = "NONE"; - // Wrap decoding in a try block, in case of exception on xml. - try { - - - // Read in the stationNumber table XML if not exists - if (grib2vcrdTbl == null) { - readG2vcrdTable(); - } - // Search station ID and return whole station record - if (grib2vcrdTbl != null) { - g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); - } - - if ( g2vcrd != null) { - gvrdName = g2vcrd.gnam; - scale = g2vcrd.scale; - } - } - catch (Exception e) { - //TODO: Use central error logging if this code is kept - throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); - } - - return gvrdName; - } - - public static Grib2Vcrd getGrib2VcrdByGrib1VcrdId ( int vcrdid ) throws GribException { - Grib2Vcrd g2vcrd=null; - // Wrap decoding in a try block, in case of exception on xml. - try { - - - // Read in the stationNumber table XML if not exists - if (grib2vcrdTbl == null) { - readG2vcrdTable(); - } - // Search station ID and return whole station record - if (grib2vcrdTbl != null) { - g2vcrd = grib2vcrdTbl.getGrib2VcrdByVcrd1(vcrdid); - } - } - catch (Exception e) { - //TODO: Use central error logging if this code is kept - throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); - } - - return g2vcrd; - } - - public static String getScaleByVcrdId ( int vcrdid1, int vcrdid2) throws GribException { - Grib2Vcrd g2vcrd=null; - // Wrap decoding in a try block, in case of exception on xml. - try { - - - // Read in the stationNumber table XML if not exists - if (grib2vcrdTbl == null) { - readG2vcrdTable(); - } - // Search station ID and return whole station record - if (grib2vcrdTbl != null) { - g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); - } - - if ( g2vcrd != null) { - scale = g2vcrd.scale; - } - } - catch (Exception e) { - //TODO: Use central error logging if this code is kept - throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); - } - - return scale; - } - - public static String getUnits() { - return units; - } - - public static void setUnits(String units) { - Grib2VcrdTableLookup.units = units; - } - - public static String getScale() { - return scale; - } - - public static void setScale(String scale) { - Grib2VcrdTableLookup.scale = scale; - } - - public static String getGnam() { - return gnam; - } - - public static void setGnam(String gnam) { - Grib2VcrdTableLookup.gnam = gnam; - } - -} +/** + * Grib2vcrdTableLookup - A Java class to define some known + * both g2vcrdncep1.tbl and g2vcrdwmo2.tbl. + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * 10/2010 276 L. Lin Initial creation + * 06/2011 X. Guo Added getGnamByVcrdId(() + * getScaleByVcrdId() + * 07/2011 X. Guo Added getGrib2VcrdByGrib1VcrdId() + * + * + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * @author L. Lin + * @version 1.0 + */ +package gov.noaa.nws.ncep.edex.util.grib2vcrd; + +import java.io.File; + +import gov.noaa.nws.ncep.common.dataplugin.ncgrib.exception.GribException; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.edex.core.props.PropertiesFactory; + +public class Grib2VcrdTableLookup { + + private static Grib2VcrdTable grib2vcrdTbl=null; + private static String name; + private static String units; + private static String scale; + private static String gnam; + + public static synchronized String readG2vcrdTable () throws GribException{ + + Grib2VcrdTable myTbl = null; + + /* + * Gets all predefined found in the utility directory + */ + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext commonStaticBase = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.BASE); + + LocalizationContext commonStaticSite = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.SITE); + + String path = ""; + String sitePath = ""; + + try { + path = pathMgr.getFile( + commonStaticBase, + "ncgrid" + File.separator + "grib2vcrd.xml") + .getCanonicalPath(); + + //System.out.println (" grib2 vcrd table lookup path=" + path); + + sitePath = pathMgr.getFile( + commonStaticSite, + PropertiesFactory.getInstance().getEnvProperties() + .getEnvValue("SITENAME") + + File.separator + + "ncgrid" + + File.separator + + "g2vcrd.xml").getCanonicalPath(); + //System.out.println (" grib2 vcrd table lookup sitepath=" + sitePath); + } catch (Exception e) { + throw new GribException("Unable to unmarshal ncep grib2vcrd.xml file"); + } + + File modelFile = new File(path); + try { + if (modelFile.exists()) { + myTbl = new Grib2VcrdTable(path); + setG2vcrdTable(myTbl); + //System.out.println("Grib2varsTableLookup- read grib2vars.xml file=" + path); + } + } catch (Exception e) { + throw new GribException("Unable to read ncep grib2vcrd file"); + } + return path; + } + + /** + * Given discipline, category, pid, and pdt, find g2vcrd entry in "grib2vcrd.xml" + * and set g2vcrdid, name, units, scale, gnam, and missing fields. + * . + * + * @param discipline, category, pid and pdt are integers. + * @return + * @throws GribException + * + */ + public static int getG2vcrdId(int vcrdid1, int vcrdid2) throws GribException { + Grib2Vcrd g2vcrd=null; + int g2vcrdid = -1; + // Wrap decoding in a try block, in case of exception on xml. + try { + + + // Read in the stationNumber table XML if not exists + if (grib2vcrdTbl == null) { + readG2vcrdTable(); + } + // Search station ID and return whole station record + if (grib2vcrdTbl != null) { + g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); + } + + if ( g2vcrd != null) { + g2vcrdid = g2vcrd.g2Vcrdid; + name = g2vcrd.name; + units = g2vcrd.units; + gnam = g2vcrd.gnam; + scale = g2vcrd.scale; + } + } + catch (Exception e) { + //TODO: Use central error logging if this code is kept + throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); + } + + return g2vcrdid; + } + + /** + * @return the grib2vcrdTbl + */ + public static Grib2VcrdTable getG2vcrdTable() { + return grib2vcrdTbl; + } + + /** + * @param Grib2VcrdTable + * the grib2vcrdTbl to set + */ + public static void setG2vcrdTable(Grib2VcrdTable grib2vcrdTbl) { + Grib2VcrdTableLookup.grib2vcrdTbl = grib2vcrdTbl; + } + + public static String getName() { + return name; + } + + public static void setName(String name) { + Grib2VcrdTableLookup.name = name; + } + + public static String getGnamByVcrdId ( int vcrdid1, int vcrdid2) throws GribException { + Grib2Vcrd g2vcrd=null; + String gvrdName = "NONE"; + // Wrap decoding in a try block, in case of exception on xml. + try { + + + // Read in the stationNumber table XML if not exists + if (grib2vcrdTbl == null) { + readG2vcrdTable(); + } + // Search station ID and return whole station record + if (grib2vcrdTbl != null) { + g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); + } + + if ( g2vcrd != null) { + gvrdName = g2vcrd.gnam; + scale = g2vcrd.scale; + } + } + catch (Exception e) { + //TODO: Use central error logging if this code is kept + throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); + } + + return gvrdName; + } + + public static Grib2Vcrd getGrib2VcrdByGrib1VcrdId ( int vcrdid ) throws GribException { + Grib2Vcrd g2vcrd=null; + // Wrap decoding in a try block, in case of exception on xml. + try { + + + // Read in the stationNumber table XML if not exists + if (grib2vcrdTbl == null) { + readG2vcrdTable(); + } + // Search station ID and return whole station record + if (grib2vcrdTbl != null) { + g2vcrd = grib2vcrdTbl.getGrib2VcrdByVcrd1(vcrdid); + } + } + catch (Exception e) { + //TODO: Use central error logging if this code is kept + throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); + } + + return g2vcrd; + } + + public static String getScaleByVcrdId ( int vcrdid1, int vcrdid2) throws GribException { + Grib2Vcrd g2vcrd=null; + // Wrap decoding in a try block, in case of exception on xml. + try { + + + // Read in the stationNumber table XML if not exists + if (grib2vcrdTbl == null) { + readG2vcrdTable(); + } + // Search station ID and return whole station record + if (grib2vcrdTbl != null) { + g2vcrd = grib2vcrdTbl.getGrib2Vcrd(vcrdid1, vcrdid2); + } + + if ( g2vcrd != null) { + scale = g2vcrd.scale; + } + } + catch (Exception e) { + //TODO: Use central error logging if this code is kept + throw new GribException("Error occurs while finding g2vcrd entry from g2vcrd.xml table"); + } + + return scale; + } + + public static String getUnits() { + return units; + } + + public static void setUnits(String units) { + Grib2VcrdTableLookup.units = units; + } + + public static String getScale() { + return scale; + } + + public static void setScale(String scale) { + Grib2VcrdTableLookup.scale = scale; + } + + public static String getGnam() { + return gnam; + } + + public static void setGnam(String gnam) { + Grib2VcrdTableLookup.gnam = gnam; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/IGrib2VcrdField.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/IGrib2VcrdField.java index 26fcb158bf..be73da436f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/IGrib2VcrdField.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/grib2vcrd/IGrib2VcrdField.java @@ -1,15 +1,15 @@ -package gov.noaa.nws.ncep.edex.util.grib2vcrd; - -public interface IGrib2VcrdField { - - public static enum Grib2VcrdField { - G2VCRDID, // g2vars id - VCRDID1, // The vertical coordination 1 - VCRDID2, // The vertical coordination 2 - NAME, // description of this g2vars - UNITS, // units - GNAM, // gnam - SCALE, // scale - } - -} +package gov.noaa.nws.ncep.edex.util.grib2vcrd; + +public interface IGrib2VcrdField { + + public static enum Grib2VcrdField { + G2VCRDID, // g2vars id + VCRDID1, // The vertical coordination 1 + VCRDID2, // The vertical coordination 2 + NAME, // description of this g2vars + UNITS, // units + GNAM, // gnam + SCALE, // scale + } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/ncgrib/NcgribModelLookup.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/ncgrib/NcgribModelLookup.java index bf4c4ab6f7..a640067c3f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/ncgrib/NcgribModelLookup.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/src/gov/noaa/nws/ncep/edex/util/ncgrib/NcgribModelLookup.java @@ -47,6 +47,7 @@ import com.raytheon.uf.common.serialization.SerializationUtil; * ------------ ---------- ----------- -------------------------- * 3/12/10 4758 bphillip Initial creation * 10/13/10 276 llin Modified for NC GRIB. + * 11/02/11 xguo Updated gridid * * * @author njensen @@ -108,7 +109,7 @@ public class NcgribModelLookup { model.setCenter(center); model.setName(modelName); model.setSubCenter(Integer.toString(subcenter)); - model.setGrid(Integer.parseInt(grid)); + model.setGrid(grid); ArrayList processList = new ArrayList(); processList.add(process); model.setProcess(processList); diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/grib2vars.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/grib2vars.xml index 5866fda0d7..de38d7b957 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/grib2vars.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/grib2vars.xml @@ -2578,7 +2578,7 @@ 0 Weather NA - WTHR + WXTR 0 -9999.00
@@ -2590,7 +2590,7 @@ 1 Weather NA - WTHR + WXTR 0 -9999.00
@@ -3183,7 +3183,7 @@ -9999.00
- 888 + 22220 0 2 222 @@ -3195,7 +3195,19 @@ -9999.00 - 888 + 22228 + 0 + 2 + 222 + 8 + U Component of Hourly Maximum 10m Wind Speed + m/s + MAXUW-- + 0 + -9999.00 + + + 22230 0 2 223 @@ -3206,6 +3218,30 @@ 0 -9999.00 + + 22238 + 0 + 2 + 223 + 8 + V Component of Hourly Maximum 10m Wind Speed + m/s + MAXVW-- + 0 + -9999.00 + + + 22240 + 0 + 2 + 224 + 0 + Ventilation Rate + m**2/s + VRATE + 0 + -9999.00 + 290 0 @@ -3374,6 +3410,19 @@ -2 -9999.00 + + + 888 + 0 + 3 + 1 + 0 + mean sea level pressure (Standard Atmosphere Reduction) + Pa + MSLSA + -2 + -9999.00 + 888 0 @@ -3950,6 +3999,42 @@ 0 -9999.00 + + 8192 + 0 + 16 + 192 + 0 + Equivalent radar refectivity factor for rain + mm**6/m**3 + REFZR + 0 + -9999.00 + + + 8193 + 0 + 16 + 193 + 0 + Equivalent radar refectivity factor for snow + mm**6/m**3 + REFZI + 0 + -9999.00 + + + 8194 + 0 + 16 + 194 + 0 + Equivalent radar refectivity factor for parameterized convection + mm**6/m**3 + REFZC + 0 + -9999.00 + 888 0 @@ -4010,6 +4095,18 @@ 0 -9999.00 + + 8812 + 0 + 19 + 12 + 0 + Planetary Boundary Layer Regime + Table 4.209 + PBLREG + 0 + -9999.00 + 888 0 diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgrib1ParamTableMap.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgrib1ParamTableMap.xml index 6f58970601..f111034efa 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgrib1ParamTableMap.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgrib1ParamTableMap.xml @@ -120,5 +120,10 @@ 7 0 2 + + 54 0 2 + 7 0 2 + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgribModels.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgribModels.xml index 1d929b93af..f30703e2b6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgribModels.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/common_static/base/ncgrid/ncgribModels.xml @@ -36,6 +36,32 @@
3
+ + GFS PGRB 0.5 degree + GFS0.5 +
7
+ 0 + 230 + + 96 + 77 + 81 + +
3
+
+ + + GFS PGRB 0.5 degree + GFS0.5 +
7
+ 0 + 408 + + 255 + +
3
+
+ GFS PGRB 1.0 DEGREE GFS @@ -46,10 +72,23 @@ 96 77 81 + 255
4
- + + + ECMWF Analysis from Global Data Assimilation System 1.0 DEGREE + GDAS +
7
+ 0 + 375 + + 82 + +
4
+
+ Analysis from Global Data Assimilation System 1.0 DEGREE GDAS @@ -61,7 +100,19 @@
4
- + + + Analysis from Global Data Assimilation System 1.0 DEGREE + GDAS +
7
+ 0 + 229 + + 82 + +
4
+
+ GFS PGRB 1.0 DEGREE GFS @@ -75,10 +126,34 @@
4
- + + + NOGAPS 361X181 Lat/Lon 1.0 DEGREE - nogaps*/wave_* + NOGAPS +
58
+ 0 + 401 + + 58 + +
4
+
+ + + NOGAPS 361X181 Lat/Lon 1.0 DEGREE - NAM Model 15km version + NOGAPS110 +
58
+ 0 + 401 + + 110 + +
4
+
+ GFS PGRB 2.5 DEGREE - GFS2.5 + GFS
7
0 2 @@ -90,6 +165,56 @@
6
+ + North American Regional Reanalysis GFS PGRB 2.5 DEGREE + NARR +
98
+ 0 + 14529 + + 140 + +
6
+
+ + + North American Regional Reanalysis GFS PGRB 2.5 DEGREE + NARR +
98
+ 0 + 2 + + 140 + +
6
+
+ + + North American Regional Reanalysis GFS PGRB 2.5 DEGREE + NARR +
98
+ 0 + 228 + + 140 + +
6
+
+ + + GFS PGRB 2.5 DEGREE + GFS +
7
+ 0 + 228 + + 96 + 77 + 81 + +
6
+
+ NAM Arakawa E-Grid NAM99 @@ -104,7 +229,7 @@ NGM Super C Grid - NAM104 + NAM
7
0 104 @@ -224,7 +349,7 @@ NAEFS 16X Resolution(5 km) - NAEFS + NAEFS197
7
2 197 @@ -236,7 +361,7 @@ NAEFS Grid over Alaska(Polar Stereographic) - NAEFS + AKNAEFS
7
2 198 @@ -269,22 +394,35 @@
3
- + - GFSensemble 1.0 Degree - ENS + ECMWF North America Ensemble Forecast 1.0 Degree + NAEFS
7
2 - 3 + 375 - 107 + 114
3
GFSensemble 1.0 Degree - ENS + GEFS +
7
+ 2 + 3 + + 107 + 255 + +
3
+
+ + + GFSensemble 1.0 Degree + GEFS
7
2 229 @@ -295,8 +433,8 @@
- GFSensemble 1.0 Degree - ENS2 + GFSensemble 2.5 Degree + GEFS
7
2 2 @@ -308,7 +446,7 @@ GFSensemble 5KM - ENS_NDGD + GEFSNDGD
7
2 197 @@ -317,6 +455,18 @@
3
+ + + ECMWF Global Ensemble 1.0 Degree + ECENS +
7
+ 2 + 375 + + 107 + +
3
+
World wide ECMWF @@ -330,9 +480,21 @@
3
+ + World wide ECMWF 1 degree LAMP + ECMWF +
98
+ 0 + 403 + + 108 + +
3
+
+ World wide ECMWF 1 degree WAVE - ECMWF_WAVE + ECMWFWAVE
98
0 374 @@ -344,7 +506,7 @@ World wide ECMWF 1 degree WAVE - ECMWF_WAVE + ECMWFWAVE
98
0 375 @@ -490,6 +652,32 @@
6
+ + GFS-NOAMHI-High Resolution North American Master Grid(Lambert Conformal) + GFSNOAMHI +
7
+ 0 + 221 + + 81 + 96 + +
6
+
+ + + GFS in the ECMWF grid navigation + GFS +
7
+ 0 + 375 + + 96 + 81 + +
6
+
+ gfsLR mrfNH @@ -823,9 +1011,34 @@
6
+ + Coastal Ocean Circulation + RTOFSATL +
7
+ 0 + 15058391 + + 45 + +
6
+
+ + + Coastal Ocean Circulation Short Term Forecast + RTOFSATLSTF +
7
+ 0 + -26535243 + + 45 + +
6
+
+ + UKMET - UKMET-NorthernHemisphere + UKMETNorthernHemisphere
74
0 371 @@ -951,7 +1164,7 @@ UKMET - UKMET45 + UKMET
74
0 45 @@ -965,7 +1178,7 @@ GFSGbl - AVN-NorthernHemisphere + AVNNorthernHemisphere
7
2 371 @@ -1089,6 +1302,30 @@
6
+ + Global Wind-Wave Forecast Model + GWW +
7
+ 0 + 3 + + 10 + +
6
+
+ + + Global Wind-Wave Forecast Model + GWW +
7
+ 0 + 229 + + 10 + +
6
+
+ GWW GWW233 @@ -1101,6 +1338,79 @@
6
+ + GWW + GWW375 +
7
+ 0 + 375 + + 10 + 255 + +
6
+
+ + + NWW3 + NWWIII233 +
7
+ 0 + 233 + + 88 + +
6
+
+ + + Southern Hemisphere High Resolution Sea Ice + SeaIceSouthernHemisphere +
7
+ 0 + 400 + + 120 + +
1
+
+ + + Southern Hemisphere High Resolution Sea Ice 0.5 degree + SeaIceSouthernHemisphere0.5 +
7
+ 0 + 405 + + 120 + +
1
+
+ + + Northern Hemisphere High Resolution Sea Ice + SeaIceNorthernHemisphere +
7
+ 0 + 171 + + 120 + +
1
+
+ + + Global 1/12 degree Lat/Lon grid Sea Ice + SeaIce173 +
7
+ 0 + 173 + + 120 + +
1
+
+ SeaIce SeaIce @@ -1113,6 +1423,18 @@
1
+ + SeaIce + SeaIce235 +
7
+ 0 + 235 + + 120 + +
1
+
+ RFCqpf RFCqpf @@ -1153,7 +1475,7 @@ AKWAVE - AKWAVE239 + WAVEAK
7
0 239 @@ -1165,12 +1487,14 @@ WNAwave - WNAWAVE238 + WAVEWNA
7
0 238 121 + 123 + 255
6
@@ -1223,6 +1547,54 @@
3
+ + NAM Hawaii + NAMHI +
7
+ 0 + 406 + + 84 + +
3
+
+ + + NAM Alaska + NAMAK +
7
+ 0 + 198 + + 84 + +
3
+
+ + + NAM over the contiguous US 16X Resolution(5Km) Lambert Conformal + NAM227 +
7
+ 0 + 227 + + 84 + +
3
+
+ + + NAM Puerto Rico + NAMPR +
7
+ 0 + 407 + + 84 + +
3
+
+ GLERL GLERL @@ -1249,12 +1621,25 @@ ENPwave - ENPWAVE253 + ENPWAVE
7
0 253 124 + 255 + +
6
+
+ + + North Pacific Hurricane Wave Model + NPWAVE +
7
+ 0 + 253 + + 125
6
@@ -1319,6 +1704,102 @@
720
+ + Grid over CONUS(Lat/Lon) 1 degree + CCPA +
7
+ 4 + 3 + + 184 + +
1
+
+ + + Grid over CONUS(Lat/Lon) 1 degree + CCPA +
7
+ 4 + 229 + + 184 + +
1
+
+ + + LDAS Grid over CONUS(Lat/Lon) + CCPA110 +
7
+ 4 + 110 + + 184 + +
1
+
+ + + Global 1/12 degree Lat/Lon -SST-Analysis + SSTA173 +
7
+ 4 + 173 + + 44 + +
1
+
+ + + Grid over CONUS- 16X Resolution(5 Km) Lambert Conformal + CCPA197 +
7
+ 4 + 197 + + 184 + +
1
+
+ + + HRAP Grid over the Contiguous United States and Puerto Rico (polar stereographic) + CCPAHRAPPR +
7
+ 4 + 240 + + 184 + +
1
+
+ + + CCPA over conus 0.5 DEGREE + CCPA0.5 +
7
+ 4 + 402 + + 184 + +
1
+
+ + + ECMWF Analysis from CCPA System 1.0 DEGREE + CCPA +
7
+ 4 + 375 + + 184 + +
1
+
+ RTG-SST-Analysis RTGSST @@ -1331,6 +1812,18 @@
1
+ + Global 0.5 degree Lat/Lon -SST-Analysis + SSTA235 +
7
+ 4 + 235 + + 44 + +
1
+
+ NICICE NICICE @@ -1345,7 +1838,7 @@ AK-NICICE - AK-NICICE + AKNICICE
7
0 242 @@ -1546,8 +2039,8 @@
- RTMA - RTMA + RTMA Grid over the contiguous US - 16X Resolution + RTMA5KM
7
0 197 @@ -1558,11 +2051,11 @@
- RTMA - RTMA + RTMA Grid over the contiguous US - 32X Resolution + RTMA2P5KM
7
4 - 21451377-196 + 1971 109 @@ -1571,7 +2064,7 @@ RTMA Grid over - Guam(Mercator) - RTMA + RTMAGUAM
7
4 199 @@ -1594,8 +2087,8 @@
- AK-RTMA - AK-RTMA + RTMA-AK + RTMAAK
7
0 198 @@ -1606,8 +2099,8 @@
- AK-RTMA - AK-RTMA + RTMA-AK + RTMAAK
7
4 198 @@ -1618,8 +2111,8 @@
- HI-RTMA - HI-RTMA + RTMA-HI + RTMAHI
7
4 196 @@ -1630,8 +2123,8 @@
- PR-RTMA - PR-RTMA + RTMA-PR + RTMAPR
7
4 195 @@ -1703,7 +2196,7 @@ ECMWF-HiRes - ECMWF-HiRes + ECMWFHiRes
98
0 232 @@ -1970,7 +2463,7 @@ ECMWF-LowRes - ECMF-NorthernHemisphere + ECMWFNorthernHemisphere
98
0 372 @@ -2116,7 +2609,7 @@
ECMWF-LowRes - ECMF1 + ECMWF1
98
0 255101 @@ -2263,7 +2756,7 @@ ECMWF-LowRes - ECMF2 + ECMWF2
98
0 255102 @@ -2410,7 +2903,7 @@ ECMWF-LowRes - ECMF3 + ECMWF3
98
0 255103 @@ -2557,7 +3050,7 @@ ECMWF-LowRes - ECMF4 + ECMWF4
98
0 255104 @@ -2704,7 +3197,7 @@ ECMWF-LowRes - ECMF5 + ECMWF5
98
0 255105 @@ -2851,7 +3344,7 @@ ECMWF-LowRes - ECMF6 + ECMWF6
98
0 255106 @@ -2998,7 +3491,7 @@ ECMWF-LowRes - ECMF7 + ECMWF7
98
0 255107 @@ -3145,7 +3638,7 @@ ECMWF-LowRes - ECMF8 + ECMWF8
98
0 255108 @@ -3363,11 +3856,35 @@
- GlobalWave - GlobalWave + Global Multi-Grid Wave + GMGWGLO
7
0 - 011 + 77528250 + + 11 + +
3
+
+ + + Global Multi-Grid Wave + GMGWAO +
7
+ 0 + 90042500 + + 11 + +
3
+
+ + + GlobalWave + WAVEGLOBAL +
7
+ 0 + 11 11 @@ -3375,8 +3892,20 @@
- AKwave10 - AKwave10 + GlobalWave + WAVEGLOBAL +
7
+ 0 + 408 + + 11 + +
3
+
+ + + AKwave 0.25X0.167 degree Lan/Lon grid - Alaska + WAVEAK0.25
7
0 15 @@ -3387,8 +3916,20 @@
- AKwave4 - AKwave4 + AKwave 0.25X0.167 degree Lan/Lon grid - Alaska + WAVEAK0.25 +
7
+ 0 + 15 + + 255 + +
3
+
+ + + AKwave 0.133X0.067 degree Lan/Lon grid - Alaska + WAVEAK0.133
7
0 16 @@ -3399,8 +3940,8 @@
- EPwave10 - EPwave10 + Wave 0.167 degree Lan/Lon grid - US Eastern Pacific + WAVEEP
7
0 14 @@ -3411,8 +3952,8 @@
- WCwave10 - WCwave10 + Wave 0.167 degree Lan/Lon grid - US Weste Coast + WAVEWC
7
0 13 @@ -3423,8 +3964,20 @@
- WCwave4 - WCwave4 + Wave 0.167 degree Lan/Lon grid - US Weste Coast + WAVEWC +
7
+ 0 + 13 + + 255 + +
3
+
+ + + Wave 0.067 degree Lan/Lon grid - US Weste Coast + WAVEWCHI
7
0 17 @@ -3435,20 +3988,69 @@
- WNAwave10 - WNAwave10 + Global Multi-Grid Wave Model 0.167 degree -- US East Coast + WAVEGLOBALE
7
0 12 11 + 255
3
- WNAwave4 - WNAwave4 + Global Multi-Grid Wave Model 0.167 degree-- Hawaii + WAVEGLOBALHI +
7
+ 0 + 14 + + 255 + +
3
+
+ + + Global Multi-Grid Wave Model 0.133X0.067 degree-- Alaska + WAVEGLOBALAK +
7
+ 0 + 16 + + 255 + +
3
+
+ + + Global Multi-Grid Wave Model 0.067 degree-- US West Coast + WAVEGLOBALW +
7
+ 0 + 17 + + 255 + +
3
+
+ + + Global Multi-Grid Wave Model 0.067 degree-- US East Coast + WAVEGLOBALE18 +
7
+ 0 + 18 + + 255 + +
3
+
+ + + Global Multi-Grid Wave Model 0.067 degree-- US East Coast + WAVEGLOBALE18
7
0 18 @@ -3536,7 +4138,7 @@ AK-GriddedMOS - MOSGuide-AK + MOSGuideAK
7
14 1023 @@ -3547,8 +4149,8 @@
- AK-NamDNG5 - AK-NamDNG5 + NamDNG5-AK + NamDNG5AK
7
0 198 @@ -3559,8 +4161,8 @@
- HI-NamDNG5 - HI-NamDNG5 + NamDNG5-HI + NamDNG5HI
7
0 196 @@ -3571,8 +4173,8 @@
- PR-NamDNG5 - PR-NamDNG5 + NamDNG5-PR + NamDNG5PR
7
0 195 @@ -3582,9 +4184,33 @@
3
+ + ARW-Guam + ARWGUAM +
7
+ 0 + 11731129 + + 116 + +
3
+
+ + + ARW-PR + ARWPR +
7
+ 0 + 13560489 + + 116 + +
3
+
+ HiResW-ARW-East - HiResW-ARW-East + HiResWARWEast
7
0 255001 @@ -3596,7 +4222,7 @@ HiResW-ARW-West - HiResW-ARW-West + HiResWARWWest
7
0 255002 @@ -3608,7 +4234,7 @@ HiResW-ARW-AK - HiResW-ARW-AK + HiResWARWAK
7
0 255003 @@ -3620,7 +4246,7 @@ HiResW-ARW-PR - HiResW-ARW-PR + HiResWARWPR
7
0 255004 @@ -3632,7 +4258,7 @@ HiResW-ARW-HI - HiResW-ARW-HI + HiResWARWHI
7
0 255005 @@ -3642,6 +4268,30 @@
3
+ + NMM-GUAM + NMMGUAM +
7
+ 0 + 11731129 + + 112 + +
3
+
+ + + NMM-PR + NMMPR +
7
+ 0 + 13560489 + + 112 + +
3
+
+ HiResW-NMM-East EASTNMM @@ -3718,7 +4368,7 @@ CPCoutlook-Short - CPCoutlook-Short + CPCoutlookShort
7
0 197 @@ -3730,7 +4380,7 @@ CPCoutlook-Medium - CPCoutlook-Medium + CPCoutlookMedium
7
0 197 @@ -3742,7 +4392,7 @@ CPCoutlook-Short-AK - CPCoutlook-Short-AK + CPCoutlookShortAK
7
0 198 @@ -3754,7 +4404,7 @@ CPCoutlook-Medium-AK - CPCoutlook-Medium-AK + CPCoutlookMediumAK
7
0 198 @@ -3948,7 +4598,7 @@ FFG-TUA - FFG-TUA + FFGTUA
9
150 240150 @@ -3960,7 +4610,7 @@ FFG-ACR - FFG-ACR + FFGACR
9
151 240151 @@ -3972,7 +4622,7 @@ FFG-STR - FFG-STR + FFGSTR
9
152 240152 @@ -3984,7 +4634,7 @@ FFG-RSA - FFG-RSA + FFGRSA
9
153 240153 @@ -3996,7 +4646,7 @@ FFG-ORN - FFG-ORN + FFGORN
9
154 240154 @@ -4008,7 +4658,7 @@ FFG-RHA - FFG-RHA + FFGRHA
9
155 240155 @@ -4020,7 +4670,7 @@ FFG-KRF - FFG-KRF + FFGKRF
9
156 240156 @@ -4032,7 +4682,7 @@ FFG-MSR - FFG-MSR + FFGMSR
9
157 240157 @@ -4044,7 +4694,7 @@ FFG-TAR - FFG-TAR + FFGTAR
9
158 240158 @@ -4056,7 +4706,7 @@ FFG-PTR - FFG-PTR + FFGPTR
9
159 240159 @@ -4068,7 +4718,7 @@ FFG-TIR - FFG-TIR + FFGTIR
9
160 240160 @@ -4080,7 +4730,7 @@ FFG-ALR - FFG-ALR + FFGALR
9
161 240161 @@ -4092,7 +4742,7 @@ FFG-FWR - FFG-FWR + FFGFWR
9
162 240162 @@ -4165,8 +4815,8 @@
- NOGAPS - NOGAPS + NOGAPS - Ice Concentration Analysis + NOGAPSWAVE
58
20 218 @@ -4211,5 +4861,41 @@
8
- + + + CMC-HYCOM - North Pacific basin + CMC +
54
+ 0 + 374 + + 47 + +
3
+
+ + + CMC-QLM + CMCQLM +
54
+ 2 + -90045000 + + 70 + +
3
+
+ + + CMC-GEFS + CMCENS +
54
+ 2 + 401 + + 70 + +
3
+
+ diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/edex_static/base/ncgrib/tables/7/0/4.2.0.2.table b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/edex_static/base/ncgrib/tables/7/0/4.2.0.2.table index 9ecf2b4ebf..c7d9406d05 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/edex_static/base/ncgrib/tables/7/0/4.2.0.2.table +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/utility/edex_static/base/ncgrib/tables/7/0/4.2.0.2.table @@ -32,4 +32,5 @@ 221:221:Hourly Maximum of Downward Vertical Vorticity in the lowest 400hPa:m/s:MAXDVV 222:222:U Component of Hourly Maximum 10m Wind Speed:m/s:MAXUW 223:223:V Component of Hourly Maximum 10m Wind Speed:m/s:MAXVW +224:224:Ventilation Rate:m^2/s:VRATE 255:255:Missing diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/component-deploy.xml index 30469198f1..2042b653f3 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/package-info.java index df085bc36d..62235cfcd6 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscat/src/gov/noaa/nws/ncep/edex/plugin/ncscat/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.ncscat.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.ncscat.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/component-deploy.xml index 47c631d655..4d9fb5cb4f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextFileNameGenerator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextFileNameGenerator.java index 9ca37c5a27..c411b5bcfd 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextFileNameGenerator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextFileNameGenerator.java @@ -17,11 +17,11 @@ import java.io.LineNumberReader; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.GregorianCalendar; +//import java.util.Collections; +//import java.util.GregorianCalendar; import java.util.List; import java.util.Calendar; -import java.util.Date; +//import java.util.Date; import java.util.TimeZone; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,33 +36,27 @@ import com.raytheon.uf.common.dataplugin.PluginException; * Date Ticket Engineer Description * ------------ ---------- ----------- -------------------------- * 22-Jun-2010 191 Archana.S Initial Creation + * 21-Nov-2011 Chin Chen change code that will not to decode nctext unknown/unsupported products, clean up code as well * @author Archana * @version 1 */ public class NctextFileNameGenerator { private final SimpleDateFormat DATE_WITH_HOUR = new SimpleDateFormat("yyyyMMddHH"); //private final SimpleDateFormat DATE_WITHOUT_HOUR = new SimpleDateFormat("yyyyMMdd"); - private final int NUM_SECS_PER_DAY = 3600; - private final int NUM_LINES_IN_HEADER = 20; - - private final Calendar calendar; - private long currTimeInSec; - private int currentYear; - private int currentMonth; - private int currentDayofMonth; + private final int NUM_LINES_IN_HEADER = 10; - private Long timeStamp; - private Integer fileCreatedMonth; - private Integer fileCreatedYear; - private Integer fileCreatedDayOfMonth; - private Date fileCreatedDate; + //private Long timeStamp; + //private Integer fileCreatedMonth; + //private Integer fileCreatedYear; + //private Integer fileCreatedDayOfMonth; + //private Date fileCreatedDate; private Calendar fileCreatedCalendar; private List formattedFileNameList; private String pluginName; private Log logger = LogFactory.getLog(getClass()); - private String filePath; + //private String filePath; /** @@ -71,8 +65,6 @@ public class NctextFileNameGenerator { public NctextFileNameGenerator() { DATE_WITH_HOUR.setTimeZone( TimeZone.getTimeZone("GMT")); formattedFileNameList = new ArrayList(0); - calendar = Calendar.getInstance(); - //DATE_WITHOUT_HOUR.setTimeZone( TimeZone.getTimeZone("GMT")); } /*** @@ -91,72 +83,81 @@ public class NctextFileNameGenerator { * @throws IOException */ public synchronized PluginDataObject[] renameAndDecodeFile(File fileToRename) throws IOException{ - logger.debug("renameAndDecodeFile() called..."); + //logger.debug("renameAndDecodeFile() called..."); System.out.println("renameAndDecodeFile() invoked"); PluginDataObject[] srcArray = new PluginDataObject[0]; List dynamicDestArray = new ArrayList(0); this.formattedFileNameList = new ArrayList(0); String filePath = fileToRename.getAbsolutePath(); String fileHeader = this.readFileHeader(NUM_LINES_IN_HEADER,filePath); + //System.out.println("file header="+ fileHeader); String[] linesOfFileHeader = fileHeader.split(System.getProperty("line.separator")); if(linesOfFileHeader != null && linesOfFileHeader.length > 1){ -// System.out.println("Date of file creation: "+ this.fileCreatedCalendar.getTime().toString()); - int i=0; - while( i < linesOfFileHeader.length - 1){ - int j = i+1; - if(linesOfFileHeader[j].isEmpty()){ - j++; - } - String consecutive2Lines = new String(linesOfFileHeader[i] + linesOfFileHeader[j]); -// System.out.println(consecutive2Lines); - if( createFormattedFileName(consecutive2Lines, this.fileCreatedCalendar)){ -// System.out.println("The match was found at: "+ consecutive2Lines); -// System.out.println("The final list of formatted file names: "+ this.formattedFileNameList); - break; - } - i++; - } - } + // System.out.println("Date of file creation: "+ this.fileCreatedCalendar.getTime().toString()); + for(int k =0; k < linesOfFileHeader.length; k++){ + System.out.println("Line "+ k + " ="+ linesOfFileHeader[k]); + } + + int i=0; + while( i < linesOfFileHeader.length - 1){ + int j = i+1; + if(linesOfFileHeader[j].isEmpty()){ + j++; + } + //Chin: add \n to separate the 2 lines to make regular expression work "correctly" on those products with + //product type coded at 2nd line + String consecutive2Lines = new String(linesOfFileHeader[i]+"\n" +linesOfFileHeader[j]); + // System.out.println(consecutive2Lines); + if( createFormattedFileName(consecutive2Lines, this.fileCreatedCalendar)){ + // System.out.println("The match was found at: "+ consecutive2Lines); + // System.out.println("The final list of formatted file names: "+ this.formattedFileNameList); + break; + } + i++; + } + + } List pdoList = new ArrayList(0); if (this.formattedFileNameList.size() > 0) { -// System.out.println("The final list of formatted file names: "+ this.formattedFileNameList); + // System.out.println("The final list of formatted file names: "+ this.formattedFileNameList); boolean isFileRenamedInPostProcess = false; - + for(int p =0; p < formattedFileNameList.size(); p++){ + System.out.println("File name "+p+ " ="+formattedFileNameList.get(p)); + } int index = 0; int listSize = this.formattedFileNameList.size(); while(index < listSize && !isFileRenamedInPostProcess){ String outFilePath = this.formattedFileNameList.get(index); - logger.debug("New name for file: "+ outFilePath); - /* - * OMR and cgr files have similar regular expressions, hence the same raw data could be decoded as either product. - * OMR files have the words "OTHER MARINE REPORTS" placed either in the file header or the file body, - * while cgr (coast guard report) files lack this feature. - * Hence if either one of these extensions are encountered, the entire file is read to check if it contains the - * words "OTHER MARINE REPORTS" - */ - if( outFilePath.endsWith(".cgr") || outFilePath.endsWith(".OMR") + //logger.debug("New name for file: "+ outFilePath); + /* + * OMR and cgr files have similar regular expressions, hence the same raw data could be decoded as either product. + * OMR files have the words "OTHER MARINE REPORTS" placed either in the file header or the file body, + * while cgr (coast guard report) files lack this feature. + * Hence if either one of these extensions are encountered, the entire file is read to check if it contains the + * words "OTHER MARINE REPORTS" + */ + if( outFilePath.endsWith(".cgr") || outFilePath.endsWith(".OMR") - ) { - outFilePath = new String(outFilePath.substring(0, 11) + getFileNameAfterPostProcess(fileToRename, outFilePath)); - isFileRenamedInPostProcess = true; - } - - System.out.println("New name for file: "+ outFilePath); - srcArray = decodeFile(fileToRename, outFilePath); - pdoList = new ArrayList(Arrays.asList(srcArray)); - dynamicDestArray.addAll(pdoList); - index++; - } - + ) { + outFilePath = new String(outFilePath.substring(0, 11) + getFileNameAfterPostProcess(fileToRename, outFilePath)); + isFileRenamedInPostProcess = true; + } + System.out.println("New name for file: "+ outFilePath); + srcArray = decodeFile(fileToRename, outFilePath); + pdoList = new ArrayList(Arrays.asList(srcArray)); + dynamicDestArray.addAll(pdoList); + index++; + } }else{ - System.out.println("No match found with any regular expression- using default file name to decode "+ fileToRename.getName()); - srcArray = decodeFile(fileToRename, fileToRename.getName()); - pdoList = new ArrayList(Arrays.asList(srcArray)); - dynamicDestArray.addAll(pdoList); + System.out.println("No match found with any regular expression- file= "+ fileToRename.getName()); + //Chin:TESTING + //srcArray = decodeFile(fileToRename, fileToRename.getName()); + // pdoList = new ArrayList(Arrays.asList(srcArray)); + //dynamicDestArray.addAll(pdoList); } -// System.out.println("The final array length : " + dynamicDestArray.size()); + System.out.println("The final array length : " + dynamicDestArray.size()); PluginDataObject[] returnArray = new PluginDataObject[0]; return dynamicDestArray.toArray(returnArray); @@ -214,7 +215,7 @@ public class NctextFileNameGenerator { */ private synchronized PluginDataObject[] decodeFile(File fileToDecode, String derivedFileName){ try { - System.out.println("decodeFile() entered..."); + //System.out.println("decodeFile() entered..."); return (new NctextDecoder().decodeTextInputFileWithName(fileToDecode, derivedFileName)); } catch (DecoderException e) { @@ -243,7 +244,6 @@ public class NctextFileNameGenerator { */ private synchronized boolean createFormattedFileName(String fileContent, Calendar productCreationDateCalendar){ - if(NctextRegexMatcher.matchFileRegex(fileContent)){ // System.out.println("productCreationDateCalendar= "+ productCreationDateCalendar.getTime().toString()); List nctextProductTypeList = new ArrayList( NctextRegexMatcher.getProductType()); @@ -267,8 +267,8 @@ public class NctextFileNameGenerator { tempCal.clear(Calendar.MONTH); tempCal.set(Calendar.MONTH, productCreationDateCalendar.get(Calendar.MONTH)); - long derivedTime = tempCal.getTimeInMillis()/1000; - long fileCreatedTime = productCreationDateCalendar.getTimeInMillis()/1000; + //long derivedTime = tempCal.getTimeInMillis()/1000; + //long fileCreatedTime = productCreationDateCalendar.getTimeInMillis()/1000; // System.out.println("File created time in seconds = "+ fileCreatedTime); // System.out.println("File derived time after updating tempCal = "+ derivedTime); @@ -288,53 +288,26 @@ public class NctextFileNameGenerator { } - /** - * Provides the list of filenames formatted as yyyymmddhh.proudctType - * @return the formattedFileNameList if it has atleast one element or an empty list otherwise - */ - private List getFormattedFileName() { - if(this.formattedFileNameList.size() > 0){ - return new ArrayList(formattedFileNameList); - }else{ - return Collections.emptyList(); - } - - } - - /** - * @return the fileCreatedYear - */ - private Integer getFileCreatedYear() { - return fileCreatedYear; - } - /** * @param fileCreatedYear the fileCreatedYear to set */ - private void setFileCreatedYear(Integer fileCreatedYear) { - this.fileCreatedYear = fileCreatedYear; - } - - /** - * @return the fileCreatedDayOfMonth - */ - private Integer getFileCreatedDayOfMonth() { - return fileCreatedDayOfMonth; - } + //private void setFileCreatedYear(Integer fileCreatedYear) { + // this.fileCreatedYear = fileCreatedYear; + //} /** * @param fileCreatedDayOfMonth the fileCreatedDayOfMonth to set */ - private void setFileCreatedDayOfMonth(Integer fileCreatedDayOfMonth) { - this.fileCreatedDayOfMonth = fileCreatedDayOfMonth; - } + //private void setFileCreatedDayOfMonth(Integer fileCreatedDayOfMonth) { + // this.fileCreatedDayOfMonth = fileCreatedDayOfMonth; + //} /** * @param fileCreatedMonth the fileCreatedMonth to set */ - private void setFileCreatedMonth(Integer fileCreatedMonth) { - this.fileCreatedMonth = fileCreatedMonth; - } + //private void setFileCreatedMonth(Integer fileCreatedMonth) { + // this.fileCreatedMonth = fileCreatedMonth; + //} /** * Reads a fixed number of lines from a file into a String @@ -421,25 +394,25 @@ public class NctextFileNameGenerator { setFileCreatedCalendar(Calendar.getInstance()); getFileCreatedCalendar().setTimeZone(TimeZone.getTimeZone("GMT")); getFileCreatedCalendar().setTimeInMillis(theFileTimeStamp); - setFileCreatedDate(new Date(theFileTimeStamp)); - setFileCreatedDayOfMonth( new Integer (getFileCreatedCalendar().get(Calendar.DAY_OF_MONTH))); - setFileCreatedMonth( new Integer (getFileCreatedCalendar().get(Calendar.MONTH))); - setFileCreatedYear( new Integer (getFileCreatedCalendar().get(Calendar.YEAR))); + //setFileCreatedDate(new Date(theFileTimeStamp)); + //setFileCreatedDayOfMonth( new Integer (getFileCreatedCalendar().get(Calendar.DAY_OF_MONTH))); + //setFileCreatedMonth( new Integer (getFileCreatedCalendar().get(Calendar.MONTH))); + //setFileCreatedYear( new Integer (getFileCreatedCalendar().get(Calendar.YEAR))); } /** * @return the fileCreatedDate */ - private Date getFileCreatedDate() { - return fileCreatedDate; - } + //private Date getFileCreatedDate() { + // return fileCreatedDate; + //} /** * @param fileCreatedDate the fileCreatedDate to set */ - private void setFileCreatedDate(Date fileCreatedDate) { - this.fileCreatedDate = fileCreatedDate; - } + //private void setFileCreatedDate(Date fileCreatedDate) { + // this.fileCreatedDate = fileCreatedDate; + //} /** * @return the fileCreatedCalendar @@ -458,16 +431,16 @@ public class NctextFileNameGenerator { /** * @return the timeStamp */ - private Long getTimeStamp() { - return timeStamp; - } + //private Long getTimeStamp() { + // return timeStamp; + //} /** * @param timeStamp the timeStamp to set */ - private void setTimeStamp(Long timeStamp) { - this.timeStamp = timeStamp; - } + //private void setTimeStamp(Long timeStamp) { + // this.timeStamp = timeStamp; + //} /** * @return the pluginName diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextRegexMatcher.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextRegexMatcher.java index 3e5a31e112..675f123bfe 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextRegexMatcher.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextRegexMatcher.java @@ -27,6 +27,7 @@ import java.util.regex.Pattern; * ------------ ---------- ----------- -------------------------- * 06-Jul-2010 191 Archana.S Initial Creation * 18-Aug-2010 191 Archana .S Minor update in regex for vlcw +* 21-Nov-2011 Chin Chen update and re-organize regex to fix several product type decoding errors * * @author Archana * @version 1 @@ -88,8 +89,8 @@ public final class NctextRegexMatcher { if(!isNctextProductAlreadyInList(prodType)){ //add it to the list strNctextProductType.add(prodType); -// System.out.println("Product type is " + prodType); -// System.out.println("Matching pattern is: " + thisPattern.pattern()); + System.out.println("Product type is " + prodType); + System.out.println("Matching pattern is: " + thisPattern.pattern()); } if(thisMatcher.groupCount() > 1){ @@ -141,162 +142,159 @@ public final class NctextRegexMatcher { // and the code will crash when it tries to extract a digit from the captured regular expression groups // thisMap.put(Pattern.compile("(^S[IM]V[IGNS])|(^SNV[INS])|(^S[IMN](W[KZ]|[^VW]))"), "syn"); - - thisMap.put(Pattern.compile("^FXCA62 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); - thisMap.put(Pattern.compile("^WWUS30 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"wtch2"); - thisMap.put(Pattern.compile("^FNUS21 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"fwddy1"); - thisMap.put(Pattern.compile("^FNUS22 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"fwddy2"); - thisMap.put(Pattern.compile("^WOUS64 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "wou"); - thisMap.put(Pattern.compile("^ABNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "outlk"); //clashes with TWO - thisMap.put(Pattern.compile("^ACPN50 PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "outlk"); - thisMap.put(Pattern.compile("^ABPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "outlk"); - thisMap.put(Pattern.compile("^ABCA33 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "outlk"); - thisMap.put(Pattern.compile("^WTNT4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "disc"); - thisMap.put(Pattern.compile("^WTPA4[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "disc"); - thisMap.put(Pattern.compile("^WTPZ4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "disc"); - thisMap.put(Pattern.compile("^WONT41 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "disc"); - thisMap.put(Pattern.compile("^WTNT3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTNT3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTPZ3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTPZ3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTCA4[1-5] TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WHCA31 TFFF (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTPN2[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pblc"); - thisMap.put(Pattern.compile("^WTNT2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mar"); - thisMap.put(Pattern.compile("^WTPA2[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mar"); - thisMap.put(Pattern.compile("^WTPZ2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mar"); - thisMap.put(Pattern.compile("^W[H|T]PS01 NFFN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mar"); - thisMap.put(Pattern.compile("^WTPN3[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mar"); - thisMap.put(Pattern.compile("^URNT12 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "rcn"); -// thisMap.put(Pattern.compile("^U[RZ]NT14 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "rcn");//no test data - thisMap.put(Pattern.compile("^AXPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "tdsc"); //clashes with TWD - thisMap.put(Pattern.compile("^AXNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "tdsc"); //clashes with TWD - thisMap.put(Pattern.compile("^WTNT7[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "strk"); - thisMap.put(Pattern.compile("^NOUS42 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pod"); //no regex for aasdl and pasdl - thisMap.put(Pattern.compile("^WWJP25 RJTD (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HSF.*"), "HSF"); - thisMap.put(Pattern.compile("^WCPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "conv"); - thisMap.put(Pattern.compile("^WSUS3[1-3] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "conv"); - thisMap.put(Pattern.compile("^W[CSV][NT|PN|PA|AK][01][0-9] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "intl"); - thisMap.put(Pattern.compile("^W[CSV][NT|PN|PA|AK][01][0-9] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "intl"); - thisMap.put(Pattern.compile("^W[CSV][NT|PN|PA|AK][01][0-9] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "intl"); - thisMap.put(Pattern.compile("^W[CSV]US0[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*"), "sgmt"); - thisMap.put(Pattern.compile("^WAUS4[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); - thisMap.put(Pattern.compile("^WAAK4[7-9] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); - thisMap.put(Pattern.compile("^FAAK2[1-6] KZAN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cwa"); - thisMap.put(Pattern.compile("^FAUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cwa"); - thisMap.put(Pattern.compile("^WCUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cwa"); - thisMap.put(Pattern.compile("^FAUS20 PANC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mis"); - thisMap.put(Pattern.compile("^FOUS14 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmmos"); - thisMap.put(Pattern.compile("^FOAK2[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmmos"); - thisMap.put(Pattern.compile("^FOPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsmos"); - thisMap.put(Pattern.compile("^FOUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsmos"); - thisMap.put(Pattern.compile("^FOAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsmos"); - thisMap.put(Pattern.compile("^FEPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsxmos"); - thisMap.put(Pattern.compile("^FEUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsxmos"); - thisMap.put(Pattern.compile("^FEAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsxmos"); - thisMap.put(Pattern.compile("^FECN21 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "gfsxmos"); - thisMap.put(Pattern.compile("^FOUS4[4-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "etamos"); - thisMap.put(Pattern.compile("^FQUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MMG.*"), "marnmos"); - thisMap.put(Pattern.compile("^FOUE6[0-4] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUE80 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUM6[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUM7[01] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUM8[124] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUS8[6-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUS90 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUW7[238] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUW83 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOHW50 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOCA5[12] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOCN7[456] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOGX77 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ngmgd"); - thisMap.put(Pattern.compile("^FOUS6[0-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "etagd"); - thisMap.put(Pattern.compile("^FOUS7[0-8] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "etagd"); - thisMap.put(Pattern.compile("^FXUS02 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDEPD.*"), "PMDEPD"); - thisMap.put(Pattern.compile("^FXUS02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PREEPD.*"), "PREEPD"); - thisMap.put(Pattern.compile("^FXUS01 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDSPD.*"), "PMDSPD"); - thisMap.put(Pattern.compile("^FXHW01 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDHI.*"), "PMDHI"); - thisMap.put(Pattern.compile("^FXSA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDSA.*"), "PMDSA"); - thisMap.put(Pattern.compile("^FXCA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDCA.*"), "PMDCA"); - thisMap.put(Pattern.compile("^FXAK02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDAK.*"), "PMDAK"); - thisMap.put(Pattern.compile("^NOUS42 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "sdm"); - thisMap.put(Pattern.compile("^NOUS42 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "sdm"); - thisMap.put(Pattern.compile("^NPXX10 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "intl"); - thisMap.put(Pattern.compile("^NPXX10 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "intl"); - thisMap.put(Pattern.compile("^FXUS10 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "PMDHMD"); - thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HI.*"), "hmean"); - thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HH.*"), "hmax"); - thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HL.*"), "hmin"); - thisMap.put(Pattern.compile("^FXUS06 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "n610"); - thisMap.put(Pattern.compile("^FEUS40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "f610"); //no data to test - thisMap.put(Pattern.compile("^FXUS07 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "n30"); - thisMap.put(Pattern.compile("^FXUS05 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "n90"); - thisMap.put(Pattern.compile("^FXHW40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "hawaii"); //hawaii instead of h3090 - thisMap.put(Pattern.compile("^FXUS21 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "PMDTHR"); - thisMap.put(Pattern.compile("^FXUS25 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "drought"); - thisMap.put(Pattern.compile("^FVAK2[1-5] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "volc"); - thisMap.put(Pattern.compile("^WUUS48 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "ptsd48"); - thisMap.put(Pattern.compile("^FAUS20 KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mis"); - thisMap.put(Pattern.compile("^FXUS6[1-6] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); - thisMap.put(Pattern.compile("^FXUS7[1-6] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); -// thisMap.put(Pattern.compile("^FPAK20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area");//no data to test -// thisMap.put(Pattern.compile("^FPHW03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area");//no data to test - thisMap.put(Pattern.compile("^FXHW60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); //derived from FX(HW|PN|PS)60 - thisMap.put(Pattern.compile("^FXPN60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); //derived from FX(HW|PN|PS)60 - thisMap.put(Pattern.compile("^FXPS60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "area"); //derived from FX(HW|PN|PS)60 -// thisMap.put(Pattern.compile("^FANT02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "offsh"); //no raw data at all!! - thisMap.put(Pattern.compile("^WSUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "sgmt"); //no data to test - thisMap.put(Pattern.compile("^WAHW[03]1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); -// thisMap.put(Pattern.compile("^WAUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); //no data to test - thisMap.put(Pattern.compile("^WAUS1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); //no data to test -// thisMap.put(Pattern.compile("^WAAK01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "airm"); //no data to test - thisMap.put(Pattern.compile("^WOUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "stat"); - thisMap.put(Pattern.compile("^FVXX2[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "volc"); - thisMap.put(Pattern.compile("^FVCN0[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "volc"); - thisMap.put(Pattern.compile("^FVAU0[2-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "volc"); - thisMap.put(Pattern.compile("^ACUS4[1-5] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "storm"); - thisMap.put(Pattern.compile("^FSUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "srp"); - thisMap.put(Pattern.compile("^ASUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "sus"); -// thisMap.put(Pattern.compile("^FXPA00 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "expac"); //no folder for raw data in server - thisMap.put(Pattern.compile("^FVXX2[0-7] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "vlcf"); //clashes with volc FVXX2[0-4] - thisMap.put(Pattern.compile("^ACUS48 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "day48"); - thisMap.put(Pattern.compile("^FNUS31 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWFD1.*"), "pfwfd1"); - thisMap.put(Pattern.compile("^FNUS32 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWFD2.*"), "pfwfd2"); - thisMap.put(Pattern.compile("^FNUS38 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWF38.*"), "pfwf38"); - thisMap.put(Pattern.compile("^NOUS6. .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FTM.*"), "ftm"); - thisMap.put(Pattern.compile("^WFCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "tornado"); - thisMap.put(Pattern.compile("^WUCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "severe"); - thisMap.put(Pattern.compile("^WOCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "sps"); - thisMap.put(Pattern.compile("^WWCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "warwatch"); - thisMap.put(Pattern.compile("^WWCN3[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "warnsumm"); - thisMap.put(Pattern.compile("^FOCN45 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "coutlook"); - thisMap.put(Pattern.compile("^ACUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "day1"); - thisMap.put(Pattern.compile("^ACUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "day2"); - thisMap.put(Pattern.compile("^ACUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "day3"); - thisMap.put(Pattern.compile("^WWUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"ptsdy1"); //no data to test - thisMap.put(Pattern.compile("^WWUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"ptsdy2");//no data to test - thisMap.put(Pattern.compile("^WWUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"ptsdy3");//no data to test - thisMap.put(Pattern.compile("^WWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"watch"); - thisMap.put(Pattern.compile("^WWUS50 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SEV[0-9].*"),"sev"); - thisMap.put(Pattern.compile("^WWUS60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SEVSPC.*"),"sevmkc"); - thisMap.put(Pattern.compile("^WOUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"public"); - thisMap.put(Pattern.compile("^NWUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*STAHRY.*"),"hry"); - thisMap.put(Pattern.compile("^ACUS11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"meso"); - thisMap.put(Pattern.compile("^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*STADTS"),"dts"); - thisMap.put(Pattern.compile("^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"),"svr"); - thisMap.put(Pattern.compile("^FNUS21 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWDDY1.*"),"fire1"); //spc uses this regex for fwddy1 also - thisMap.put(Pattern.compile("^FNUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWDDY2.*"),"fire2"); //spc uses this regex for fwddy2 also -// thisMap.put(Pattern.compile("^WHXX9[09] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mdl"); // not sure if this regex is correct - no test data to verify - thisMap.put(Pattern.compile("^WHXX0[1-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "mdl"); - thisMap.put(Pattern.compile("^URNT10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "antreco"); - thisMap.put(Pattern.compile("^URNT11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "areco"); - thisMap.put(Pattern.compile("^URNT12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "avortex"); - thisMap.put(Pattern.compile("^URNT14 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "asupvort"); - thisMap.put(Pattern.compile("^UZNT13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "adrops"); - thisMap.put(Pattern.compile("^URPN10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pntreco"); //no data to test - thisMap.put(Pattern.compile("^URPN11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "preco");//no data to test - thisMap.put(Pattern.compile("^URPN12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pvortex");//no data to test + + //Chin: add \n to separate the 2 lines to make regular expression work "correctly" on those products with + //product type coded at 2nd line + thisMap.put(Pattern.compile("^FXCA62 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "area"); + thisMap.put(Pattern.compile("^FXUS[67][1-6] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "area"); + thisMap.put(Pattern.compile("^FPAK20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "area");//no data to test + thisMap.put(Pattern.compile("^FPHW03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "area");//no data to test + thisMap.put(Pattern.compile("^FX(HW|PN|PS)60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "area"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)FA[0-9].*"), "area"); //aviation forecasts + thisMap.put(Pattern.compile("^WWUS30 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"wtch2"); + thisMap.put(Pattern.compile("^FNUS21 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"fwddy1"); + thisMap.put(Pattern.compile("^FNUS22 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"fwddy2"); + thisMap.put(Pattern.compile("^WOUS64 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "wou"); + thisMap.put(Pattern.compile("^ABNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "outlk"); //clashes with TWO + thisMap.put(Pattern.compile("^ACPN50 PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "outlk"); + thisMap.put(Pattern.compile("^ABPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "outlk"); + thisMap.put(Pattern.compile("^ABCA33 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "outlk"); + thisMap.put(Pattern.compile("^WTNT4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "disc"); + thisMap.put(Pattern.compile("^WTPA4[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "disc"); + thisMap.put(Pattern.compile("^WTPZ4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "disc"); + thisMap.put(Pattern.compile("^WONT41 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "disc"); + thisMap.put(Pattern.compile("^WTNT3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTNT3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTPZ3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTPZ3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTCA4[1-5] TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WHCA31 TFFF (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTPN2[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pblc"); + thisMap.put(Pattern.compile("^WTNT2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mar"); + thisMap.put(Pattern.compile("^WTPA2[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mar"); + thisMap.put(Pattern.compile("^WTPZ2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mar"); + thisMap.put(Pattern.compile("^W[H|T]PS01 NFFN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mar"); + thisMap.put(Pattern.compile("^WTPN3[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mar"); + thisMap.put(Pattern.compile("^URNT12 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "rcn"); + thisMap.put(Pattern.compile("^U[RZ]NT14 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "rcn");//no test data + thisMap.put(Pattern.compile("^AXPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "tdsc"); //clashes with TWD + thisMap.put(Pattern.compile("^AXNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "tdsc"); //clashes with TWD + thisMap.put(Pattern.compile("^WTNT7[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "strk"); + thisMap.put(Pattern.compile("^NOUS42 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pod"); //no regex for aasdl and pasdl + thisMap.put(Pattern.compile("^WWJP25 RJTD (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "HSF"); + thisMap.put(Pattern.compile("^WCPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "conv"); + thisMap.put(Pattern.compile("^WSUS3[1-3] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "conv"); + thisMap.put(Pattern.compile("^WAUS4[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); + thisMap.put(Pattern.compile("^WAAK4[7-9] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); + thisMap.put(Pattern.compile("^FAAK2[1-6] KZAN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cwa"); + thisMap.put(Pattern.compile("^FAUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cwa"); + thisMap.put(Pattern.compile("^WCUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cwa"); + thisMap.put(Pattern.compile("^FAUS20 (KZ..|PANC) (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mis"); + thisMap.put(Pattern.compile("^FOUS14 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmmos"); + thisMap.put(Pattern.compile("^FOAK2[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmmos"); + thisMap.put(Pattern.compile("^FOPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsmos"); + thisMap.put(Pattern.compile("^FOUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsmos"); + thisMap.put(Pattern.compile("^FOAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsmos"); + thisMap.put(Pattern.compile("^FEPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsxmos"); + thisMap.put(Pattern.compile("^FEUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsxmos"); + thisMap.put(Pattern.compile("^FEAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsxmos"); + thisMap.put(Pattern.compile("^FECN21 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "gfsxmos"); + thisMap.put(Pattern.compile("^FOUS4[4-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "etamos"); + thisMap.put(Pattern.compile("^FQUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)MMG.*"), "marnmos"); + thisMap.put(Pattern.compile("^FQAK37 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)MMG.*"), "marnmos"); + thisMap.put(Pattern.compile("^FQPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)MMG.*"), "marnmos"); + thisMap.put(Pattern.compile("^FOUE6[0-4] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUE80 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUM6[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUM7[01] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUM8[124] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUS8[6-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUS90 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUW7[238] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUW83 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOHW50 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOCA5[12] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOCN7[456] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOGX77 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ngmgd"); + thisMap.put(Pattern.compile("^FOUS6[0-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "etagd"); + thisMap.put(Pattern.compile("^FOUS7[0-8] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "etagd"); + thisMap.put(Pattern.compile("^FXUS02 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDEPD.*"), "PMDEPD"); + thisMap.put(Pattern.compile("^FXUS02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PREEPD.*"), "PREEPD"); + thisMap.put(Pattern.compile("^FXUS01 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDSPD.*"), "PMDSPD"); + thisMap.put(Pattern.compile("^FXHW01 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDHI.*"), "PMDHI"); + thisMap.put(Pattern.compile("^FXSA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDSA.*"), "PMDSA"); + thisMap.put(Pattern.compile("^FXCA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDCA.*"), "PMDCA"); + thisMap.put(Pattern.compile("^FXAK02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PMDAK.*"), "PMDAK"); + thisMap.put(Pattern.compile("^NOUS42 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sdm"); + thisMap.put(Pattern.compile("^NOUS42 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sdm"); + thisMap.put(Pattern.compile("^NPXX10 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "intl"); + thisMap.put(Pattern.compile("^NPXX10 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "intl"); + thisMap.put(Pattern.compile("^FXUS10 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "PMDHMD"); + thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PRB[EW]HI.*"), "hmean"); + thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PRB[EW]HH.*"), "hmax"); + thisMap.put(Pattern.compile("^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PRB[EW]HL.*"), "hmin"); + thisMap.put(Pattern.compile("^FXUS06 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "n610"); + thisMap.put(Pattern.compile("^FEUS40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "f610"); //no data to test + thisMap.put(Pattern.compile("^FXUS07 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "n30"); + thisMap.put(Pattern.compile("^FXUS05 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "n90"); + thisMap.put(Pattern.compile("^FXHW40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "hawaii"); //hawaii instead of h3090 + thisMap.put(Pattern.compile("^FXUS21 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "PMDTHR"); + thisMap.put(Pattern.compile("^FXUS25 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "drought"); + thisMap.put(Pattern.compile("^FVAK2[1-5] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "volc"); + thisMap.put(Pattern.compile("^WUUS48 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "ptsd48"); + thisMap.put(Pattern.compile("^FAUS20 KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mis"); + thisMap.put(Pattern.compile("^FANT02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "offsh"); //no raw data at all!! + //thisMap.put(Pattern.compile("^WSUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sgmt"); //no data to test + thisMap.put(Pattern.compile("^WAHW[03]1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); + thisMap.put(Pattern.compile("^WAUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); //no data to test + thisMap.put(Pattern.compile("^WAUS1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); //no data to test + thisMap.put(Pattern.compile("^WAAK01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "airm"); //no data to test + thisMap.put(Pattern.compile("^WOUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "stat"); + thisMap.put(Pattern.compile("^FVXX2[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "volc"); + thisMap.put(Pattern.compile("^FVCN0[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "volc"); + thisMap.put(Pattern.compile("^FVAU0[2-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "volc"); + thisMap.put(Pattern.compile("^ACUS4[1-5] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "storm"); + thisMap.put(Pattern.compile("^FSUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "srp"); + thisMap.put(Pattern.compile("^ASUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sus"); + thisMap.put(Pattern.compile("^FXPA00 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "expac"); //no folder for raw data in server + thisMap.put(Pattern.compile("^FVXX2[0-7] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "vlcf"); //clashes with volc FVXX2[0-4] + thisMap.put(Pattern.compile("^ACUS48 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "day48"); + thisMap.put(Pattern.compile("^FNUS31 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PFWFD1.*"), "pfwfd1"); + thisMap.put(Pattern.compile("^FNUS32 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PFWFD2.*"), "pfwfd2"); + thisMap.put(Pattern.compile("^FNUS38 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)PFWF38.*"), "pfwf38"); + thisMap.put(Pattern.compile("^WFCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "tornado"); + thisMap.put(Pattern.compile("^WUCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "severe"); + thisMap.put(Pattern.compile("^WOCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sps"); + thisMap.put(Pattern.compile("^WWCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "warwatch"); + thisMap.put(Pattern.compile("^WWCN3[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "warnsumm"); + thisMap.put(Pattern.compile("^FOCN45 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "coutlook"); + thisMap.put(Pattern.compile("^ACUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "day1"); + thisMap.put(Pattern.compile("^ACUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "day2"); + thisMap.put(Pattern.compile("^ACUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "day3"); + thisMap.put(Pattern.compile("^WWUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"ptsdy1"); //no data to test + thisMap.put(Pattern.compile("^WWUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"ptsdy2");//no data to test + thisMap.put(Pattern.compile("^WWUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"ptsdy3");//no data to test + thisMap.put(Pattern.compile("^WWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"watch"); + thisMap.put(Pattern.compile("^WWUS50 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)SEV[0-9].*"),"sev"); + thisMap.put(Pattern.compile("^WWUS60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)SEVSPC.*"),"sevmkc"); + thisMap.put(Pattern.compile("^WOUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"public"); + thisMap.put(Pattern.compile("^NWUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)STAHRY.*"),"hry"); + thisMap.put(Pattern.compile("^ACUS11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"meso"); + thisMap.put(Pattern.compile("^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)STADTS"),"dts"); + thisMap.put(Pattern.compile("^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"),"svr"); + thisMap.put(Pattern.compile("^FNUS21 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)FWDDY1.*"),"fire1"); //spc uses this regex for fwddy1 also + thisMap.put(Pattern.compile("^FNUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)FWDDY2.*"),"fire2"); //spc uses this regex for fwddy2 also + thisMap.put(Pattern.compile("^WHXX9[09] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mdl"); // not sure if this regex is correct - no test data to verify + thisMap.put(Pattern.compile("^WHXX0[1-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "mdl"); + thisMap.put(Pattern.compile("^URNT10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "antreco"); + thisMap.put(Pattern.compile("^URNT11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "areco"); + thisMap.put(Pattern.compile("^URNT12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "avortex"); + thisMap.put(Pattern.compile("^URNT14 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "asupvort"); + thisMap.put(Pattern.compile("^UZNT13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "adrops"); + thisMap.put(Pattern.compile("^URPN10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pntreco"); //no data to test + thisMap.put(Pattern.compile("^URPN11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "preco");//no data to test + thisMap.put(Pattern.compile("^URPN12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pvortex");//no data to test // thisMap.put(Pattern.compile("^URNT15 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "North Atlantic High Density Observations"); // thisMap.put(Pattern.compile("^URPA15 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "North West Pacific High Density Observations"); // thisMap.put(Pattern.compile("^URPA11 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "North West Pacific Reco Observation"); @@ -304,100 +302,102 @@ public final class NctextRegexMatcher { // thisMap.put(Pattern.compile("^URPA10 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "North West Pacific Reco Observation non-tropical"); // thisMap.put(Pattern.compile("^URPN15 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "North East and Central Pacific High Density Observations"); - thisMap.put(Pattern.compile("^UZPN13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "pdrops");//no data to test - thisMap.put(Pattern.compile("^UZPA13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "wpdrops");//no data to test - thisMap.put(Pattern.compile("^TXUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "satest"); - thisMap.put(Pattern.compile("^SXUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cgr"); - thisMap.put(Pattern.compile("^SXUS08 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cgr"); - thisMap.put(Pattern.compile("^SXUS86 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "cgr");//regexes clash for cgr and OMR - thisMap.put(Pattern.compile("^WV.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*"), "vlcw"); //might clash with regex for inl and sgmt - thisMap.put(Pattern.compile("^W[CSV].... [^KP]... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*"), "intl"); //regexes clash for intl and sgmt - thisMap.put(Pattern.compile("^WSUS4[012] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "conv"); - thisMap.put(Pattern.compile("^WSUK.. .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*"), "sgmt"); - thisMap.put(Pattern.compile("^WS[^U]... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*"), "sgmt"); //regexes clash for intl and sgmt - thisMap.put(Pattern.compile("^FT.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+"), "fts"); - thisMap.put(Pattern.compile("^...... KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HSF.*"), "HSF"); //conflicts with FLN - thisMap.put(Pattern.compile("^...... PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HSF.*"), "HSF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AGO.*"), "AGO"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FZL.*"), "FZL"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AFD.*"), "AFD"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SFP.*"), "SFP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*ZFP.*"), "ZFP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*LFP.*"), "LFP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CCF.*"), "CCF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RDF.*"), "RDF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFM.*"), "PFM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AFM.*"), "AFM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SFT.*"), "SFT"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RTP.*"), "RTP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CLI.*"), "CLI"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CLM.*"), "CLM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*LSR.*"), "LSR"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RER.*"), "RER"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*NOW.*"), "NOW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PNS.*"),"PNS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HWO.*"),"HWO"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RWR.*"),"RWR"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MIS.*"),"MIS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*ADA.*"),"ADA"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SVR.*"),"SVR"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TOR.*"),"TOR"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RWS.*"),"RWS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*WSW.*"),"WSW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SPS.*"),"SPS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SVS.*"),"SVS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SLS.*"),"SLS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*WCN.*"),"WCN"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*NPW.*"),"NPW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HLS.*"),"HLS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFG.*"), "FFG"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFA.*"), "FFA"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFW.*"), "FFW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFS.*"), "FFS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLS.*"), "FLS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLW.*"), "FLW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLN.*"), "FLN"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RVS.*"), "RVS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR1.*"), "RR1"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR2.*"), "RR2"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR3.*"), "RR3"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR4.*"), "RR4"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR5.*"), "RR5"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR6.*"), "RR6"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR7.*"), "RR7"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR8.*"), "RR8"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR9.*"), "RR9"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RRA.*"), "RRA"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RRM.*"), "RRM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CWF.*"), "CWF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*OFF.*"), "OFF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PLS.*"), "PLS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*OMR.*"), "OMR"); //regexes clash for cgr and OMR - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SMW.*"), "SMW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CFW.*"), "CFW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MWS.*"), "MWS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MRP.*"), "MRP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MIM.*"), "MIM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FA[0-9].*"), "area"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TAV.*"), "TAV"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SCS.*"), "SCS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWO.*"), "TWO"); //clashes with outlk - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWS.*"), "TWS"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWD.*"), "TWD"); //clashes with tdsc - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCM.*"), "TCM"); //clashes with mar - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCP.*"), "TCP"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCD.*"), "TCD"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCE.*"), "TCE"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCU.*"), "TCU"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*DSA.*"), "DSA"); //clashes with disc - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RFW.*"), "RFW"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWF.*"), "FWF"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWM.*"), "FWM"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RFD.*"), "RFD"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*UVI.*"), "UVI"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFPFD.*"), "QPFPFD"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFERD.*"), "QPFERD"); - thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFHSD.*"), "QPFHSD"); + thisMap.put(Pattern.compile("^UZPN13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "pdrops");//no data to test + thisMap.put(Pattern.compile("^UZPA13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "wpdrops");//no data to test + thisMap.put(Pattern.compile("^TXUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "satest"); + thisMap.put(Pattern.compile("^SXUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cgr"); + thisMap.put(Pattern.compile("^SXUS08 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cgr"); + thisMap.put(Pattern.compile("^SXUS86 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "cgr");//regexes clash for cgr and OMR + thisMap.put(Pattern.compile("^WV.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "vlcw"); //might clash with regex for inl and sgmt + thisMap.put(Pattern.compile("^W[CSV].... [^KP]... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "intl"); //regexes clash for intl and sgmt + thisMap.put(Pattern.compile("^W[CSV](NT|PN|PA|AK)[01][0-9] (KKCI|PHFO|PAWU) (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "intl"); //regexes clash for intl and sgmt + thisMap.put(Pattern.compile("^WSUS4[012] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "conv"); + thisMap.put(Pattern.compile("^W[CSV]US0[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sgmt"); + thisMap.put(Pattern.compile("^WSUK.. .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sgmt"); + thisMap.put(Pattern.compile("^WS[^U]... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "sgmt"); //regexes clash for intl and sgmt + thisMap.put(Pattern.compile("^FT.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9])(.|\r|\n)+"), "fts"); //aviation TAFS + thisMap.put(Pattern.compile("^...... KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(HSF).*"), "HSF"); //conflicts with FLN + thisMap.put(Pattern.compile("^...... PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(HSF).*"), "HSF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(AGO).*"), "AGO"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FZL).*"), "FZL"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(AFD).*"), "AFD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SFP).*"), "SFP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(ZFP).*"), "ZFP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(LFP).*"), "LFP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(CCF).*"), "CCF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RDF).*"), "RDF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(PFM).*"), "PFM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(AFM).*"), "AFM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SFT).*"), "SFT"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RTP).*"), "RTP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(CLI).*"), "CLI"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(CLM).*"), "CLM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(LSR).*"), "LSR"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RER).*"), "RER"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(NOW).*"), "NOW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(PNS).*"),"PNS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(HWO).*"),"HWO"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RWR).*"),"RWR"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(MIS).*"),"MIS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(ADA).*"),"ADA"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SVR).*"),"SVR"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TOR).*"),"TOR"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RWS).*"),"RWS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(WSW).*"),"WSW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SPS).*"),"SPS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SVS).*"),"SVS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SLS).*"),"SLS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(WCN).*"),"WCN"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(NPW).*"),"NPW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(HLS).*"),"HLS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FFG).*"), "FFG"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FFA).*"), "FFA"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FFW).*"), "FFW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FFS).*"), "FFS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FLS).*"), "FLS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FLW).*"), "FLW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FLN).*"), "FLN"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RVS).*"), "RVS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR1).*"), "RR1"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR2).*"), "RR2"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR3).*"), "RR3"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR4).*"), "RR4"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR5).*"), "RR5"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR6).*"), "RR6"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR7).*"), "RR7"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR8).*"), "RR8"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RR9).*"), "RR9"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RRA).*"), "RRA"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RRM).*"), "RRM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(CWF).*"), "CWF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(OFF).*"), "OFF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(PLS).*"), "PLS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(OMR).*"), "OMR"); //regexes clash for cgr and OMR + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SMW).*"), "SMW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(CFW).*"), "CFW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(MWS).*"), "MWS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(MRP).*"), "MRP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(MIM).*"), "MIM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TAV).*"), "TAV"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(SCS).*"), "SCS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TWO).*"), "TWO"); //clashes with outlk + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TWS).*"), "TWS"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TWD).*"), "TWD"); //clashes with tdsc + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TCM).*"), "TCM"); //clashes with mar + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TCP).*"), "TCP"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TCD).*"), "TCD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TCE).*"), "TCE"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(TCU).*"), "TCU"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(DSA).*"), "DSA"); //clashes with disc + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RFW).*"), "RFW"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FWF).*"), "FWF"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FWM).*"), "FWM"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(RFD).*"), "RFD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(UVI).*"), "UVI"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(QPFPFD).*"), "QPFPFD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(QPFERD).*"), "QPFERD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(QPFHSD).*"), "QPFHSD"); + thisMap.put(Pattern.compile("^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*(\n|\r)(FTM).*"), "ftm"); return Collections.unmodifiableMap(thisMap); diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextSeparator.java index 61f8e96a7f..24f7bc2f31 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/src/gov/noaa/nws/ncep/edex/plugin/nctext/decoder/NctextSeparator.java @@ -63,8 +63,20 @@ public class NctextSeparator extends AbstractRecordSeparator { public static final String R_TYPE_SEPARATOR2 = "00///"; public static final String R_TYPE_SEPARATOR3 = "[A-Z]{3,4}"; + + public static String [][] gdStnGp= {{"PWM","BGR","CAR","CON","AFA"},{"ALB","BOS","PHL","BTV","LGA","IPT"},{"DCA","RDU","ILM","ORF","HAT"}, + {"CAE","MIA","TLH","SAV","LAL"},{"BUF","CLE","CRW","PIT","DAY","IND"},{"STL","MEM","TYS","SDF","BNA","ATL"},{"BHM","JAN","SHV","MOB","MSY","LIT"}, + {"DTW","MKE","INL","SSM","MSP","ORD"},{"DSM","DDC","LBF","TOP","OMA","BFF"},{"OKC","SAT","BRO","DFW","IAH","DRT"},{"BIS","RAP","BIL","FSD","GTF","MSO"}, + {"LBB","ABQ","DEN","ELP","PHX","CYS"},{"SEA","PDX","BOI","GEG","MFR","PIH"},{"SFO","LAX","SLC","FAT","RNO","CDC"},{"YQB","YOW","YYB","YQT","YMW","YLH"}, + {"YWG","YQR","YYC","YQD","YPA","YEG"},{"MCD","YXC","YVR","YRV","YCG","YXS"}, {"X68","EDW","LWS","UCC","BTNM","LGIN"}, {"SYR","ROA","ZZV","AOO","AVL"}, + {"SGF","GRB","GJT","JKL","MLI","FAR","LND"},{"MAF","LCH","TUL","DHT","DHN","DAB"},{"GGW","RDD","LAS","PDT","EKO","FLG"}, + {"AKN","CZF","EDF","EHM","SVW","TLJ"},{"EIL","GAL","LUR","TNC","UTO"},{"ANC","ANN","CDV","JNU","ORT","YAK"},{"ADQ","BET","CDB","MCG","SNP"}, + {"BRW","BTI","BTT","FAI","OME","OTZ"},{"TJSJ","TJMZ","TJPS","TJBQ","TJGU","TJAD"},{"TIST","TISX","TNCM","TKPK","TJNR","TISJ"},{"PHNL","PHLI","PHOG","PHTO","HIB1","HIB4"}}; public static final byte ASCII_RS = 0x1E; // record separator "^^" + public static final byte ASCII_SP = 0x20; // SPACE + + // private static final int DTGROUP_SIZE = 6; private String cccc = null; @@ -323,6 +335,7 @@ public class NctextSeparator extends AbstractRecordSeparator { */ @Override public void setData(byte[] rawMessage, Headers headers) { + /* currentReport = -1; // Now check for some binary data types, Stop decoding, if it is binary @@ -339,16 +352,16 @@ public class NctextSeparator extends AbstractRecordSeparator { pos = sRawMessage.indexOf("GIF87"); notStored = notStored || ((pos >= 0) && (pos < 20)); - int rawMsglength = rawMessage.length; /* - * start from this, and - * decremented when each bulletin - * found - */ - int rawMsgPointer = 0;/* - * start from 0 and incremented when each bulletin - * found - */ - int recordId = 1; /* to record number of records with same AWIPS header */ + int rawMsglength = rawMessage.length; // + // * start from this, and + // * decremented when each bulletin + // * found + // + int rawMsgPointer = 0;//* + // * start from 0 and incremented when each bulletin + // * found + // + int recordId = 1; ///* to record number of records with same AWIPS header reports = new ArrayList(); String sRawMsgInProcessing = null; int endPos; @@ -400,7 +413,7 @@ public class NctextSeparator extends AbstractRecordSeparator { // cumRsPos = cumRsPos + nextRsPos; int testCount1 = 0; while ((nextRsPos >= 0) - && (/* cumRsPos */nextRsPos < endPos)) { + && (nextRsPos < endPos)) { // find record(s) within the section, store // it testCount1++; @@ -475,7 +488,7 @@ public class NctextSeparator extends AbstractRecordSeparator { + awipsId + " BUT, no RS ^^ found!"); - rawMsglength = 0; /* get out of here */ + rawMsglength = 0; ///* get out of here } // System.out.println("M type report size : "+ // reports.size()); @@ -519,7 +532,7 @@ public class NctextSeparator extends AbstractRecordSeparator { // + WMOId + " " + cccc + " " + YYGGgg+ " " + awipsId + // " " + proType // /*+"\n rawMsgLn " + rawMsglength + "rawMsgPointer " + - // rawMsgPointer + "endPos " + endPos*/); + // rawMsgPointer + "endPos " + endPos); resetVaraable(); } else { @@ -527,22 +540,22 @@ public class NctextSeparator extends AbstractRecordSeparator { logger.info("setData : find wmoHeader " + (recordId - 1) + ": " + WMOId + " " + cccc + " " + YYGGgg + " " + awipsId - + " BUT, no message data end Ctl-C found! "/* - * + - * " rawMsgLn " - * + - * rawMsglength - * + - * " rawMsgPointer " - * + - * rawMsgPointer - * + - * " endPos " - * + - * endPos - */); + + " BUT, no message data end Ctl-C found! "//* + // * + + // * " rawMsgLn " + // * + + // * rawMsglength + /// * + + // * " rawMsgPointer " + // * + + // * rawMsgPointer + // * + + // * " endPos " + // * + + // * endPos + // ); - rawMsglength = 0; /* get out of here */ + rawMsglength = 0; ///* get out of here } } // Chin debug @@ -614,6 +627,7 @@ public class NctextSeparator extends AbstractRecordSeparator { // Chin debug logger.info(traceId + " - setData():No reports found in data."); } + */ } private synchronized boolean parseRcdHeader(String sInputMessageData) { @@ -705,6 +719,16 @@ public class NctextSeparator extends AbstractRecordSeparator { } return isValid; } + private String[] getGdStnGp(String stnId){ + for(String[] stnGp: gdStnGp){ + for(int i=0; i < stnGp.length; i++){ + if(stnId.equals(stnGp[i])){ + return stnGp; + } + } + } + return null; + } /** * Set the raw message data and invoke the internal message separation @@ -753,8 +777,12 @@ public class NctextSeparator extends AbstractRecordSeparator { // They are separated by Record Separator "^^". rsPos = strRcd.indexOf(ASCII_RS); // find first RS if ((rsPos >= 0) && (rsPos < endPos)) { + int stnidEnd; + + stnidEnd = strRcd.substring(rsPos + 1).indexOf(ASCII_SP) + 1; //Chin fix mos stnid bug + String stnId = strRcd.substring(rsPos + 1, - rsPos + 5); + rsPos + stnidEnd); curPos = rsPos + 1; nextRsPos = strRcd.indexOf(ASCII_RS, curPos); // 2nd // RS @@ -769,9 +797,11 @@ public class NctextSeparator extends AbstractRecordSeparator { // stndId // found for // this record - reports.add(nctextrecord); + if(stnId.length() <= 8) //Chin : to make sure we do not get unwanted/bad record with longer than 8 chars stnid + reports.add(nctextrecord); + stnidEnd = strRcd.substring(nextRsPos + 1).indexOf(ASCII_SP) + 1; //Chin fix mos stnid bug stnId = strRcd.substring(nextRsPos + 1, - nextRsPos + 5); + nextRsPos + stnidEnd); curPos = nextRsPos + 1; nextRsPos = strRcd.indexOf(ASCII_RS, @@ -788,11 +818,12 @@ public class NctextSeparator extends AbstractRecordSeparator { // with stndId // found for this // record - reports.add(nctextrecord); + if(stnId.length() <= 8) + reports.add(nctextrecord); } else { // Chin debug System.out - .println("setData for M type: find wmoHeader " + .println("setRecordData for M type: find wmoHeader " + (recordId - 1) + ": " + WMOId @@ -803,44 +834,60 @@ public class NctextSeparator extends AbstractRecordSeparator { + " " + awipsId + " BUT, no RS ^^ found!"); } - }/* - * else if (fileType.equals("RGD")){ Pattern p = - * Pattern.compile(R_TYPE_SEPARATOR); Matcher m = - * p.matcher(strRcd); String stnIdFound="NA", gpStnId = - * "NA", subStr; boolean saveit = false; if (m.find()) { - * stnIdFound = m.group(); stnIdFound = - * stnIdFound.substring(0, stnIdFound.length()-2); gpStnId - * = nctextStnGroupingDao.getStnGpId(stnIdFound); saveit = - * true; } else { //This record may have different format, - * Its Stn ID is one line before "00///" found p = - * Pattern.compile(R_TYPE_SEPARATOR2); m = - * p.matcher(strRcd); if (m.find()) { subStr = - * strRcd.substring(m.start()); // find the first "00///" - * and move str to here //from subStr, find a first stn id - * of this gp stns p = Pattern.compile(R_TYPE_SEPARATOR3); - * m = p.matcher(subStr); if (m.find()){ stnIdFound = - * m.group(); gpStnId = - * nctextStnGroupingDao.getStnGpId(stnIdFound); saveit = - * true; } else { - * logger.info("Could not find stn id in RGD file record !!!" - * ); } } else { - * logger.info("Could not find stn id in RGD file record!" - * ); } } if((saveit == true) && (gpStnId.equals("NA") == - * false)){ NctextRecord nctextrecord = new NctextRecord(); - * setNctextRecord(nctextrecord); - * nctextrecord.setRawRecord(strRcd.substring(recordStart, - * endPos-1)); nctextrecord.setRecordId(recordId++); - * nctextrecord.setIssueSite(gpStnId); // replace cccc with - * group stndId found for this record - * reports.add(nctextrecord); } else logger.info("stn id " - * + stnIdFound + " But gp Stnid is "+ gpStnId); - * - * } - */ + } + else if (fileType.equals("R")){ + Pattern p = Pattern.compile(R_TYPE_SEPARATOR); + Matcher m =p.matcher(strRcd); + String stnIdFound="NA", subStr; + String[] stnGp=null; + boolean saveit = false; + if (m.find()) { + stnIdFound = m.group(); + stnIdFound = stnIdFound.substring(0, stnIdFound.length()-2); + stnGp = getGdStnGp(stnIdFound); + if(stnGp !=null) + saveit =true; + } else { //This record may have different format, Its Stn ID is one line before "00///" + p = Pattern.compile(R_TYPE_SEPARATOR2); + m = p.matcher(strRcd); + if (m.find()) { + subStr = strRcd.substring(m.start()); + // find the first "00///" and move str to here + //from subStr, find a first stn id of this gp stns + //this stn is actually not the first stn in the record. but it is ok, we only need one stn id in the gp. + p = Pattern.compile(R_TYPE_SEPARATOR3); + m = p.matcher(subStr); + if (m.find()){ + stnIdFound = m.group(); + stnGp = getGdStnGp(stnIdFound); + if(stnGp !=null) + saveit = true; + } else { + logger.info("Could not find stn id in RGD file record !!!"); + } + } else { + logger.info("Could not find stn id in RGD file record!" ); + } + } + if(saveit == true && stnGp != null) { + //For consistent with all other text record, we have to save smae record for each stn in the gp, + // so appication can query record based on stnId + for(String stn: stnGp){ + NctextRecord nctextrecord = new NctextRecord(); + setNctextRecord(nctextrecord); + nctextrecord.setRawRecord(strRcd.substring(recordStart,endPos-1)); + nctextrecord.setRecordId(recordId++); + nctextrecord.setIssueSite(stn); + // replace cccc with group stndId found for this record + reports.add(nctextrecord); + } + } else + logger.info("stn id "+ stnIdFound + " But gp Stn is not found"); + } else if (fileType.equals("O")) { logger.info("Observer data is not supported now!!!"); } else { - // other data types - I.e. B, W, Z, F, R types + // other data types - I.e. B, W, Z, F types NctextRecord nctextrecord = new NctextRecord(); setNctextRecord(nctextrecord); nctextrecord.setRawRecord(strRcd.substring(recordStart, @@ -863,38 +910,38 @@ public class NctextSeparator extends AbstractRecordSeparator { + " BUT, some issues found! "); switch (parseErr) { case NO_AWIPS_HDR: - logger.info("setData : no header found. Stop here! "); + logger.info("setRecordData : no header found. Stop here! "); logErrToFile("No AWIPS header found in this file. Stop Parsing!\n"); break; case NO_AWIPS_HDR_IN_BULLETIN: - logger.info("setData : no header found in a bulletin. "); + logger.info("setRecordData : no header found in a bulletin. "); // Skip this part of data. adjust buffer to next // possible bulletin logErrToFile("A Bulletin without good AWIPS header found. Skip it!\n"); break; case NO_CTLA_IN_BULLETIN: - logger.info("setData : no ctl-A found in a bulletin. "); + logger.info("setRecordData : no ctl-A found in a bulletin. "); // Skip this part of data. adjust buffer to next // possible bulletin logErrToFile("A Bulletin without ctl-A found. Skip it!\n"); break; case NO_CTLA_TO_END: - logger.info("setData : no ctl-A found from this point down. Stop here! "); + logger.info("setRecordData : no ctl-A found from this point down. Stop here! "); // Skip this part of data. adjust buffer to next // possible bulletin logErrToFile("No ctl-A found from this point down. Stop here!\n"); break; case NO_CTLC_TO_END: - logger.info("setData : no ctl-C found from this point down. Stop here! "); + logger.info("setRecordData : no ctl-C found from this point down. Stop here! "); // Skip this part of data. adjust buffer to next // possible bulletin logErrToFile("No ctl-C found from this point down. Stop here!\n"); break; case NO_ERR: - logger.info("setData : end of file. Stop here! "); + logger.info("setRecordData : end of file. Stop here! "); break; default: - logger.info("setData : general error! Stop here! "); + logger.info("setRecordData : general error! Stop here! "); logErrToFile("Unknow parsing error. Stop here!\n"); break; } @@ -908,7 +955,7 @@ public class NctextSeparator extends AbstractRecordSeparator { currentReport = 0; } else { // Chin debug - logger.info(traceId + " - setData():No reports found in data."); + logger.info(traceId + " - setRecordData():No reports found in data."); } } diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/utility/edex_static/base/distribution/nctext.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/utility/edex_static/base/distribution/nctext.xml index 1383ef7324..38b37da8cd 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/utility/edex_static/base/distribution/nctext.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctext/utility/edex_static/base/distribution/nctext.xml @@ -1,4 +1,259 @@ - ^FOUS6[1-6].* - \ No newline at end of file +^FXCA62 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ +^FXUS[67][1-6] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FPAK20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FPHW03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FX(HW|PN|PS)60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FA[0-9].* + ^WWUS30 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FNUS21 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FNUS22 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WOUS64 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ABNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACPN50 PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ABPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ABCA33 TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTNT4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPA4[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPZ4[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WONT41 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTNT3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTNT3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPZ3[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPZ3[1-5] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTCA4[1-5] TJSJ (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WHCA31 TFFF (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPN2[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTNT2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPA2[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPZ2[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^W[H|T]PS01 NFFN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTPN3[1-5] PGTW (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URNT12 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^U[RZ]NT14 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^AXPZ20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^AXNT20 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WTNT7[1-5] KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NOUS42 KNHC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWJP25 RJTD (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WCPA3[1-5] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WSUS3[1-3] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^W[CSV][NT|PN|PA|AK][01][0-9] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^W[CSV][NT|PN|PA|AK][01][0-9] PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^W[CSV][NT|PN|PA|AK][01][0-9] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^W[CSV]US0[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* + ^WAUS4[1-6] KKCI (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WAAK4[7-9] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FAAK2[1-6] KZAN (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FAUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WCUS2[1-6] KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FAUS20 (KZ..|PANC) (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS14 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOAK2[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FEPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FEUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FEAK3[7-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FECN21 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS4[4-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FQUS2[1-6] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MMG.* + ^FQAK37 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MMG.* + ^FQPA20 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MMG.* + ^FOUE6[0-4] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUE80 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUM6[5-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUM7[01] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUM8[124] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS8[6-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS90 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUW7[238] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUW83 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOHW50 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOCA5[12] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOCN7[456] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOGX77 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS6[0-9] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOUS7[0-8] KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS02 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDEPD.* + ^FXUS02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PREEPD.* + ^FXUS01 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDSPD.* + ^FXHW01 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDHI.* + ^FXSA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDSA.* + ^FXCA20 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDCA.* + ^FXAK02 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PMDAK.* + ^NOUS42 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NOUS42 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NPXX10 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NPXX10 KWNO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS10 KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HI.* + ^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HH.* + ^FMUS2[34] KWNH (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PRB[EW]HL.* + ^FXUS06 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FEUS40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS07 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS05 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXHW40 KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS21 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXUS25 KWNC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FVAK2[1-5] PAWU (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WUUS48 KWNS (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FAUS20 KZ.. (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + + ^WSUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WAHW[03]1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WAUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WAUS1 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WAAK01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WOUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FVXX2[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FVCN0[0-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FVAU0[2-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACUS4[1-5] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FSUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ASUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FXPA00 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FVXX2[0-7] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACUS48 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FNUS31 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWFD1.* + ^FNUS32 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWFD2.* + ^FNUS38 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFWF38.* + ^WFCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WUCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WOCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWCN1[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWCN3[1|2] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FOCN45 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^ACUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWUS01 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWUS02 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWUS03 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WWUS50 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SEV[0-9].* + ^WWUS60 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SEVSPC.* + ^WOUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NWUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*STAHRY.* + ^ACUS11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*STADTS + ^NWUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^FNUS21 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWDDY1.* + ^FNUS22 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWDDY2.* + ^WHXX9[09] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WHXX0[1-4] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URNT10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URNT11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URNT12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URNT14 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^UZNT13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URPN10 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URPN11 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^URPN12 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + + ^UZPN13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^UZPA13 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^TXUS20 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^SXUS40 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^SXUS08 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^SXUS86 .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WV.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* + ^W[CSV].... [^KP]... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* + ^WSUS4[012] .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^WSUK.. .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* + ^WS[^U]... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).* + ^FT.... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).+ + ^...... KWBC (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HSF.* + ^...... PHFO (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HSF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AGO.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FZL.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AFD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SFP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*ZFP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*LFP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CCF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RDF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PFM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*AFM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SFT.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RTP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CLI.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CLM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*LSR.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RER.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*NOW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PNS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HWO.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RWR.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MIS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*ADA.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SVR.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TOR.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RWS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*WSW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SPS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SVS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SLS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*WCN.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*NPW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*HLS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFG.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFA.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FFS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FLN.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RVS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR1.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR2.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR3.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR4.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR5.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR6.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR7.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR8.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RR9.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RRA.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RRM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CWF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*OFF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*PLS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*OMR.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SMW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*CFW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MWS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MRP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*MIM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TAV.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*SCS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWO.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWS.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TWD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCP.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCE.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*TCU.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*DSA.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RFW.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWF.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FWM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*RFD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*UVI.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*FTM.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFPFD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFERD.* + ^...... .... (0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])([0-5][0-9]).*QPFHSD.* + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/component-deploy.xml old mode 100755 new mode 100644 index 3e961a1a28..a71fed23b4 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/component-deploy.xml @@ -1,10 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-common.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-common.xml old mode 100755 new mode 100644 index b47ebc7901..d5927f1699 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-common.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-common.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml old mode 100755 new mode 100644 index e9b2d3798a..f6ac80cb6a --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml @@ -1,73 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - nonconvsigmet - - - - - - - - - - - - - java.lang.Throwable - - - - - - - java.lang.Throwable - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + nonconvsigmet + + + + + + + + + + + + + java.lang.Throwable + + + + + + + java.lang.Throwable + + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetDecoder.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetDecoder.java old mode 100755 new mode 100644 index e47ebce5d2..689b177f00 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetDecoder.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetDecoder.java @@ -1,111 +1,111 @@ -/** - * - * Non-Convective Sigmet Decoder - * - * This java class decodes NONCONVSIGMET (non-convective sigmet) raw data. - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 Uma Josyula Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder; - -import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetRecord; -import gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util.NonConvSigmetParser; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.Scanner; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.exception.DecoderException; -import com.raytheon.edex.plugin.AbstractDecoder; -import com.raytheon.uf.common.dataplugin.PluginDataObject; -import com.raytheon.uf.common.dataplugin.PluginException; -import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; - -public class NonConvSigmetDecoder extends AbstractDecoder { - - private final String pluginName; - - /** - * Constructor - * - * @throws DecoderException - */ - public NonConvSigmetDecoder(String name) throws DecoderException { - pluginName = name; - } - - public PluginDataObject[] decode(byte[] data, Headers headers) - throws DecoderException { - - PluginDataObject [] recs = null; - NonConvSigmetRecord currentRecord = null; - String traceId = ""; - if (headers != null) { - traceId = (String) headers.get("traceId"); - } - if((data != null) && (data.length > 0)) { - String etx = IDecoderConstants.ETX; - String theBulletin = null; - byte[] messageData = null; - NonConvSigmetSeparator sep = NonConvSigmetSeparator.separate(data, - headers); - messageData = sep.next(); - String theMessage = new String(messageData); - - /* - * May have multiple duplicate bulletins, only get the first bulletin - * and eliminate the remaining bulletins after the first bulletin. - */ - Scanner cc = new Scanner(theMessage).useDelimiter(etx); - if (cc.hasNext()) { - theBulletin = cc.next(); - } else { - theBulletin = theMessage; - } - /* - * Decode by calling the NonconvSigmetParser method processRecord - */ - currentRecord = NonConvSigmetParser.processRecord(theBulletin, headers); - if (currentRecord != null) { - currentRecord.setReportType(pluginName); - /* - * Replace special characters to a blank so that it may be readable - */ - currentRecord.setBullMessage(UtilN - .removeLeadingWhiteSpaces((theBulletin.substring(5)) - .replace('\036', ' ').replace('\r', ' ') - .replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' '))); - /* - * Check the NonConvsigmet record object. If not, throws exception. - */ - currentRecord.setTraceId(traceId); - currentRecord.setPluginName(pluginName); - try { - currentRecord.constructDataURI(); - - } catch (PluginException e) { - logger.error(traceId + "- Unable to construct dataURI", e); - currentRecord = null; - } - } - } - - /* - * Return the NonConvsigmetRecord record object. - */ - if (currentRecord == null) { - recs = new PluginDataObject[0]; - } else { - recs = new PluginDataObject[] { currentRecord }; - } - return recs; - } - +/** + * + * Non-Convective Sigmet Decoder + * + * This java class decodes NONCONVSIGMET (non-convective sigmet) raw data. + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 Uma Josyula Initial creation + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder; + +import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetRecord; +import gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util.NonConvSigmetParser; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.Scanner; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.exception.DecoderException; +import com.raytheon.edex.plugin.AbstractDecoder; +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.edex.decodertools.core.IDecoderConstants; + +public class NonConvSigmetDecoder extends AbstractDecoder { + + private final String pluginName; + + /** + * Constructor + * + * @throws DecoderException + */ + public NonConvSigmetDecoder(String name) throws DecoderException { + pluginName = name; + } + + public PluginDataObject[] decode(byte[] data, Headers headers) + throws DecoderException { + + PluginDataObject [] recs = null; + NonConvSigmetRecord currentRecord = null; + String traceId = ""; + if (headers != null) { + traceId = (String) headers.get("traceId"); + } + if((data != null) && (data.length > 0)) { + String etx = IDecoderConstants.ETX; + String theBulletin = null; + byte[] messageData = null; + NonConvSigmetSeparator sep = NonConvSigmetSeparator.separate(data, + headers); + messageData = sep.next(); + String theMessage = new String(messageData); + + /* + * May have multiple duplicate bulletins, only get the first bulletin + * and eliminate the remaining bulletins after the first bulletin. + */ + Scanner cc = new Scanner(theMessage).useDelimiter(etx); + if (cc.hasNext()) { + theBulletin = cc.next(); + } else { + theBulletin = theMessage; + } + /* + * Decode by calling the NonconvSigmetParser method processRecord + */ + currentRecord = NonConvSigmetParser.processRecord(theBulletin, headers); + if (currentRecord != null) { + currentRecord.setReportType(pluginName); + /* + * Replace special characters to a blank so that it may be readable + */ + currentRecord.setBullMessage(UtilN + .removeLeadingWhiteSpaces((theBulletin.substring(5)) + .replace('\036', ' ').replace('\r', ' ') + .replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' '))); + /* + * Check the NonConvsigmet record object. If not, throws exception. + */ + currentRecord.setTraceId(traceId); + currentRecord.setPluginName(pluginName); + try { + currentRecord.constructDataURI(); + + } catch (PluginException e) { + logger.error(traceId + "- Unable to construct dataURI", e); + currentRecord = null; + } + } + } + + /* + * Return the NonConvsigmetRecord record object. + */ + if (currentRecord == null) { + recs = new PluginDataObject[0]; + } else { + recs = new PluginDataObject[] { currentRecord }; + } + return recs; + } + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetSeparator.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetSeparator.java old mode 100755 new mode 100644 index a25c682b04..d91836dc4f --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetSeparator.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/NonConvSigmetSeparator.java @@ -1,137 +1,137 @@ -/** - * NonConvsigmetSeparator - * - * This class sets the raw data to an Arraylist, records, of - * String based on a uniquely identified separator. - * - *
- * Uma Josyula                               06/2009         Creation
- * 
- * - * This code has been developed by the SIB for use in the AWIPS system. - */ - -package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.edex.plugin.AbstractRecordSeparator; -import com.raytheon.edex.util.Util; -import com.raytheon.uf.edex.wmo.message.WMOHeader; - -public class NonConvSigmetSeparator extends AbstractRecordSeparator { - private final Log logger = LogFactory.getLog(getClass()); - - /** Regex used for separate the bulletins */ - private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; - - /** Regex matcher */ - private Matcher matcher; - - /** Pattern object for regex search */ - private Pattern pattern; - - /** List of records contained in file */ - private List records; - - private Iterator iterator = null; - - /** - * Constructor. - * - */ - public NonConvSigmetSeparator() { - records = new ArrayList(); - } - - public static NonConvSigmetSeparator separate(byte[] data, Headers headers) { - NonConvSigmetSeparator ds = new NonConvSigmetSeparator(); - ds.setData(data, headers); - return ds; - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.plugin.AbstractRecordSeparator#setData(byte[], - * com.raytheon.edex.esb.Headers) - */ - public void setData(byte[] data, Headers headers) { - try { - doSeparate(new String(data)); - } catch (Exception e) { - logger.warn("No valid records found!", e); - } finally { - iterator = records.iterator(); - } - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() - */ - public boolean hasNext() { - if (iterator == null) { - return false; - } else { - return iterator.hasNext(); - } - } - - /** - * Get record - */ - public byte[] next() { - try { - String temp = iterator.next(); - if (Util.isEmptyString(temp)) { - return new byte [0]; - } else { - return temp.getBytes(); - } - } catch (NoSuchElementException e) { - return (byte[]) null; - } - } - - /** - * @param message - * separate bulletins - */ - private void doSeparate(String message) { - /* Regex used for separate the bulletins */ - - String data = message; - - WMOHeader h1 = new WMOHeader(data.getBytes()); - boolean done = false; - while (!done) { - if((h1 != null)&&(h1.isValid())) { - String body = data.substring(h1.getMessageDataStart()); - WMOHeader h2 = new WMOHeader(body.getBytes()); - if((h2 != null)&&(h2.isValid())) { - int endPos = h2.getWmoHeaderStart(); - records.add(h1.getWmoHeader() + "\n" + body.substring(0,endPos)); - data = body.substring(endPos); - h1 = new WMOHeader(data.getBytes()); - } else { - records.add(data); - done = true; - } - } else { - records.add(data); - done = true; - } - } - } +/** + * NonConvsigmetSeparator + * + * This class sets the raw data to an Arraylist, records, of + * String based on a uniquely identified separator. + * + *
+ * Uma Josyula                               06/2009         Creation
+ * 
+ * + * This code has been developed by the SIB for use in the AWIPS system. + */ + +package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.edex.plugin.AbstractRecordSeparator; +import com.raytheon.edex.util.Util; +import com.raytheon.uf.edex.wmo.message.WMOHeader; + +public class NonConvSigmetSeparator extends AbstractRecordSeparator { + private final Log logger = LogFactory.getLog(getClass()); + + /** Regex used for separate the bulletins */ + private static final String BULLSEPARATOR = "([0-9]{3})( )*\\x0d\\x0d\\x0a([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( [A-Z]{3})?\\x0d\\x0d\\x0a"; + + /** Regex matcher */ + private Matcher matcher; + + /** Pattern object for regex search */ + private Pattern pattern; + + /** List of records contained in file */ + private List records; + + private Iterator iterator = null; + + /** + * Constructor. + * + */ + public NonConvSigmetSeparator() { + records = new ArrayList(); + } + + public static NonConvSigmetSeparator separate(byte[] data, Headers headers) { + NonConvSigmetSeparator ds = new NonConvSigmetSeparator(); + ds.setData(data, headers); + return ds; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.AbstractRecordSeparator#setData(byte[], + * com.raytheon.edex.esb.Headers) + */ + public void setData(byte[] data, Headers headers) { + try { + doSeparate(new String(data)); + } catch (Exception e) { + logger.warn("No valid records found!", e); + } finally { + iterator = records.iterator(); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.edex.plugin.IRecordSeparator#hasNext() + */ + public boolean hasNext() { + if (iterator == null) { + return false; + } else { + return iterator.hasNext(); + } + } + + /** + * Get record + */ + public byte[] next() { + try { + String temp = iterator.next(); + if (Util.isEmptyString(temp)) { + return new byte [0]; + } else { + return temp.getBytes(); + } + } catch (NoSuchElementException e) { + return (byte[]) null; + } + } + + /** + * @param message + * separate bulletins + */ + private void doSeparate(String message) { + /* Regex used for separate the bulletins */ + + String data = message; + + WMOHeader h1 = new WMOHeader(data.getBytes()); + boolean done = false; + while (!done) { + if((h1 != null)&&(h1.isValid())) { + String body = data.substring(h1.getMessageDataStart()); + WMOHeader h2 = new WMOHeader(body.getBytes()); + if((h2 != null)&&(h2.isValid())) { + int endPos = h2.getWmoHeaderStart(); + records.add(h1.getWmoHeader() + "\n" + body.substring(0,endPos)); + data = body.substring(endPos); + h1 = new WMOHeader(data.getBytes()); + } else { + records.add(data); + done = true; + } + } else { + records.add(data); + done = true; + } + } + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/package-info.java old mode 100755 new mode 100644 index 505c4ab822..5913d39c3b --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/decoder/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains decoder.java for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder;; +/** +* Contains decoder.java for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.decoder;; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/NonConvSigmetParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/NonConvSigmetParser.java old mode 100755 new mode 100644 index 28d4c7b6f1..1ff5b0523b --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/NonConvSigmetParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/NonConvSigmetParser.java @@ -1,397 +1,397 @@ -/* - * NonConvsigmet DecoderUtil - * - * This java class intends to serve as a decoder utility for NonConvsigmet. - * - * HISTORY - * - * Date Author Description - * ------------ ---------- ----------- -------------------------- - * 06/2009 Uma Josyula Initial creation - * - * This code has been developed by the SIB for use in the AWIPS2 system. - */ - -package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util; - -import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetLocation; -import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetRecord; -import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; -import gov.noaa.nws.ncep.edex.util.UtilN; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.raytheon.edex.esb.Headers; -import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.edex.decodertools.core.LatLonPoint; -import com.raytheon.uf.edex.decodertools.time.TimeTools; - -public class NonConvSigmetParser { - - /** - * Constructor - */ - public NonConvSigmetParser() { - } - - /** - * Parse the WMO line and store WMO header, OfficeID, issue time, - * designatorBBB,... - * - * @param wmoline - * The bulletin message - * - * @return a NonConvsigmetRecord - */ - public static NonConvSigmetRecord processWMO(String wmoline, Headers headers) { - - NonConvSigmetRecord currentRecord = null; - // Regular expression for WMO/ICAO, station ID, and issue date (and - // maybe designator BBB) - final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; - - // Pattern used for extracting WMO header,issue office and issue date - // and designatorBBB - final Pattern wmoPattern = Pattern.compile(WMO_EXP); - Matcher theMatcher = wmoPattern.matcher(wmoline); - - if (theMatcher.find()) { - currentRecord = new NonConvSigmetRecord(); - - currentRecord.setWmoHeader(theMatcher.group(1)); - currentRecord.setIssueOffice(theMatcher.group(2)); - currentRecord.setDesignatorBBB(theMatcher.group(5)); - - // Decode the issue time. - Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), - headers); - currentRecord.setIssueTime(issueTime); - - DataTime dataTime = new DataTime(issueTime); - currentRecord.setDataTime(dataTime); - } - return currentRecord; - } - - /** - * Obtains start time and end time and forecast Region from input report - * - * @param theBullMsg - * The bulletin message which contains start time and end time. - * - * @param NonConvSigmetRecord - * - * @return a NonConvsigmetRecord - */ - - public static NonConvSigmetRecord processStartEndTime(String theBullMsg, - NonConvSigmetRecord nconvRecord, Headers headers) { - final String STARTTIME_EXP = "([A-Z]{4}) WS ([0-9]{6})( [A-Z]{3})?"; - final String ENDTIME_EXP = "VALID UNTIL ([0-9]{6})"; - - final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); - final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); - - Calendar stTime = null; - Calendar endTime = null; - /* - * Default equal to one hour if there is no valid time in report - */ - - NonConvSigmetRecord currentRecord = nconvRecord; - - // Calculate the startTime - Matcher theMatcher = starttimePattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setForecastRegion(theMatcher.group(1)); - stTime = TimeTools.findDataTime(theMatcher.group(2), headers); - } - if (stTime == null) { - currentRecord.setStartTime(currentRecord.getIssueTime()); - } else { - currentRecord.setStartTime(stTime); - } - - // Calculate the endTime - theMatcher = endtimePattern.matcher(theBullMsg); - - if (theMatcher.find()) { - endTime = TimeTools.findDataTime(theMatcher.group(1), headers); - } - if (endTime == null) { - endTime = currentRecord.getIssueTime(); - currentRecord.setEndTime(endTime); - } else { - currentRecord.setEndTime(endTime); - } - - return currentRecord; - } - - /** - * Obtains SigmetId from input report - * - * @param theBullMsg - * The bulletin message. - * - * @param NonConvSigmetRecord - * - * @return a NonConvsigmetRecord - */ - public static NonConvSigmetRecord processSigmetId(String theBullMsg, - NonConvSigmetRecord nconvRecord) { - final String SIGMETID_EXP = "SIGMET ([A-Z]{2,} [0-9]{1})"; - final Pattern sigPattern = Pattern.compile(SIGMETID_EXP); - NonConvSigmetRecord currentRecord = nconvRecord; - // Parse sigmetId - Matcher theMatcher = sigPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setSigmetId(theMatcher.group(1)); - } - - return currentRecord; - } - - /** - * Parse the phenomena... Hazard Type,Hazard Intensity,Hazard Cause,Hazard - * Condition,FlightLevel1,FlightLevel2,SigmetId,AWIPSId,CorAmdTest,StateList - * - * @param theBullMsg - * from bulletin message - * - * @param a - * NonConvsigmetRecord - * - * @return a NonConvsigmetRecord - */ - public static NonConvSigmetRecord processPhenomena(String theBullMsg, - NonConvSigmetRecord nconvRecord) { - - final String FL_EXP1 = "BTN (FL)?([0-9]{3}) AND (FL)?([0-9]{3})"; - - final String FL_EXP2 = "BLW (FL)?([0-9]{3})"; - - final String HAZARDTYPE_EXP = " (TURB|ICGICIP|ICE) "; - - final String HAZARDINTS_EXP = "(OCNL [A-Z0-9]{2,})(BLW (FL)?([0-9]{3}).|BTN|TURB|ICGICIP|ICE|ICGIC|VA|DU)?"; - - final String HAZARDCAUS_EXP = "OCNL ([\\w| ])*(.|DUE TO)?([\\w| ]*). CONDS"; - - final String HAZARDCOND_EXP = "(CONDS [\\w| ]*)(\\x0d\\x0d\\x0a)?([\\w| ]*)([0-9]{4})Z"; - - final String STATELIST_EXP = "(([A-Z]{2})( [A-Z]{2})*)[\\r\\n]+"; - - final String AWIPSID_EXP = "([A-Z]{2}[0-9]{1}[A-Z]{1})( )*[\\r\\n]+"; - - final String CORREMARK_EXP = "(COR|AMD|TEST)"; - - final Pattern flPattern1 = Pattern.compile(FL_EXP1); - - final Pattern flPattern2 = Pattern.compile(FL_EXP2); - - final Pattern hzTypePattern = Pattern.compile(HAZARDTYPE_EXP); - - final Pattern hzIntsPattern = Pattern.compile(HAZARDINTS_EXP); - - final Pattern hzCausPattern = Pattern.compile(HAZARDCAUS_EXP); - - final Pattern hzCondPattern = Pattern.compile(HAZARDCOND_EXP); - - final Pattern stPattern = Pattern.compile(STATELIST_EXP); - - final Pattern awipsPattern = Pattern.compile(AWIPSID_EXP); - - final Pattern corRemarkPattern = Pattern.compile(CORREMARK_EXP); - - NonConvSigmetRecord currentRecord = nconvRecord; - - Matcher theMatcher = flPattern1.matcher(theBullMsg); - - if (theMatcher.find()) { - currentRecord - .setFlightLevel2(Integer.parseInt(theMatcher.group(4))); - currentRecord - .setFlightLevel1(Integer.parseInt(theMatcher.group(2))); - } else { - theMatcher = flPattern2.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setFlightLevel1(Integer.parseInt(theMatcher - .group(2))); - } - } - theMatcher = hzCausPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setHazardCause(theMatcher.group(3)); - } - theMatcher = hzCondPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setHazardCondition(theMatcher.group(0)); - } - theMatcher = hzIntsPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setHazardIntensity(theMatcher.group(1)); - } - theMatcher = hzTypePattern.matcher(theBullMsg); - if (theMatcher.find()) { - if ("TURB".equals(theMatcher.group(1))) { - currentRecord.setHazardType("TURBULENCE"); - } else { - currentRecord.setHazardType(theMatcher.group(1)); - } - } - theMatcher = stPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setStateList(theMatcher.group(1)); - } - theMatcher = awipsPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setAwipsId(theMatcher.group(1)); - } - theMatcher = corRemarkPattern.matcher(theBullMsg); - if (theMatcher.find()) { - currentRecord.setCorrectionRemarks(theMatcher.group(0)); - } - - return currentRecord; - - } - - /** - * Parse the location lines... Add location table to the section table if - * any - * - * @param theBullMsg - * from bulletin message - * - * @param recordTable - * The record Table - * - * @return true if finds a location line - */ - public static Boolean processLocation(String theBullMsg, - NonConvSigmetRecord recordTable) { - - Boolean hasLocationLine = true; - String locationDelimiter = "-| TO "; - ArrayList terminationList = new ArrayList(); - terminationList.addAll(Arrays.asList(new String[] { "OCNL", "SEV" })); - Scanner sclocations = new Scanner(theBullMsg).useDelimiter("FROM"); - - /* - * throws away the first section which is not the "FROM" location - */ - LatLonPoint point; - String locationRecord = sclocations.next(); - - if (sclocations.hasNext()) { - locationRecord = sclocations.next(); - - Scanner scLocationLine = new Scanner(locationRecord) - .useDelimiter("[\\r\\n]+"); - String lines = " "; - String curLine = null; - ArrayList locationList = new ArrayList(); - locationList.clear(); - Boolean notBreak = true; - - while (scLocationLine.hasNext() && notBreak) { - curLine = scLocationLine.next();// Get next location line - Scanner scLocationToken = new Scanner(curLine); - if (scLocationToken.hasNext()) { - // Check the first token from each line - String firstToken = scLocationToken.next(); - if (terminationList.contains(firstToken)) { - notBreak = false;// terminate - break; - } - } - lines = lines.concat(" ").concat(curLine); - } - - // Clean up the leading space - lines = UtilN.removeLeadingWhiteSpaces(lines); - // Parse the location lines by a "-" or "TO" - Scanner scLocation = new Scanner(lines) - .useDelimiter(locationDelimiter); - locationList.clear(); - // Get all locations - while (scLocation.hasNext()) { - locationList.add(scLocation.next()); - } - - // set locations to data base - if (locationList.size() > 1) { - Integer idxLocation = 0; - for (String location : locationList) { - NonConvSigmetLocation currentLocation = new NonConvSigmetLocation(); - currentLocation.setLocationLine(lines); - currentLocation.setLocation(location); - point = LatLonLocTbl.getLatLonPoint(location, "vors"); - currentLocation.setIndex(idxLocation + 1); - idxLocation++; - currentLocation.setLatitude(point - .getLatitude(LatLonPoint.INDEGREES)); - currentLocation.setLongitude(point - .getLongitude(LatLonPoint.INDEGREES)); - recordTable.addNonConvSigmetLocation(currentLocation); - } - } else { - hasLocationLine = false; - } - - } else { - hasLocationLine = false; - } - - return hasLocationLine; - } - - /** - * process regular section of a non-convective sigmet report - * - * @return a NonConvsigmetRecord table - */ - public static NonConvSigmetRecord processRecord(String theBullMsg, - Headers headers) { - final String CANCELSIGMET_EXP = "(CANCEL SIGMET|TEST)"; - final Pattern cancelSigPattern = Pattern.compile(CANCELSIGMET_EXP); - Matcher theMatcher = cancelSigPattern.matcher(theBullMsg); - // Decode the WMO Header - NonConvSigmetRecord currentRecord = NonConvSigmetParser.processWMO( - theBullMsg, headers); - // Decode the sigmetId - currentRecord = NonConvSigmetParser.processSigmetId(theBullMsg, - currentRecord); - // Decode the Start Time,End Time,ForecastRegion - currentRecord = NonConvSigmetParser.processStartEndTime(theBullMsg, - currentRecord, headers); - // Decode the phenomena description - currentRecord = NonConvSigmetParser.processPhenomena(theBullMsg, - currentRecord); - // Replace the special characters - currentRecord - .setBullMessage(theBullMsg.replace('\r', ' ') - .replace('\003', ' ').replace('\000', ' ') - .replace('\001', ' ')); - - if (theMatcher.find()) { - if ("UNKNOWN".equals(currentRecord.getHazardType())) { - if ("TEST".equals(theMatcher.group(0))) { - currentRecord.setHazardType("TEST"); - } else { - currentRecord.setHazardType("CANCEL"); - } - } - } else { - // Decode the locations - NonConvSigmetParser.processLocation(theBullMsg, currentRecord); - } - return currentRecord; - } - +/* + * NonConvsigmet DecoderUtil + * + * This java class intends to serve as a decoder utility for NonConvsigmet. + * + * HISTORY + * + * Date Author Description + * ------------ ---------- ----------- -------------------------- + * 06/2009 Uma Josyula Initial creation + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util; + +import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetLocation; +import gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet.NonConvSigmetRecord; +import gov.noaa.nws.ncep.edex.tools.decoder.LatLonLocTbl; +import gov.noaa.nws.ncep.edex.util.UtilN; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.edex.esb.Headers; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.edex.decodertools.core.LatLonPoint; +import com.raytheon.uf.edex.decodertools.time.TimeTools; + +public class NonConvSigmetParser { + + /** + * Constructor + */ + public NonConvSigmetParser() { + } + + /** + * Parse the WMO line and store WMO header, OfficeID, issue time, + * designatorBBB,... + * + * @param wmoline + * The bulletin message + * + * @return a NonConvsigmetRecord + */ + public static NonConvSigmetRecord processWMO(String wmoline, Headers headers) { + + NonConvSigmetRecord currentRecord = null; + // Regular expression for WMO/ICAO, station ID, and issue date (and + // maybe designator BBB) + final String WMO_EXP = "([A-Z]{4}[0-9]{2}) ([A-Z]{4}) ([0-9]{6})( ([A-Z]{3}))?"; + + // Pattern used for extracting WMO header,issue office and issue date + // and designatorBBB + final Pattern wmoPattern = Pattern.compile(WMO_EXP); + Matcher theMatcher = wmoPattern.matcher(wmoline); + + if (theMatcher.find()) { + currentRecord = new NonConvSigmetRecord(); + + currentRecord.setWmoHeader(theMatcher.group(1)); + currentRecord.setIssueOffice(theMatcher.group(2)); + currentRecord.setDesignatorBBB(theMatcher.group(5)); + + // Decode the issue time. + Calendar issueTime = TimeTools.findDataTime(theMatcher.group(3), + headers); + currentRecord.setIssueTime(issueTime); + + DataTime dataTime = new DataTime(issueTime); + currentRecord.setDataTime(dataTime); + } + return currentRecord; + } + + /** + * Obtains start time and end time and forecast Region from input report + * + * @param theBullMsg + * The bulletin message which contains start time and end time. + * + * @param NonConvSigmetRecord + * + * @return a NonConvsigmetRecord + */ + + public static NonConvSigmetRecord processStartEndTime(String theBullMsg, + NonConvSigmetRecord nconvRecord, Headers headers) { + final String STARTTIME_EXP = "([A-Z]{4}) WS ([0-9]{6})( [A-Z]{3})?"; + final String ENDTIME_EXP = "VALID UNTIL ([0-9]{6})"; + + final Pattern starttimePattern = Pattern.compile(STARTTIME_EXP); + final Pattern endtimePattern = Pattern.compile(ENDTIME_EXP); + + Calendar stTime = null; + Calendar endTime = null; + /* + * Default equal to one hour if there is no valid time in report + */ + + NonConvSigmetRecord currentRecord = nconvRecord; + + // Calculate the startTime + Matcher theMatcher = starttimePattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setForecastRegion(theMatcher.group(1)); + stTime = TimeTools.findDataTime(theMatcher.group(2), headers); + } + if (stTime == null) { + currentRecord.setStartTime(currentRecord.getIssueTime()); + } else { + currentRecord.setStartTime(stTime); + } + + // Calculate the endTime + theMatcher = endtimePattern.matcher(theBullMsg); + + if (theMatcher.find()) { + endTime = TimeTools.findDataTime(theMatcher.group(1), headers); + } + if (endTime == null) { + endTime = currentRecord.getIssueTime(); + currentRecord.setEndTime(endTime); + } else { + currentRecord.setEndTime(endTime); + } + + return currentRecord; + } + + /** + * Obtains SigmetId from input report + * + * @param theBullMsg + * The bulletin message. + * + * @param NonConvSigmetRecord + * + * @return a NonConvsigmetRecord + */ + public static NonConvSigmetRecord processSigmetId(String theBullMsg, + NonConvSigmetRecord nconvRecord) { + final String SIGMETID_EXP = "SIGMET ([A-Z]{2,} [0-9]{1})"; + final Pattern sigPattern = Pattern.compile(SIGMETID_EXP); + NonConvSigmetRecord currentRecord = nconvRecord; + // Parse sigmetId + Matcher theMatcher = sigPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setSigmetId(theMatcher.group(1)); + } + + return currentRecord; + } + + /** + * Parse the phenomena... Hazard Type,Hazard Intensity,Hazard Cause,Hazard + * Condition,FlightLevel1,FlightLevel2,SigmetId,AWIPSId,CorAmdTest,StateList + * + * @param theBullMsg + * from bulletin message + * + * @param a + * NonConvsigmetRecord + * + * @return a NonConvsigmetRecord + */ + public static NonConvSigmetRecord processPhenomena(String theBullMsg, + NonConvSigmetRecord nconvRecord) { + + final String FL_EXP1 = "BTN (FL)?([0-9]{3}) AND (FL)?([0-9]{3})"; + + final String FL_EXP2 = "BLW (FL)?([0-9]{3})"; + + final String HAZARDTYPE_EXP = " (TURB|ICGICIP|ICE) "; + + final String HAZARDINTS_EXP = "(OCNL [A-Z0-9]{2,})(BLW (FL)?([0-9]{3}).|BTN|TURB|ICGICIP|ICE|ICGIC|VA|DU)?"; + + final String HAZARDCAUS_EXP = "OCNL ([\\w| ])*(.|DUE TO)?([\\w| ]*). CONDS"; + + final String HAZARDCOND_EXP = "(CONDS [\\w| ]*)(\\x0d\\x0d\\x0a)?([\\w| ]*)([0-9]{4})Z"; + + final String STATELIST_EXP = "(([A-Z]{2})( [A-Z]{2})*)[\\r\\n]+"; + + final String AWIPSID_EXP = "([A-Z]{2}[0-9]{1}[A-Z]{1})( )*[\\r\\n]+"; + + final String CORREMARK_EXP = "(COR|AMD|TEST)"; + + final Pattern flPattern1 = Pattern.compile(FL_EXP1); + + final Pattern flPattern2 = Pattern.compile(FL_EXP2); + + final Pattern hzTypePattern = Pattern.compile(HAZARDTYPE_EXP); + + final Pattern hzIntsPattern = Pattern.compile(HAZARDINTS_EXP); + + final Pattern hzCausPattern = Pattern.compile(HAZARDCAUS_EXP); + + final Pattern hzCondPattern = Pattern.compile(HAZARDCOND_EXP); + + final Pattern stPattern = Pattern.compile(STATELIST_EXP); + + final Pattern awipsPattern = Pattern.compile(AWIPSID_EXP); + + final Pattern corRemarkPattern = Pattern.compile(CORREMARK_EXP); + + NonConvSigmetRecord currentRecord = nconvRecord; + + Matcher theMatcher = flPattern1.matcher(theBullMsg); + + if (theMatcher.find()) { + currentRecord + .setFlightLevel2(Integer.parseInt(theMatcher.group(4))); + currentRecord + .setFlightLevel1(Integer.parseInt(theMatcher.group(2))); + } else { + theMatcher = flPattern2.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setFlightLevel1(Integer.parseInt(theMatcher + .group(2))); + } + } + theMatcher = hzCausPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setHazardCause(theMatcher.group(3)); + } + theMatcher = hzCondPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setHazardCondition(theMatcher.group(0)); + } + theMatcher = hzIntsPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setHazardIntensity(theMatcher.group(1)); + } + theMatcher = hzTypePattern.matcher(theBullMsg); + if (theMatcher.find()) { + if ("TURB".equals(theMatcher.group(1))) { + currentRecord.setHazardType("TURBULENCE"); + } else { + currentRecord.setHazardType(theMatcher.group(1)); + } + } + theMatcher = stPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setStateList(theMatcher.group(1)); + } + theMatcher = awipsPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setAwipsId(theMatcher.group(1)); + } + theMatcher = corRemarkPattern.matcher(theBullMsg); + if (theMatcher.find()) { + currentRecord.setCorrectionRemarks(theMatcher.group(0)); + } + + return currentRecord; + + } + + /** + * Parse the location lines... Add location table to the section table if + * any + * + * @param theBullMsg + * from bulletin message + * + * @param recordTable + * The record Table + * + * @return true if finds a location line + */ + public static Boolean processLocation(String theBullMsg, + NonConvSigmetRecord recordTable) { + + Boolean hasLocationLine = true; + String locationDelimiter = "-| TO "; + ArrayList terminationList = new ArrayList(); + terminationList.addAll(Arrays.asList(new String[] { "OCNL", "SEV" })); + Scanner sclocations = new Scanner(theBullMsg).useDelimiter("FROM"); + + /* + * throws away the first section which is not the "FROM" location + */ + LatLonPoint point; + String locationRecord = sclocations.next(); + + if (sclocations.hasNext()) { + locationRecord = sclocations.next(); + + Scanner scLocationLine = new Scanner(locationRecord) + .useDelimiter("[\\r\\n]+"); + String lines = " "; + String curLine = null; + ArrayList locationList = new ArrayList(); + locationList.clear(); + Boolean notBreak = true; + + while (scLocationLine.hasNext() && notBreak) { + curLine = scLocationLine.next();// Get next location line + Scanner scLocationToken = new Scanner(curLine); + if (scLocationToken.hasNext()) { + // Check the first token from each line + String firstToken = scLocationToken.next(); + if (terminationList.contains(firstToken)) { + notBreak = false;// terminate + break; + } + } + lines = lines.concat(" ").concat(curLine); + } + + // Clean up the leading space + lines = UtilN.removeLeadingWhiteSpaces(lines); + // Parse the location lines by a "-" or "TO" + Scanner scLocation = new Scanner(lines) + .useDelimiter(locationDelimiter); + locationList.clear(); + // Get all locations + while (scLocation.hasNext()) { + locationList.add(scLocation.next()); + } + + // set locations to data base + if (locationList.size() > 1) { + Integer idxLocation = 0; + for (String location : locationList) { + NonConvSigmetLocation currentLocation = new NonConvSigmetLocation(); + currentLocation.setLocationLine(lines); + currentLocation.setLocation(location); + point = LatLonLocTbl.getLatLonPoint(location, "vors"); + currentLocation.setIndex(idxLocation + 1); + idxLocation++; + currentLocation.setLatitude(point + .getLatitude(LatLonPoint.INDEGREES)); + currentLocation.setLongitude(point + .getLongitude(LatLonPoint.INDEGREES)); + recordTable.addNonConvSigmetLocation(currentLocation); + } + } else { + hasLocationLine = false; + } + + } else { + hasLocationLine = false; + } + + return hasLocationLine; + } + + /** + * process regular section of a non-convective sigmet report + * + * @return a NonConvsigmetRecord table + */ + public static NonConvSigmetRecord processRecord(String theBullMsg, + Headers headers) { + final String CANCELSIGMET_EXP = "(CANCEL SIGMET|TEST)"; + final Pattern cancelSigPattern = Pattern.compile(CANCELSIGMET_EXP); + Matcher theMatcher = cancelSigPattern.matcher(theBullMsg); + // Decode the WMO Header + NonConvSigmetRecord currentRecord = NonConvSigmetParser.processWMO( + theBullMsg, headers); + // Decode the sigmetId + currentRecord = NonConvSigmetParser.processSigmetId(theBullMsg, + currentRecord); + // Decode the Start Time,End Time,ForecastRegion + currentRecord = NonConvSigmetParser.processStartEndTime(theBullMsg, + currentRecord, headers); + // Decode the phenomena description + currentRecord = NonConvSigmetParser.processPhenomena(theBullMsg, + currentRecord); + // Replace the special characters + currentRecord + .setBullMessage(theBullMsg.replace('\r', ' ') + .replace('\003', ' ').replace('\000', ' ') + .replace('\001', ' ')); + + if (theMatcher.find()) { + if ("UNKNOWN".equals(currentRecord.getHazardType())) { + if ("TEST".equals(theMatcher.group(0))) { + currentRecord.setHazardType("TEST"); + } else { + currentRecord.setHazardType("CANCEL"); + } + } + } else { + // Decode the locations + NonConvSigmetParser.processLocation(theBullMsg, currentRecord); + } + return currentRecord; + } + } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/package-info.java old mode 100755 new mode 100644 index a0947a6f6d..09e93d1a71 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/src/gov/noaa/nws/ncep/edex/plugin/nonconvsigmet/util/package-info.java @@ -1,4 +1,4 @@ -/** -* Contains tools for decoder plug-ins -*/ -package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util; +/** +* Contains tools for decoder plug-ins +*/ +package gov.noaa.nws.ncep.edex.plugin.nonconvsigmet.util; diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/component-deploy.xml index d03d3fd333..3d25848c16 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/component-deploy.xml @@ -1,10 +1,8 @@ - - + + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/component-deploy.xml index 860c8714c5..a9dee42040 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/src/gov/noaa/nws/ncep/edex/plugin/wcp/decoder/package-info.java b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/src/gov/noaa/nws/ncep/edex/plugin/wcp/decoder/package-info.java index f3fea73665..f52fb89e82 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/src/gov/noaa/nws/ncep/edex/plugin/wcp/decoder/package-info.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/src/gov/noaa/nws/ncep/edex/plugin/wcp/decoder/package-info.java @@ -1,7 +1,7 @@ -/** - * WCP implementation of the plugin pattern. - * - * Package includes classes to decode the WCP message and persist the data. - * - */ +/** + * WCP implementation of the plugin pattern. + * + * Package includes classes to decode the WCP message and persist the data. + * + */ package gov.noaa.nws.ncep.edex.plugin.wcp.decoder; \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.purgeutil/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.purgeutil/component-deploy.xml index 3551db84ac..7b6fb841a4 100644 --- a/ncep/gov.noaa.nws.ncep.edex.purgeutil/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.purgeutil/component-deploy.xml @@ -1,10 +1,8 @@ - - + + - \ No newline at end of file + +
+ diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.edex.uengine/META-INF/MANIFEST.MF index 3eff7aacac..16c2d33264 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/META-INF/MANIFEST.MF @@ -24,7 +24,7 @@ Require-Bundle: com.raytheon.edex.uengine, com.raytheon.uf.common.dataplugin.level;bundle-version="1.12.1174", com.raytheon.uf.common.pointdata;bundle-version="1.12.1174", gov.noaa.nws.ncep.edex.plugin.ncgrib;bundle-version="1.0.0", - gov.noaa.nws.ncep.common.dataplugin.h5uair;bundle-version="1.0.0" + gov.noaa.nws.ncep.common.dataplugin.ncuair;bundle-version="1.0.0" Export-Package: gov.noaa.nws.ncep.edex.uengine.output, gov.noaa.nws.ncep.edex.uengine.tasks.radar, gov.noaa.nws.ncep.edex.uengine.tasks.response, @@ -35,9 +35,10 @@ Import-Package: com.raytheon.edex.plugin.modelsounding.common, com.raytheon.uf.common.pointdata, com.raytheon.uf.common.pointdata.spatial, com.raytheon.uf.edex.pointdata, - gov.noaa.nws.ncep.common.dataplugin.uair, gov.noaa.nws.ncep.common.tools, + gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion, gov.noaa.nws.ncep.edex.plugin.ncgrib.dao, + gov.noaa.nws.ncep.edex.common.metparameters, javax.measure.converter, javax.measure.unit, org.apache.commons.logging, diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/component-deploy.xml b/ncep/gov.noaa.nws.ncep.edex.uengine/component-deploy.xml index 9fc7f0246b..728789edc1 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/component-deploy.xml +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/component-deploy.xml @@ -1,10 +1,7 @@ - - + + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MdlSoundingQuery.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MdlSoundingQuery.java index aff2c113be..051e98c149 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MdlSoundingQuery.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MdlSoundingQuery.java @@ -233,7 +233,7 @@ public class MdlSoundingQuery { else pf.setSfcPress(sfcPressure); } - System.out.println("surface pressure ="+pf.getSfcPress()); + //System.out.println("surface pressure ="+pf.getSfcPress()+ " lat= "+lat+ " lon="+lon); //calculate dew point if necessary MergeSounding ms = new MergeSounding(); ms.spfhToDewpoint(layerList); @@ -839,7 +839,12 @@ public class MdlSoundingQuery { } long t02 = System.currentTimeMillis(); - System.out.println("MDL profile retreival took " + (t02 - t01)); + //System.out.println("MDL profile retreival took " + (t02 - t01)); + /*/debug + for(NcSoundingLayer layer: soundLyList){ + System.out.println("pre="+ layer.getPressure()+ " h="+layer.getGeoHeight()+ " T="+layer.getTemperature()+" D="+ + layer.getDewpoint()+ " WS="+layer.getWindSpeed()+ " WD="+layer.getWindDirection() + " SH="+layer.getSpecHumidity()+ " RH="+layer.getRelativeHumidity()); + }*/ return soundLyList; } diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding.java index 72f719bc8b..91eee4f760 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/MergeSounding.java @@ -1,13 +1,15 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; -import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +//import edu.emory.mathcs.backport.java.util.Collections; +import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer2; + /** * * gov.noaa.nws.ncep.ui.nsharp.rsc.NsharpMapResource This java class performs @@ -33,1587 +35,1666 @@ import java.util.List; */ public class MergeSounding { - final float RMISSD = IDecoderConstantsN.UAIR_FLOAT_MISSING; - - final int IMISSD = IDecoderConstantsN.INTEGER_MISSING; - - /** - * Default constructor - */ - public MergeSounding() { - } - - /* - * Process native sounding data. Convert specific humidity to dew point - * temperature then compute the moist height. - */ - public List nativeModelSounding(List sls, - float elevation) { - spfhToDewpoint(sls); - constructHeight(sls, elevation); - return sls; - } - - /* - * Process upper air sounding data. Note that TTAA is the original/sorted - * data, while MAN is the TTAA without underground data and MAN_D is the - * TTAA for display, i.e., the first level is the surface level, any under - * -ground levels will be above the surface level. - */ - public List mergeUairSounding(String level, - List ttaa, List ttbb, - List ttcc, List ttdd, - List ppaa, List ppbb, - List ppcc, List ppdd, - List trop_a, List trop_c, - List wmax_a, List wmax_c, - float elevation) { - List sndata = new ArrayList(); - List man = null; - - /* - * ///for debug System.out.println("TTAA:"); for (NcSoundingLayer l: - * ttaa){ - * System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T=" - * +l.getTemperature - * ()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws=" - * +l.getWindSpeed()); } System.out.println("TTBB:"); for - * (NcSoundingLayer l: ttbb){ - * System.out.println("P="+l.getPressure()+"H=" - * +l.getGeoHeight()+"T="+l.getTemperature - * ()+"D="+l.getDewpoint()+"Wd="+l - * .getWindDirection()+"Ws="+l.getWindSpeed()); } - * System.out.println("PPAA:"); for (NcSoundingLayer l: ppaa){ - * System.out - * .println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l.getTemperature - * ( - * )+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws="+l.getWindSpeed - * ()); } System.out.println("PPBB:"); for (NcSoundingLayer l: ppbb){ - * System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l. - * getTemperature - * ()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws=" - * +l.getWindSpeed()); } - */ - // Return the specific levels requested by users - if (ttaa.size() > 0) { - Collections.sort(ttaa, new reverseSortByPressure()); - if (level.toUpperCase().equalsIgnoreCase("MAN")) { - return ttaa; - } - man = removeUnderGround(ttaa); - - } else { - man = ttaa; - if (level.toUpperCase().equalsIgnoreCase("MAN")) { - return setMissing(); - } - - } - - // Sorting the data - - if (ttbb.size() > 0) { - Collections.sort(ttbb, new reverseSortByPressure()); - } - - if (ttcc.size() > 0) { - Collections.sort(ttcc, new reverseSortByPressure()); - } - - if (ttcc.size() > 0) { - Collections.sort(ttdd, new reverseSortByPressure()); - } - - if (ppaa.size() > 0) { - if (checkWindData(ppaa)) { - Collections.sort(ppaa, new MergeSounding.sortByHeight()); - } else { - Collections.sort(ppaa, - new MergeSounding.reverseSortByPressure()); - } - } - - if (ppcc.size() > 0) { - if (checkWindData(ppcc)) { - Collections.sort(ppcc, new MergeSounding.sortByHeight()); - } else { - Collections.sort(ppcc, - new MergeSounding.reverseSortByPressure()); - } - } - - if (ppbb.size() > 0) { - if (checkWindData(ppbb)) { - Collections.sort(ppbb, new MergeSounding.sortByHeight()); - } else { - Collections.sort(ppbb, - new MergeSounding.reverseSortByPressure()); - } - } - - if (ppdd.size() > 0) { - - if (checkWindData(ppdd)) { - Collections.sort(ppdd, new MergeSounding.sortByHeight()); - } else { - Collections.sort(ppdd, - new MergeSounding.reverseSortByPressure()); - } - - } - - // Find surface data, return if users request surface data only. - NcSoundingLayer sl = new NcSoundingLayer(); - sl = getSurfaceData(man, ttbb, ppbb, elevation); - sndata.add(0, sl); - - if (isNumber(level) >= 0) { - if (equal(0.f, Float.valueOf(level.trim()).floatValue()) - || equal(sl.getPressure(), Float.valueOf(level.trim()) - .floatValue())) { - return sndata; - } - } - - // Merge mandatory data - mergeMandatory(man, ttcc, sndata); - - // Check if the single level is mandatory or not - if (isNumber(level) >= 0) { - for (int kk = 0; kk < sndata.size(); kk++) { - if (equal(Float.valueOf(level.trim()).floatValue(), - sndata.get(kk).getPressure())) { - sl.setPressure(sndata.get(kk).getPressure()); - sl.setTemperature(sndata.get(kk).getTemperature()); - sl.setDewpoint(sndata.get(kk).getDewpoint()); - sl.setWindDirection(sndata.get(kk).getWindDirection()); - sl.setWindSpeed(sndata.get(kk).getWindSpeed()); - sl.setGeoHeight(sndata.get(kk).getGeoHeight()); - sndata.clear(); - sndata.add(sl); - return sndata; - } - } - } - - // Merge mandatory winds - mergeMandatoryWinds(ppaa, ppcc, sndata); - - // Merge tropopause - mergeTropSigTemp(trop_a, trop_c, sndata); - - // Merge TTBB - mergeTropSigTemp(ttbb, ttdd, sndata); - - // Construct height for ttbb - constructTtbbHeight(sndata); - - // Merge significant winds on pressure surfaces - if (!checkWindData(ppbb)) { - mergeSigMaxWindOnPressure(ppbb, ppdd, sndata); - } - - mergeSigMaxWindOnPressure(wmax_a, wmax_c, sndata); - constructPpbbHeight(sndata); - - if (checkWindData(ppbb)) { - mergeSigWindOnHeight(ppbb, ppdd, sndata); - constructPpbbPressure(sndata); - } - - // Reorder sounding profile so the first level is the surface data. - // No need to reorder now becuz surface data is always the 1st level. - // reOrderSounding(sndata); - - // Interpolate missing temperature, dew point and winds. - constructMissing(1, sndata); - constructMissing(2, sndata); - constructMissing(3, sndata); - - // Return single level or add underground mandatory data to the sounding - // profile - if (isNumber(level) == 0) { - float rlev = new Integer(Integer.parseInt(level.trim())) - .floatValue(); - return getSingLevel(rlev, sndata); - } else if (isNumber(level) == 1) { - float rlev = new Float(Float.parseFloat(level.trim())); - return getSingLevel(rlev, sndata); - } else { - return addUnderGround(ttaa, sndata); - } - - } - - /* - * Check an alpha-numerical string is a number or characters. - */ - public int isNumber(String level) { - try { - if (Integer.parseInt(level) >= 0) { - return 0; - } else { - return -1; - } - } catch (NumberFormatException nfe1) { - try { - if (Float.parseFloat(level) >= 0.f) { - return 1; - } else { - return -1; - } - } catch (NumberFormatException nfe2) { - try { - if (Double.parseDouble(level) >= 0.) { - return 2; - } else { - return -1; - } - } catch (NumberFormatException nfe3) { - return -1; - } - } - } - } - - /* - * convert specific humidity to dew point temperature. - */ - float elevation; - - public List spfhToDewpoint(List sndata) { - float spfh, pres; - float dwpc = RMISSD; - - for (NcSoundingLayer layer : sndata) { - if (layer.getDewpoint() == RMISSD) { - spfh = layer.getSpecHumidity(); - pres = layer.getPressure(); - - if (spfh == RMISSD || pres == RMISSD || spfh <= 0.f - || pres <= 0.f) { - continue; - } else { - float rmix = spfh / (1.f - spfh); - float e = (pres * rmix) / (.62197f + rmix); - e = e / (1.001f + ((pres - 100.f) / 900.f) * .0034f); - dwpc = (float) (Math.log(e / 6.112) * 243.5 / (17.67 - Math - .log((e / 6.112)))); - layer.setDewpoint(dwpc); - // System.out.println("spfhToDewpoint dwpc: " + dwpc); - } - - } - } - return sndata; - } - - /* - * computes DWPC from TMPC and RELH Note: If DWPC is less than -190 degrees - * C, it is treated as missing data Code is based on GEMPAK's prrhdp.f - */ - public List rhToDewpoint(List sndata) { - float rh, vapr, vaps, temp; - float dwpc = RMISSD; - - for (NcSoundingLayer layer : sndata) { - if (layer.getDewpoint() == RMISSD) { - rh = layer.getRelativeHumidity(); - temp = layer.getTemperature(); - - if (rh == RMISSD || temp == RMISSD) { - continue; - } else { - vaps = tempToVapr(temp); - vapr = rh * vaps / 100; - if (vapr < Math.exp(-30)) - continue; - else { - dwpc = (float) (243.5 * (Math.log(6.112) - Math - .log(vapr)) / (Math.log(vapr) - Math.log(6.112) - 17.67)); - layer.setDewpoint(dwpc); - // System.out.println("rhToDewpoint dwpc: " + dwpc); - } - } - } - } - return sndata; - } - - /* - * computes VAPR from TMPC Code is based on GEMPAK's prvapr.f - */ - private float tempToVapr(float temp) { - return (float) (6.112 * Math.exp((17.67 * temp) / (temp + 243.5))); - } - - private void constructHeight(List sndata, float elev) { - - /* - * For native model sounding, using hypsometric equation to build height - */ - elevation = elev; - int lev = sndata.size(); - float tb = RMISSD, tdb = RMISSD, pb = RMISSD; - float tt = RMISSD, tdt = RMISSD, pt = RMISSD; - float dwptsf, psfc, tmpcsf, scaleh, mhgt = RMISSD; - - for (int k = 0; k < lev; k++) { - - if (k == 0) { - tmpcsf = sndata.get(k).getTemperature(); - dwptsf = sndata.get(k).getDewpoint(); - psfc = sndata.get(k).getPressure(); - tb = tmpcsf; - tt = tmpcsf; - tdb = dwptsf; - tdt = dwptsf; - pb = psfc; - pt = psfc; - - scaleh = scaleHeight(tb, tt, tdb, tdt, pb, pt); - mhgt = moistHeight(elevation, pb, pt, scaleh); - } else { - tt = sndata.get(k).getTemperature(); - tdt = sndata.get(k).getDewpoint(); - pt = sndata.get(k).getPressure(); - scaleh = scaleHeight(tb, tt, tdb, tdt, pb, pt); - - mhgt = moistHeight(mhgt, pb, pt, scaleh); - tb = tt; - tdb = tdt; - pb = pt; - - } - sndata.get(k).setGeoHeight(mhgt); - } - } - - /* - * Compute moist height. - */ - private float moistHeight(float zb, float pb, float pt, float scale) { - if (zb == RMISSD || pb == RMISSD || pt == RMISSD || scale == RMISSD) { - return RMISSD; - } else { - return (float) (zb + scale * Math.log(pb / pt)); - } - } - - /* - * Compute scale height. - */ - private float scaleHeight(float tb, float tt, float tdb, float tdt, - float pb, float pt) { - final float RDGAS = 287.04f, GRAVTY = 9.80616f, RKAP = RDGAS / GRAVTY; - if (tb == RMISSD || tt == RMISSD || pb == RMISSD || pt == RMISSD) { - return RMISSD; - } else { - float tvb = virtualTemperature(tb, tdb, pb); - float tvt = virtualTemperature(tt, tdt, pt); - - if (tvb == RMISSD || tvt == RMISSD) { - return RMISSD; - } else { - float tav = (tvb + tvt) / 2.0f; - return (RKAP * tav); - } - } - } - - /* - * Compute virtual temperature - */ - private float virtualTemperature(float tt, float td, float pres) { - if (tt == RMISSD || pres == RMISSD) { - return RMISSD; - } else if (td == RMISSD) { - return celciusToKevin(tt); - } else { - float tmpk = celciusToKevin(tt); - float rmix = mixingRatio(td, pres); - if (rmix == RMISSD) { - return celciusToKevin(tt); - } else { - return tmpk * (1.f + .001f * rmix / .62197f) - / (1.f + .001f * rmix); - } - } - } - - /* - * Convert Celcius to Kelvin. - */ - float TMCK = 273.15f; - - private float celciusToKevin(float tc) { - if (tc == RMISSD) { - return RMISSD; - } else { - return (tc + TMCK); - } - } - - /* - * Compute mixing ratio from DWPC and PRES. - */ - private float mixingRatio(float td, float pres) { - if (td == RMISSD || pres == RMISSD) { - return RMISSD; - } else { - float vapr = vaporPressure(td); - if (vapr == RMISSD) { - return RMISSD; - } - - float corr = (1.001f + ((pres - 100.f) / 900.f) * .0034f); - - float e = corr * vapr; - if (e > (.5f * pres)) { - return RMISSD; - } else { - return .62197f * (e / (pres - e)) * 1000.f; - } - } - } - - /* - * Compute vapor pressure from DWPC. - */ - private float vaporPressure(float td) { - if (td == RMISSD) { - return RMISSD; - } else { - return (6.112f * (float) Math.exp((17.67 * td) / (td + 243.5))); - } - } - - /* - * Merge observed sounding data - */ - - /* - * Check significant wind data (PPBB/PPDD) to see if the data is reported on - * pressure or height surfaces. Return TRUE if reported on height. The input - * can be PPBB or PPDD winds. (MR_CHKW) - * - * Note that this is coded different from MR_CHKW, in that it will set zwind - * to false only if pressure is less than 0. An odd logic. - */ - public boolean checkWindData(List sndata) { - boolean zwind = true; - for (int kk = 0; kk < sndata.size(); kk++) { - if (sndata.get(kk).getPressure() != RMISSD) { - zwind = false; - } - } - return zwind; - } - - /* - * Find surface data. (MR_SRFC) - */ - final int NPARMS = 7; - - public NcSoundingLayer getSurfaceData(List man, - List ttbb, List ppbb, - float elevation) { - float pres = RMISSD; - NcSoundingLayer sl_sfc = new NcSoundingLayer(); - - /* - * Check for surface information in mandatory data. - */ - if (man.size() < 1) { - for (int k = 0; k < NPARMS; k++) { - sl_sfc.setPressure(RMISSD); - sl_sfc.setTemperature(RMISSD); - sl_sfc.setDewpoint(RMISSD); - sl_sfc.setWindDirection(RMISSD); - sl_sfc.setWindSpeed(RMISSD); - sl_sfc.setGeoHeight(RMISSD); - sl_sfc.setOmega(RMISSD); - return sl_sfc; - } - } else { - - // If surface pressure is higher than 1080mb, set to missing. - // Note that GEMPAK sets it to 1060mb. - pres = man.get(0).getPressure(); - if (pres > 1080.) { - sl_sfc.setPressure(RMISSD); - } else { - sl_sfc.setPressure(pres); - } - sl_sfc.setTemperature(man.get(0).getTemperature()); - sl_sfc.setDewpoint(man.get(0).getDewpoint()); - sl_sfc.setWindDirection(man.get(0).getWindDirection()); - sl_sfc.setWindSpeed(man.get(0).getWindSpeed()); - sl_sfc.setGeoHeight(elevation); - sl_sfc.setOmega(man.get(0).getOmega()); - } - - /* - * Find the first reporting mandatory level above the surface. - */ - float pman = RMISSD; - int iman = 1; - while (pman == RMISSD && iman < man.size()) { - if (man.get(iman).getPressure() != RMISSD - && man.get(iman).getTemperature() != RMISSD - && man.get(iman).getGeoHeight() != RMISSD) { - pman = man.get(0).getPressure(); - } - iman++; - } - - /* - * If surface pressure is missing or is less than first reporting - * mandatory level, set all surface data to missing - */ - if (pres == RMISSD || (pres < pman && pman != RMISSD)) { - sl_sfc = setMissing().get(0); - } - - /* - * If the surface significant temperature data is not missing, use it to - * replace the surface pressure, temperature and dewpoint. The check for - * significant level pressure to be less than or equal to pman - * eliminates using wildly erroneous data. - */ - - if (ttbb.size() >= 1 && ttbb.get(0).getPressure() != RMISSD - && ttbb.get(0).getTemperature() != RMISSD) { - pman = sl_sfc.getPressure(); - float psql = ttbb.get(0).getPressure(); - if (pman == RMISSD || equal(pman, psql)) { - sl_sfc.setPressure(ttbb.get(0).getPressure()); - sl_sfc.setTemperature(ttbb.get(0).getTemperature()); - sl_sfc.setDewpoint(ttbb.get(0).getDewpoint()); - } - - } - - /* - * If the first significant level wind data is surface information, use - * it to replace the surface data if the pressure is at surface. - */ - - // PPBB reported on P-surfaces. - - if (checkWindData(ppbb)) { - if (ppbb.size() > 0 && ppbb.get(0).getGeoHeight() == 0. - && ppbb.get(0).getWindDirection() != RMISSD) { - sl_sfc.setWindDirection(ppbb.get(0).getWindDirection()); - sl_sfc.setWindSpeed(ppbb.get(0).getWindSpeed()); - } - - } else { - if (ppbb.size() > 0 && ppbb.get(0).getPressure() != RMISSD - && ppbb.get(0).getWindDirection() != RMISSD) { - pman = sl_sfc.getPressure(); - float psgl = Math.abs(ppbb.get(0).getPressure()); - if (pman == RMISSD || equal(pman, psgl)) { - sl_sfc.setPressure(psgl); - sl_sfc.setWindDirection(ppbb.get(0).getWindDirection()); - sl_sfc.setWindSpeed(ppbb.get(0).getWindSpeed()); - } - } - } - - /* - * Add surface data to station data. - */ - return sl_sfc; - } - - private boolean equal(float x, float y) { - final float RDIFFD = .0001f; - if ((x + y) == 0.) { - return Math.abs(x - y) < RDIFFD; - } else { - return Math.abs(x - y) / Math.abs((x + y) / 2.) < RDIFFD; - } - } - - /* - * Merge the mandatory below 100 mb data and the mandatory above data. - * sndata has surface observation ONLY. (MR_MAND) - */ - - public void mergeMandatory(List man_a, - List man_c, List sndata) { - - float plast; - if (man_a.size() < 1 && man_c.size() < 1) { - return; - } - - if (sndata.get(0).getPressure() == RMISSD) { - plast = 2000.f; - } else { - plast = sndata.get(0).getPressure(); - } - - /* - * Move the mandatory data below 100mb to the output array, sndata. - * Check that pressure is not missing and is decreasing. - */ - float pres; - if (man_a.size() > 0) { - for (int kk = 0; kk < man_a.size(); kk++) { - pres = man_a.get(kk).getPressure(); - if (pres < plast - && pres != RMISSD - && (man_a.get(kk).getTemperature() != RMISSD || man_a - .get(kk).getWindDirection() != RMISSD)) { - addDataToList(kk, man_a, sndata); - plast = pres; - } - } - } - - /* - * Move the mandatory data above 100 mb to the output array. - */ - if (man_c.size() > 0) { - for (int kk = 0; kk < man_c.size(); kk++) { - pres = man_c.get(kk).getPressure(); - if (pres < plast && pres != RMISSD - && man_c.get(kk).getTemperature() != RMISSD) { - addDataToList(kk, man_c, sndata); - plast = man_c.get(kk).getPressure(); - } - } - } - } - - /* - * Merge the mandatory below 100 mb wind data and the mandatory above wind - * data. (MR_MANW) - */ - public void mergeMandatoryWinds(List man_wa, - List man_wc, List sndata) { - - if (man_wa.size() < 1 && man_wc.size() < 1) { - return; - } - - /* - * Append data. - */ - if (man_wc.size() > 0) { - for (int kk = 0; kk < man_wc.size(); kk++) { - man_wa.add(man_wc.get(kk)); - } - } - /* - * Loop through mandatory wind data. - */ - for (int lev = 0; lev < man_wa.size(); lev++) { - - /* - * If this is the correct level, add wind data. - */ - boolean found = false; - float ppp = man_wa.get(lev).getPressure(); - for (int kk = 0; kk < sndata.size() && !found; kk++) { - float pres = sndata.get(kk).getPressure(); - if (equal(ppp, pres)) { - if (sndata.get(kk).getWindDirection() == RMISSD) { - sndata.get(kk).setWindDirection( - man_wa.get(lev).getWindDirection()); - sndata.get(kk).setWindSpeed( - man_wa.get(lev).getWindSpeed()); - } - found = true; - } - } - - /* - * If not found, add to the list - */ - if (!found) { - float ddd = man_wa.get(lev).getWindDirection(); - if (ppp != RMISSD && ddd != RMISSD) { - addDataToList(lev, man_wa, sndata); - } - } - } - } - - /* - * Merge tropopause, max wind and significant temperature data (TTBB) to the - * station data array. The input parameter could be tropopause data or - * significant temperature data. MR_TROP & MR_SIGT - */ - public List mergeTropSigTemp(List trop_a, - List trop_c, List sndata) { - if (trop_a.size() < 1 && trop_c.size() < 1) { - return sndata; - } - - /* - * Append two lists of wind data. - */ - if (trop_c.size() > 0) { - for (int kk = 0; kk < trop_c.size(); kk++) { - trop_a.add(trop_c.get(kk)); - } - } - - for (int lev = 0; lev < trop_a.size(); lev++) { - boolean found = false; - float ppp = trop_a.get(lev).getPressure(); - for (int kk = 0; kk < sndata.size() && !found; kk++) { - float pres = sndata.get(kk).getPressure(); - if (equal(ppp, pres)) { - - // add data to missing - if (sndata.get(kk).getTemperature() == RMISSD) { - sndata.get(kk).setTemperature( - trop_a.get(lev).getTemperature()); - sndata.get(kk).setDewpoint( - trop_a.get(lev).getDewpoint()); - } - - if (sndata.get(kk).getWindDirection() == RMISSD) { - sndata.get(kk).setWindDirection( - trop_a.get(lev).getWindDirection()); - sndata.get(kk).setWindSpeed( - trop_a.get(lev).getWindSpeed()); - - } - found = true; - } - } - - /* - * if not found, add to the list - */ - if (!found) { - float ttt = trop_a.get(lev).getTemperature(); - if (ppp != RMISSD && ttt != RMISSD) { - addDataToList(lev, trop_a, sndata); - } - } - - } - - /* - * Sort the sounding data in descending order. - */ - Collections.sort(sndata, new reverseSortByPressure()); - return sndata; - } - - /* - * Compute height at significant temperature levels (TTBB) using a moist - * hydrostatic computation. (MR_SCMZ) - */ - public void constructTtbbHeight(List sndata) { - boolean mand = false; - boolean newblock = true; - int blev = 0, tlev = 0; - float[] scale = new float[200]; - float pb, zb, tb, tdb, zlev, plev; - float pt, zt = 0.f, tt, tdt, znew = 0.f; - - if (sndata.size() <= 2) - return; - - for (int nlev = 0; nlev < sndata.size(); nlev++) { - if (newblock) { - if (sndata.get(nlev).getGeoHeight() != RMISSD - && sndata.get(nlev).getPressure() != RMISSD - && sndata.get(nlev).getTemperature() != RMISSD) { - - blev = nlev; - newblock = false; - } - } else { - if (sndata.get(nlev).getGeoHeight() != RMISSD - && sndata.get(nlev).getTemperature() != RMISSD) { - tlev = nlev; - mand = true; - } - } - - /* - * Compute scale height to this level - */ - if (mand) { - pb = sndata.get(blev).getPressure(); - zb = sndata.get(blev).getGeoHeight(); - tb = sndata.get(blev).getTemperature(); - tdb = sndata.get(blev).getDewpoint(); - zlev = sndata.get(blev).getGeoHeight(); - plev = sndata.get(blev).getPressure(); - - for (int kk = blev + 1; kk <= tlev; kk++) { - pt = sndata.get(kk).getPressure(); - zt = sndata.get(kk).getGeoHeight(); - tt = sndata.get(kk).getTemperature(); - tdt = sndata.get(kk).getDewpoint(); - scale[kk] = scaleHeight(tb, tt, tdb, tdt, pb, pt); - znew = moistHeight(zb, pb, pt, scale[kk]); - if (znew != RMISSD) { - pb = pt; - tb = tt; - tdb = tdt; - zb = znew; - } - } - - /* - * Compute the scaling factor so the computed moist height is - * consistent at the mandatory level. Then recompute the height. - */ - float s = (zt - zlev) / (znew - zlev); - float zbb = zlev; - float pbb = plev; - for (int kk = blev + 1; kk < tlev; kk++) { - pt = sndata.get(kk).getPressure(); - zt = sndata.get(kk).getGeoHeight(); - scale[kk] = scale[kk] * s; - znew = moistHeight(zbb, pbb, pt, scale[kk]); - if (znew != RMISSD) { - pbb = pt; - zbb = znew; - sndata.get(kk).setGeoHeight(znew); - } - } - mand = false; - newblock = true; - - if ((tlev + 1) != sndata.size()) { - if (sndata.get(tlev + 1).getGeoHeight() == RMISSD - && sndata.get(tlev + 1).getPressure() != RMISSD - && sndata.get(tlev + 1).getTemperature() != RMISSD) { - nlev--; - } - } - } - } - - // Compute height at the missing top levels - - if ((tlev + 1) < sndata.size()) { - blev = tlev; - pb = sndata.get(blev).getPressure(); - zb = sndata.get(blev).getGeoHeight(); - tb = sndata.get(blev).getTemperature(); - tdb = sndata.get(blev).getDewpoint(); - zlev = sndata.get(blev).getGeoHeight(); - plev = sndata.get(blev).getPressure(); - for (int kk = tlev + 1; kk < sndata.size(); kk++) { - pt = sndata.get(kk).getPressure(); - zt = sndata.get(kk).getGeoHeight(); - tt = sndata.get(kk).getTemperature(); - tdt = sndata.get(kk).getDewpoint(); - float xxx = scaleHeight(tb, tt, tdb, tdt, pb, pt); - znew = moistHeight(zb, pb, pt, xxx); - if (znew != RMISSD) { - sndata.get(kk).setGeoHeight(znew); - pb = pt; - tb = tt; - tdb = tdt; - zb = znew; - } - } - } - - return; - } - - /* - * Merge the significant and maximum wind data on pressure surfaces. MR_PWND - */ - public void mergeSigMaxWindOnPressure(List sig_wa, - List sig_wc, List sndata) { - - /* - * Do nothing if wind report is reported on height surfaces. - */ - - if (checkWindData(sig_wa) || checkWindData(sig_wc) - || (sig_wa.size() < 1 && sig_wc.size() < 1)) { - return; - } - - /* - * Append two lists of wind data. - */ - if (sig_wc.size() > 0) { - for (int kk = 0; kk < sig_wc.size(); kk++) { - sig_wa.add(sig_wc.get(kk)); - } - } - - /* - * Merging - */ - int nlevel = sndata.size(); - for (int kk = 0; kk < sig_wa.size(); kk++) { - boolean found = false; - for (int lev = 0; lev < nlevel; lev++) { - if (equal(sndata.get(lev).getPressure(), sig_wa.get(kk) - .getPressure())) { - - // add data to missing - if (sndata.get(lev).getWindDirection() == RMISSD) { - sndata.get(lev).setWindDirection( - sig_wa.get(kk).getWindDirection()); - sndata.get(lev).setWindSpeed( - sig_wa.get(kk).getWindSpeed()); - } - found = true; - } - } - - /* - * if not found, add to the list. - */ - if (!found) { - if ((sig_wa.get(kk).getWindDirection() != RMISSD && sig_wa.get( - kk).getPressure() != RMISSD)) { - - NcSoundingLayer sl = new NcSoundingLayer(); - sl.setPressure(sig_wa.get(kk).getPressure()); - sl.setTemperature(sig_wa.get(kk).getTemperature()); - sl.setDewpoint(sig_wa.get(kk).getDewpoint()); - sl.setWindDirection(sig_wa.get(kk).getWindDirection()); - sl.setWindSpeed(sig_wa.get(kk).getWindSpeed()); - sl.setGeoHeight(sig_wa.get(kk).getGeoHeight()); - sl.setOmega(sig_wa.get(kk).getOmega()); - sndata.add(sl); - } - } - Collections.sort(sndata, new reverseSortByPressure()); - } - return; - } - - /* - * Construct height at significant wind levels (PPBB) if reported on - * pressure levels. Using moist hydrostatic computation for missing height - * at top levels. MR_INTZ - */ - public void constructPpbbHeight(List sndata) { - int tlev = 0; - for (int kk = sndata.size() - 1; kk >= 0; kk--) { - if (sndata.get(kk).getGeoHeight() != RMISSD) { - tlev = kk; - break; - } - } - - float pb = RMISSD, pt = RMISSD, zt = RMISSD, zb = RMISSD; - int next; - - if (sndata.size() <= 2) - return; - - for (int kk = 0; kk < tlev; kk++) { - float pres = sndata.get(kk).getPressure(); - float hght = sndata.get(kk).getGeoHeight(); - if (pres == RMISSD) { - // DO NOTHING - } else if (hght != RMISSD) { - pb = pres; - zb = hght; - pt = 2000.f; - } else if (pb == RMISSD) { - // DO NOTHING - } else { - - /* - * Find next level with height and then interpolate the data. - */ - next = kk + 1; - while (pres <= pt) { - if (sndata.get(next).getGeoHeight() != RMISSD) { - pt = sndata.get(next).getPressure(); - zt = sndata.get(next).getGeoHeight(); - } else { - next++; - } - } - float hhh = (float) (zb + (zt - zb) - * (Math.log(pres / pb) / Math.log(pt / pb))); - sndata.get(kk).setGeoHeight(hhh); - } - } - - if (tlev == (sndata.size() - 1)) { - return; - } else { - - /* - * Compute moist hydrostatic height for missing height at top - * levels. - */ - float scale; - float tb, tdb; - float tt, tdt, mhght = 0.f; - pb = sndata.get(tlev).getPressure(); - zb = sndata.get(tlev).getGeoHeight(); - tb = sndata.get(tlev).getTemperature(); - tdb = sndata.get(tlev).getDewpoint(); - - for (int kk = tlev + 1; kk < sndata.size(); kk++) { - if (sndata.get(kk).getGeoHeight() == RMISSD) { - pt = sndata.get(kk).getPressure(); - zt = sndata.get(kk).getGeoHeight(); - tt = sndata.get(kk).getTemperature(); - tdt = sndata.get(kk).getDewpoint(); - scale = scaleHeight(tb, tt, tdb, tdt, pb, pt); - mhght = moistHeight(zb, pb, pt, scale); - sndata.get(kk).setGeoHeight(mhght); - if (mhght != RMISSD) { - pb = pt; - zb = zt; - tb = tt; - tdb = tdt; - } - } - } - return; - } - } - - /* - * Merge significant wind on height surfaces. The argument is sndata. - */ - public void mergeSigWindOnHeight(List sig_wa, - List sig_wc, List sndata) { - - /* - * The following code needs to be replaced by significant wind data from - * database. - */ - - /* - * Do nothing if wind report is not on height surfaces. - */ - if (!checkWindData(sig_wa) || !checkWindData(sig_wc) - || (sig_wa.size() < 1 && sig_wc.size() < 1)) { - return; - } - - /* - * Add two lists of wind data. - */ - if (sig_wc.size() > 0) { - for (int kk = 0; kk < sig_wc.size(); kk++) { - sig_wa.add(sig_wc.get(kk)); - } - } - - int nlevel = sndata.size(); - for (int kk = 0; kk < sig_wa.size(); kk++) { - boolean found = false; - float zzz = sig_wa.get(kk).getGeoHeight(); - - // Check surface level independently because sometimes station - // report wind data twice at surface. We don't want the surface - // pressure to be missing. - if (zzz == 0) { - if (sndata.get(0).getWindDirection() == RMISSD) { - sndata.get(0).setWindDirection( - sig_wa.get(0).getWindDirection()); - sndata.get(0).setWindSpeed(sig_wa.get(kk).getWindSpeed()); - } - found = true; - } else { - for (int lev = 0; lev < nlevel; lev++) { - float hght = sndata.get(lev).getGeoHeight(); - if (equal(zzz, hght) || (zzz == 0 && lev == 0 && kk == 0)) { - // add data to missing - if (sndata.get(lev).getWindDirection() == RMISSD) { - sndata.get(lev).setWindDirection( - sig_wa.get(kk).getWindDirection()); - sndata.get(lev).setWindSpeed( - sig_wa.get(kk).getWindSpeed()); - } - found = true; - } - } - } - - /* - * if not found, add to the list. - */ - if (!found) { - if (sig_wa.get(kk).getWindDirection() != RMISSD - && sig_wa.get(kk).getGeoHeight() != RMISSD) { - NcSoundingLayer sl = new NcSoundingLayer(); - sl.setPressure(sig_wa.get(kk).getPressure()); - sl.setTemperature(sig_wa.get(kk).getTemperature()); - sl.setDewpoint(sig_wa.get(kk).getDewpoint()); - sl.setWindDirection(sig_wa.get(kk).getWindDirection()); - sl.setWindSpeed(sig_wa.get(kk).getWindSpeed()); - sl.setGeoHeight(sig_wa.get(kk).getGeoHeight()); - sl.setOmega(sig_wa.get(kk).getOmega()); - sndata.add(sl); - } - } - } - - /* - * Sorting the combined temperature and wind data based on Geopotential - * height. - */ - Collections.sort(sndata, new sortByHeight()); - return; - } - - // Sort by height - public static class sortByHeight implements Comparator { - @Override - public int compare(NcSoundingLayer l1, NcSoundingLayer l2) { - return Float.compare(l1.getGeoHeight(), l2.getGeoHeight()); - } - - } - - // Reverse sort by pressure - public static class reverseSortByPressure implements - Comparator { - @Override - public int compare(NcSoundingLayer l1, NcSoundingLayer l2) { - return Float.compare(l2.getPressure(), l1.getPressure()); - } - - } - - /* - * Construct pressure at significant wind levels (PPBB) that are reported on - * height levels. MR_INTP - */ - public List constructPpbbPressure( - List sndata) { - - if (sndata.size() <= 2) - return sndata; - - float pb = RMISSD, pt = RMISSD, zt = RMISSD, zb = RMISSD; - int blev = IMISSD, tlev = IMISSD; - for (int lev = 0; lev < sndata.size(); lev++) { - float pres = sndata.get(lev).getPressure(); - float hght = sndata.get(lev).getGeoHeight(); - if (pres != RMISSD && hght != RMISSD) { - tlev = lev; - pt = pres; - zt = hght; - } - - if (blev != IMISSD && tlev != IMISSD) { - for (int kk = blev + 1; kk < tlev; kk++) { - float z = sndata.get(kk).getGeoHeight(); - if (sndata.get(kk).getGeoHeight() != RMISSD) { - float ppp = (float) (pb * Math.exp(((z - zb) - * Math.log(pt / pb) / (zt - zb)))); - sndata.get(kk).setPressure(ppp); - } - } - } - blev = tlev; - pb = pt; - zb = zt; - } - - // System.out.println ( " tlev: " + tlev + " sndata.size() -1 " + - // (sndata.size()-1)); - - if (tlev == (sndata.size() - 1) || tlev == IMISSD) { - return sndata; - } else { - - /* - * Compute missing pressure at top levels. - */ - pb = sndata.get(tlev - 1).getPressure(); - zb = sndata.get(tlev - 1).getGeoHeight(); - - for (int kk = tlev + 1; kk < sndata.size(); kk++) { - if (sndata.get(kk).getPressure() == RMISSD) { - pt = sndata.get(kk - 1).getPressure(); - zt = sndata.get(kk - 1).getGeoHeight(); - float zz = sndata.get(kk).getGeoHeight(); - float rmult = ((zz - zb) / (zt - zb)); - sndata.get(kk).setPressure( - (float) (pb * (Math.pow(pt / pb, rmult)))); - pb = pt; - zb = zt; - } - } - } - return sndata; - } - - /* - * Reorder the sounding data so the first level is always the surface data. - */ - public List reOrderSounding(List sndata) { - List outdat = new ArrayList(); - float tt, td, dd, ff; - int klev = 0; - if (sndata.size() <= 1) - return sndata; - - /* - * Find the surface level - */ - for (int kk = 0; kk < sndata.size(); kk++) { - tt = sndata.get(kk).getTemperature(); - td = sndata.get(kk).getDewpoint(); - dd = sndata.get(kk).getWindDirection(); - ff = sndata.get(kk).getWindSpeed(); - if (tt == RMISSD && td == RMISSD && dd == RMISSD && ff == RMISSD) { - // DO NOTHING - } else { - klev = kk; - addDataToList(0, sndata, outdat); - } - } - - /* - * Reorder the data below the surface levels. - */ - for (int kk = 0; kk < klev; kk++) { - addDataToList(kk, sndata, outdat); - } - - for (int kk = klev + 1; kk < sndata.size(); kk++) { - addDataToList(kk, sndata, outdat); - } - return outdat; - } - - /* - * Construct missing temperature (iflag = 1), dewpoint temperature (iflag=2) - * and wind (iflag = 3). This method is called after reOrderSounding(). - * MR_MISS - */ - public List constructMissing(int iflag, - List sndata) { - float pb = RMISSD, pt = RMISSD, data = RMISSD, pres, tb, tt, tdb, tdt; - int jlev = IMISSD, tlev = IMISSD; - boolean contin = true; - if (sndata.size() <= 2) - return sndata; - for (int blev = 1; blev < sndata.size() - 1 && contin; blev++) { - jlev = blev; - - switch (iflag) { - case 1: { - data = sndata.get(blev).getTemperature(); - break; - } - case 2: { - data = sndata.get(blev).getDewpoint(); - break; - } - case 3: { - data = sndata.get(blev).getWindDirection(); - break; - } - default: { - System.out.println("Invalid data flag"); - return sndata; - } - } - - if (data == RMISSD) { - - /* - * find data at level above. Data should already be at level - * below after reOrderSounding() call. - */ - boolean found = false; - while (!found) { - jlev++; - switch (iflag) { - case 1: { - data = sndata.get(jlev).getTemperature(); - break; - } - case 2: { - data = sndata.get(jlev).getDewpoint(); - break; - } - case 3: { - data = sndata.get(jlev).getWindDirection(); - break; - } - default: { - System.out.println("Invalid data flag"); - } - } - int top = sndata.size(); - if (data != RMISSD || jlev + 1 >= top) { - found = true; - tlev = jlev; - if (jlev >= top) { - tlev = IMISSD; - contin = false; - } - } - } - - /* - * Add check to eliminate dew point layer more than 100mb. - */ - if (iflag == 2 && tlev != IMISSD) { - if ((sndata.get(blev).getPressure() - sndata.get(tlev) - .getPressure()) > 100.) { - for (int kk = tlev; kk < sndata.size(); kk++) { - sndata.get(kk).setDewpoint(RMISSD); - } - tlev = IMISSD; - contin = false; - } - } - - /* - * Add check to eliminate interpolation of winds from below 100 - * mb to above 100 mb. This eliminates interpolation to very - * high level winds. - */ - /* - * if (iflag == 3 && tlev != IMISSD && (sndata.get(blev - - * 1).getPressure() > 100.) && (sndata.get(tlev).getPressure() < - * 100.)) { tlev = IMISSD; } - */ - /* - * Interpolate with respect to logP. - */ - - if (tlev != IMISSD) { - pb = sndata.get(blev - 1).getPressure(); - pres = sndata.get(blev).getPressure(); - pt = sndata.get(tlev).getPressure(); - float rmult = (float) (Math.log(pres / pb) / Math.log(pt - / pb)); - switch (iflag) { - case 1: { - tb = sndata.get(blev - 1).getTemperature(); - tt = sndata.get(tlev).getTemperature(); - if (tb != RMISSD && tt != RMISSD) { - data = tb + (tt - tb) * rmult; - sndata.get(blev).setTemperature(data); - } - - tdb = sndata.get(blev - 1).getDewpoint(); - tdt = sndata.get(tlev).getDewpoint(); - if (tdb != RMISSD && tdt != RMISSD) { - data = tdb + (tdt - tdb) * rmult; - sndata.get(blev).setDewpoint(data); - } - break; - } - case 2: { - tdb = sndata.get(blev - 1).getDewpoint(); - tdt = sndata.get(tlev).getDewpoint(); - if (tdb != RMISSD && tdt != RMISSD) { - data = tdb + (tdt - tdb) * rmult; - sndata.get(blev).setDewpoint(data); - } - break; - } - case 3: { - float drctb = sndata.get(blev - 1).getWindDirection(); - float drctt = sndata.get(tlev).getWindDirection(); - - if (drctt != RMISSD && drctb != RMISSD) { - drctb = drctb % 360.f; - drctt = drctt % 360.f; - if (Math.abs(drctb - drctt) > 180.f) { - if (drctb < drctt) { - drctb = drctb + 360.f; - } else { - drctt = drctt + 360.f; - } - } - float drct = (drctb + (drctt - drctb) * rmult) % 360.f; - sndata.get(blev).setWindDirection(drct); - - // Interpolate wind speed - float spedb = sndata.get(blev - 1).getWindSpeed(); - float spedt = sndata.get(tlev).getWindSpeed(); - float sped = spedb + (spedt - spedb) * rmult; - sndata.get(blev).setWindSpeed(sped); - } - break; - - } - } - } - } - } - return sndata; - } - - /* - * Re-order the data so the first level is always the ground level. MR_COND - */ - public List addUnderGround(List man, - List sndata) { - - if (sndata.get(0).getPressure() == RMISSD || man.size() < 1 - || sndata.size() <= 1) { - return sndata; - } - - int blev = 0; - boolean contin = true; - while (blev < sndata.size() && contin) { - if (man.get(blev).getPressure() > sndata.get(0).getPressure()) { - blev++; - } else { - contin = false; - } - } - - if (blev >= sndata.size()) { - return sndata; - } - - /* - * Added below-ground mandatory levels to sounding layers. - */ - List outdat = new ArrayList(); - - int nlev = sndata.size(); - - // write to surface data first - addDataToList(0, sndata, outdat); - - // add below-ground mandatory data - if (blev > 0 && blev < sndata.size()) { - for (int kk = 0; kk < blev; kk++) { - addDataToList(kk, man, outdat); - } - } - - // add the rest of the data - for (int kk = 1; kk < nlev; kk++) { - addDataToList(kk, sndata, outdat); - } - return outdat; - - } - - /* - * Re-order the data so the first level is always the ground level. MR_COND - */ - public List removeUnderGround(List sndata) { - List outdat = new ArrayList(); - /* - * Remove below-ground mandatory levels from sounding layers. Only the - * first 8 missing levels can be mandatory levels. - */ - if (sndata.size() <= 1) - return sndata; - for (int kk = 0; kk < sndata.size(); kk++) { - if (sndata.get(kk).getTemperature() <= RMISSD - && sndata.get(kk).getDewpoint() <= RMISSD - && sndata.get(kk).getWindDirection() <= RMISSD - && sndata.get(kk).getWindSpeed() <= RMISSD) { - } else if (sndata.get(kk).getPressure() <= RMISSD) { - } else { - addDataToList(kk, sndata, outdat); - } - } - return outdat; - } - - /* - * Interpolate data to a single level, including surface. - */ - public List getSingLevel(float pres, - List sndata) { - NcSoundingLayer sl = new NcSoundingLayer(); - List sls = new ArrayList(); - if (sndata.size() <= 1) - return setMissing(); - - sndata = removeUnderGround(sndata); - - for (int kk = 0; kk < sndata.size(); kk++) { - if (pres > sndata.get(0).getPressure() || pres < 0.f) { - return setMissing(); - } else { - - if (pres >= sndata.get(kk).getPressure()) { - float pt, pb, zt, zb, tt, tb, tdt, tdb, dt, db, st, sb; - pb = sndata.get(kk - 1).getPressure(); - pt = sndata.get(kk).getPressure(); - tb = sndata.get(kk - 1).getTemperature(); - tt = sndata.get(kk).getTemperature(); - tdb = sndata.get(kk - 1).getDewpoint(); - tdt = sndata.get(kk).getDewpoint(); - db = sndata.get(kk - 1).getWindDirection() % 360.f; - dt = sndata.get(kk).getWindDirection() % 360.f; - sb = sndata.get(kk - 1).getWindSpeed(); - st = sndata.get(kk).getWindSpeed(); - zb = sndata.get(kk - 1).getGeoHeight(); - zt = sndata.get(kk).getGeoHeight(); - sl.setPressure(pres); - - float rmult = (float) (Math.log(pres / pb) / Math.log(pt - / pb)); - sl.setTemperature(tb + (tt - tb) * rmult); - sl.setDewpoint(tdb + (tdt - tdb) * rmult); - if (Math.abs(db - dt) > 180.) { - if (db < dt) { - db = db + 360.f; - } else { - dt = dt + 360.f; - } - } - sl.setWindDirection(db + (dt - db) * rmult); - sl.setWindSpeed(sb + (st - sb) * rmult); - sl.setGeoHeight(zb + (zt - zb) * rmult); - sls.add(sl); - return sls; - } - } - } - return setMissing(); - } - - /* - * Add data to output sounding profile. - */ - public void addDataToList(int index, List indat, - List outdat) { - NcSoundingLayer sl = new NcSoundingLayer(); - sl.setPressure(indat.get(index).getPressure()); - sl.setTemperature(indat.get(index).getTemperature()); - sl.setDewpoint(indat.get(index).getDewpoint()); - sl.setWindDirection(indat.get(index).getWindDirection()); - sl.setWindSpeed(indat.get(index).getWindSpeed()); - sl.setGeoHeight(indat.get(index).getGeoHeight()); - sl.setOmega(indat.get(index).getOmega()); - outdat.add(sl); - } - - /* - * Set missing to output sounding profile. - */ - public List setMissing() { - List outdat = new ArrayList(); - NcSoundingLayer sl = new NcSoundingLayer(); - sl.setPressure(RMISSD); - sl.setTemperature(RMISSD); - sl.setDewpoint(RMISSD); - sl.setWindDirection(RMISSD); - sl.setWindSpeed(RMISSD); - sl.setGeoHeight(RMISSD); - sl.setOmega(RMISSD); - outdat.add(sl); - return outdat; - } + final float RMISSD = IDecoderConstantsN.UAIR_FLOAT_MISSING; + final int IMISSD = IDecoderConstantsN.INTEGER_MISSING; + + /** + * Default constructor + */ + public MergeSounding() { + } + + /* + * Process native sounding data. Convert specific humidity to dew point + * temperature then compute the moist height. + */ + public List nativeModelSounding(List sls, + float elevation) { + spfhToDewpoint(sls); + constructHeight(sls, elevation); + return sls; + } + + /* + * Process upper air sounding data. Note that TTAA is the original/sorted + * data, while MAN is the TTAA without underground data and MAN_D is the + * TTAA for display, i.e., the first level is the surface level, any under + * -ground levels will be above the surface level. + */ + public List mergeUairSounding(String level, + List ttaa, Listttbb, + List ttcc, Listttdd, + List ppaa, Listppbb, + List ppcc, Listppdd, + List trop_a, List trop_c, + List wmax_a, List wmax_c, + float elevation ) { + List sndata = new ArrayList(); + List man = null; +//System.out.println ( "From mergeUairSounding " ); + /*///for debug +//System.out.println("TTAA:"); + for (NcSoundingLayer l: ttaa){ + //System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l.getTemperature()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws="+l.getWindSpeed()); + } +//System.out.println("TTBB:"); + for (NcSoundingLayer l: ttbb){ + //System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l.getTemperature()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws="+l.getWindSpeed()); + } +//System.out.println("PPAA:"); + for (NcSoundingLayer l: ppaa){ + //System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l.getTemperature()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws="+l.getWindSpeed()); + } +//System.out.println("PPBB:"); + for (NcSoundingLayer l: ppbb){ + //System.out.println("P="+l.getPressure()+"H="+l.getGeoHeight()+"T="+l.getTemperature()+"D="+l.getDewpoint()+"Wd="+l.getWindDirection()+"Ws="+l.getWindSpeed()); + }*/ + // Return the specific levels requested by users + if ( ttaa.size() > 0 ) { + Collections.sort(ttaa, new reverseSortByPressure()); + //System.out.println("TTAA sounding: "); + for ( NcSoundingLayer soundLy : ttaa ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + if (level.toUpperCase().equalsIgnoreCase("MAN")) { + return ttaa; + } + man = removeUnderGround(ttaa); + + } else { + man=ttaa; + if (level.toUpperCase().equalsIgnoreCase("MAN")) { + return setMissing(); + } + + } + + + // Sorting the data + + if ( ttbb.size() > 0) { + Collections.sort(ttbb, new reverseSortByPressure()); + //System.out.println("TTBB sounding: "); + for ( NcSoundingLayer soundLy : ttbb ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + + if ( ttcc.size() > 0) { + Collections.sort(ttcc, new reverseSortByPressure()); + //System.out.println("TTCC sounding: "); + for ( NcSoundingLayer soundLy : ttcc ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + + if ( ttdd.size() > 0) { + Collections.sort(ttdd, new reverseSortByPressure()); + //System.out.println("TTDD sounding: "); + for ( NcSoundingLayer soundLy : ttdd ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + + if ( ppaa.size() > 0 ) { + if (checkWindData(ppaa)) { + Collections.sort(ppaa, new MergeSounding.sortByHeight()); + //System.out.println("TTAA sounding: "); + for ( NcSoundingLayer soundLy : ttaa ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } else { + Collections.sort(ppaa, new MergeSounding.reverseSortByPressure()); + //System.out.println("TTAA sounding: "); + for ( NcSoundingLayer soundLy : ttaa ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + } + + + if ( ppcc.size() > 0 ) { + if (checkWindData(ppcc)) { + Collections.sort(ppcc, new MergeSounding.sortByHeight()); + //System.out.println("PPCC sounding: "); + for ( NcSoundingLayer soundLy : ppcc ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } else { + Collections.sort(ppcc, new MergeSounding.reverseSortByPressure()); + //System.out.println("PPCC sounding: "); + for ( NcSoundingLayer soundLy : ppcc ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + } + + if ( ppbb.size() > 0 ) { + if (checkWindData(ppbb)) { + Collections.sort(ppbb, new MergeSounding.sortByHeight()); + //System.out.println("PPBB sounding: "); + for ( NcSoundingLayer soundLy : ppbb ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } else { + Collections.sort(ppbb, new MergeSounding.reverseSortByPressure()); + //System.out.println("PPBB sounding: "); + for ( NcSoundingLayer soundLy : ppbb ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + } + + if ( ppdd.size() > 0 ) { + + if (checkWindData(ppdd)) { + Collections.sort(ppdd, new MergeSounding.sortByHeight()); + //System.out.println("PPDD sounding: "); + for ( NcSoundingLayer soundLy : ppdd ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } else { + Collections.sort(ppdd, new MergeSounding.reverseSortByPressure()); + //System.out.println("PPDD sounding: "); + for ( NcSoundingLayer soundLy : ppdd ){ + System.out.print(soundLy.getPressure() + " , "); + } + //System.out.println(); + } + + } + + // Find surface data, return if users request surface data only. + NcSoundingLayer sl = new NcSoundingLayer(); + sl = getSurfaceData(man, ttbb, ppbb, elevation); + sndata.add(0, sl); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling getSurfaceData(): " + sndata.size() ); + if ( isNumber(level) >= 0 ) { + if ( equal(0.f, Float.valueOf(level.trim()).floatValue()) || + equal(sl.getPressure(), Float.valueOf(level.trim()).floatValue())) { + //System.out.println("Returning surface data...."); + return sndata; + } + } + + // Merge mandatory data +//System.out.println ( "Just before calling mergeMandatory() " ); + mergeMandatory(man, ttcc, sndata); + int sndataSize = sndata.size(); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling mergeMandatory(): " + sndata.size() ); + + // Check if the single level is mandatory or not + if ( isNumber(level) >= 0 ) { + for ( int kk = 0; kk < sndata.size(); kk++) { + if ( equal(Float.valueOf(level.trim()).floatValue(), sndata.get(kk).getPressure())) { + sl.setPressure(sndata.get(kk).getPressure()); + sl.setTemperature(sndata.get(kk).getTemperature()); + sl.setDewpoint(sndata.get(kk).getDewpoint()); + sl.setWindDirection(sndata.get(kk).getWindDirection()); + sl.setWindSpeed(sndata.get(kk).getWindSpeed()); + sl.setGeoHeight(sndata.get(kk).getGeoHeight()); + sndata.clear(); + sndata.add(sl); + //System.out.println( "single layer of sounding added to sndata" ); + return sndata; + } + } + } + + // Merge mandatory winds + mergeMandatoryWinds (ppaa, ppcc, sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling mergeMandatoryWinds(): " + sndata.size() ); + // Merge tropopause + mergeTropSigTemp (trop_a, trop_c, sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " mergeTropSigTemp() for merging trop_a and trop_c: " + sndata.size() ); + // Merge TTBB + mergeTropSigTemp (ttbb, ttdd, sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " mergeTropSigTemp() for merging ttbb and ttdd: " + sndata.size() ); + // Construct height for ttbb + constructTtbbHeight(sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " constructTtbbHeight(): " + sndata.size() ); + // Merge significant winds on pressure surfaces + if (!checkWindData(ppbb)) { + mergeSigMaxWindOnPressure(ppbb,ppdd,sndata); + //System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " mergeSigMaxWindOnPressure() for merging ppbb and ppdd: " + sndata.size() ); + } + + mergeSigMaxWindOnPressure(wmax_a,wmax_c,sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " mergeSigMaxWindOnPressure() for merging wmax_a and wmax_c: " + sndata.size() ); + + constructPpbbHeight(sndata); +//System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " constructPpbbHeight()" + sndata.size() ); + if (checkWindData(ppbb)) { + mergeSigWindOnHeight(ppbb,ppdd,sndata); + //System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " mergeSigWindOnHeight() for merging ppbb and ppdd: " + sndata.size() ); + constructPpbbPressure(sndata); + //System.out.println ( "sndataSize in mergeUairSounding(), after calling" + +// " constructPpbbPressure()" + sndata.size() ); + } + + // Reorder sounding profile so the first level is the surface data. + // No need to reorder now becuz surface data is always the 1st level. + //reOrderSounding(sndata); + + // Interpolate missing temperature, dew point and winds. + constructMissing(1,sndata); + constructMissing(2,sndata); + constructMissing(3,sndata); + + // Return single level or add underground mandatory data to the sounding profile + if ( isNumber (level) == 0 ) { + float rlev = new Integer(Integer.parseInt(level.trim())).floatValue(); + return getSingLevel(rlev, sndata); + } else if ( isNumber (level) == 1 ) { + float rlev = new Float(Float.parseFloat(level.trim())); + return getSingLevel(rlev, sndata); + } else { + return addUnderGround(ttaa,sndata); + } + + } + + /* + * Check an alpha-numerical string is a number or characters. + */ + public int isNumber (String level) { + try { + if (Integer.parseInt(level) >=0 ) { + return 0; + } else { + return -1; + } + } catch (NumberFormatException nfe1){ + try { + if (Float.parseFloat(level) >= 0.f) { + return 1; + } else { + return -1; + } + } catch (NumberFormatException nfe2) { + try { + if (Double.parseDouble(level) >= 0.) { + return 2; + } else { + return -1; + } + } catch (NumberFormatException nfe3) { + return -1; + } + } + } + } + + /* + * convert specific humidity to dew point temperature. + */ + float elevation; + + public List spfhToDewpoint(List sndata) { + float spfh, pres; + float dwpc = RMISSD; + + for (NcSoundingLayer layer: sndata) { + if (layer.getDewpoint() == RMISSD) { + spfh = layer.getSpecHumidity(); + pres = layer.getPressure(); + + if (spfh == RMISSD || pres == RMISSD || spfh <= 0.f + || pres <= 0.f) { + continue; + } else { + float rmix = spfh / (1.f - spfh); + float e = (pres * rmix) / (.62197f + rmix); + e = e / (1.001f + ((pres - 100.f) / 900.f) * .0034f); + dwpc = (float) (Math.log(e / 6.112) * 243.5 / (17.67 - Math + .log((e / 6.112)))); + layer.setDewpoint(dwpc); + ////System.out.println("spfhToDewpoint dwpc: " + dwpc); + } + + } + } + return sndata; + } + /* + * computes DWPC from TMPC and RELH + * Note: If DWPC is less than -190 degrees C, it is treated as + * missing data + * Code is based on GEMPAK's prrhdp.f + */ + public List rhToDewpoint(List sndata) { + float rh, vapr,vaps, temp; + float dwpc = RMISSD; + + for (NcSoundingLayer layer: sndata) { + if (layer.getDewpoint() == RMISSD) { + rh = layer.getRelativeHumidity(); + temp = layer.getTemperature(); + + if (rh == RMISSD || temp == RMISSD ) { + continue; + } else { + vaps = tempToVapr(temp); + vapr = rh * vaps /100; + if(vapr < Math.exp(-30)) + continue; + else { + dwpc = (float) (243.5 * ( Math.log(6.112) - Math.log(vapr)) / (Math.log(vapr) - Math.log(6.112)-17.67)); + layer.setDewpoint(dwpc); + ////System.out.println("rhToDewpoint dwpc: " + dwpc); + } + } + } + } + return sndata; + } + /* + * computes VAPR from TMPC + * Code is based on GEMPAK's prvapr.f + */ + private float tempToVapr(float temp){ + return(float)(6.112 * Math.exp((17.67* temp)/(temp+243.5))); + } + + private void constructHeight(List sndata, float elev) { + + /* + * For native model sounding, using hypsometric equation to build height + */ + elevation = elev; + int lev = sndata.size(); + float tb = RMISSD, tdb = RMISSD, pb = RMISSD; + float tt = RMISSD, tdt = RMISSD, pt = RMISSD; + float dwptsf, psfc, tmpcsf, scaleh, mhgt = RMISSD; + + for (int k = 0; k < lev; k++) { + + if (k == 0) { + tmpcsf = sndata.get(k).getTemperature(); + dwptsf = sndata.get(k).getDewpoint(); + psfc = sndata.get(k).getPressure(); + tb = tmpcsf; + tt = tmpcsf; + tdb = dwptsf; + tdt = dwptsf; + pb = psfc; + pt = psfc; + + scaleh = scaleHeight(tb, tt, tdb, tdt, pb, pt); + mhgt = moistHeight(elevation, pb, pt, scaleh); + } else { + tt = sndata.get(k).getTemperature(); + tdt = sndata.get(k).getDewpoint(); + pt = sndata.get(k).getPressure(); + scaleh = scaleHeight(tb, tt, tdb, tdt, pb, pt); + + mhgt = moistHeight(mhgt, pb, pt, scaleh); + tb = tt; + tdb = tdt; + pb = pt; + + } + sndata.get(k).setGeoHeight(mhgt); + } + } + + /* + * Compute moist height. + */ + private float moistHeight(float zb, float pb, float pt, float scale) { +//System.out.println("From moistHeight: "); + if (zb == RMISSD || pb == RMISSD || pt == RMISSD || scale == RMISSD) { + return RMISSD; + } else { + //System.out.println("the computed moistHeight is " + (float) (zb + scale * Math.log(pb / pt))); + return (float) (zb + scale * Math.log(pb / pt)); + } + } + + /* + * Compute scale height. + */ + private float scaleHeight(float tb, float tt, float tdb, float tdt, + float pb, float pt) { +//System.out.println("From scaleHeight: " ); + final float RDGAS = 287.04f, GRAVTY = 9.80616f, RKAP = RDGAS / GRAVTY; + if (tb == RMISSD || tt == RMISSD || pb == RMISSD || pt == RMISSD) { + return RMISSD; + } else { + float tvb = virtualTemperature(tb, tdb, pb); + float tvt = virtualTemperature(tt, tdt, pt); + //System.out.println("tvb = " + tvb); + //System.out.println("tvt = " + tvt); + if (tvb == RMISSD || tvt == RMISSD) { + return RMISSD; + } else { + float tav = (tvb + tvt) / 2.0f; + + //System.out.println("tav = " + tav); + //System.out.println("RKAP * tav = " + RKAP * tav); + return (RKAP * tav); + } + } + } + + /* + * Compute virtual temperature + */ + private float virtualTemperature(float tt, float td, float pres) { + if (tt == RMISSD || pres == RMISSD) { + return RMISSD; + } else if (td == RMISSD) { + return celciusToKevin(tt); + } else { + float tmpk = celciusToKevin(tt); + float rmix = mixingRatio(td, pres); + if (rmix == RMISSD) { + return celciusToKevin(tt); + } else { + return tmpk * (1.f + .001f * rmix / .62197f) + / (1.f + .001f * rmix); + } + } + } + + /* + * Convert Celcius to Kelvin. + */ + float TMCK = 273.15f; + + private float celciusToKevin(float tc) { + if (tc == RMISSD) { + return RMISSD; + } else { + return (tc + TMCK); + } + } + + /* + * Compute mixing ratio from DWPC and PRES. + */ + private float mixingRatio(float td, float pres) { + if (td == RMISSD || pres == RMISSD) { + return RMISSD; + } else { + float vapr = vaporPressure(td); + if (vapr == RMISSD) { + return RMISSD; + } + + float corr = (1.001f + ((pres - 100.f) / 900.f) * .0034f); + + float e = corr * vapr; + if (e > (.5f * pres)) { + return RMISSD; + } else { + return .62197f * (e / (pres - e)) * 1000.f; + } + } + } + + /* + * Compute vapor pressure from DWPC. + */ + private float vaporPressure(float td) { + if (td == RMISSD) { + return RMISSD; + } else { + return (6.112f * (float) Math.exp((17.67 * td) / (td + 243.5))); + } + } + + /* + * Merge observed sounding data + */ + + /* + * Check significant wind data (PPBB/PPDD) to see if the data is reported on + * pressure or height surfaces. Return TRUE if reported on height. The + * input can be PPBB or PPDD winds. (MR_CHKW) + * + * Note that this is coded different from MR_CHKW, in that it will set zwind + * to false only if pressure is less than 0. An odd logic. + */ + public boolean checkWindData(List sndata) { + boolean zwind = true; + for (int kk = 0; kk < sndata.size(); kk++) { + if (sndata.get(kk).getPressure() != RMISSD) { + zwind = false; + } + } + return zwind; + } + + /* + * Find surface data. (MR_SRFC) + */ + final int NPARMS = 7; + + + public NcSoundingLayer getSurfaceData(List man, + List ttbb, List ppbb, float elevation ) { + float pres = RMISSD; + NcSoundingLayer sl_sfc = new NcSoundingLayer(); + + /* + * Check for surface information in mandatory data. + */ + if (man.size() < 1) { + for (int k = 0; k < NPARMS; k++) { + sl_sfc.setPressure(RMISSD); + sl_sfc.setTemperature(RMISSD); + sl_sfc.setDewpoint(RMISSD); + sl_sfc.setWindDirection(RMISSD); + sl_sfc.setWindSpeed(RMISSD); + sl_sfc.setGeoHeight(RMISSD); + sl_sfc.setOmega(RMISSD); + return sl_sfc; + } + } else { + + // If surface pressure is higher than 1080mb, set to missing. + // Note that GEMPAK sets it to 1060mb. + pres = man.get(0).getPressure(); + if (pres > 1080.) { + sl_sfc.setPressure(RMISSD); + } else { + sl_sfc.setPressure(pres); + } + sl_sfc.setTemperature(man.get(0).getTemperature()); + sl_sfc.setDewpoint(man.get(0).getDewpoint()); + sl_sfc.setWindDirection(man.get(0).getWindDirection()); + sl_sfc.setWindSpeed(man.get(0).getWindSpeed()); + sl_sfc.setGeoHeight(elevation); + sl_sfc.setOmega(man.get(0).getOmega()); + } + + /* + * Find the first reporting mandatory level above the surface. + */ + float pman = RMISSD; + int iman = 1; + while (pman == RMISSD && iman < man.size()) { + if (man.get(iman).getPressure() != RMISSD + && man.get(iman).getTemperature() != RMISSD + && man.get(iman).getGeoHeight() != RMISSD) { + pman = man.get(0).getPressure(); + } + iman++; + } + + /* + * If surface pressure is missing or is less than first reporting + * mandatory level, set all surface data to missing + */ + if (pres == RMISSD || (pres < pman && pman != RMISSD)) { + sl_sfc = setMissing().get(0); + } + + /* + * If the surface significant temperature data is not missing, use it to + * replace the surface pressure, temperature and dewpoint. The check for + * significant level pressure to be less than or equal to pman eliminates + * using wildly erroneous data. + */ + + if (ttbb.size() >= 1 && ttbb.get(0).getPressure() != RMISSD + && ttbb.get(0).getTemperature() != RMISSD) { + pman = sl_sfc.getPressure(); + float psql = ttbb.get(0).getPressure(); + if (pman == RMISSD || equal(pman, psql)) { + sl_sfc.setPressure(ttbb.get(0).getPressure()); + sl_sfc.setTemperature(ttbb.get(0).getTemperature()); + sl_sfc.setDewpoint(ttbb.get(0).getDewpoint()); + } + + } + + /* + * If the first significant level wind data is surface information, use + * it to replace the surface data if the pressure is at surface. + */ + + // PPBB reported on P-surfaces. + + if (checkWindData(ppbb)) { + if (ppbb.size() > 0 && ppbb.get(0).getGeoHeight() == 0. + && ppbb.get(0).getWindDirection() != RMISSD) { + sl_sfc.setWindDirection(ppbb.get(0).getWindDirection()); + sl_sfc.setWindSpeed(ppbb.get(0).getWindSpeed()); + } + + } else { + if (ppbb.size() > 0 && ppbb.get(0).getPressure() != RMISSD + && ppbb.get(0).getWindDirection() != RMISSD) { + pman = sl_sfc.getPressure(); + float psgl = Math.abs(ppbb.get(0).getPressure()); + if (pman == RMISSD || equal(pman, psgl)) { + sl_sfc.setPressure(psgl); + sl_sfc.setWindDirection(ppbb.get(0).getWindDirection()); + sl_sfc.setWindSpeed(ppbb.get(0).getWindSpeed()); + } + } + } + + /* + * Add surface data to station data. + */ + return sl_sfc; + } + + + private boolean equal(float x, float y) { + final float RDIFFD = .0001f; + if ( (x + y) == 0. ) { + return Math.abs(x-y) < RDIFFD; + } else { + return Math.abs(x - y) / Math.abs( (x+y) / 2.) < RDIFFD; + } + } + + /* + * Merge the mandatory below 100 mb data and the mandatory above data. sndata + * has surface observation ONLY. + * (MR_MAND) + */ + + public void mergeMandatory( + List man_a, List man_c, + List sndata ) { + + float plast; + if ( man_a.size() < 1 && man_c.size() < 1 ) { + return; + } + + if ( sndata.get(0).getPressure() == RMISSD) { + plast = 2000.f; + } else { + plast = sndata.get(0).getPressure(); + } + + /* + * Move the mandatory data below 100mb to the output array, sndata. + * Check that pressure is not missing and is decreasing. + */ + float pres; + if ( man_a.size() > 0 ) { + for (int kk = 0; kk < man_a.size(); kk++) { + pres = man_a.get(kk).getPressure(); + if (pres < plast && pres != RMISSD + && ( man_a.get(kk).getTemperature() != RMISSD + || man_a.get(kk).getWindDirection() != RMISSD)) { + addDataToList(kk, man_a, sndata); + plast = pres; + } + } + } + + /* + * Move the mandatory data above 100 mb to the output array. + */ + if ( man_c.size() > 0 ) { + for (int kk = 0; kk < man_c.size(); kk++) { + pres = man_c.get(kk).getPressure(); + if (pres < plast && pres != RMISSD + && man_c.get(kk).getTemperature() != RMISSD) { + addDataToList(kk, man_c, sndata); + plast = man_c.get(kk).getPressure(); + } + } + } + } + + /* + * Merge the mandatory below 100 mb wind data and the mandatory above wind + * data. (MR_MANW) + */ + public void mergeMandatoryWinds( List man_wa, + List man_wc, List sndata ) { + + if ( man_wa.size() < 1 && man_wc.size() < 1 ) { + return; + } + + /* + * Append data. + */ + if (man_wc.size() > 0) { + for (int kk = 0; kk < man_wc.size(); kk++) { + man_wa.add(man_wc.get(kk)); + } + } + /* + * Loop through mandatory wind data. + */ + for (int lev = 0; lev < man_wa.size(); lev++) { + + /* + * If this is the correct level, add wind data. + */ + boolean found = false; + float ppp = man_wa.get(lev).getPressure(); + for (int kk = 0; kk < sndata.size() && !found; kk++ ) { + float pres = sndata.get(kk).getPressure(); + if (equal(ppp,pres)) { + if (sndata.get(kk).getWindDirection() == RMISSD) { + sndata.get(kk).setWindDirection(man_wa.get(lev).getWindDirection()); + sndata.get(kk).setWindSpeed(man_wa.get(lev).getWindSpeed()); + } + found = true; + } + } + + /* + * If not found, add to the list + */ + if (!found) { + float ddd = man_wa.get(lev).getWindDirection(); + if (ppp != RMISSD && ddd != RMISSD) { + addDataToList(lev,man_wa,sndata); + } + } + } + } + + /* + * Merge tropopause, max wind and significant temperature data (TTBB) to the + * station data array. The input parameter could be tropopause data or + * significant temperature data. MR_TROP & MR_SIGT + */ + public List mergeTropSigTemp( List trop_a, + List trop_c, List sndata) { + if ( trop_a.size() < 1 && trop_c.size() < 1 ) { + return sndata; + } + + /* + * Append two lists of wind data. + */ + if ( trop_c.size() > 0 ) { + for (int kk = 0; kk < trop_c.size(); kk++) { + trop_a.add(trop_c.get(kk)); + } + } + + for (int lev = 0; lev < trop_a.size(); lev++) { + boolean found = false; + float ppp = trop_a.get(lev).getPressure(); + for (int kk = 0; kk < sndata.size() && !found; kk++) { + float pres = sndata.get(kk).getPressure(); + if (equal(ppp ,pres)) { + + // add data to missing + if (sndata.get(kk).getTemperature() == RMISSD) { + sndata.get(kk).setTemperature(trop_a.get(lev).getTemperature()); + sndata.get(kk).setDewpoint(trop_a.get(lev).getDewpoint()); + } + + if (sndata.get(kk).getWindDirection() == RMISSD) { + sndata.get(kk).setWindDirection( + trop_a.get(lev).getWindDirection()); + sndata.get(kk).setWindSpeed( + trop_a.get(lev).getWindSpeed()); + + } + found = true; + } + } + + /* + * if not found, add to the list + */ + if (!found) { + float ttt = trop_a.get(lev).getTemperature(); + if (ppp != RMISSD && ttt != RMISSD) { + addDataToList(lev,trop_a,sndata); + } + } + + } + + /* + * Sort the sounding data in descending order. + */ + Collections.sort(sndata, new reverseSortByPressure()); + return sndata; + } + + /* + * Compute height at significant temperature levels (TTBB) using a moist + * hydrostatic computation. (MR_SCMZ) + */ + public void constructTtbbHeight(List sndata) { + boolean mand = false; + boolean newblock = true; + int blev = 0, tlev = 0; + float[] scale = new float[200]; + float pb, zb, tb, tdb, zlev, plev; + float pt, zt = 0.f, tt, tdt, znew = 0.f; + + if ( sndata.size() <= 2) return; + + for (int nlev = 0; nlev < sndata.size(); nlev++) { +// //System.out.println("blev = " + blev ); + //System.out.println("nlev = " + nlev ); +// //System.out.println("tlev = " + tlev ); + if (newblock) { + if (sndata.get(nlev).getGeoHeight() != RMISSD + && sndata.get(nlev).getPressure() != RMISSD + && sndata.get(nlev).getTemperature() != RMISSD) { + + blev = nlev; + newblock = false; + // double h = sndata.get(nlev).getGeoHeight(); +// if ( h < 0 && h != -9999 ) + //System.out.println("if newblock - height is negative: " + h ); + } + } else { + if (sndata.get(nlev).getGeoHeight() != RMISSD + && sndata.get(nlev).getTemperature() != RMISSD) { + tlev = nlev; + mand = true; +//System.out.println("tlev is now set to nlev and its value is " + tlev ); + // double h = sndata.get(nlev).getGeoHeight(); + // if ( h < 0 && h != -9999 ) + //System.out.println("if not newblock - height is negative: " + h ); + } + } + + /* + * Compute scale height to this level + */ + if (mand) { + pb = sndata.get(blev).getPressure(); + zb = sndata.get(blev).getGeoHeight(); + tb = sndata.get(blev).getTemperature(); + tdb = sndata.get(blev).getDewpoint(); + zlev = sndata.get(blev).getGeoHeight(); + plev = sndata.get(blev).getPressure(); + + for (int kk = blev + 1; kk <= tlev; kk++) { + pt = sndata.get(kk).getPressure(); + zt = sndata.get(kk).getGeoHeight(); + tt = sndata.get(kk).getTemperature(); + tdt = sndata.get(kk).getDewpoint(); + scale[kk] = scaleHeight(tb, tt, tdb, tdt, pb, pt); + //System.out.println("scale[" + kk + "] = " + scale[kk]); + znew = moistHeight(zb, pb, pt, scale[kk]); + if (znew != RMISSD) { + pb = pt; + tb = tt; + tdb = tdt; + zb = znew; +// if ( znew < 0 ) + //System.out.println("negative moist height = " + znew ); + } + } + + /* + * Compute the scaling factor so the computed moist height is + * consistent at the mandatory level. Then recompute the height. + */ + float s = (zt - zlev) / (znew - zlev); + //System.out.println("scaling factor s = " + s); + float zbb = zlev; + float pbb = plev; + for (int kk = blev + 1; kk < tlev; kk++) { + pt = sndata.get(kk).getPressure(); + zt = sndata.get(kk).getGeoHeight(); + scale[kk] = scale[kk] * s; + //System.out.println("Now, scale[" + kk + "] = " + scale[kk]); + znew = moistHeight(zbb, pbb, pt, scale[kk]); + if (znew != RMISSD) { + pbb = pt; + zbb = znew; + sndata.get(kk).setGeoHeight(znew); +// double h = sndata.get(kk).getGeoHeight(); +// if ( h < 0 && h != RMISSD ) + //System.out.println("newly computed moist height is negative " + h ); + } + } + mand = false; + newblock = true; + + if ( (tlev+1) != sndata.size() ) { + if ( sndata.get(tlev+1).getGeoHeight() == RMISSD + && sndata.get(tlev+1).getPressure() != RMISSD + && sndata.get(tlev+1).getTemperature() != RMISSD) { + nlev--; + //System.out.println("after subtracting nlev, its value is : " + nlev ); + } + } + } + } + + // Compute height at the missing top levels + + if ( ( tlev + 1 ) < sndata.size() ) { + blev = tlev; + pb = sndata.get(blev).getPressure(); + zb = sndata.get(blev).getGeoHeight(); + tb = sndata.get(blev).getTemperature(); + tdb = sndata.get(blev).getDewpoint(); + zlev = sndata.get(blev).getGeoHeight(); + plev = sndata.get(blev).getPressure(); + for ( int kk = tlev+1; kk < sndata.size(); kk++ ) { + pt = sndata.get(kk).getPressure(); + zt = sndata.get(kk).getGeoHeight(); + tt = sndata.get(kk).getTemperature(); + tdt = sndata.get(kk).getDewpoint(); + float xxx = scaleHeight(tb, tt, tdb, tdt, pb, pt); + znew = moistHeight(zb, pb, pt, xxx); + if (znew != RMISSD) { + sndata.get(kk).setGeoHeight(znew); + pb = pt; + tb = tt; + tdb = tdt; + zb = znew; + } + } + } + + return; + } + + /* + * Merge the significant and maximum wind data on pressure surfaces. MR_PWND + */ + public void mergeSigMaxWindOnPressure(List sig_wa, + List sig_wc,List sndata) { + + /* + * Do nothing if wind report is reported on height surfaces. + */ + + if (checkWindData(sig_wa) || checkWindData(sig_wc) || + (sig_wa.size() < 1 && sig_wc.size() < 1 )) { + return; + } + + /* + * Append two lists of wind data. + */ + if ( sig_wc.size() > 0) { + for (int kk = 0; kk < sig_wc.size(); kk++) { + sig_wa.add(sig_wc.get(kk)); + } + } + + /* + * Merging + */ + int nlevel = sndata.size(); + for (int kk = 0; kk < sig_wa.size(); kk++) { + boolean found = false; + for (int lev = 0; lev < nlevel; lev++) { + if (equal(sndata.get(lev).getPressure(),sig_wa.get(kk) + .getPressure())) { + + // add data to missing + if (sndata.get(lev).getWindDirection() == RMISSD) { + sndata.get(lev).setWindDirection( + sig_wa.get(kk).getWindDirection()); + sndata.get(lev).setWindSpeed( + sig_wa.get(kk).getWindSpeed()); + } + found = true; + } + } + + /* + * if not found, add to the list. + */ + if (!found) { + if ( ( sig_wa.get(kk).getWindDirection() != RMISSD + && sig_wa.get(kk).getPressure() != RMISSD )) { + + NcSoundingLayer sl = new NcSoundingLayer(); + sl.setPressure(sig_wa.get(kk).getPressure()); + sl.setTemperature(sig_wa.get(kk).getTemperature()); + sl.setDewpoint(sig_wa.get(kk).getDewpoint()); + sl.setWindDirection(sig_wa.get(kk).getWindDirection()); + sl.setWindSpeed(sig_wa.get(kk).getWindSpeed()); + sl.setGeoHeight(sig_wa.get(kk).getGeoHeight()); + sl.setOmega(sig_wa.get(kk).getOmega()); + sndata.add(sl); + } + } + Collections.sort(sndata, new reverseSortByPressure()); + } + return; + } + + /* + * Construct height at significant wind levels (PPBB) if reported on + * pressure levels. Using moist hydrostatic computation for missing height + * at top levels. MR_INTZ + */ + public void constructPpbbHeight(List sndata) { + int tlev = 0; +//System.out.println("From constructPpbbHeight(): " ); + for (int kk = sndata.size() - 1; kk >= 0; kk--) { + if (sndata.get(kk).getGeoHeight() != RMISSD) { + tlev = kk; + //System.out.println("tlev is set to " + tlev ); + break; + } + } + + float pb = RMISSD, pt = RMISSD, zt = RMISSD, zb = RMISSD; + int next; + + if ( sndata.size() <= 2) return; + + for (int kk = 0; kk < tlev; kk++) { + float pres = sndata.get(kk).getPressure(); + float hght = sndata.get(kk).getGeoHeight(); + if (pres == RMISSD) { + // DO NOTHING + } else if (hght != RMISSD) { + pb = pres; + zb = hght; + pt = 2000.f; + } else if (pb == RMISSD) { + // DO NOTHING + } else { + + /* + * Find next level with height and then interpolate the data. + */ + next = kk + 1; + while (pres <= pt) { + if (sndata.get(next).getGeoHeight() != RMISSD) { + pt = sndata.get(next).getPressure(); + zt = sndata.get(next).getGeoHeight(); + } else { + next++; + } + } + float hhh = (float) (zb + (zt - zb) + * (Math.log(pres / pb) / Math.log(pt / pb))); + sndata.get(kk).setGeoHeight(hhh); + } + } + + if (tlev == (sndata.size()-1) ) { + return; + } else { + + /* + * Compute moist hydrostatic height for missing height at top + * levels. + */ + float scale; + float tb, tdb; + float tt, tdt, mhght = 0.f; + pb = sndata.get(tlev).getPressure(); + zb = sndata.get(tlev).getGeoHeight(); + tb = sndata.get(tlev).getTemperature(); + tdb = sndata.get(tlev).getDewpoint(); + + for (int kk = tlev+1; kk < sndata.size(); kk++) { + if (sndata.get(kk).getGeoHeight() == RMISSD) { + pt = sndata.get(kk).getPressure(); + zt = sndata.get(kk).getGeoHeight(); + tt = sndata.get(kk).getTemperature(); + tdt = sndata.get(kk).getDewpoint(); + scale = scaleHeight(tb, tt, tdb, tdt, pb, pt); + mhght = moistHeight(zb, pb, pt, scale); + sndata.get(kk).setGeoHeight(mhght); + if (mhght != RMISSD) { + pb = pt; + zb = zt; + tb = tt; + tdb = tdt; + } + } + } + return; + } + } + + /* + * Merge significant wind on height surfaces. The argument is sndata. + */ + public void mergeSigWindOnHeight(List sig_wa, + List sig_wc,List sndata ) { + + /* + * The following code needs to be replaced by significant wind data from + * database. + */ + + /* + * Do nothing if wind report is not on height surfaces. + */ + if (!checkWindData(sig_wa) || !checkWindData(sig_wc) || + (sig_wa.size() < 1 && sig_wc.size() < 1)) { + return; + } + + /* + * Add two lists of wind data. + */ + if ( sig_wc.size() > 0 ) { + for (int kk = 0; kk < sig_wc.size(); kk++) { + sig_wa.add(sig_wc.get(kk)); + } + } + + int nlevel = sndata.size(); + for (int kk = 0; kk < sig_wa.size(); kk++) { + boolean found = false; + float zzz = sig_wa.get(kk).getGeoHeight(); + + // Check surface level independently because sometimes station + // report wind data twice at surface. We don't want the surface + // pressure to be missing. + if ( zzz == 0 ) { + if (sndata.get(0).getWindDirection() == RMISSD) { + sndata.get(0).setWindDirection( + sig_wa.get(0).getWindDirection()); + sndata.get(0).setWindSpeed( + sig_wa.get(kk).getWindSpeed()); + } + found = true; + } else { + for (int lev = 0; lev < nlevel; lev++) { + float hght = sndata.get(lev).getGeoHeight(); + if (equal(zzz,hght) || (zzz == 0 && lev == 0 && kk == 0)) { + // add data to missing + if (sndata.get(lev).getWindDirection() == RMISSD) { + sndata.get(lev).setWindDirection( + sig_wa.get(kk).getWindDirection()); + sndata.get(lev).setWindSpeed( + sig_wa.get(kk).getWindSpeed()); + } + found = true; + } + } + } + + /* + * if not found, add to the list. + */ + if (!found) { + if (sig_wa.get(kk).getWindDirection() != RMISSD + && sig_wa.get(kk).getGeoHeight() != RMISSD) { + NcSoundingLayer sl = new NcSoundingLayer(); + sl.setPressure(sig_wa.get(kk).getPressure()); + sl.setTemperature(sig_wa.get(kk).getTemperature()); + sl.setDewpoint(sig_wa.get(kk).getDewpoint()); + sl.setWindDirection(sig_wa.get(kk).getWindDirection()); + sl.setWindSpeed(sig_wa.get(kk).getWindSpeed()); + sl.setGeoHeight(sig_wa.get(kk).getGeoHeight()); + sl.setOmega(sig_wa.get(kk).getOmega()); + sndata.add(sl); + } + } + } + + /* + * Sorting the combined temperature and wind data based on Geopotential + * height. + */ + Collections.sort(sndata, new sortByHeight()); + return; + } + + // Sort by height + public static class sortByHeight implements Comparator { + public int compare(NcSoundingLayer l1, NcSoundingLayer l2) { + return Float.compare(l1.getGeoHeight(), l2.getGeoHeight()); + } + + } + + // Reverse sort by pressure + public static class reverseSortByPressure implements Comparator { + public int compare(NcSoundingLayer l1, NcSoundingLayer l2) { + return Float.compare(l2.getPressure(), l1.getPressure()); + } + + } + + /* + * Construct pressure at significant wind levels (PPBB) that are reported on + * height levels. MR_INTP + */ + public List constructPpbbPressure(List sndata) { + + if ( sndata.size() <= 2) return sndata; + + float pb = RMISSD, pt = RMISSD, zt = RMISSD, zb = RMISSD; + int blev = IMISSD, tlev = IMISSD; + for (int lev = 0; lev < sndata.size(); lev++) { + float pres = sndata.get(lev).getPressure(); + float hght = sndata.get(lev).getGeoHeight(); + if (pres != RMISSD && hght != RMISSD) { + tlev = lev; + pt = pres; + zt = hght; + } + + if (blev != IMISSD && tlev != IMISSD) { + for (int kk = blev + 1; kk < tlev; kk++) { + float z = sndata.get(kk).getGeoHeight(); + if (sndata.get(kk).getGeoHeight() != RMISSD) { + float ppp = (float) (pb * Math.exp((double) ((z - zb) + * Math.log(pt / pb) / (zt - zb)))); + sndata.get(kk).setPressure(ppp); + } + } + } + blev = tlev; + pb = pt; + zb = zt; + } + + ////System.out.println ( " tlev: " + tlev + " sndata.size() -1 " + (sndata.size()-1)); + + if (tlev == (sndata.size()-1) || tlev == IMISSD ) { + return sndata; + } else { + + /* + * Compute missing pressure at top + * levels. + */ + pb = sndata.get(tlev-1).getPressure(); + zb = sndata.get(tlev-1).getGeoHeight(); + + for (int kk = tlev+1; kk < sndata.size(); kk++) { + if (sndata.get(kk).getPressure() == RMISSD) { + pt = sndata.get(kk-1).getPressure(); + zt = sndata.get(kk-1).getGeoHeight(); + float zz = sndata.get(kk).getGeoHeight(); + float rmult = (float) ((zz- zb) / (zt - zb)); + sndata.get(kk).setPressure((float)(pb*(Math.pow(pt/pb,rmult)))); + pb = pt; + zb = zt; + } + } + } + return sndata; + } + + + + /* + * Reorder the sounding data so the first level is always the surface data. + */ + public List reOrderSounding(List sndata) { + List outdat = new ArrayList(); + float tt, td, dd, ff; + int klev = 0; + if ( sndata.size() <= 1) return sndata; + + /* + * Find the surface level + */ + for (int kk = 0; kk < sndata.size(); kk++) { + tt = sndata.get(kk).getTemperature(); + td = sndata.get(kk).getDewpoint(); + dd = sndata.get(kk).getWindDirection(); + ff = sndata.get(kk).getWindSpeed(); + if (tt == RMISSD && td == RMISSD && dd == RMISSD && ff == RMISSD) { + // DO NOTHING + } else { + klev = kk; + addDataToList(0, sndata, outdat); + } + } + + /* + * Reorder the data below the surface levels. + */ + for (int kk = 0; kk < klev; kk++) { + addDataToList(kk, sndata, outdat); + } + + for (int kk = klev + 1; kk < sndata.size(); kk++) { + addDataToList(kk, sndata, outdat); + } + return outdat; + } + + /* + * Construct missing temperature (iflag = 1), dewpoint temperature (iflag=2) + * and wind (iflag = 3). This method is called after reOrderSounding(). + * MR_MISS + */ + public List constructMissing(int iflag, + List sndata) { + float pb = RMISSD, pt = RMISSD, data = RMISSD, pres, tb, tt, tdb, tdt; + int jlev = IMISSD, tlev = IMISSD; + boolean contin = true; + if ( sndata.size() <= 2) return sndata; + for (int blev = 1; blev < sndata.size() - 1 && contin; blev++) { + jlev = blev; + + switch (iflag) { + case 1: { + data = sndata.get(blev).getTemperature(); + break; + } + case 2: { + data = sndata.get(blev).getDewpoint(); + break; + } + case 3: { + data = sndata.get(blev).getWindDirection(); + break; + } + default: { + //System.out.println("Invalid data flag"); + return sndata; + } + } + + if (data == RMISSD) { + + /* + * find data at level above. Data should already be at level + * below after reOrderSounding() call. + */ + boolean found = false; + while (!found) { + jlev++; + switch (iflag) { + case 1: { + data = sndata.get(jlev).getTemperature(); + break; + } + case 2: { + data = sndata.get(jlev).getDewpoint(); + break; + } + case 3: { + data = sndata.get(jlev).getWindDirection(); + break; + } + default: { + //System.out.println("Invalid data flag"); + } + } + int top = sndata.size(); + if (data != RMISSD || jlev+1 >= top) { + found = true; + tlev = jlev; + if (jlev >= top) { + tlev = IMISSD; + contin = false; + } + } + } + + /* + * Add check to eliminate dew point layer more than 100mb. + */ + if (iflag == 2 && tlev != IMISSD) { + if ((sndata.get(blev).getPressure() - sndata.get(tlev) + .getPressure()) > 100.) { + for (int kk = tlev; kk < sndata.size(); kk++) { + sndata.get(kk).setDewpoint(RMISSD); + } + tlev = IMISSD; + contin = false; + } + } + + /* + * Add check to eliminate interpolation of winds from below 100 + * mb to above 100 mb. This eliminates interpolation to very + * high level winds. + */ + /* if (iflag == 3 && tlev != IMISSD + && (sndata.get(blev - 1).getPressure() > 100.) + && (sndata.get(tlev).getPressure() < 100.)) { + tlev = IMISSD; + } + */ + /* + * Interpolate with respect to logP. + */ + + if (tlev != IMISSD) { + pb = sndata.get(blev - 1).getPressure(); + pres = sndata.get(blev).getPressure(); + pt = sndata.get(tlev).getPressure(); + float rmult = (float) (Math.log(pres / pb) / Math.log(pt / pb)); + switch (iflag) { + case 1: { + tb = sndata.get(blev - 1).getTemperature(); + tt = sndata.get(tlev).getTemperature(); + if ( tb != RMISSD && tt != RMISSD ) { + data = tb + (tt - tb) * rmult; + sndata.get(blev).setTemperature(data); + } + + tdb = sndata.get(blev - 1).getDewpoint(); + tdt = sndata.get(tlev).getDewpoint(); + if (tdb != RMISSD && tdt != RMISSD) { + data = tdb + (tdt - tdb) * rmult; + sndata.get(blev).setDewpoint(data); + } + break; + } + case 2: { + tdb = sndata.get(blev - 1).getDewpoint(); + tdt = sndata.get(tlev).getDewpoint(); + if (tdb != RMISSD && tdt != RMISSD) { + data = tdb + (tdt - tdb) * rmult; + sndata.get(blev).setDewpoint(data); + } + break; + } + case 3: { + float drctb = sndata.get(blev - 1).getWindDirection() ; + float drctt = sndata.get(tlev).getWindDirection() ; + + if ( drctt != RMISSD && drctb!= RMISSD ) { + drctb = drctb % 360.f; + drctt = drctt % 360.f; + if (Math.abs(drctb - drctt) > 180.f) { + if (drctb < drctt) { + drctb = drctb + 360.f; + } else { + drctt = drctt + 360.f; + } + } + float drct = ( drctb + (drctt - drctb) * rmult) % 360.f; + sndata.get(blev).setWindDirection(drct); + + // Interpolate wind speed + float spedb = sndata.get(blev - 1).getWindSpeed(); + float spedt = sndata.get(tlev).getWindSpeed(); + float sped = spedb + (spedt - spedb) * rmult; + sndata.get(blev).setWindSpeed(sped); + } + break; + + } + } + } + } + } + return sndata; + } + + + /* + * Re-order the data so the first level is always the ground level. MR_COND + */ + public List addUnderGround(List man, + List sndata ) { + + if (sndata.get(0).getPressure() == RMISSD || man.size() < 1 || sndata.size() <= 1) { + return sndata; + } + + int blev = 0; + boolean contin = true; + while ( blev < sndata.size() && contin ) { + if (man.get(blev).getPressure() > sndata.get(0).getPressure() ) { + blev++; + } else { + contin = false; + } + } + + if ( blev >= sndata.size()) { + return sndata; + } + + /* + * Added below-ground mandatory levels to sounding layers. + */ + List outdat = new ArrayList(); + + int nlev = sndata.size(); + + // write to surface data first + addDataToList (0, sndata, outdat); + + // add below-ground mandatory data + if (blev > 0 && blev < sndata.size()) { + for (int kk = 0; kk < blev; kk++ ) { + addDataToList(kk,man,outdat); + } + } + + // add the rest of the data + for (int kk = 1; kk < nlev; kk++) { + addDataToList(kk,sndata,outdat); + } + return outdat; + + } + + /* + * Re-order the data so the first level is always the ground level. MR_COND + */ + public List removeUnderGround(List sndata) { + List outdat = new ArrayList(); + /* + * Remove below-ground mandatory levels from sounding layers. Only the + * first 8 missing levels can be mandatory levels. + */ + if ( sndata.size() <= 1) return sndata; + for ( int kk = 0; kk < sndata.size(); kk++ ) { + if ( sndata.get(kk).getTemperature() <= RMISSD && + sndata.get(kk).getDewpoint() <= RMISSD && + sndata.get(kk).getWindDirection() <= RMISSD && + sndata.get(kk).getWindSpeed() <= RMISSD ) { + } else if ( sndata.get(kk).getPressure() <= RMISSD ) { + } else { + addDataToList(kk, sndata, outdat); + } + } + return outdat; + } + + /* + * Interpolate data to a single level, including surface. + */ + public List getSingLevel (float pres, List sndata) { + NcSoundingLayer sl = new NcSoundingLayer(); + List sls = new ArrayList(); + sndata = removeUnderGround(sndata); + if ( sndata.size() <= 1) return setMissing(); //Chin: check size again, after remove under ground lavel, size changed + + for ( int kk = 1;/*chin 0;*/ kk < sndata.size()-1; kk++ ) { + if (pres > sndata.get(0).getPressure()|| pres < 0.f) { + return setMissing(); + } else { + + if ( pres >= sndata.get(kk).getPressure()) { + float pt, pb, zt, zb, tt, tb, tdt, tdb, dt, db, st, sb; + pb = sndata.get(kk-1).getPressure(); + pt = sndata.get(kk).getPressure(); + tb = sndata.get(kk-1).getTemperature(); + tt = sndata.get(kk).getTemperature(); + tdb = sndata.get(kk-1).getDewpoint(); + tdt = sndata.get(kk).getDewpoint(); + db = sndata.get(kk-1).getWindDirection() % 360.f; + dt = sndata.get(kk).getWindDirection() % 360.f; + sb = sndata.get(kk-1).getWindSpeed(); + st = sndata.get(kk).getWindSpeed(); + zb = sndata.get(kk-1).getGeoHeight(); + zt = sndata.get(kk).getGeoHeight(); + sl.setPressure(pres); + + float rmult = (float) (Math.log(pres / pb) / Math.log(pt/ pb)); + sl.setTemperature(tb+(tt-tb)*rmult); + sl.setDewpoint(tdb+(tdt-tdb)*rmult); + if (Math.abs(db-dt) > 180.) { + if ( db < dt ) { + db = db + 360.f; + } else { + dt = dt + 360.f; + } + } + sl.setWindDirection(db+(dt-db)*rmult); + sl.setWindSpeed(sb+(st-sb)*rmult); + sl.setGeoHeight(zb+(zt-zb)*rmult); + sls.add(sl); + return sls; + } + } + } + return setMissing(); + } + + /* + * Add data to output sounding profile. + */ + public void addDataToList(int index, + List indat, List outdat) { + NcSoundingLayer sl = new NcSoundingLayer(); + sl.setPressure(indat.get(index).getPressure()); + sl.setTemperature(indat.get(index).getTemperature()); + sl.setDewpoint(indat.get(index).getDewpoint()); + sl.setWindDirection(indat.get(index).getWindDirection()); + sl.setWindSpeed(indat.get(index).getWindSpeed()); + sl.setGeoHeight(indat.get(index).getGeoHeight()); + sl.setOmega(indat.get(index).getOmega()); + outdat.add(sl); + } + + /* + * Set missing to output sounding profile. + */ + public List setMissing () { + List outdat = new ArrayList(); + NcSoundingLayer sl = new NcSoundingLayer(); + sl.setPressure(RMISSD); + sl.setTemperature(RMISSD); + sl.setDewpoint(RMISSD); + sl.setWindDirection(RMISSD); + sl.setWindSpeed(RMISSD); + sl.setGeoHeight(RMISSD); + sl.setOmega(RMISSD); + outdat.add(sl); + return outdat; + } } diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java index 941220b27e..ac8acf49b0 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java @@ -1,5 +1,4 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; - /** * * gov.noaa.nws.ncep.edex.uengine.tasks.profile.NcSoundingDrv @@ -20,39 +19,45 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; * 12/16/2010 301 Chin Chen add support of BUFRUA observed sounding and PFC (NAM and GFS) model sounding data * May 2011 301 Chin Chen add support of grib sounding data * June 2011 301 Chin Chen add support of time range query + * Sept 2011 457 S. Gurung Renamed h5 to nc + * Sep 2011 465 Archana Added methods to use NcSoundingLayer2 + * Oct 2011 465 Archana Used the Amount class to set values for Met parameters + * Noc 2011 Chin Chen changed Ncuair table query algorithm for performance improvement + * 01/05/2012 S. Gurung Removed references to UAIR (performed cleanup) + * 01/05/2012 Chin Chen fixed bug that cause exception when query NCUair with bad result * * Python Script example to query multiple locations at one request: * The following 3 query examples, returns same results. * use lat/lon array - import NcSoundingDataRequest - sndRq = NcSoundingDataRequest.NcSoundingDataRequest() - sndRq.setSndType('UAIR') - sndRq.setRefTime(1290254400000L) - sndRq.setMerge(1) - return sndRq.getSoundingDataBylaLonArray([[37.72999954223633,-122.20999908447266],[32.849998474121094,-117.11000061035156]]) +import NcSoundingDataRequest +sndRq = NcSoundingDataRequest.NcSoundingDataRequest() +sndRq.setSndType('UAIR') +sndRq.setRefTime(1290254400000L) +sndRq.setMerge(1) +return sndRq.getSoundingDataBylaLonArray([[37.72999954223633,-122.20999908447266],[32.849998474121094,-117.11000061035156]]) * use stnId array, use ref time string as input - import NcSoundingDataRequest - sndRq = NcSoundingDataRequest.NcSoundingDataRequest() - sndRq.setSndType('UAIR') - sndRq.setRefTimeStr('2010-11-20 12') - sndRq.setMerge(1) - return sndRq.getSoundingDataByStnIdArray(['OAK','NKX']) +import NcSoundingDataRequest +sndRq = NcSoundingDataRequest.NcSoundingDataRequest() +sndRq.setSndType('UAIR') +sndRq.setRefTimeStr('2010-11-20 12') +sndRq.setMerge(1) +return sndRq.getSoundingDataByStnIdArray(['OAK','NKX']) * use stn number array - import NcSoundingDataRequest - sndRq = NcSoundingDataRequest.NcSoundingDataRequest() - sndRq.setSndType('UAIR') - sndRq.setRefTime(1290254400000L) - sndRq.setMerge(1) - return sndRq.getSoundingDataByStnNumArray(['72293','72493']) +import NcSoundingDataRequest +sndRq = NcSoundingDataRequest.NcSoundingDataRequest() +sndRq.setSndType('UAIR') +sndRq.setRefTime(1290254400000L) +sndRq.setMerge(1) +return sndRq.getSoundingDataByStnNumArray(['72293','72493']) - import NcSoundingDataRequest - sndRq = NcSoundingDataRequest.NcSoundingDataRequest() - sndRq.setSndType('NAMSND') - sndRq.setRefTime('2010-12-08 12:00') - sndRq.setValidTime('2010-12-10 19:00') - sndRq.setMerge(1) - return sndRq.getSoundingDataByStnIdArray(['ATLH']) +import NcSoundingDataRequest +sndRq = NcSoundingDataRequest.NcSoundingDataRequest() +sndRq.setSndType('NAMSND') +sndRq.setRefTime('2010-12-08 12:00') +sndRq.setValidTime('2010-12-10 19:00') +sndRq.setMerge(1) +return sndRq.getSoundingDataByStnIdArray(['ATLH']) * * * @@ -60,21 +65,6 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; * @version 1.0 */ -import gov.noaa.nws.ncep.common.dataplugin.h5uair.H5MaxWind; -import gov.noaa.nws.ncep.common.dataplugin.h5uair.H5ObsLevels; -import gov.noaa.nws.ncep.common.dataplugin.h5uair.H5Tropopause; -import gov.noaa.nws.ncep.common.dataplugin.h5uair.H5UairRecord; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingCube; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer.DataType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingModel; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.MdlSndType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.ObsSndType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.PfcSndType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.SndQueryKeyType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection; - import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -86,1458 +76,2618 @@ import java.util.TimeZone; import javax.measure.converter.UnitConverter; import javax.measure.unit.NonSI; import javax.measure.unit.SI; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -public class NcSoundingDrv { - private static final UnitConverter metersPerSecondToKnots = SI.METERS_PER_SECOND - .getConverterTo(NonSI.KNOT); - - private Double lat, lon; - - private long refTime = 0, validTimeStart = 0, validTimeEnd = 0; - - private String timeLine, refTimeStr, validTimeStartStr = null, - validTimeEndStr = null; - - private Calendar refTimeCal, validTimeStartCal, validTimeEndCal; - - private String stid, level, dataType, sndType, queryType, tableName; - - private int merge; - - private int[] dbIdList; - - private String[] stnIdArr; - - private String[] stnNumArr; - - private String modelName; - - private String pluginName; - - private float[][] latLonArray; // e.g. at nth element, lat=[n][0], - // lon=[n][1] - - public float[][] getLatLons() { - return latLonArray; - } - - public String[] getStnIdArr() { - return stnIdArr; - } - - public void setStnIdArr(String[] stnIdArr) { - this.stnIdArr = stnIdArr; - } - - public String[] getStnNumArr() { - return stnNumArr; - } - - public void setStnNumArr(String[] stnNumArr) { - this.stnNumArr = stnNumArr; - } - - public void setLatLons(float[] latLons) { - - // from python script, I only know a way to pass one dimensional array, - // therefore convert it 2-D here. - if (latLons.length > 0) { - latLonArray = new float[latLons.length / 2][2]; - for (int i = 0, j = 0; i < latLons.length; i++, j++) { - this.latLonArray[j][0] = latLons[i]; - this.latLonArray[j][1] = latLons[++i]; - // System.out.println("latlons = "+ latLonArray[j][0] + ","+ - // latLonArray[j][1]); - } - } - } - - /** The logger */ - protected final transient Log logger = LogFactory.getLog(getClass()); - - public String getRefTimeStr() { - return refTimeStr; - } - - /* - * Reference time String should have this format: "yyyy-mm-dd hh" - */ - public void setRefTimeStr(String refTimeStr) { - this.refTimeStr = refTimeStr; - refTimeCal = convertTimeStrToCalendar(refTimeStr); - /* - * int year, mon, date, hr; int index = refTimeStr.indexOf('-'); if - * (index >= 4 ){ year = Integer.parseInt(refTimeStr.substring(index-4, - * index)); refTimeStr = refTimeStr.substring(index+1); index = - * refTimeStr.indexOf('-'); if(index >= 2 ){ mon = - * Integer.parseInt(refTimeStr.substring(index-2, index)); refTimeStr = - * refTimeStr.substring(index+1); index = refTimeStr.indexOf(' '); - * if(index >= 2 ){ date = - * Integer.parseInt(refTimeStr.substring(index-2, index)); refTimeStr = - * refTimeStr.substring(index+1); //index = refTimeStr.indexOf(':'); - * if(refTimeStr.length() >= 2 ){ hr = - * Integer.parseInt(refTimeStr.substring(0, 2)); refTimeCal = - * Calendar.getInstance(TimeZone.getTimeZone("GMT")); // reset time - * refTimeCal.setTimeInMillis(0); // set new time refTimeCal.set(year, - * mon-1, date, hr, 0,0); System.out.println("set time Str " + - * refTimeStr + " cal time in GMT " + refTimeCal.getTime().toGMTString() - * + " in msec = " + refTimeCal.getTimeInMillis()); } } } } - */ - - } - - public void setValidTimeStartStr(String validTimeStartStr) { - this.validTimeStartStr = validTimeStartStr; - validTimeStartCal = convertTimeStrToCalendar(validTimeStartStr); - /* - * int year, mon, date, hr; int index = validTimeStartStr.indexOf('-'); - * if (index >= 4 ){ year = - * Integer.parseInt(validTimeStartStr.substring(index-4, index)); - * validTimeStartStr = validTimeStartStr.substring(index+1); index = - * validTimeStartStr.indexOf('-'); if(index >= 2 ){ mon = - * Integer.parseInt(validTimeStartStr.substring(index-2, index)); - * validTimeStartStr = validTimeStartStr.substring(index+1); index = - * validTimeStartStr.indexOf(' '); if(index >= 2 ){ date = - * Integer.parseInt(validTimeStartStr.substring(index-2, index)); - * validTimeStartStr = validTimeStartStr.substring(index+1); //index = - * refTimeStr.indexOf(':'); if(validTimeStartStr.length() >= 2 ){ hr = - * Integer.parseInt(validTimeStartStr.substring(0, 2)); - * validTimeStartCal = - * Calendar.getInstance(TimeZone.getTimeZone("GMT")); // reset time - * validTimeStartCal.setTimeInMillis(0); // set new time - * validTimeStartCal.set(year, mon-1, date, hr, 0,0); - * System.out.println("set valid time start Str " + validTimeStartStr + - * " cal time in GMT " + validTimeStartCal.getTime().toGMTString() + - * " in msec = " + validTimeStartCal.getTimeInMillis()); } } } } - */ - - } - - public void setValidTimeEndStr(String validTimeEndStr) { - this.validTimeEndStr = validTimeEndStr; - validTimeEndCal = convertTimeStrToCalendar(validTimeEndStr); - /* - * int year, mon, date, hr; int index = validTimeEndStr.indexOf('-'); if - * (index >= 4 ){ year = - * Integer.parseInt(validTimeEndStr.substring(index-4, index)); - * validTimeEndStr = validTimeEndStr.substring(index+1); index = - * validTimeEndStr.indexOf('-'); if(index >= 2 ){ mon = - * Integer.parseInt(validTimeEndStr.substring(index-2, index)); - * validTimeEndStr = validTimeEndStr.substring(index+1); index = - * validTimeEndStr.indexOf(' '); if(index >= 2 ){ date = - * Integer.parseInt(validTimeEndStr.substring(index-2, index)); - * validTimeEndStr = validTimeEndStr.substring(index+1); //index = - * refTimeStr.indexOf(':'); if(validTimeEndStr.length() >= 2 ){ hr = - * Integer.parseInt(validTimeEndStr.substring(0, 2)); validTimeEndCal = - * Calendar.getInstance(TimeZone.getTimeZone("GMT")); // reset time - * validTimeEndCal.setTimeInMillis(0); // set new time - * validTimeEndCal.set(year, mon-1, date, hr, 0,0); - * System.out.println("set valid time end Str " + validTimeEndStr + - * " cal time in GMT " + validTimeEndCal.getTime().toGMTString() + - * " in msec = " + validTimeEndCal.getTimeInMillis()); } } } } - */ - - } - - private Calendar convertTimeStrToCalendar(String intimeStr) { - int year, mon, date, hr; - String timeStr = new String(intimeStr); - int index = timeStr.indexOf('-'); - - if (index >= 4) { - year = Integer.parseInt(timeStr.substring(index - 4, index)); - timeStr = timeStr.substring(index + 1); - index = timeStr.indexOf('-'); - if (index >= 2) { - mon = Integer.parseInt(timeStr.substring(index - 2, index)); - timeStr = timeStr.substring(index + 1); - index = timeStr.indexOf(' '); - if (index >= 2) { - date = Integer - .parseInt(timeStr.substring(index - 2, index)); - timeStr = timeStr.substring(index + 1); - // index = refTimeStr.indexOf(':'); - if (timeStr.length() >= 2) { - hr = Integer.parseInt(timeStr.substring(0, 2)); - Calendar cal; - cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // reset time - cal.setTimeInMillis(0); - // set new time - cal.set(year, mon - 1, date, hr, 0, 0); - return cal; - } - } - } - } - return null; - } - - public void setQueryType(String queryType) { - this.queryType = queryType; - } - - public String getTimeLine() { - return timeLine; - } - - public void setTimeLine(String timeLine) { - this.timeLine = timeLine; - } - - public NcSoundingDrv() { - super(); - dbIdList = null; - level = "-9999"; - merge = 0; - queryType = "LATLON"; - dataType = "ALLDATA"; - } - - public String getTableName() { - return tableName; - } - - public void setTableName(String tableName) { - this.tableName = tableName; - - } - - public String getDataType() { - return dataType; - } - - public void setDataType(String dataType) { - this.dataType = dataType; - } - - public int[] getDbIdList() { - return dbIdList; - } - - public void setDbIdList(int[] dbIdList) { - this.dbIdList = dbIdList; - } - - public double getLat() { - return lat; - } - - public void setLat(double lat) { - this.lat = lat; - } - - public void setLevel(String level) { - this.level = level; - } - - public void setStid(String stid) { - this.stid = stid; - } - - public double getLon() { - return lon; - } - - public String getValidTimeStr() { - return validTimeStartStr; - } - - public String getStid() { - return stid; - } - - public void setLon(double lon) { - this.lon = lon; - } - - public void setMerge(int merge) { - // for native model sounding and model sounding, there is no need to - // merge. Set merge - // to false accordingly. - this.merge = merge; - } - - public long getRefTime() { - return refTime; - } - - public void setRefTime(long refTime) { - this.refTime = refTime; - refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - refTimeCal.setTimeInMillis(refTime); - } - - public long getValidTimeStart() { - return validTimeStart; - } - - public void setValidTimeStart(long validTimeStart) { - this.validTimeStart = validTimeStart; - validTimeStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - validTimeStartCal.setTimeInMillis(validTimeStart); - } - - public long getValidTimeEnd() { - return validTimeEnd; - } - - public void setValidTimeEnd(long validTimeEnd) { - this.validTimeEnd = validTimeEnd; - validTimeEndCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - validTimeEndCal.setTimeInMillis(validTimeEnd); - } - - public String getSndType() { - return sndType; - } - - public void setSndType(String sndType) { - this.sndType = sndType; - } - - boolean proces = true; - - public void setModelName(String aModelName) { - this.modelName = aModelName; - } - - public void setPluginName(String aPluginName) { - this.pluginName = aPluginName; - } - - public String getModelName() { - return modelName; - } - - public String getPluginName() { - return pluginName; - } - - /* - * public Object execute() throws Exception { Object returnedObject = new - * Object(); System.out.println ( " Enter execute "); MergeSounding ms = new - * MergeSounding(); - * - * List sls = new ArrayList(); - * List ttaa = new ArrayList(); - * List ttbb = new ArrayList(); - * List ttcc = new ArrayList(); - * List ttdd = new ArrayList(); - * List ppaa = new ArrayList(); - * List ppbb = new ArrayList(); - * List ppcc = new ArrayList(); - * List ppdd = new ArrayList(); - * List trop_a = new ArrayList(); - * List trop_c = new ArrayList(); - * List wmax_a = new ArrayList(); - * List wmax_c = new ArrayList(); - * - * NcSoundingProfile pf = null; - * if(sndType.equals(PfcSndType.NAMSND.toString()) || - * sndType.equals(PfcSndType.GFSSND.toString()) || - * sndType.equals(PfcSndType.RUC2SND.toString())) { System.out.println ( - * " Processing native model data"); pf = - * PfcSoundingQuery.getPfcSndData(lat, lon, refTime, validTime, sndType); - * ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); - * } else if (sndType.equals(ObsSndType.UAIR.toString()) || - * sndType.equals(ObsSndType.DROP.toString()) || - * sndType.equals(ObsSndType.TAMDAR.toString())) { - * - * - * System.out.println ( - * " Processing UAIR data! sndType could be UAIR, BUFRUA, DROP, TAMDAR, etc" - * ); - * - * if(dbIdList!= null) { pf = - * ObservedSoundingQuery.getObservedSndData(dbIdList, sndType, dataType); } - * else { - * - * if ( merge == 0 ) { // ms.unMergedUairSounding System.out.println ( - * " Request unmerged data"); - * - * pf = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "ALLDATA"); } else { - * - * // Get TTAA. If not existent, try ship data (UUAA). If level is not null - * or missing, // the body of code will return a sounding list with MAN data - * or single level data. System.out.println ( " Request merged data"); - * - * // TO DO -----> add station ID and station number and a list of stations - * queries. pf = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "TTAA"); ttaa = pf.getSoundingLyLst(); if (ttaa.size() == 0) { - * ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "UUAA").getSoundingLyLst(); } - * - * ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "TTBB").getSoundingLyLst(); if (ttbb.size() == 0) { ttbb = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "UUBB").getSoundingLyLst(); } - * - * ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "TTCC").getSoundingLyLst(); if (ttcc.size() == 0) { ttcc = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "UUCC").getSoundingLyLst(); } - * - * ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "TTDD").getSoundingLyLst(); if (ttdd.size() == 0) { ttdd = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "UUDD").getSoundingLyLst(); } - * - * ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, - * sndType, "PPAA").getSoundingLyLst(); ppbb = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "PPBB").getSoundingLyLst(); ppcc = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "PPCC").getSoundingLyLst(); ppdd = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "PPDD").getSoundingLyLst(); wmax_a = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "MAXWIND_A").getSoundingLyLst(); wmax_c = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "MAXWIND_C").getSoundingLyLst(); trop_a = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "TROPOPAUSE_A").getSoundingLyLst(); trop_c = - * ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, - * "TROPOPAUSE_C").getSoundingLyLst(); sls = - * ms.mergeUairSounding(level,ttaa, - * ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a, - * trop_c,wmax_a,wmax_c,pf.getStationElevation()); pf.setSoundingLyLst(sls); - * } } } else if(sndType.equals(ObsSndType.BUFRUA.toString())){ pf = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * dataType); - * - * // TO DO: need to add "dataType" to bufr data - * - * if ( merge == 0 ) { // ms.unMergedUairSounding System.out.println ( - * " Request unmerged data"); - * - * //// pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "ALLDATA"); } else { - * - * // Get TTAA. If not existent, try ship data (UUAA). If level is not null - * or missing, // the body of code will return a sounding list with MAN data - * or single level data. System.out.println ( " Request merged data"); - * - * // TO DO -----> add station ID and station number and a list of stations - * queries. //// pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, - * lon, refTime, sndType, "TTAA"); ttaa = pf.getSoundingLyLst(); if - * (ttaa.size() == 0) { //// ttaa = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "UUAA").getSoundingLyLst(); } - * - * //// ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "TTBB").getSoundingLyLst(); if (ttbb.size() == 0) { - * //// ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "UUBB").getSoundingLyLst(); } - * - * //// ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "TTCC").getSoundingLyLst(); if (ttcc.size() == 0) { - * //// ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "UUCC").getSoundingLyLst(); } - * - * //// ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "TTDD").getSoundingLyLst(); if (ttdd.size() == 0) { - * //// ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "UUDD").getSoundingLyLst(); } - * - * //// ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, - * refTime, sndType, "PPAA").getSoundingLyLst(); //// ppbb = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "PPBB").getSoundingLyLst(); //// ppcc = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "PPCC").getSoundingLyLst(); //// ppdd = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "PPDD").getSoundingLyLst(); //// wmax_a = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "MAXWIND_A").getSoundingLyLst(); //// wmax_c = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "MAXWIND_C").getSoundingLyLst(); //// trop_a = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "TROPOPAUSE_A").getSoundingLyLst(); //// trop_c = - * ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, - * sndType, "TROPOPAUSE_C").getSoundingLyLst(); sls = - * ms.mergeUairSounding(level - * ,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a, - * trop_c,wmax_a,wmax_c,pf.getStationElevation()); pf.setSoundingLyLst(sls); - * } } - * - * - * else { - * - * pf = null; } returnedObject = pf; return returnedObject; } - */ - // for static sounding type query - public Object getSoundingRangeTimeLine() throws Exception { - Object returnedObject = null; - if (sndType.equals(ObsSndType.UAIR.toString()) - || sndType.equals(ObsSndType.H5UAIR.toString()) - || sndType.equals(ObsSndType.DROP.toString()) - || sndType.equals(ObsSndType.TAMDAR.toString())) { - - // *System.out.println ( - // "getSoundingTimeLine Processing UAIR request."); - returnedObject = ObservedSoundingQuery - .getObservedSndTimeLine(sndType); - } else if (sndType.equals(PfcSndType.NAMSND.toString()) - || sndType.equals(PfcSndType.GFSSND.toString())) { - returnedObject = PfcSoundingQuery.getPfcSndRangeTimeLine(sndType, - refTimeStr); - } - /* - * else if (sndType.equals(MdlSndType.GFSSNDMDL.toString())|| - * sndType.equals(MdlSndType.NAMSNDMDL.toString()) || - * sndType.equals(MdlSndType.RUC2SNDMDL.toString())|| - * sndType.equals(MdlSndType.NGMSNDMDL.toString()) || - * sndType.equals(MdlSndType.UKMETSNDMDL.toString())) { returnedObject = - * MdlSoundingQuery.getMdlSndRangeTimeLine(sndType, refTimeStr, - * tableName); } - */ - return returnedObject; - } - - // for static sounding type query - public Object getSoundingTimeLine() throws Exception { - Object returnedObject = null; - if (sndType.equals(ObsSndType.UAIR.toString()) - || sndType.equals(ObsSndType.H5UAIR.toString()) - || sndType.equals(ObsSndType.BUFRUA.toString()) - || sndType.equals(ObsSndType.DROP.toString()) - || sndType.equals(ObsSndType.TAMDAR.toString())) { - - // *System.out.println ( - // "getSoundingTimeLine Processing UAIR request."); - returnedObject = ObservedSoundingQuery - .getObservedSndTimeLine(sndType); - } else if (sndType.equals(PfcSndType.NAMSND.toString()) - || sndType.equals(PfcSndType.GFSSND.toString())) { - returnedObject = PfcSoundingQuery.getPfcSndTimeLine(sndType); - - } /* - * else if (sndType.equals(MdlSndType.GFSSNDMDL.toString())|| - * sndType.equals(MdlSndType.NAMSNDMDL.toString()) || - * sndType.equals(MdlSndType.RUC2SNDMDL.toString())|| - * sndType.equals(MdlSndType.NGMSNDMDL.toString()) || - * sndType.equals(MdlSndType.UKMETSNDMDL.toString())) { returnedObject - * = MdlSoundingQuery.getMdlSndTimeLine(sndType, tableName); } - */ - - return returnedObject; - } - - // for model sounding query - its model type is returned during query time. - public Object getMdlSoundingRangeTimeLine() throws Exception { - Object returnedObject = null; - returnedObject = MdlSoundingQuery.getMdlSndRangeTimeLine(sndType, - refTimeStr, tableName); - return returnedObject; - } - - // for model sounding query - its model type is returned during query time. - public Object getMdlSoundingTimeLine() throws Exception { - Object returnedObject = null; - - returnedObject = MdlSoundingQuery.getMdlSndTimeLine(sndType, tableName); - - return returnedObject; - } - - public Object getSoundingStnInfoCol() throws Exception { - Object returnedObject = null; - // System.out.println ( "getSoundingStnInfoCol sndType ="+sndType); - NcSoundingStnInfoCollection stnInfoCol = null; - if (sndType.equals(ObsSndType.UAIR.toString()) - || sndType.equals(ObsSndType.H5UAIR.toString()) - || sndType.equals(ObsSndType.BUFRUA.toString()) - || sndType.equals(ObsSndType.DROP.toString()) - || sndType.equals(ObsSndType.TAMDAR.toString())) { - stnInfoCol = ObservedSoundingQuery.getObservedSndStnInfoCol( - sndType, timeLine); - } else if (sndType.equals(PfcSndType.NAMSND.toString()) - || sndType.equals(PfcSndType.GFSSND.toString()) - || sndType.equals(PfcSndType.RUCPTYPSND.toString()) - || sndType.equals(PfcSndType.RUC2SND.toString())) { - stnInfoCol = PfcSoundingQuery - .getPfcSndStnInfoCol(sndType, timeLine); - } - - else - return returnedObject; - - returnedObject = stnInfoCol; - return returnedObject; - } - - private List getSndLayersFromH5UairRecordObsLevel( - H5UairRecord record) { - List sndLayers = new ArrayList(); - Set obLevels = record.getObsLevels(); - - if (obLevels.size() > 0) { - for (H5ObsLevels obLev : obLevels) { - NcSoundingLayer sndLayer = new NcSoundingLayer(); - sndLayer.setTemperature(obLev.getTemp()); - sndLayer.setDewpoint(obLev.getDwpt()); - sndLayer.setGeoHeight(obLev.getHght()); - sndLayer.setPressure(obLev.getPres()); - sndLayer.setWindDirection(obLev.getDrct()); - if (obLev.getSped() >= 0) - sndLayer.setWindSpeed((float) metersPerSecondToKnots - .convert(obLev.getSped())); - else - sndLayer.setWindSpeed(obLev.getSped()); - sndLayers.add(sndLayer); - } - } - // System.out.println("ObsLevel="+obLevels.size()+" sndLayers="+sndLayers.size()); - return sndLayers; - } - - private List getSndLayersFromH5UairRecordTrop( - H5UairRecord record) { - List sndLayers = new ArrayList(); - Set trops = record.getTropopause(); - if (trops.size() > 0) { - for (H5Tropopause trop : trops) { - NcSoundingLayer sndLayer = new NcSoundingLayer(); - sndLayer.setTemperature(trop.getTemp()); - sndLayer.setDewpoint(trop.getDwpt()); - sndLayer.setPressure(trop.getPres()); - sndLayer.setWindDirection(trop.getDrct()); - if (trop.getSped() >= 0) - sndLayer.setWindSpeed((float) metersPerSecondToKnots - .convert(trop.getSped())); - else - sndLayer.setWindSpeed(trop.getSped()); - sndLayers.add(sndLayer); - } - } - // System.out.println("trops="+trops.size()+" sndLayers="+sndLayers.size()); - return sndLayers; - } - - private List getSndLayersFromH5UairRecordMaxw( - H5UairRecord record) { - List sndLayers = new ArrayList(); - Set maxWinds = record.getMaxWind(); - if (maxWinds.size() > 0) { - for (H5MaxWind maxWind : maxWinds) { - NcSoundingLayer sndLayer = new NcSoundingLayer(); - sndLayer.setPressure(maxWind.getPres()); - sndLayer.setWindDirection(maxWind.getDrct()); - if (maxWind.getSped() >= 0) - sndLayer.setWindSpeed((float) metersPerSecondToKnots - .convert(maxWind.getSped())); - else - sndLayer.setWindSpeed(maxWind.getSped()); - sndLayers.add(sndLayer); - } - } - // System.out.println("maxWinds="+maxWinds.size()+" sndLayers="+sndLayers.size()); - return sndLayers; - } - - /* - * This API is for getting multiple locations sounding info at one shot. - * latLonArray is used to input lat/lon for each location. Use StnID as - * input location is NOT SUPPORTED in this API - */ - public Object getSoundingDataByLatLonArray() throws Exception { - // long t01 = System.currentTimeMillis(); - Object returnedObject = new Object(); - // *System.out.println ( " getSoundingDataByLatLonArray "); - if (latLonArray.length <= 0) { - returnedObject = null; - return returnedObject; - } - List timeLineStrList = new ArrayList(); - ; - List timeLimeCalList = new ArrayList(); - if (validTimeEnd != 0 && validTimeEnd > validTimeStart) { - // range of time line request - timeLimeCalList = ObservedSoundingQuery - .getObservedSndTimeRangeList(sndType, validTimeStartCal, - validTimeEndCal); - for (int i = 0; i < timeLimeCalList.size(); i++) { - Calendar timeCal = timeLimeCalList.get(i); - String timeStr = String.format( - "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); - timeLineStrList.add(timeStr); - - } - } else { - // one single time line - timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - .format(refTimeCal.getTime())); - timeLimeCalList.add(refTimeCal); - } - NcSoundingCube cube = new NcSoundingCube(); - List soundingProfileList = new ArrayList(); - SndQueryKeyType sndQuery = SndQueryKeyType.LATLON; - NcSoundingCube.QueryStatus failedRtnStatus = NcSoundingCube.QueryStatus.FAILED; - for (int i = 0; i < latLonArray.length; i++) { - for (int j = 0; j < timeLineStrList.size(); j++) { - String timeStr = timeLineStrList.get(j); - Calendar timeCal = timeLimeCalList.get(j); - - MergeSounding ms = new MergeSounding(); - // make sure we have right precision... - lat = Double.parseDouble(Float.toString(latLonArray[i][0])); - lon = Double.parseDouble(Float.toString(latLonArray[i][1])); - /* - * Process sounding data. - */ - - List sls = new ArrayList(); - List ttaa = new ArrayList(); - List ttbb = new ArrayList(); - List ttcc = new ArrayList(); - List ttdd = new ArrayList(); - List ppaa = new ArrayList(); - List ppbb = new ArrayList(); - List ppcc = new ArrayList(); - List ppdd = new ArrayList(); - List trop_a = new ArrayList(); - List trop_c = new ArrayList(); - List wmax_a = new ArrayList(); - List wmax_c = new ArrayList(); - - NcSoundingProfile pf = null; - if (sndType.equals(PfcSndType.NAMSND.toString()) - || sndType.equals(PfcSndType.GFSSND.toString()) - || sndType.equals(PfcSndType.RUCPTYPSND.toString()) - || sndType.equals(PfcSndType.RUC2SND.toString())) { - - // *System.out.println ( " Processing native model data"); - pf = PfcSoundingQuery.getPfcSndData2(lat, lon, "", - refTimeCal, validTimeStartCal, sndType, sndQuery); - // PfcSoundingQuery.getPfcSndData(lat, lon, "",refTimeCal, - // validTimeCal, sndType,sndQuery); - ms.nativeModelSounding(pf.getSoundingLyLst(), - pf.getStationElevation()); - } else if (sndType.equals(MdlSndType.ANY.toString())) { - - pf = MdlSoundingQuery.getMdlSndData(lat, lon, refTimeStr, - validTimeStartStr, pluginName, modelName); - if (pf.getRtnStatus() != NcSoundingCube.QueryStatus.OK) { - failedRtnStatus = pf.getRtnStatus(); - pf = null; - } - } else if (sndType.equals(ObsSndType.H5UAIR.toString())) { - // System.out.println("getSoundingDataByLatLonArray:H5Uair: lat="+lat+ - // " lon="+lon); - // make sure we have right precision... - - if (merge == 0) { - // Chin...need more coding - pf = ObservedSoundingQuery.getObservedSndH5UairAllData( - lat, lon, "", timeStr, "TTAA", sndQuery); - } else { - long t001 = System.currentTimeMillis(); - - // get TTAA & TROPOPAUSE_A & MAXWIND_A - H5UairRecord record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "TTAA", sndQuery); - if (record != null) { - ttaa = getSndLayersFromH5UairRecordObsLevel(record); - trop_a = getSndLayersFromH5UairRecordTrop(record); - wmax_a = getSndLayersFromH5UairRecordMaxw(record); - } - // get TTCC & TROPOPAUSE_C & MAXWIND_C - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "TTCC", sndQuery); - if (record != null) { - ttcc = getSndLayersFromH5UairRecordObsLevel(record); - trop_c = getSndLayersFromH5UairRecordTrop(record); - wmax_c = getSndLayersFromH5UairRecordMaxw(record); - } - // get TTBB - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "TTBB", sndQuery); - if (record != null) { - ttbb = getSndLayersFromH5UairRecordObsLevel(record); - } - // get TTDD - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "TTDD", sndQuery); - if (record != null) { - ttdd = getSndLayersFromH5UairRecordObsLevel(record); - } - // get PPAA - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "PPAA", sndQuery); - if (record != null) { - ppaa = getSndLayersFromH5UairRecordObsLevel(record); - } - // get PPBB - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "PPBB", sndQuery); - if (record != null) { - ppbb = getSndLayersFromH5UairRecordObsLevel(record); - } - // get PPCC - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "PPCC", sndQuery); - if (record != null) { - ppcc = getSndLayersFromH5UairRecordObsLevel(record); - } - // get PPDD - record = ObservedSoundingQuery - .getObservedSndH5UairData(lat, lon, "", - timeStr, "PPDD", sndQuery); - if (record != null) { - ppdd = getSndLayersFromH5UairRecordObsLevel(record); - } - pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, - lon, "", sndType, timeCal, sndQuery); - long t02 = System.currentTimeMillis(); - // System.out.println("H5UAIR profile retreival "+timeStr+ - // " at lat="+lat+" lon="+lon+" took " + (t02 - t001)); - sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, - ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, - wmax_a, wmax_c, pf.getStationElevation()); - // System.out.println("H5UAIR Number of Layers after merge:"+sls.size() - // + " level="+level + - // " ms.isNumber(level)="+ms.isNumber(level)); - // for(NcSoundingLayer ly: sls){ - // System.out.println("Pre= "+ly.getPressure()+ - // " Dew= "+ ly.getDewpoint()+ " T= "+ - // ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); - // } - - if (level.toUpperCase().equalsIgnoreCase("MAN")) - pf.setSoundingLyLst(sls); - else if (ms.isNumber(level) >= 0) { - if (sls.size() == 1) { - // System.out.println("H5UAIR get one layer using level = "+ - // level); - pf.setSoundingLyLst(sls); - } else { - pf = null; - // System.out.println("H5UAIR get 0 layer using level = "+ - // level); - } - } else { - if (sls.isEmpty() || sls.size() <= 1) - pf = null; - else - pf.setSoundingLyLst(sls); - } - } - } else if (sndType.equals(ObsSndType.UAIR.toString()) - || sndType.equals(ObsSndType.DROP.toString()) - || sndType.equals(ObsSndType.TAMDAR.toString())) { - - if (merge == 0) { - // ms.unMergedUairSounding - // *System.out.println ( " Request unmerged data"); - if (dataType.equals(DataType.ALLDATA.toString())) - pf = ObservedSoundingQuery.getObservedSndAllData( - lat, lon, "", timeCal, sndType, sndQuery); - else - pf = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, dataType, - sndQuery); - - } else { - - // Get TTAA. If not existent, try ship data (UUAA). If - // level is not null or missing, - // the body of code will return a sounding list with MAN - // data or single level data. - // *System.out.println ( " Request merged data at lat="+ - // lat+" lon="+lon+ " refT="+ - // refTimeCal.getTime().toGMTString()); - long t001 = System.currentTimeMillis(); - pf = ObservedSoundingQuery.getObservedSndData(lat, lon, - "", timeCal, sndType, "TTAA", sndQuery); - ttaa = pf.getSoundingLyLst(); - if (ttaa.size() == 0) { - ttaa = ObservedSoundingQuery.getObservedSndData( - lat, lon, "", timeCal, sndType, "UUAA", - sndQuery).getSoundingLyLst(); - } - - ttbb = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "TTBB", sndQuery) - .getSoundingLyLst(); - if (ttbb.size() == 0) { - ttbb = ObservedSoundingQuery.getObservedSndData( - lat, lon, "", timeCal, sndType, "UUBB", - sndQuery).getSoundingLyLst(); - } - - ttcc = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "TTCC", sndQuery) - .getSoundingLyLst(); - if (ttcc.size() == 0) { - ttcc = ObservedSoundingQuery.getObservedSndData( - lat, lon, "", timeCal, sndType, "UUCC", - sndQuery).getSoundingLyLst(); - } - - ttdd = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "TTDD", sndQuery) - .getSoundingLyLst(); - if (ttdd.size() == 0) { - ttdd = ObservedSoundingQuery.getObservedSndData( - lat, lon, "", timeCal, sndType, "UUDD", - sndQuery).getSoundingLyLst(); - } - - ppaa = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "PPAA", sndQuery) - .getSoundingLyLst(); - ppbb = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "PPBB", sndQuery) - .getSoundingLyLst(); - ppcc = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "PPCC", sndQuery) - .getSoundingLyLst(); - ppdd = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "PPDD", sndQuery) - .getSoundingLyLst(); - wmax_a = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "MAXWIND_A", - sndQuery).getSoundingLyLst(); - wmax_c = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "MAXWIND_C", - sndQuery).getSoundingLyLst(); - trop_a = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "TROPOPAUSE_A", - sndQuery).getSoundingLyLst(); - trop_c = ObservedSoundingQuery.getObservedSndData(lat, - lon, "", timeCal, sndType, "TROPOPAUSE_C", - sndQuery).getSoundingLyLst(); - pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, - lon, "", sndType, timeCal, sndQuery); - long t02 = System.currentTimeMillis(); - System.out.println("UAIR profile retreival " + timeStr - + " took " + (t02 - t001)); - sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, - ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, - wmax_a, wmax_c, pf.getStationElevation()); - // System.out.println("UAIR Number of Layers:"+sls.size()); - if (level.toUpperCase().equalsIgnoreCase("MAN")) - pf.setSoundingLyLst(sls); - else if (ms.isNumber(level) >= 0) { - if (sls.size() == 1) { - pf.setSoundingLyLst(sls); - } else { - pf = null; - } - } else { - if (sls.isEmpty() || sls.size() <= 1) - pf = null; - else - pf.setSoundingLyLst(sls); - } - - } - - } else if (sndType.equals(ObsSndType.BUFRUA.toString())) { - if (merge == 0) { - // ms.unMergedUairSounding - // *System.out.println ( " Request unmerged data"); - if (dataType.equals(DataType.ALLDATA.toString())) - pf = ObservedSoundingQuery - .getObservedSndBufruaAllData(lat, lon, "", - refTimeCal, sndQuery); - else - pf = ObservedSoundingQuery - .getObservedSndBufruaData(lat, lon, "", - refTimeCal, dataType, sndQuery); - - } else { - - // Get TTAA. If not existent, try ship data (UUAA). If - // level is not null or missing, - // the body of code will return a sounding list with MAN - // data or single level data. - // *System.out.println ( " Request merged data at lat="+ - // lat+" lon="+lon+ " refT="+ - // refTimeCal.getTime().toGMTString()); - - pf = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "TTAA", sndQuery); - ttaa = pf.getSoundingLyLst(); - ttbb = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "TTBB", sndQuery) - .getSoundingLyLst(); - ttcc = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "TTCC", sndQuery) - .getSoundingLyLst(); - ttdd = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "TTDD", sndQuery) - .getSoundingLyLst(); - // ppaa = - // ObservedSoundingQuery.getObservedSndBufruaData(lat, - // lon, "", refTimeCal, "PPAA", - // sndQuery).getSoundingLyLst(); - ppbb = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "PPBB", sndQuery) - .getSoundingLyLst(); - // ppcc = - // ObservedSoundingQuery.getObservedSndBufruaData(lat, - // lon, "", refTimeCal, "PPCC", - // sndQuery).getSoundingLyLst(); - ppdd = ObservedSoundingQuery.getObservedSndBufruaData( - lat, lon, "", refTimeCal, "PPDD", sndQuery) - .getSoundingLyLst(); - wmax_a = ObservedSoundingQuery - .getObservedSndBufruaData(lat, lon, "", - refTimeCal, "MAXWIND_A", sndQuery) - .getSoundingLyLst(); - wmax_c = ObservedSoundingQuery - .getObservedSndBufruaData(lat, lon, "", - refTimeCal, "MAXWIND_C", sndQuery) - .getSoundingLyLst(); - trop_a = ObservedSoundingQuery - .getObservedSndBufruaData(lat, lon, "", - refTimeCal, "TROPOPAUSE_A", sndQuery) - .getSoundingLyLst(); - trop_c = ObservedSoundingQuery - .getObservedSndBufruaData(lat, lon, "", - refTimeCal, "TROPOPAUSE_C", sndQuery) - .getSoundingLyLst(); - pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, - lon, "", sndType, refTimeCal, sndQuery); - sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, - ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, - wmax_a, wmax_c, pf.getStationElevation()); - - // System.out.println("BUFRUA Number of Layers after merge:"+sls.size() - // + " level="+level + - // " ms.isNumber(level)="+ms.isNumber(level)); - // for(NcSoundingLayer ly: sls){ - // System.out.println("Pre= "+ly.getPressure()+ - // " Dew= "+ ly.getDewpoint()+ " T= "+ - // ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); - // } - - if (level.toUpperCase().equalsIgnoreCase("MAN")) - pf.setSoundingLyLst(sls); - else if (ms.isNumber(level) >= 0) { - if (sls.size() == 1) { - // System.out.println("H5UAIR get one layer using level = "+ - // level); - pf.setSoundingLyLst(sls); - } else { - pf = null; - // System.out.println("H5UAIR get 0 layer using level = "+ - // level); - } - } else { - if (sls.isEmpty() || sls.size() <= 1) - pf = null; - else - pf.setSoundingLyLst(sls); - } - - } - } else { - - /* - * Invalid sounding type - */ - pf = null; - } - if (pf != null && pf.getSoundingLyLst().size() > 0) { - soundingProfileList.add(pf); - // pf.setStationLatitude(lat.floatValue()); - // pf.setStationLongitude(lon.floatValue()); - pf = null; - } - } - } - if (soundingProfileList.size() == 0) - cube.setRtnStatus(failedRtnStatus); - else - cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); - - cube.setSoundingProfileList(soundingProfileList); - returnedObject = cube; - - // long t02 = System.currentTimeMillis(); - // System.out.println("PFC/OBS cube retreival took " + (t02 - t01)); - return returnedObject; - } - - /* - * This API is for getting multiple locations sounding info at one shot. - * StnIdArray or StnNumArray is used as input stn info for each location. - */ - public Object getSoundingDataByStnArray() throws Exception { - Object returnedObject = new Object(); - // System.out.println ( " getSoundingData "); - - NcSoundingCube cube = new NcSoundingCube(); - List soundingProfileList = new ArrayList(); - SndQueryKeyType sndQuery; - String[] stnArray; - if (queryType.equals(SndQueryKeyType.STNID.toString())) { - sndQuery = SndQueryKeyType.STNID; - stnArray = stnIdArr.clone(); - - } else if (queryType.equals(SndQueryKeyType.STNNUM.toString())) { - sndQuery = SndQueryKeyType.STNNUM; - stnArray = stnNumArr.clone(); - } else { - returnedObject = null; - return returnedObject; - } - if (stnArray.length <= 0) { - returnedObject = null; - return returnedObject; - } - List timeLineStrList = new ArrayList(); - ; - List timeLimeCalList = new ArrayList(); - if (validTimeEnd != 0 && validTimeEnd > validTimeStart) { - // range of time line request - timeLimeCalList = ObservedSoundingQuery - .getObservedSndTimeRangeList(sndType, validTimeStartCal, - validTimeEndCal); - for (int i = 0; i < timeLimeCalList.size(); i++) { - Calendar timeCal = timeLimeCalList.get(i); - String timeStr = String.format( - "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); - timeLineStrList.add(timeStr); - - } - } else { - // one single time line - timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - .format(refTimeCal.getTime())); - timeLimeCalList.add(refTimeCal); - } - String stn; - for (int i = 0; i < stnArray.length; i++) { - - stn = stnArray[i]; - stn.toUpperCase(Locale.ENGLISH); - // System.out.println ( "Request getSoundingData at " + stn); - MergeSounding ms = new MergeSounding(); - for (int j = 0; j < timeLineStrList.size(); j++) { - String timeStr = timeLineStrList.get(j); - Calendar timeCal = timeLimeCalList.get(j); - /* - * Process sounding data. - */ - - List sls = new ArrayList(); - List ttaa = new ArrayList(); - List ttbb = new ArrayList(); - List ttcc = new ArrayList(); - List ttdd = new ArrayList(); - List ppaa = new ArrayList(); - List ppbb = new ArrayList(); - List ppcc = new ArrayList(); - List ppdd = new ArrayList(); - List trop_a = new ArrayList(); - List trop_c = new ArrayList(); - List wmax_a = new ArrayList(); - List wmax_c = new ArrayList(); - - NcSoundingProfile pf = null; - if (sndType.equals(ObsSndType.H5UAIR.toString())) { - // System.out.println("getSoundingDataByLatLonArray:H5Uair: lat="+lat+ - // " lon="+lon); - if (merge == 0) { - // Chin...need more coding - pf = ObservedSoundingQuery.getObservedSndH5UairAllData( - 0d, 0d, stn, timeStr, "TTAA", sndQuery); - } else { - /* - * long t001 = System.currentTimeMillis(); //get TTAA & - * TROPOPAUSE_A & MAXWIND_A H5UairRecord record = - * ObservedSoundingQuery.getObservedSndH5UairData(lat, - * lon, "", refTime, "TTAA", sndQuery); if(record != - * null){ ttaa = - * getSndLayersFromH5UairRecordObsLevel(record); trop_a - * = getSndLayersFromH5UairRecordTrop(record); wmax_a = - * getSndLayersFromH5UairRecordMaxw(record); } //get - * TTCC & TROPOPAUSE_C & MAXWIND_C record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "TTCC", sndQuery); if(record != - * null){ ttcc = - * getSndLayersFromH5UairRecordObsLevel(record); trop_c - * = getSndLayersFromH5UairRecordTrop(record); wmax_c = - * getSndLayersFromH5UairRecordMaxw(record); } //get - * TTBB record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "TTBB", sndQuery); if(record != - * null){ ttbb = - * getSndLayersFromH5UairRecordObsLevel(record); } //get - * TTDD record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "TTDD", sndQuery); if(record != - * null){ ttdd = - * getSndLayersFromH5UairRecordObsLevel(record); } //get - * PPAA record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "PPAA", sndQuery); if(record != - * null){ ppaa = - * getSndLayersFromH5UairRecordObsLevel(record); } //get - * PPBB record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "PPBB", sndQuery); if(record != - * null){ ppbb = - * getSndLayersFromH5UairRecordObsLevel(record); } //get - * PPCC record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "PPCC", sndQuery); if(record != - * null){ ppcc = - * getSndLayersFromH5UairRecordObsLevel(record); } //get - * PPDD record = - * ObservedSoundingQuery.getObservedSndH5UairData(0d, - * 0d, stn, refTime, "PPDD", sndQuery); if(record != - * null){ ppdd = - * getSndLayersFromH5UairRecordObsLevel(record); } pf = - * ObservedSoundingQuery.getObservedSndStnInfo(0d, 0d, - * stn,sndType, refTimeCal,sndQuery); long t02 = - * System.currentTimeMillis(); System.out.println( - * "H5UAIR (by stn) profile retreival took " + (t02 - - * t001)); sls = - * ms.mergeUairSounding(level,ttaa,ttbb,ttcc - * ,ttdd,ppaa,ppbb - * ,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c, - * pf.getStationElevation()); - * //System.out.println("H5UAIR Number of Layers:" - * +sls.size()); //for(NcSoundingLayer ly: sls){ // - * System.out.println("Pre= "+ly.getPressure()+ - * " Dew= "+ ly.getDewpoint()+ " T= "+ - * ly.getTemperature( - * )+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); - * //} - */ - pf.setSoundingLyLst(sls); - } - } else if (sndType.equals(ObsSndType.UAIR.toString()) - || sndType.equals(ObsSndType.DROP.toString()) - || sndType.equals(ObsSndType.TAMDAR.toString())) { - - if (merge == 0) { - // ms.unMergedUairSounding - // System.out.println ( " Request unmerged data"); - if (dataType.equals(DataType.ALLDATA.toString())) - pf = ObservedSoundingQuery.getObservedSndAllData( - 0d, 0d, stn, timeCal, sndType, sndQuery); - else - pf = ObservedSoundingQuery.getObservedSndData(0d, - 0d, stn, timeCal, sndType, dataType, - sndQuery); - - } else { - - // Get TTAA. If not existent, try ship data (UUAA). If - // level is not null or missing, - // the body of code will return a sounding list with MAN - // data or single level data. - // *System.out.println ( " Request merged data at lat="+ - // lat+" lon="+lon+ " refT="+ - // refTimeCal.getTime().toGMTString()); - - // TO DO -----> add station ID and station number and a - // list of stations queries. - pf = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "TTAA", sndQuery); - ttaa = pf.getSoundingLyLst(); - if (ttaa.size() == 0) { - ttaa = ObservedSoundingQuery - .getObservedSndData(0d, 0d, stn, timeCal, - sndType, "UUAA", sndQuery) - .getSoundingLyLst(); - } - - ttbb = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "TTBB", sndQuery) - .getSoundingLyLst(); - if (ttbb.size() == 0) { - ttbb = ObservedSoundingQuery - .getObservedSndData(0d, 0d, stn, timeCal, - sndType, "UUBB", sndQuery) - .getSoundingLyLst(); - } - - ttcc = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "TTCC", sndQuery) - .getSoundingLyLst(); - if (ttcc.size() == 0) { - ttcc = ObservedSoundingQuery - .getObservedSndData(0d, 0d, stn, timeCal, - sndType, "UUCC", sndQuery) - .getSoundingLyLst(); - } - - ttdd = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "TTDD", sndQuery) - .getSoundingLyLst(); - if (ttdd.size() == 0) { - ttdd = ObservedSoundingQuery - .getObservedSndData(0d, 0d, stn, timeCal, - sndType, "UUDD", sndQuery) - .getSoundingLyLst(); - } - - ppaa = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "PPAA", sndQuery) - .getSoundingLyLst(); - ppbb = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "PPBB", sndQuery) - .getSoundingLyLst(); - ppcc = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "PPCC", sndQuery) - .getSoundingLyLst(); - ppdd = ObservedSoundingQuery.getObservedSndData(0d, 0d, - stn, timeCal, sndType, "PPDD", sndQuery) - .getSoundingLyLst(); - wmax_a = ObservedSoundingQuery.getObservedSndData(0d, - 0d, stn, timeCal, sndType, "MAXWIND_A", - sndQuery).getSoundingLyLst(); - wmax_c = ObservedSoundingQuery.getObservedSndData(0d, - 0d, stn, timeCal, sndType, "MAXWIND_C", - sndQuery).getSoundingLyLst(); - trop_a = ObservedSoundingQuery.getObservedSndData(0d, - 0d, stn, timeCal, sndType, "TROPOPAUSE_A", - sndQuery).getSoundingLyLst(); - trop_c = ObservedSoundingQuery.getObservedSndData(0d, - 0d, stn, timeCal, sndType, "TROPOPAUSE_C", - sndQuery).getSoundingLyLst(); - pf = ObservedSoundingQuery.getObservedSndStnInfo(0d, - 0d, stn, sndType, timeCal, sndQuery); - sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, - ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, - wmax_a, wmax_c, pf.getStationElevation()); - pf.setSoundingLyLst(sls); - } - - } else if (sndType.equals(ObsSndType.BUFRUA.toString())) { - if (merge == 0) { - // ms.unMergedUairSounding - // *System.out.println ( " Request unmerged data"); - if (dataType.equals(DataType.ALLDATA.toString())) - pf = ObservedSoundingQuery - .getObservedSndBufruaAllData(0d, 0d, stn, - refTimeCal, sndQuery); - else - pf = ObservedSoundingQuery - .getObservedSndBufruaData(0d, 0d, stn, - refTimeCal, dataType, sndQuery); - - } else { - - // Get TTAA. If not existent, try ship data (UUAA). If - // level is not null or missing, - // the b0dy of c0de will return a sounding list with MAN - // data or single level data. - // *System.out.println ( " Request merged data at lat="+ - // lat+" lon="+lon+ " refT="+ - // refTimeCal.getTime().toGMTString()); - - pf = ObservedSoundingQuery.getObservedSndBufruaData(0d, - 0d, stn, refTimeCal, "TTAA", sndQuery); - ttaa = pf.getSoundingLyLst(); - ttbb = ObservedSoundingQuery.getObservedSndBufruaData( - 0d, 0d, stn, refTimeCal, "TTBB", sndQuery) - .getSoundingLyLst(); - ttcc = ObservedSoundingQuery.getObservedSndBufruaData( - 0d, 0d, stn, refTimeCal, "TTCC", sndQuery) - .getSoundingLyLst(); - ttdd = ObservedSoundingQuery.getObservedSndBufruaData( - 0d, 0d, stn, refTimeCal, "TTDD", sndQuery) - .getSoundingLyLst(); - // ppaa = - // ObservedSoundingQuery.getObservedSndBufruaData(0d, - // 0d, stn, refTimeCal, "PPAA", - // sndQuery).getSoundingLyLst(); - ppbb = ObservedSoundingQuery.getObservedSndBufruaData( - 0d, 0d, stn, refTimeCal, "PPBB", sndQuery) - .getSoundingLyLst(); - // ppcc = - // ObservedSoundingQuery.getObservedSndBufruaData(0d, - // 0d, stn, refTimeCal, "PPCC", - // sndQuery).getSoundingLyLst(); - ppdd = ObservedSoundingQuery.getObservedSndBufruaData( - 0d, 0d, stn, refTimeCal, "PPDD", sndQuery) - .getSoundingLyLst(); - wmax_a = ObservedSoundingQuery - .getObservedSndBufruaData(0d, 0d, stn, - refTimeCal, "MAXWIND_A", sndQuery) - .getSoundingLyLst(); - wmax_c = ObservedSoundingQuery - .getObservedSndBufruaData(0d, 0d, stn, - refTimeCal, "MAXWIND_C", sndQuery) - .getSoundingLyLst(); - trop_a = ObservedSoundingQuery - .getObservedSndBufruaData(0d, 0d, stn, - refTimeCal, "TROPOPAUSE_A", sndQuery) - .getSoundingLyLst(); - trop_c = ObservedSoundingQuery - .getObservedSndBufruaData(0d, 0d, stn, - refTimeCal, "TROPOPAUSE_C", sndQuery) - .getSoundingLyLst(); - pf = ObservedSoundingQuery.getObservedSndStnInfo(0d, - 0d, stn, sndType, refTimeCal, sndQuery); - sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, - ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, - wmax_a, wmax_c, pf.getStationElevation()); - pf.setSoundingLyLst(sls); - } - } else if (sndType.equals(PfcSndType.NAMSND.toString()) - || sndType.equals(PfcSndType.GFSSND.toString()) - || sndType.equals(PfcSndType.RUCPTYPSND.toString()) - || sndType.equals(PfcSndType.RUC2SND.toString())) { - // *System.out.println ( " Processing native model data"); - pf = PfcSoundingQuery.getPfcSndData(0d, 0d, stn, - refTimeCal, validTimeStartCal, sndType, sndQuery); - ms.nativeModelSounding(pf.getSoundingLyLst(), - pf.getStationElevation()); - - } else if (sndType.equals(MdlSndType.ANY.toString())) { - // model sounding query by stn is not supported yet - pf = null; - } else { - - /* - * Invalid sounding type - */ - pf = null; - } - if (pf != null && pf.getSoundingLyLst().size() > 0) { - soundingProfileList.add(pf); - pf.setStationId(stn); - - pf = null; - } - } - } - if (soundingProfileList.size() == 0) - cube.setRtnStatus(NcSoundingCube.QueryStatus.FAILED); - else - cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); - - cube.setSoundingProfileList(soundingProfileList); - returnedObject = cube; - - return returnedObject; - } - - public Object getModels() throws Exception { - Object returnedObject = new Object(); - NcSoundingModel mdls = MdlSoundingQuery.getMdls(tableName); - returnedObject = mdls; - return returnedObject; - } +import gov.noaa.nws.ncep.common.dataplugin.ncuair.NcUairMaxWind; +import gov.noaa.nws.ncep.common.dataplugin.ncuair.NcUairObsLevels; +import gov.noaa.nws.ncep.common.dataplugin.ncuair.NcUairTropopause; +import gov.noaa.nws.ncep.common.dataplugin.ncuair.NcUairRecord; +import gov.noaa.nws.ncep.edex.common.metparameters.AirTemperature; +import gov.noaa.nws.ncep.edex.common.metparameters.Amount; +import gov.noaa.nws.ncep.edex.common.metparameters.DewPointTemp; +import gov.noaa.nws.ncep.edex.common.metparameters.HeightAboveSeaLevel; +import gov.noaa.nws.ncep.edex.common.metparameters.PressureLevel; +import gov.noaa.nws.ncep.edex.common.metparameters.WindDirection; +import gov.noaa.nws.ncep.edex.common.metparameters.WindSpeed; +import gov.noaa.nws.ncep.edex.common.metparameters.parameterconversion.NcUnits; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingCube; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer2; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingModel; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.MdlSndType; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer.DataType; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.ObsSndType; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.PfcSndType; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.SndQueryKeyType; +import gov.noaa.nws.ncep.edex.uengine.tasks.profile.PfcSoundingQuery; + +public class NcSoundingDrv { + private static final UnitConverter metersPerSecondToKnots = SI.METERS_PER_SECOND.getConverterTo(NonSI.KNOT); + private Double lat, lon; + private long refTime=0, validTimeStart=0, validTimeEnd=0; + private String timeLine, refTimeStr, validTimeStartStr=null, validTimeEndStr=null; + private Calendar refTimeCal, validTimeStartCal, validTimeEndCal; + private String stid,level, dataType, sndType, queryType, tableName; + private int merge; + private int[] dbIdList; + private String[] stnIdArr; + private String[] stnNumArr; + private String modelName; + private String pluginName; + private float[][] latLonArray; // e.g. at nth element, lat=[n][0], lon=[n][1] + public float[][] getLatLons() { + return latLonArray; + } + + + + + + public String[] getStnIdArr() { + return stnIdArr; + } + + + + public void setStnIdArr(String[] stnIdArr) { + this.stnIdArr = stnIdArr; + } + + + + public String[] getStnNumArr() { + return stnNumArr; + } + + + + public void setStnNumArr(String[] stnNumArr) { + this.stnNumArr = stnNumArr; + } + + + + public void setLatLons(float[] latLons) { + + + //from python script, I only know a way to pass one dimensional array, therefore convert it 2-D here. + if(latLons.length >0){ + latLonArray = new float[latLons.length/2][2]; + for(int i=0, j=0; i < latLons.length; i++,j++){ + this.latLonArray[j][0] = latLons[i]; + this.latLonArray[j][1] = latLons[++i]; + //System.out.println("latlons = "+ latLonArray[j][0] + ","+ latLonArray[j][1]); + } + } + } + + /** The logger */ + protected final transient Log logger = LogFactory.getLog(getClass()); + + public String getRefTimeStr() { + return refTimeStr; + } + + + /* + * Reference time String should have this format: + * "yyyy-mm-dd hh" + */ + public void setRefTimeStr(String refTimeStr) { + this.refTimeStr = refTimeStr; + refTimeCal = convertTimeStrToCalendar(refTimeStr); + /*int year, mon, date, hr; + int index = refTimeStr.indexOf('-'); + if (index >= 4 ){ + year = Integer.parseInt(refTimeStr.substring(index-4, index)); + refTimeStr = refTimeStr.substring(index+1); + index = refTimeStr.indexOf('-'); + if(index >= 2 ){ + mon = Integer.parseInt(refTimeStr.substring(index-2, index)); + refTimeStr = refTimeStr.substring(index+1); + index = refTimeStr.indexOf(' '); + if(index >= 2 ){ + date = Integer.parseInt(refTimeStr.substring(index-2, index)); + refTimeStr = refTimeStr.substring(index+1); + //index = refTimeStr.indexOf(':'); + if(refTimeStr.length() >= 2 ){ + hr = Integer.parseInt(refTimeStr.substring(0, 2)); + refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // reset time + refTimeCal.setTimeInMillis(0); + // set new time + refTimeCal.set(year, mon-1, date, hr, 0,0); + System.out.println("set time Str " + refTimeStr + " cal time in GMT " + refTimeCal.getTime().toGMTString() + " in msec = " + refTimeCal.getTimeInMillis()); +} +} +} +}*/ + + } + public void setValidTimeStartStr(String validTimeStartStr) { + this.validTimeStartStr = validTimeStartStr; + validTimeStartCal = convertTimeStrToCalendar(validTimeStartStr); + /* + int year, mon, date, hr; + int index = validTimeStartStr.indexOf('-'); + if (index >= 4 ){ + year = Integer.parseInt(validTimeStartStr.substring(index-4, index)); + validTimeStartStr = validTimeStartStr.substring(index+1); + index = validTimeStartStr.indexOf('-'); + if(index >= 2 ){ + mon = Integer.parseInt(validTimeStartStr.substring(index-2, index)); + validTimeStartStr = validTimeStartStr.substring(index+1); + index = validTimeStartStr.indexOf(' '); + if(index >= 2 ){ + date = Integer.parseInt(validTimeStartStr.substring(index-2, index)); + validTimeStartStr = validTimeStartStr.substring(index+1); + //index = refTimeStr.indexOf(':'); + if(validTimeStartStr.length() >= 2 ){ + hr = Integer.parseInt(validTimeStartStr.substring(0, 2)); + validTimeStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // reset time + validTimeStartCal.setTimeInMillis(0); + // set new time + validTimeStartCal.set(year, mon-1, date, hr, 0,0); + System.out.println("set valid time start Str " + validTimeStartStr + " cal time in GMT " + validTimeStartCal.getTime().toGMTString() + " in msec = " + validTimeStartCal.getTimeInMillis()); +} +} +} +}*/ + + } + public void setValidTimeEndStr(String validTimeEndStr) { + this.validTimeEndStr = validTimeEndStr; + validTimeEndCal = convertTimeStrToCalendar(validTimeEndStr); + /* + int year, mon, date, hr; + int index = validTimeEndStr.indexOf('-'); + if (index >= 4 ){ + year = Integer.parseInt(validTimeEndStr.substring(index-4, index)); + validTimeEndStr = validTimeEndStr.substring(index+1); + index = validTimeEndStr.indexOf('-'); + if(index >= 2 ){ + mon = Integer.parseInt(validTimeEndStr.substring(index-2, index)); + validTimeEndStr = validTimeEndStr.substring(index+1); + index = validTimeEndStr.indexOf(' '); + if(index >= 2 ){ + date = Integer.parseInt(validTimeEndStr.substring(index-2, index)); + validTimeEndStr = validTimeEndStr.substring(index+1); + //index = refTimeStr.indexOf(':'); + if(validTimeEndStr.length() >= 2 ){ + hr = Integer.parseInt(validTimeEndStr.substring(0, 2)); + validTimeEndCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // reset time + validTimeEndCal.setTimeInMillis(0); + // set new time + validTimeEndCal.set(year, mon-1, date, hr, 0,0); + System.out.println("set valid time end Str " + validTimeEndStr + " cal time in GMT " + validTimeEndCal.getTime().toGMTString() + " in msec = " + validTimeEndCal.getTimeInMillis()); +} +} +} +}*/ + + } + private Calendar convertTimeStrToCalendar(String intimeStr){ + int year, mon, date, hr; + String timeStr = new String(intimeStr); + int index = timeStr.indexOf('-'); + + if (index >= 4 ){ + year = Integer.parseInt(timeStr.substring(index-4, index)); + timeStr = timeStr.substring(index+1); + index = timeStr.indexOf('-'); + if(index >= 2 ){ + mon = Integer.parseInt(timeStr.substring(index-2, index)); + timeStr = timeStr.substring(index+1); + index = timeStr.indexOf(' '); + if(index >= 2 ){ + date = Integer.parseInt(timeStr.substring(index-2, index)); + timeStr = timeStr.substring(index+1); + //index = refTimeStr.indexOf(':'); + if(timeStr.length() >= 2 ){ + hr = Integer.parseInt(timeStr.substring(0, 2)); + Calendar cal; + cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // reset time + cal.setTimeInMillis(0); + // set new time + cal.set(year, mon-1, date, hr, 0,0); + return cal; + } + } + } + } + return null; + } + + public void setQueryType(String queryType) { + this.queryType = queryType; + } + + + + public String getTimeLine() { + return timeLine; + } + + + public void setTimeLine(String timeLine) { + this.timeLine = timeLine; + } + + + public NcSoundingDrv() { + super(); + dbIdList=null; + level="-9999"; + merge = 0; + queryType = "LATLON"; + dataType = "ALLDATA"; + } + + + public String getTableName() { + return tableName; + } + + + + public void setTableName(String tableName) { + this.tableName = tableName; + + } + + + + public String getDataType() { + return dataType; + } + + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + + + public int[] getDbIdList() { + return dbIdList; + } + + + public void setDbIdList(int[] dbIdList) { + this.dbIdList = dbIdList; + } + + + + public double getLat() { + return lat; + } + + + + public void setLat(double lat) { + this.lat = lat; + } + + public void setLevel (String level) { + this.level = level; + } + + public void setStid (String stid) { + this.stid = stid; + } + + public double getLon() { + return lon; + } + + + + public String getValidTimeStr() { + return validTimeStartStr; + } + + + + public String getStid() { + return stid; + } + + + + public void setLon(double lon) { + this.lon = lon; + } + + public void setMerge (int merge) { + // for native model sounding and model sounding, there is no need to merge. Set merge + // to false accordingly. + this.merge = merge; + } + + + public long getRefTime() { + return refTime; + } + + + + public void setRefTime(long refTime) { + this.refTime = refTime; + refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + refTimeCal.setTimeInMillis(refTime); + } + + + + public long getValidTimeStart() { + return validTimeStart; + } + + + + public void setValidTimeStart(long validTimeStart) { + this.validTimeStart = validTimeStart; + validTimeStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + validTimeStartCal.setTimeInMillis(validTimeStart); + } + + public long getValidTimeEnd() { + return validTimeEnd; + } + + + + public void setValidTimeEnd(long validTimeEnd) { + this.validTimeEnd = validTimeEnd; + validTimeEndCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + validTimeEndCal.setTimeInMillis(validTimeEnd); + } + + + + public String getSndType() { + return sndType; + } + + + + public void setSndType(String sndType) { + this.sndType = sndType; + } + + boolean proces = true; + + public void setModelName(String aModelName) { + this.modelName = aModelName; + } + + public void setPluginName(String aPluginName) { + this.pluginName = aPluginName; + } + + public String getModelName() { + return modelName; + } + + public String getPluginName() { + return pluginName; + } + + + /* + public Object execute() throws Exception { + Object returnedObject = new Object(); + System.out.println ( " Enter execute "); + MergeSounding ms = new MergeSounding(); + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList();import BaseRequest +dataRequest = BaseRequest.BaseRequest("sgwh") +dataRequest.setCount(1500) +return dataRequest.execute() + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + NcSoundingProfile pf = null; + if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData(lat, lon, refTime, validTime, sndType); + ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); +} + else if (sndType.equals(ObsSndType.UAIR.toString()) || + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + + System.out.println ( " Processing UAIR data! sndType could be UAIR, BUFRUA, DROP, TAMDAR, etc"); + + if(dbIdList!= null) { + pf = ObservedSoundingQuery.getObservedSndData(dbIdList, sndType, dataType); +} else { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + System.out.println ( " Request unmerged data"); + + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "ALLDATA"); +} else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + System.out.println ( " Request merged data"); + + // TO DO -----> add station ID and station number and a list of stations queries. + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TTAA"); + ttaa = pf.getSoundingLyLst(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "UUAA").getSoundingLyLst(); +} + + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TTBB").getSoundingLyLst(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "UUBB").getSoundingLyLst(); +} + + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TTCC").getSoundingLyLst(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "UUCC").getSoundingLyLst(); +} + + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TTDD").getSoundingLyLst(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "UUDD").getSoundingLyLst(); +} + + ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "PPAA").getSoundingLyLst(); + ppbb = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "PPBB").getSoundingLyLst(); + ppcc = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "PPCC").getSoundingLyLst(); + ppdd = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "PPDD").getSoundingLyLst(); + wmax_a = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "MAXWIND_A").getSoundingLyLst(); + wmax_c = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "MAXWIND_C").getSoundingLyLst(); + trop_a = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TROPOPAUSE_A").getSoundingLyLst(); + trop_c = ObservedSoundingQuery.getObservedSndData(lat, lon, refTime, sndType, "TROPOPAUSE_C").getSoundingLyLst(); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + pf.setSoundingLyLst(sls); +} +} +} + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, dataType); + + // TO DO: need to add "dataType" to bufr data + + if ( merge == 0 ) { + // ms.unMergedUairSounding + System.out.println ( " Request unmerged data"); + +//// pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "ALLDATA"); +} else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + System.out.println ( " Request merged data"); + + // TO DO -----> add station ID and station number and a list of stations queries. +//// pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TTAA"); + ttaa = pf.getSoundingLyLst(); + if (ttaa.size() == 0) { +//// ttaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "UUAA").getSoundingLyLst(); +} + +//// ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TTBB").getSoundingLyLst(); + if (ttbb.size() == 0) { +//// ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "UUBB").getSoundingLyLst(); +} + +//// ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TTCC").getSoundingLyLst(); + if (ttcc.size() == 0) { +//// ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "UUCC").getSoundingLyLst(); +} + +//// ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TTDD").getSoundingLyLst(); + if (ttdd.size() == 0) { +//// ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "UUDD").getSoundingLyLst(); +} + +//// ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "PPAA").getSoundingLyLst(); +//// ppbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "PPBB").getSoundingLyLst(); +//// ppcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "PPCC").getSoundingLyLst(); +//// ppdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "PPDD").getSoundingLyLst(); +//// wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "MAXWIND_A").getSoundingLyLst(); +//// wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "MAXWIND_C").getSoundingLyLst(); +//// trop_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TROPOPAUSE_A").getSoundingLyLst(); +//// trop_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, refTime, sndType, "TROPOPAUSE_C").getSoundingLyLst(); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + pf.setSoundingLyLst(sls); +} +} + + + else { + + pf = null; +} + returnedObject = pf; + return returnedObject; +} + + */ + //for static sounding type query + public Object getSoundingRangeTimeLine() throws Exception { + Object returnedObject=null; + if (sndType.equals(ObsSndType.NCUAIR.toString())|| + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + + //*System.out.println ( "getSoundingTimeLine Processing UAIR request."); + returnedObject = ObservedSoundingQuery.getObservedSndTimeLine(sndType); + } else if (sndType.equals(PfcSndType.NAMSND.toString())|| + sndType.equals(PfcSndType.GFSSND.toString())) { + returnedObject = PfcSoundingQuery.getPfcSndRangeTimeLine(sndType, refTimeStr); + } + /*else if (sndType.equals(MdlSndType.GFSSNDMDL.toString())|| + sndType.equals(MdlSndType.NAMSNDMDL.toString()) || + sndType.equals(MdlSndType.RUC2SNDMDL.toString())|| + sndType.equals(MdlSndType.NGMSNDMDL.toString()) || + sndType.equals(MdlSndType.UKMETSNDMDL.toString())) { + returnedObject = MdlSoundingQuery.getMdlSndRangeTimeLine(sndType, refTimeStr, tableName); +}*/ + return returnedObject; + } + + //for static sounding type query + public Object getSoundingTimeLine() throws Exception { + Object returnedObject=null; + if (sndType.equals(ObsSndType.NCUAIR.toString()) || + sndType.equals(ObsSndType.BUFRUA.toString()) || + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + + //*System.out.println ( "getSoundingTimeLine Processing UAIR request."); + returnedObject = ObservedSoundingQuery.getObservedSndTimeLine(sndType); + } else if (sndType.equals(PfcSndType.NAMSND.toString())|| + sndType.equals(PfcSndType.GFSSND.toString())) { + returnedObject = PfcSoundingQuery.getPfcSndTimeLine(sndType); + + } /*else if (sndType.equals(MdlSndType.GFSSNDMDL.toString())|| + sndType.equals(MdlSndType.NAMSNDMDL.toString()) || + sndType.equals(MdlSndType.RUC2SNDMDL.toString())|| + sndType.equals(MdlSndType.NGMSNDMDL.toString()) || + sndType.equals(MdlSndType.UKMETSNDMDL.toString())) { + returnedObject = MdlSoundingQuery.getMdlSndTimeLine(sndType, tableName); +}*/ + + return returnedObject; + } + //for model sounding query - its model type is returned during query time. + public Object getMdlSoundingRangeTimeLine() throws Exception { + Object returnedObject=null; + returnedObject = MdlSoundingQuery.getMdlSndRangeTimeLine(sndType, refTimeStr, tableName); + return returnedObject; + } + //for model sounding query - its model type is returned during query time. + public Object getMdlSoundingTimeLine() throws Exception { + Object returnedObject=null; + + returnedObject = MdlSoundingQuery.getMdlSndTimeLine(sndType, tableName); + + + return returnedObject; + } + public Object getSoundingStnInfoCol() throws Exception { + Object returnedObject=null; + //System.out.println ( "getSoundingStnInfoCol sndType ="+sndType); + NcSoundingStnInfoCollection stnInfoCol=null; + if (sndType.equals(ObsSndType.NCUAIR.toString()) || + sndType.equals(ObsSndType.BUFRUA.toString()) || + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + stnInfoCol = ObservedSoundingQuery.getObservedSndStnInfoCol(sndType, timeLine); + } + else if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + stnInfoCol = PfcSoundingQuery.getPfcSndStnInfoCol(sndType, timeLine); + } + + else + return returnedObject; + + returnedObject = stnInfoCol; + return returnedObject; + } + + private List getSndLayersFromNcUairRecordObsLevel(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set obLevels = record.getObsLevels(); + // System.out.println("The datauri for this record is: " + record.getDataURI() ); + if(obLevels.size()>0){ + for(NcUairObsLevels obLev: obLevels){ + NcSoundingLayer sndLayer = new NcSoundingLayer(); + sndLayer.setTemperature(obLev.getTemp()); + sndLayer.setDewpoint(obLev.getDwpt()); + sndLayer.setGeoHeight(obLev.getHght()); + // System.out.println("Sounding layer height = " + sndLayer.getGeoHeight() ); + sndLayer.setPressure(obLev.getPres()); + sndLayer.setWindDirection(obLev.getDrct()); + if(obLev.getSped() >=0 ) + sndLayer.setWindSpeed((float)metersPerSecondToKnots.convert(obLev.getSped())); + else + sndLayer.setWindSpeed(obLev.getSped()); + sndLayers.add(sndLayer); + } + } + //System.out.println("ObsLevel="+obLevels.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + private List getSoundingLayer2FromNcUairRecordObsLevel(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set obLevels = record.getObsLevels(); + + //System.out.println("The datatype for this record is: " + record.getDataType() ); + if( obLevels.size() > 0 ){ + for( NcUairObsLevels obLev: obLevels ){ + // System.out.println("\n\nFrom NcUairObsLevel:"); + // System.out.println("Temperature = " + obLev.getTemp()); + // System.out.println("Pressure = " + obLev.getPres()); + // System.out.println("Dewpoint = " + obLev.getDwpt()); + // System.out.println("Height = " + obLev.getHght()); + // System.out.println("Wind direction = " + obLev.getDrct()); + // System.out.println("Wind speed in m/s= " + obLev.getSped()); + try{ + NcSoundingLayer2 sndLayer = new NcSoundingLayer2(); + /* + * (Non-Javadoc) + * The units for each quantity are chosen based upon the units defined for these quantities + * in the pointdata description file for NcUair + * */ + AirTemperature airTemp = new AirTemperature(); + airTemp.setValue( new Amount ( obLev.getTemp(), SI.CELSIUS ) ); + DewPointTemp dewPoint = new DewPointTemp(); + dewPoint.setValue( new Amount ( obLev.getDwpt(), SI.CELSIUS ) ); + HeightAboveSeaLevel height = new HeightAboveSeaLevel(); + height.setValue(obLev.getHght(), SI.METER ); + + // System.out.println("Sounding layer height = " + sndLayer.getGeoHeight().doubleValue() ); + PressureLevel pressure = new PressureLevel(); + pressure.setValue( new Amount (obLev.getPres(), NcUnits.MILLIBAR )); + + WindDirection windDirection = new WindDirection(); + windDirection.setValue(obLev.getDrct(), NonSI.DEGREE_ANGLE); + WindSpeed windSpeed = new WindSpeed(); + float speed = obLev.getSped(); + + /* + * ( Non-Javadoc ) + * There are no negative speed values decoded except for either -999 or -9999 + * to indicate that the speed is missing. The check for the positive speed value + * ensures that the unit conversion happens for non-missing speed values. + */ + if ( speed >= 0 ){ + double convertedSpeed = metersPerSecondToKnots.convert(speed); + windSpeed.setValue( convertedSpeed, NonSI.KNOT); + } + else{ + windSpeed.setValueToMissing(); + } + + // System.out.println("\nFrom MetParameters:"); + // System.out.println("Temperature = " + airTemp.getValue().floatValue()); + // System.out.println("Pressure = " + pressure.getValue().floatValue()); + // System.out.println("Dewpoint = " + dewPoint.getValue().floatValue()); + // System.out.println("Height = " + height.getValue().floatValue()); + // System.out.println("Wind direction = " + windDirection.getValue().floatValue()); + // System.out.println("Wind speed = " + windSpeed.getValue().floatValue()); + sndLayer.setTemperature(airTemp); + sndLayer.setPressure(pressure); + sndLayer.setDewpoint(dewPoint); + sndLayer.setGeoHeight(height); + sndLayer.setWindDirection(windDirection); + sndLayer.setWindSpeed(windSpeed); + sndLayers.add(sndLayer); + } + catch ( Exception e ){ + e.printStackTrace(); + } + } + } + //System.out.println("ObsLevel="+obLevels.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + private List getSndLayersFromNcUairRecordTrop(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set trops = record.getTropopause(); + if(trops.size()>0){ + for(NcUairTropopause trop: trops){ + NcSoundingLayer sndLayer = new NcSoundingLayer(); + sndLayer.setTemperature(trop.getTemp()); + sndLayer.setDewpoint(trop.getDwpt()); + sndLayer.setPressure(trop.getPres()); + sndLayer.setWindDirection(trop.getDrct()); + if(trop.getSped() >=0 ) + sndLayer.setWindSpeed((float)metersPerSecondToKnots.convert(trop.getSped())); + else + sndLayer.setWindSpeed(trop.getSped()); + sndLayers.add(sndLayer); + } + } + //System.out.println("trops="+trops.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + private List getSoundingLayer2FromNcUairRecordTrop(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set trops = record.getTropopause(); + if(trops.size()>0){ + for(NcUairTropopause trop: trops){ + try{ + NcSoundingLayer2 sndLayer = new NcSoundingLayer2(); + /* + * (Non-Javadoc) + * The units for each quantity are chosen based upon the units defined for these quantities + * in the pointdata description file for NcUair + * */ + AirTemperature airTemp = new AirTemperature(); + airTemp.setValue( new Amount ( trop.getTemp(), SI.CELSIUS ) ); + DewPointTemp dewPoint = new DewPointTemp(); + dewPoint.setValue( new Amount ( trop.getDwpt(), SI.CELSIUS) ); + PressureLevel pressure = new PressureLevel(); + pressure.setValue( new Amount (trop.getPres(), NcUnits.MILLIBAR )); + WindDirection windDirection = new WindDirection(); + windDirection.setValue(trop.getDrct(), NonSI.DEGREE_ANGLE); + WindSpeed windSpeed = new WindSpeed(); + float speed = trop.getSped(); + /* + * ( Non-Javadoc ) + * There are no negative speed values decoded except for either -999 or -9999 + * to indicate that the speed is missing. The check for the positive speed value + * ensures that the unit conversion happens for non-missing speed values. + */ + if ( speed >= 0 ){ + double convertedSpeed = metersPerSecondToKnots.convert(speed); + windSpeed.setValue( convertedSpeed, NonSI.KNOT); + } + else{ + windSpeed.setValueToMissing(); + } + sndLayer.setTemperature(airTemp); + sndLayer.setPressure(pressure); + sndLayer.setDewpoint(dewPoint); + sndLayer.setWindDirection(windDirection); + sndLayer.setWindSpeed(windSpeed); + sndLayers.add(sndLayer); + } + catch ( Exception e ){ + e.printStackTrace(); + } + } + } + //System.out.println("trops="+trops.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + private List getSndLayersFromNcUairRecordMaxw(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set maxWinds = record.getMaxWind(); + if(maxWinds.size()>0){ + for(NcUairMaxWind maxWind: maxWinds){ + NcSoundingLayer sndLayer = new NcSoundingLayer(); + sndLayer.setPressure(maxWind.getPres()); + sndLayer.setWindDirection(maxWind.getDrct()); + if(maxWind.getSped() >=0 ) + sndLayer.setWindSpeed((float)metersPerSecondToKnots.convert(maxWind.getSped())); + else + sndLayer.setWindSpeed(maxWind.getSped()); + sndLayers.add(sndLayer); + } + } + //System.out.println("maxWinds="+maxWinds.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + private List getSoundingLayer2FromNcUairRecordMaxw(NcUairRecord record){ + List sndLayers = new ArrayList(); + Set maxWinds = record.getMaxWind(); + if(maxWinds.size()>0){ + /* + * (Non-Javadoc) + * The units for each quantity are chosen based upon the units defined for these quantities in the pointdata description file for NcUair + * */ + for(NcUairMaxWind maxWind: maxWinds){ + try{ + NcSoundingLayer2 sndLayer = new NcSoundingLayer2(); + PressureLevel pressure = new PressureLevel(); + // pressure.setValueAs(maxWind.getPres(), "hPa" ); + pressure.setValue( new Amount (maxWind.getPres(), NcUnits.MILLIBAR )); + WindDirection windDirection = new WindDirection(); + windDirection.setValue(maxWind.getDrct(), NonSI.DEGREE_ANGLE ); + WindSpeed windSpeed = new WindSpeed(); + float speed = maxWind.getSped(); + /* + * ( Non-Javadoc ) + * There are no negative speed values decoded except for either -999 or -9999 + * to indicate that the speed is missing. The check for the positive speed value + * ensures that the unit conversion happens for non-missing speed values. + */ + if ( speed >= 0 ){ + double convertedSpeed = metersPerSecondToKnots.convert(speed); + windSpeed.setValue( convertedSpeed, NonSI.KNOT); + } + else{ + windSpeed.setValueToMissing(); + } + sndLayer.setPressure(pressure); + sndLayer.setWindDirection(windDirection); + sndLayer.setWindSpeed(windSpeed); + sndLayers.add(sndLayer); + } + catch ( Exception e ){ + e.printStackTrace(); + } + } + } + //System.out.println("maxWinds="+maxWinds.size()+" sndLayers="+sndLayers.size()); + return sndLayers; + } + + /** + * This API is for getting multiple locations sounding info at one shot. + * latLonArray is used to input lat/lon for each location. + * Use StnID as input location is NOT SUPPORTED in this API + */ + public Object getSoundingDataByLatLonArray() throws Exception { + //long t01 = System.currentTimeMillis(); + Object returnedObject = new Object(); + //*System.out.println ( " getSoundingDataByLatLonArray "); + if(latLonArray.length <= 0){ + returnedObject = null; + return returnedObject; + } + List timeLineStrList=new ArrayList(); + List timeLimeCalList = new ArrayList(); + if(validTimeEnd !=0 && validTimeEnd > validTimeStart){ + //range of time line request + timeLimeCalList = ObservedSoundingQuery.getObservedSndTimeRangeList(sndType, validTimeStartCal, validTimeEndCal); + for (int i=0; i< timeLimeCalList.size(); i++){ + Calendar timeCal = timeLimeCalList.get(i); + String timeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); + timeLineStrList.add(timeStr); + + } + } + else { + //one single time line + timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refTimeCal.getTime())); + timeLimeCalList.add(refTimeCal); + } + NcSoundingCube cube = new NcSoundingCube(); + List soundingProfileList = new ArrayList(); + SndQueryKeyType sndQuery = SndQueryKeyType.LATLON; + NcSoundingCube.QueryStatus failedRtnStatus = NcSoundingCube.QueryStatus.FAILED; + for ( int i=0; i < latLonArray.length ; i++) + { + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + Calendar timeCal = timeLimeCalList.get(j); + + MergeSounding ms = new MergeSounding(); + //make sure we have right precision... + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + /* + * Process sounding data. + */ + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + NcSoundingProfile pf = null; + if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + + //*System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData2(lat, lon, "",refTimeCal, validTimeStartCal, sndType,sndQuery); + //PfcSoundingQuery.getPfcSndData(lat, lon, "",refTimeCal, validTimeCal, sndType,sndQuery); + ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); + if ( ms.isNumber (level) == 0 ) { + //level is an integer >=0. It means user request a single level + float rlev = new Integer(Integer.parseInt(level.trim())).floatValue(); + pf.setSoundingLyLst(ms.getSingLevel(rlev, pf.getSoundingLyLst())); + } else if ( ms.isNumber (level) == 1 ) { + //level is an float >=0. It also means user request a single level + float rlev = new Float(Float.parseFloat(level.trim())); + pf.setSoundingLyLst(ms.getSingLevel(rlev, pf.getSoundingLyLst())); + } + //for(NcSoundingLayer ly: pf.getSoundingLyLst()){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + } + else if(sndType.equals(MdlSndType.ANY.toString()) ) { + + pf = MdlSoundingQuery.getMdlSndData( lat, lon, refTimeStr, validTimeStartStr, pluginName, modelName ); + if(pf.getRtnStatus() != NcSoundingCube.QueryStatus.OK){ + failedRtnStatus = pf.getRtnStatus(); + pf = null; + } + } + else if (sndType.equals(ObsSndType.NCUAIR.toString())) { + //System.out.println("getSoundingDataByLatLonArray:NcUair: lat="+lat+ " lon="+lon); + //make sure we have right precision... + + if ( merge == 0 ) { + //Chin...need more coding + pf = null; + } + else{ + //long t001 = System.currentTimeMillis(); + + NcUairRecord[] recordArray = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr); + if(recordArray != null && recordArray.length >0){ + for(int k=0; k< recordArray.length; k++){ + NcUairRecord record= recordArray[k]; + if(record.getDataType().equals("TTAA")){ + ttaa = getSndLayersFromNcUairRecordObsLevel(record); + trop_a = getSndLayersFromNcUairRecordTrop(record); + wmax_a = getSndLayersFromNcUairRecordMaxw(record); + } + else if(record.getDataType().equals("TTBB")){ + ttbb = getSndLayersFromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("TTCC")){ + ttcc = getSndLayersFromNcUairRecordObsLevel(record); + trop_c = getSndLayersFromNcUairRecordTrop(record); + wmax_c = getSndLayersFromNcUairRecordMaxw(record); + } + else if(record.getDataType().equals("TTDD")){ + ttdd = getSndLayersFromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPAA")){ + ppaa= getSndLayersFromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPBB")){ + ppbb = getSndLayersFromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPCC")){ + ppcc = getSndLayersFromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPDD")){ + ppdd = getSndLayersFromNcUairRecordObsLevel(record); + } + } + pf = new NcSoundingProfile(); + pf.setStationElevation((float)recordArray[0].getElevation()); + pf.setStationId(recordArray[0].getStationId()); + if(recordArray[0].getStnum() != null && recordArray[0].getStnum().length()>0) + pf.setStationNum(Integer.parseInt(recordArray[0].getStnum())); + pf.setStationLatitude((float)recordArray[0].getLatitude()); + pf.setStationLongitude((float)recordArray[0].getLongitude()); + //System.out.println(" input lat="+lat+" pf's lat="+pf.getStationLatitude()+" elv="+pf.getStationElevation()+" stnId="+pf.getStationId()); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("NCUAIR Number of Layers after merge:"+sls.size() + " level="+level + " ms.isNumber(level)="+ms.isNumber(level)); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + if (level.toUpperCase().equalsIgnoreCase("MAN") ) + pf.setSoundingLyLst(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + //System.out.println("NCUAIR get one layer using level = "+ level); + pf.setSoundingLyLst(sls); + } + else { + pf = null; + //System.out.println("NCUAIR get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst(sls); + } + } + else + pf = null; + + } + } + else if (//sndType.equals(ObsSndType.UAIR.toString()) || + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + //System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndAllData(lat, lon,"", timeCal, sndType, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + long t001 = System.currentTimeMillis(); + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTAA", sndQuery); + ttaa = pf.getSoundingLyLst(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUAA", sndQuery).getSoundingLyLst(); + } + + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTBB", sndQuery).getSoundingLyLst(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUBB", sndQuery).getSoundingLyLst(); + } + + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTCC", sndQuery).getSoundingLyLst(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUCC", sndQuery).getSoundingLyLst(); + } + + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTDD", sndQuery).getSoundingLyLst(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUDD", sndQuery).getSoundingLyLst(); + } + + ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPAA", sndQuery).getSoundingLyLst(); + ppbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPBB", sndQuery).getSoundingLyLst(); + ppcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPCC", sndQuery).getSoundingLyLst(); + ppdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPDD", sndQuery).getSoundingLyLst(); + wmax_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_A", sndQuery).getSoundingLyLst(); + wmax_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_C", sndQuery).getSoundingLyLst(); + trop_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_A", sndQuery).getSoundingLyLst(); + trop_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_C", sndQuery).getSoundingLyLst(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, timeCal,sndQuery); + long t02 = System.currentTimeMillis(); + System.out.println("UAIR profile retreival "+ timeStr+" took " + (t02 - t001)); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("UAIR Number of Layers:"+sls.size()); + if (level.toUpperCase().equalsIgnoreCase("MAN")) + pf.setSoundingLyLst(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + pf.setSoundingLyLst(sls); + } + else { + pf = null; + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst(sls); + } + + + } + + } + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndBufruaAllData(lat, lon,"", refTimeCal, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal,"TTAA", sndQuery); + ttaa = pf.getSoundingLyLst(); + ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTBB", sndQuery).getSoundingLyLst(); + ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTCC", sndQuery).getSoundingLyLst(); + ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTDD", sndQuery).getSoundingLyLst(); + //ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPAA", sndQuery).getSoundingLyLst(); + ppbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPBB", sndQuery).getSoundingLyLst(); + //ppcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPCC", sndQuery).getSoundingLyLst(); + ppdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPDD", sndQuery).getSoundingLyLst(); + wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_A", sndQuery).getSoundingLyLst(); + wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_C", sndQuery).getSoundingLyLst(); + trop_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_A", sndQuery).getSoundingLyLst(); + trop_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_C", sndQuery).getSoundingLyLst(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, refTimeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + //System.out.println("BUFRUA Number of Layers after merge:"+sls.size() + " level="+level + " ms.isNumber(level)="+ms.isNumber(level)); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + if (level.toUpperCase().equalsIgnoreCase("MAN") ) + pf.setSoundingLyLst(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + //System.out.println("NCUAIR get one layer using level = "+ level); + pf.setSoundingLyLst(sls); + } + else { + pf = null; + //System.out.println("NCUAIR get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst(sls); + } + + } + } + else { + + /* + * Invalid sounding type + */ + pf = null; + } + if(pf != null && pf.getSoundingLyLst().size()>0) { + soundingProfileList.add(pf); + //pf.setStationLatitude(lat.floatValue()); + //pf.setStationLongitude(lon.floatValue()); + pf = null; + } + } + } + if(soundingProfileList.size() == 0 ) + cube.setRtnStatus(failedRtnStatus); + else + cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); + + cube.setSoundingProfileList(soundingProfileList); + returnedObject = cube; + + //long t02 = System.currentTimeMillis(); + //System.out.println("PFC/OBS cube retreival took " + (t02 - t01)); + return returnedObject; + } + + + /* Chin:: this metod uses algorithm to query all station at one shot + * Only NCUair query is using such algorithm now + * */ + public Object getSoundingLayer2DataUsingLatLonArray() throws Exception { + //long t01 = System.currentTimeMillis(); + Object returnedObject = new Object(); + //*System.out.println ( " getSoundingDataByLatLonArray "); + if(latLonArray.length <= 0){ + returnedObject = null; + return returnedObject; + } + List timeLineStrList=new ArrayList();; + List timeLimeCalList = new ArrayList(); + if(validTimeEnd !=0 && validTimeEnd > validTimeStart){ + //range of time line request + timeLimeCalList = ObservedSoundingQuery.getObservedSndTimeRangeList(sndType, validTimeStartCal, validTimeEndCal); + for (int i=0; i< timeLimeCalList.size(); i++){ + Calendar timeCal = timeLimeCalList.get(i); + String timeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); + timeLineStrList.add(timeStr); + + } + } + else { + //one single time line + timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refTimeCal.getTime())); + timeLimeCalList.add(refTimeCal); + } + NcSoundingCube cube = new NcSoundingCube(); + List soundingProfileList = new ArrayList(0); + SndQueryKeyType sndQuery = SndQueryKeyType.LATLON; + NcSoundingCube.QueryStatus failedRtnStatus = NcSoundingCube.QueryStatus.FAILED; + + NcSoundingProfile pf; + MergeSounding2 ms = new MergeSounding2(); + if (sndType.equals(ObsSndType.NCUAIR.toString())) { + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + List uairRecordArrList; + uairRecordArrList = ObservedSoundingQuery.getAllStnObservedSndNcUairData(latLonArray,"", timeStr); + + if(uairRecordArrList!=null && uairRecordArrList.size()>0){ + //for each station, processing its records list and keep in one profile + for(NcUairRecord[] recordArray:uairRecordArrList){ + + //System.out.println("getSoundingDataByLatLonArray:NcUair: lat="+lat+ " lon="+lon); + //make sure we have right precision... + + if ( merge == 0 ) { + //Chin...need more coding + pf = null; + } + else{ + pf = new NcSoundingProfile(); + /* Chin: If caller need all query stns returned (no matter there is no data), then we may need to add this code... + if(recordArray != null && recordArray.length == 1){ + //could be a special case that the record is just used to return this stn's lat/lon back + if(recordArray[0].getNil() == true){ + pf.setStationLatitude((float)recordArray[0].getLatitude()); + pf.setStationLongitude((float)recordArray[0].getLongitude()); + soundingProfileList.add(pf); + continue; // skip this stn as there are no real data retrieved + } + }*/ + if(recordArray != null && recordArray.length >0){ + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + for(int k=0; k< recordArray.length; k++){ + NcUairRecord record= recordArray[k]; + if(record.getDataType().equals("TTAA")){ + ttaa = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_a = getSoundingLayer2FromNcUairRecordTrop( record); + wmax_a = getSoundingLayer2FromNcUairRecordMaxw(record ); + } + else if(record.getDataType().equals("TTBB")){ + ttbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("TTCC")){ + ttcc = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_c = getSoundingLayer2FromNcUairRecordTrop( record ); + wmax_c = getSoundingLayer2FromNcUairRecordMaxw( record ); + } + else if(record.getDataType().equals("TTDD")){ + ttdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPAA")){ + ppaa= getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPBB")){ + ppbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPCC")){ + ppcc = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPDD")){ + ppdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + } + pf.setStationElevation((float)recordArray[0].getElevation()); + pf.setStationId(recordArray[0].getStationId()); + if(recordArray[0].getStnum() != null && recordArray[0].getStnum().length()>0) + pf.setStationNum(Integer.parseInt(recordArray[0].getStnum())); + pf.setStationLatitude((float)recordArray[0].getLatitude()); + pf.setStationLongitude((float)recordArray[0].getLongitude()); + //System.out.println(" input lat="+lat+" pf's lat="+pf.getStationLatitude()+" elv="+pf.getStationElevation()+" stnId="+pf.getStationId()); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + if (level.toUpperCase().equalsIgnoreCase("MAN") ){ + pf.setSoundingLyLst2( sls ); + // System.out.println("sls set to the sounding profile"); + } + else if( ms.isNumber( level )>=0 ){ + if(sls.size() == 1){ + // System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2( sls ); + } + else { + pf = null; + // System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1){ + pf = null; + // System.out.println("not MAN level & sls is empty or 1"); + } + else{ + pf.setSoundingLyLst2 ( sls ); + // System.out.println("sls set to the sounding profile for level = " + level); + } + } + } + } + if(pf != null && pf.getSoundingLyLst2().size()>0) { + //System.out.println(" pf is not null, so adding a profile to the list of NcSoundingProfiles "); + soundingProfileList.add(pf); + pf = null; + } + + } + } + } + } + else{ + for ( int i=0; i < latLonArray.length ; i++) + { + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + Calendar timeCal = timeLimeCalList.get(j); + + //MergeSounding2 ms = new MergeSounding2(); + //make sure we have right precision... + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + /* + * Process sounding data. + */ + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + //NcSoundingProfile pf = new NcSoundingProfile(); + if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + + //*System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData2(lat, lon, "",refTimeCal, validTimeStartCal, sndType,sndQuery); + //PfcSoundingQuery.getPfcSndData(lat, lon, "",refTimeCal, validTimeCal, sndType,sndQuery); + // ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); - revisit this - Archana + } + else if(sndType.equals(MdlSndType.ANY.toString()) ) { + + pf = MdlSoundingQuery.getMdlSndData( lat, lon, refTimeStr, validTimeStartStr, pluginName, modelName ); + if(pf.getRtnStatus() != NcSoundingCube.QueryStatus.OK){ + failedRtnStatus = pf.getRtnStatus(); + pf = null; + } + } + else if (sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndAllData(lat, lon,"", timeCal, sndType, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + long t001 = System.currentTimeMillis(); + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUAA", sndQuery).getSoundingLyLst2(); + } + + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTBB", sndQuery).getSoundingLyLst2(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUBB", sndQuery).getSoundingLyLst2(); + } + + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTCC", sndQuery).getSoundingLyLst2(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUCC", sndQuery).getSoundingLyLst2(); + } + + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTDD", sndQuery).getSoundingLyLst2(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUDD", sndQuery).getSoundingLyLst2(); + } + + ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPBB", sndQuery).getSoundingLyLst2(); + ppcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, timeCal,sndQuery); + long t02 = System.currentTimeMillis(); + System.out.println("UAIR profile retreival "+ timeStr+" took " + (t02 - t001)); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("UAIR Number of Layers:"+sls.size()); + if (level.toUpperCase().equalsIgnoreCase("MAN")) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + + } + + } + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndBufruaAllData(lat, lon,"", refTimeCal, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal,"TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTBB", sndQuery).getSoundingLyLst2(); + ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTCC", sndQuery).getSoundingLyLst2(); + ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTDD", sndQuery).getSoundingLyLst2(); + //ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPBB", sndQuery).getSoundingLyLst2(); + //ppcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, refTimeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + //System.out.println("BUFRUA Number of Layers after merge:"+sls.size() + " level="+level + " ms.isNumber(level)="+ms.isNumber(level)); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + if (level.toUpperCase().equalsIgnoreCase("MAN") ) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + //System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + //System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + } + } + else { + + /* + * Invalid sounding type + */ + // System.out.println(" Invalid sounding type "); + pf = null; + } + if(pf != null && pf.getSoundingLyLst2().size()>0) { + //System.out.println(" pf is not null, so adding a profile to the list of NcSoundingProfiles "); + + // TODO : move this into the ObservedSoundingQuery methods. + // + pf.setStationLatitude( lat.floatValue() ); + pf.setStationLongitude( lon.floatValue() ); + + + soundingProfileList.add(pf); + //pf.setStationLatitude(lat.floatValue()); + //pf.setStationLongitude(lon.floatValue()); + pf = null; + } + } + } + } + if(soundingProfileList.size() == 0 ){ + //System.out.println(" Return status from NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray() is set to failed "); + cube.setRtnStatus(failedRtnStatus); + + } + else{ + //System.out.println(); + cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); + //long t02 = System.currentTimeMillis(); + //System.out.println("Return status from NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray() - success, cube retreival took " + (t02 - t01)); + } + cube.setSoundingProfileList(soundingProfileList); + /*for(int i =0; i < cube.getSoundingProfileList().size();i++){ + System.out.println("lat/lon="+ cube.getSoundingProfileList().get(i).getStationLatitude()+"/"+cube.getSoundingProfileList().get(i).getStationLongitude()+ + " temp="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getTemperature()+" dewp="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getDewpoint()+" press="+ + cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getPressure() + " height="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getGeoHeight()+ + " windSp="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getWindSpeed()+" windDir="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getWindDirection()+ + " omega="+cube.getSoundingProfileList().get(i).getSoundingLyLst2().get(0).getOmega()); + }*/ + returnedObject = cube; + + + return returnedObject; + } + /* Chin:: this metod is to query DB using algorithm that query on per station basis + * Currently is not used. But keep it here. May be useful later. + * + */ + public Object getSoundingLayer2DataUsingLatLonArrayPerStn() throws Exception { + //long t01 = System.currentTimeMillis(); + Object returnedObject = new Object(); + //*System.out.println ( " getSoundingDataByLatLonArray "); + if(latLonArray.length <= 0){ + returnedObject = null; + return returnedObject; + } + List timeLineStrList=new ArrayList();; + List timeLimeCalList = new ArrayList(); + if(validTimeEnd !=0 && validTimeEnd > validTimeStart){ + //range of time line request + timeLimeCalList = ObservedSoundingQuery.getObservedSndTimeRangeList(sndType, validTimeStartCal, validTimeEndCal); + for (int i=0; i< timeLimeCalList.size(); i++){ + Calendar timeCal = timeLimeCalList.get(i); + String timeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); + timeLineStrList.add(timeStr); + + } + } + else { + //one single time line + timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refTimeCal.getTime())); + timeLimeCalList.add(refTimeCal); + } + NcSoundingCube cube = new NcSoundingCube(); + List soundingProfileList = new ArrayList(0); + SndQueryKeyType sndQuery = SndQueryKeyType.LATLON; + NcSoundingCube.QueryStatus failedRtnStatus = NcSoundingCube.QueryStatus.FAILED; + for ( int i=0; i < latLonArray.length ; i++) + { + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + Calendar timeCal = timeLimeCalList.get(j); + + MergeSounding2 ms = new MergeSounding2(); + //make sure we have right precision... + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + /* + * Process sounding data. + */ + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + NcSoundingProfile pf = new NcSoundingProfile(); + if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + + //*System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData2(lat, lon, "",refTimeCal, validTimeStartCal, sndType,sndQuery); + //PfcSoundingQuery.getPfcSndData(lat, lon, "",refTimeCal, validTimeCal, sndType,sndQuery); + // ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); - revisit this - Archana + } + else if(sndType.equals(MdlSndType.ANY.toString()) ) { + + pf = MdlSoundingQuery.getMdlSndData( lat, lon, refTimeStr, validTimeStartStr, pluginName, modelName ); + if(pf.getRtnStatus() != NcSoundingCube.QueryStatus.OK){ + failedRtnStatus = pf.getRtnStatus(); + pf = null; + } + } + else if (sndType.equals(ObsSndType.NCUAIR.toString())) { + // System.out.println ( "From getSoundingLayer2DataUsingLatLonArray for ObsSndType.NCUAIR"); + //System.out.println("getSoundingDataByLatLonArray:NcUair: lat="+lat+ " lon="+lon); + //make sure we have right precision... + + if ( merge == 0 ) { + //Chin...need more coding + pf = null; + } + else{ + + NcUairRecord[] recordArray = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr); + if(recordArray != null && recordArray.length >0){ + for(int k=0; k< recordArray.length; k++){ + NcUairRecord record= recordArray[k]; + if(record.getDataType().equals("TTAA")){ + ttaa = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_a = getSoundingLayer2FromNcUairRecordTrop( record); + wmax_a = getSoundingLayer2FromNcUairRecordMaxw(record ); + } + else if(record.getDataType().equals("TTBB")){ + ttbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("TTCC")){ + ttcc = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_c = getSoundingLayer2FromNcUairRecordTrop( record ); + wmax_c = getSoundingLayer2FromNcUairRecordMaxw( record ); + } + else if(record.getDataType().equals("TTDD")){ + ttdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPAA")){ + ppaa= getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPBB")){ + ppbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPCC")){ + ppcc = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + else if(record.getDataType().equals("PPDD")){ + ppdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + } + } + pf.setStationElevation((float)recordArray[0].getElevation()); + pf.setStationId(recordArray[0].getStationId()); + if(recordArray[0].getStnum() != null && recordArray[0].getStnum().length()>0) + pf.setStationNum(Integer.parseInt(recordArray[0].getStnum())); + pf.setStationLatitude((float)recordArray[0].getLatitude()); + pf.setStationLongitude((float)recordArray[0].getLongitude()); + //System.out.println(" input lat="+lat+" pf's lat="+pf.getStationLatitude()+" elv="+pf.getStationElevation()+" stnId="+pf.getStationId()); + } + + + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + if (level.toUpperCase().equalsIgnoreCase("MAN") ){ + pf.setSoundingLyLst2( sls ); + // System.out.println("sls set to the sounding profile"); + } + else if( ms.isNumber( level )>=0 ){ + if(sls.size() == 1){ + // System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2( sls ); + } + else { + pf = null; + // System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1){ + pf = null; + // System.out.println("not MAN level & sls is empty or 1"); + } + else{ + pf.setSoundingLyLst2 ( sls ); + // System.out.println("sls set to the sounding profile for level = " + level); + } + } + } + } + else if (sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndAllData(lat, lon,"", timeCal, sndType, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + long t001 = System.currentTimeMillis(); + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUAA", sndQuery).getSoundingLyLst2(); + } + + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTBB", sndQuery).getSoundingLyLst2(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUBB", sndQuery).getSoundingLyLst2(); + } + + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTCC", sndQuery).getSoundingLyLst2(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUCC", sndQuery).getSoundingLyLst2(); + } + + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTDD", sndQuery).getSoundingLyLst2(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUDD", sndQuery).getSoundingLyLst2(); + } + + ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPBB", sndQuery).getSoundingLyLst2(); + ppcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, timeCal,sndQuery); + long t02 = System.currentTimeMillis(); + System.out.println("UAIR profile retreival "+ timeStr+" took " + (t02 - t001)); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("UAIR Number of Layers:"+sls.size()); + if (level.toUpperCase().equalsIgnoreCase("MAN")) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + + } + + } + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndBufruaAllData(lat, lon,"", refTimeCal, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal,"TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTBB", sndQuery).getSoundingLyLst2(); + ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTCC", sndQuery).getSoundingLyLst2(); + ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTDD", sndQuery).getSoundingLyLst2(); + //ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPBB", sndQuery).getSoundingLyLst2(); + //ppcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, refTimeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + //System.out.println("BUFRUA Number of Layers after merge:"+sls.size() + " level="+level + " ms.isNumber(level)="+ms.isNumber(level)); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + if (level.toUpperCase().equalsIgnoreCase("MAN") ) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + //System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + //System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + } + } + else { + + /* + * Invalid sounding type + */ + // System.out.println(" Invalid sounding type "); + pf = null; + } + if(pf != null && pf.getSoundingLyLst2().size()>0) { + //System.out.println(" pf is not null, so adding a profile to the list of NcSoundingProfiles "); + + // TODO : move this into the ObservedSoundingQuery methods. + // + pf.setStationLatitude( lat.floatValue() ); + pf.setStationLongitude( lon.floatValue() ); + + + soundingProfileList.add(pf); + //pf.setStationLatitude(lat.floatValue()); + //pf.setStationLongitude(lon.floatValue()); + pf = null; + } + } + } + if(soundingProfileList.size() == 0 ){ + //System.out.println(" Return status from getSoundingLayer2DataUsingLatLonArrayPerStn() is set to failed "); + cube.setRtnStatus(failedRtnStatus); + + } + else{ + //System.out.println(); + cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); + //long t02 = System.currentTimeMillis(); + //System.out.println("getSoundingLayer2DataUsingLatLonArrayPerStn() - success get stn#="+ soundingProfileList.size()+" cube retreival took " + (t02 - t01)); + } + // System.out.println(" Before storing the sounding profile list in the sounding cube"); + cube.setSoundingProfileList(soundingProfileList); + // System.out.println(" Before storing the sounding cube in the returnedObject"); + returnedObject = cube; + + + return returnedObject; + } + /* Chin + * This method use algorithm to query on per station per data type basis. It is slow. .. + * Keep for a while. To be removed later, + */ + public Object getSoundingLayer2DataUsingLatLonArrayOld() throws Exception { + long t01 = System.currentTimeMillis(); + Object returnedObject = new Object(); + //*System.out.println ( " getSoundingDataByLatLonArray "); + if(latLonArray.length <= 0){ + returnedObject = null; + return returnedObject; + } + List timeLineStrList=new ArrayList();; + List timeLimeCalList = new ArrayList(); + if(validTimeEnd !=0 && validTimeEnd > validTimeStart){ + //range of time line request + timeLimeCalList = ObservedSoundingQuery.getObservedSndTimeRangeList(sndType, validTimeStartCal, validTimeEndCal); + for (int i=0; i< timeLimeCalList.size(); i++){ + Calendar timeCal = timeLimeCalList.get(i); + String timeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); + timeLineStrList.add(timeStr); + + } + } + else { + //one single time line + timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refTimeCal.getTime())); + timeLimeCalList.add(refTimeCal); + } + NcSoundingCube cube = new NcSoundingCube(); + List soundingProfileList = new ArrayList(0); + SndQueryKeyType sndQuery = SndQueryKeyType.LATLON; + NcSoundingCube.QueryStatus failedRtnStatus = NcSoundingCube.QueryStatus.FAILED; + for ( int i=0; i < latLonArray.length ; i++) + { + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + Calendar timeCal = timeLimeCalList.get(j); + + MergeSounding2 ms = new MergeSounding2(); + //make sure we have right precision... + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + /* + * Process sounding data. + */ + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + NcSoundingProfile pf = new NcSoundingProfile(); + if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + + //*System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData2(lat, lon, "",refTimeCal, validTimeStartCal, sndType,sndQuery); + //PfcSoundingQuery.getPfcSndData(lat, lon, "",refTimeCal, validTimeCal, sndType,sndQuery); + // ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); - revisit this - Archana + } + else if(sndType.equals(MdlSndType.ANY.toString()) ) { + + pf = MdlSoundingQuery.getMdlSndData( lat, lon, refTimeStr, validTimeStartStr, pluginName, modelName ); + if(pf.getRtnStatus() != NcSoundingCube.QueryStatus.OK){ + failedRtnStatus = pf.getRtnStatus(); + pf = null; + } + } + else if (sndType.equals(ObsSndType.NCUAIR.toString())) { + // System.out.println ( "From getSoundingLayer2DataUsingLatLonArray for ObsSndType.NCUAIR"); + //System.out.println("getSoundingDataByLatLonArray:NcUair: lat="+lat+ " lon="+lon); + //make sure we have right precision... + + if ( merge == 0 ) { + //Chin...need more coding + pf = null; + } + else{ + + + + //get TTAA & TROPOPAUSE_A & MAXWIND_A + NcUairRecord record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "TTAA", sndQuery); + if(record != null){ + // ttaa = getSndLayersFromNcUairRecordObsLevel(record); + // trop_a = getSndLayersFromNcUairRecordTrop(record); + // wmax_a = getSndLayersFromNcUairRecordMaxw(record); + ttaa = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_a = getSoundingLayer2FromNcUairRecordTrop( record ); + wmax_a = getSoundingLayer2FromNcUairRecordMaxw( record ); + // System.out.println("The URI for this record is: "+ record.getDataURI() ); + // for ( NcSoundingLayer2 ttaaSnding : ttaa) { + // if ( ttaaSnding != null ){ + // PressureLevel sndingPresLevel = ttaaSnding.getPressure(); + // if ( sndingPresLevel != null && sndingPresLevel.hasValidValue() ){ + // System.out.println("TTAA_PRES = " + sndingPresLevel + // .getValue().floatValue() ); + // } + // } + // } + // System.out.println(" Size of ttaa = " + ttaa.size()); + // System.out.println(" Size of trop_a = " + trop_a.size()); + // System.out.println(" Size of wmax_a = " + wmax_a.size()); + } + //get TTCC & TROPOPAUSE_C & MAXWIND_C + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "TTCC", sndQuery); + if(record != null){ + // ttcc = getSndLayersFromNcUairRecordObsLevel(record); + // trop_c = getSndLayersFromNcUairRecordTrop(record); + // wmax_c = getSndLayersFromNcUairRecordMaxw(record); + ttcc = getSoundingLayer2FromNcUairRecordObsLevel( record ); + trop_c = getSoundingLayer2FromNcUairRecordTrop( record ); + wmax_c = getSoundingLayer2FromNcUairRecordMaxw( record ); + // System.out.println(" Size of ttcc = " + ttcc.size()); + // System.out.println(" Size of trop_c = " + trop_c.size()); + // System.out.println(" Size of wmax_c = " + wmax_c.size()); + } + //get TTBB + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "TTBB", sndQuery); + if(record != null){ + ttbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + // ttbb = getSndLayersFromNcUairRecordObsLevel(record); + // System.out.println(" Size of ttbb = " + ttbb.size()); + } + //get TTDD + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "TTDD", sndQuery); + if(record != null){ + // ttdd = getSndLayersFromNcUairRecordObsLevel(record); + ttdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + // System.out.println(" Size of ttdd = " + ttdd.size()); + } + //get PPAA + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "PPAA", sndQuery); + if(record != null){ + // ppaa = getSndLayersFromNcUairRecordObsLevel(record); + ppaa= getSoundingLayer2FromNcUairRecordObsLevel(record); + // System.out.println(" Size of ppaa = " + ppaa.size()); + } + //get PPBB + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "PPBB", sndQuery); + if(record != null){ + // ppbb = getSndLayersFromNcUairRecordObsLevel(record); + ppbb = getSoundingLayer2FromNcUairRecordObsLevel(record); + // System.out.println(" Size of ppbb = " + ppbb.size()); + } + //get PPCC + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "PPCC", sndQuery); + if(record != null){ + // ppcc = getSndLayersFromNcUairRecordObsLevel(record); + ppcc = getSoundingLayer2FromNcUairRecordObsLevel(record); + // System.out.println(" Size of ppcc = " + ppcc.size()); + } + //get PPDD + record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "PPDD", sndQuery); + if(record != null){ + // ppdd = getSndLayersFromNcUairRecordObsLevel(record); + ppdd = getSoundingLayer2FromNcUairRecordObsLevel(record); + // System.out.println(" Size of ppdd = " + ppdd.size()); + } + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, timeCal,sndQuery); + + + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + //if ( sls != null ){ + // System.out.println("Number of layers after the merging: " + sls.size() ); + // for (NcSoundingLayer2 thisSoundingLayer2: sls){ + // if ( thisSoundingLayer2 != null ){ + // System.out.println(" Pressure = " + thisSoundingLayer2.getPressure().getValue().doubleValue()); + // System.out.println(" Height = " + thisSoundingLayer2.getGeoHeight().getValue().doubleValue()); + // } + // } + //} + // System.out.println(" level = " + level ); + if (level.toUpperCase().equalsIgnoreCase("MAN") ){ + pf.setSoundingLyLst2( sls ); + // System.out.println("sls set to the sounding profile"); + } + else if( ms.isNumber( level )>=0 ){ + if(sls.size() == 1){ + // System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2( sls ); + } + else { + pf = null; + // System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1){ + pf = null; + // System.out.println("not MAN level & sls is empty or 1"); + } + else{ + pf.setSoundingLyLst2 ( sls ); + // System.out.println("sls set to the sounding profile for level = " + level); + } + } + } + } + else if (sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndAllData(lat, lon,"", timeCal, sndType, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + long t001 = System.currentTimeMillis(); + pf = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUAA", sndQuery).getSoundingLyLst2(); + } + + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTBB", sndQuery).getSoundingLyLst2(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUBB", sndQuery).getSoundingLyLst2(); + } + + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTCC", sndQuery).getSoundingLyLst2(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUCC", sndQuery).getSoundingLyLst2(); + } + + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TTDD", sndQuery).getSoundingLyLst2(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "UUDD", sndQuery).getSoundingLyLst2(); + } + + ppaa = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPBB", sndQuery).getSoundingLyLst2(); + ppcc = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndData(lat, lon, "", timeCal, sndType, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, timeCal,sndQuery); + long t02 = System.currentTimeMillis(); + System.out.println("UAIR profile retreival "+ timeStr+" took " + (t02 - t001)); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("UAIR Number of Layers:"+sls.size()); + if (level.toUpperCase().equalsIgnoreCase("MAN")) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + + } + + } + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndBufruaAllData(lat, lon,"", refTimeCal, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + pf = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal,"TTAA", sndQuery); + ttaa = pf.getSoundingLyLst2(); + ttbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTBB", sndQuery).getSoundingLyLst2(); + ttcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTCC", sndQuery).getSoundingLyLst2(); + ttdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TTDD", sndQuery).getSoundingLyLst2(); + //ppaa = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPAA", sndQuery).getSoundingLyLst2(); + ppbb = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPBB", sndQuery).getSoundingLyLst2(); + //ppcc = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPCC", sndQuery).getSoundingLyLst2(); + ppdd = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "PPDD", sndQuery).getSoundingLyLst2(); + wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_A", sndQuery).getSoundingLyLst2(); + wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "MAXWIND_C", sndQuery).getSoundingLyLst2(); + trop_a = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_A", sndQuery).getSoundingLyLst2(); + trop_c = ObservedSoundingQuery.getObservedSndBufruaData(lat, lon, "", refTimeCal, "TROPOPAUSE_C", sndQuery).getSoundingLyLst2(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(lat, lon,"",sndType, refTimeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + + //System.out.println("BUFRUA Number of Layers after merge:"+sls.size() + " level="+level + " ms.isNumber(level)="+ms.isNumber(level)); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + if (level.toUpperCase().equalsIgnoreCase("MAN") ) + pf.setSoundingLyLst2(sls); + else if( ms.isNumber(level)>=0 ){ + if(sls.size() == 1){ + //System.out.println("NcUair get one layer using level = "+ level); + pf.setSoundingLyLst2(sls); + } + else { + pf = null; + //System.out.println("NcUair get 0 layer using level = "+ level); + } + } + else { + if(sls.isEmpty() || sls.size() <=1) + pf = null; + else + pf.setSoundingLyLst2(sls); + } + + } + } + else { + + /* + * Invalid sounding type + */ + // System.out.println(" Invalid sounding type "); + pf = null; + } + if(pf != null && pf.getSoundingLyLst2().size()>0) { + //System.out.println(" pf is not null, so adding a profile to the list of NcSoundingProfiles "); + + // TODO : move this into the ObservedSoundingQuery methods. + // + pf.setStationLatitude( lat.floatValue() ); + pf.setStationLongitude( lon.floatValue() ); + + + soundingProfileList.add(pf); + //pf.setStationLatitude(lat.floatValue()); + //pf.setStationLongitude(lon.floatValue()); + pf = null; + } + } + } + if(soundingProfileList.size() == 0 ){ + System.out.println(" Return status from NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray() is set to failed "); + cube.setRtnStatus(failedRtnStatus); + + } + else{ + System.out.println(); + cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); + long t02 = System.currentTimeMillis(); + System.out.println("Return status from NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray() - success, cube retreival took " + (t02 - t01)); + } + // System.out.println(" Before storing the sounding profile list in the sounding cube"); + cube.setSoundingProfileList(soundingProfileList); + // System.out.println(" Before storing the sounding cube in the returnedObject"); + returnedObject = cube; + + + return returnedObject; + } + /* + * This API is for getting multiple locations sounding info at one shot. + * StnIdArray or StnNumArray is used as input stn info for each location. + * + */ + public Object getSoundingDataByStnArray() throws Exception { + Object returnedObject = new Object(); + //System.out.println ( " getSoundingData "); + + + NcSoundingCube cube = new NcSoundingCube(); + List soundingProfileList = new ArrayList(); + SndQueryKeyType sndQuery; + String[] stnArray; + if(queryType.equals(SndQueryKeyType.STNID.toString())){ + sndQuery = SndQueryKeyType.STNID; + stnArray = stnIdArr.clone(); + + } + else if(queryType.equals(SndQueryKeyType.STNNUM.toString())){ + sndQuery = SndQueryKeyType.STNNUM; + stnArray = stnNumArr.clone(); + } + else { + returnedObject = null; + return returnedObject; + } + if(stnArray.length <= 0){ + returnedObject = null; + return returnedObject; + } + List timeLineStrList=new ArrayList(); + List timeLimeCalList = new ArrayList(); + if(validTimeEnd !=0 && validTimeEnd > validTimeStart){ + //range of time line request + timeLimeCalList = ObservedSoundingQuery.getObservedSndTimeRangeList(sndType, validTimeStartCal, validTimeEndCal); + for (int i=0; i< timeLimeCalList.size(); i++){ + Calendar timeCal = timeLimeCalList.get(i); + String timeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timeCal); + timeLineStrList.add(timeStr); + + } + } + else { + //one single time line + timeLineStrList.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refTimeCal.getTime())); + timeLimeCalList.add(refTimeCal); + } + String stn; + for ( int i=0; i < stnArray.length ; i++) + { + + stn = stnArray[i]; + stn.toUpperCase(Locale.ENGLISH); + //System.out.println ( "Request getSoundingData at " + stn); + MergeSounding ms = new MergeSounding(); + for (int j=0; j< timeLineStrList.size(); j++){ + String timeStr = timeLineStrList.get(j); + Calendar timeCal = timeLimeCalList.get(j); + /* + * Process sounding data. + */ + + List sls = new ArrayList(); + List ttaa = new ArrayList(); + List ttbb = new ArrayList(); + List ttcc = new ArrayList(); + List ttdd = new ArrayList(); + List ppaa = new ArrayList(); + List ppbb = new ArrayList(); + List ppcc = new ArrayList(); + List ppdd = new ArrayList(); + List trop_a = new ArrayList(); + List trop_c = new ArrayList(); + List wmax_a = new ArrayList(); + List wmax_c = new ArrayList(); + + NcSoundingProfile pf = null; + if (sndType.equals(ObsSndType.NCUAIR.toString())){ + //System.out.println("getSoundingDataByLatLonArray:NcUair: lat="+lat+ " lon="+lon); + if ( merge == 0 ) { + //Chin...need more coding + pf = null; + } + else{ + + long t001 = System.currentTimeMillis(); + //get TTAA & TROPOPAUSE_A & MAXWIND_A + NcUairRecord record = ObservedSoundingQuery.getObservedSndNcUairData(lat, lon, "", timeStr, "TTAA", sndQuery); + if(record != null){ + ttaa = getSndLayersFromNcUairRecordObsLevel(record); + trop_a = getSndLayersFromNcUairRecordTrop(record); + wmax_a = getSndLayersFromNcUairRecordMaxw(record); +} + //get TTCC & TROPOPAUSE_C & MAXWIND_C + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "TTCC", sndQuery); + if(record != null){ + ttcc = getSndLayersFromNcUairRecordObsLevel(record); + trop_c = getSndLayersFromNcUairRecordTrop(record); + wmax_c = getSndLayersFromNcUairRecordMaxw(record); +} + //get TTBB + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "TTBB", sndQuery); + if(record != null){ + ttbb = getSndLayersFromNcUairRecordObsLevel(record); +} + //get TTDD + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "TTDD", sndQuery); + if(record != null){ + ttdd = getSndLayersFromNcUairRecordObsLevel(record); +} + //get PPAA + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "PPAA", sndQuery); + if(record != null){ + ppaa = getSndLayersFromNcUairRecordObsLevel(record); +} + //get PPBB + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "PPBB", sndQuery); + if(record != null){ + ppbb = getSndLayersFromNcUairRecordObsLevel(record); +} + //get PPCC + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "PPCC", sndQuery); + if(record != null){ + ppcc = getSndLayersFromNcUairRecordObsLevel(record); +} + //get PPDD + record = ObservedSoundingQuery.getObservedSndNcUairData(0d, 0d, stn, timeStr, "PPDD", sndQuery); + if(record != null){ + ppdd = getSndLayersFromNcUairRecordObsLevel(record); +} + pf = ObservedSoundingQuery.getObservedSndStnInfo(0d, 0d, stn,sndType, refTimeCal,sndQuery); + long t02 = System.currentTimeMillis(); + System.out.println("NcUair (by stn) profile retreival took " + (t02 - t001)); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + //System.out.println("NcUair Number of Layers:"+sls.size()); + //for(NcSoundingLayer ly: sls){ + // System.out.println("Pre= "+ly.getPressure()+ " Dew= "+ ly.getDewpoint()+ " T= "+ ly.getTemperature()+" H="+ly.getGeoHeight()+" WSp="+ly.getWindSpeed()); + //} + + pf.setSoundingLyLst(sls); + } + } + else if (//sndType.equals(ObsSndType.UAIR.toString()) || + sndType.equals(ObsSndType.DROP.toString()) || + sndType.equals(ObsSndType.TAMDAR.toString())) { + + if ( merge == 0 ) { + // ms.unMergedUairSounding + //System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndAllData(0d, 0d, stn, timeCal, sndType, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, dataType, sndQuery); + + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the body of code will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + // TO DO -----> add station ID and station number and a list of stations queries. + pf = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TTAA", sndQuery); + ttaa = pf.getSoundingLyLst(); + if (ttaa.size() == 0) { + ttaa = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "UUAA", sndQuery).getSoundingLyLst(); + } + + ttbb = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TTBB", sndQuery).getSoundingLyLst(); + if (ttbb.size() == 0) { + ttbb = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "UUBB", sndQuery).getSoundingLyLst(); + } + + ttcc = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TTCC", sndQuery).getSoundingLyLst(); + if (ttcc.size() == 0) { + ttcc = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "UUCC", sndQuery).getSoundingLyLst(); + } + + ttdd = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TTDD", sndQuery).getSoundingLyLst(); + if (ttdd.size() == 0) { + ttdd = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "UUDD", sndQuery).getSoundingLyLst(); + } + + ppaa = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "PPAA", sndQuery).getSoundingLyLst(); + ppbb = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "PPBB", sndQuery).getSoundingLyLst(); + ppcc = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "PPCC", sndQuery).getSoundingLyLst(); + ppdd = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "PPDD", sndQuery).getSoundingLyLst(); + wmax_a = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "MAXWIND_A", sndQuery).getSoundingLyLst(); + wmax_c = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "MAXWIND_C", sndQuery).getSoundingLyLst(); + trop_a = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TROPOPAUSE_A", sndQuery).getSoundingLyLst(); + trop_c = ObservedSoundingQuery.getObservedSndData(0d, 0d, stn, timeCal, sndType, "TROPOPAUSE_C", sndQuery).getSoundingLyLst(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(0d, 0d,stn,sndType, timeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + pf.setSoundingLyLst(sls); + } + + } + else if(sndType.equals(ObsSndType.BUFRUA.toString())){ + if ( merge == 0 ) { + // ms.unMergedUairSounding + //*System.out.println ( " Request unmerged data"); + if(dataType.equals(DataType.ALLDATA.toString())) + pf = ObservedSoundingQuery.getObservedSndBufruaAllData(0d, 0d, stn, refTimeCal, sndQuery); + else + pf = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, dataType, sndQuery); + + } else { + + // Get TTAA. If not existent, try ship data (UUAA). If level is not null or missing, + // the b0dy of c0de will return a sounding list with MAN data or single level data. + //*System.out.println ( " Request merged data at lat="+ lat+" lon="+lon+ " refT="+ refTimeCal.getTime().toGMTString()); + + pf = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal,"TTAA", sndQuery); + ttaa = pf.getSoundingLyLst(); + ttbb = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "TTBB", sndQuery).getSoundingLyLst(); + ttcc = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "TTCC", sndQuery).getSoundingLyLst(); + ttdd = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "TTDD", sndQuery).getSoundingLyLst(); + //ppaa = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "PPAA", sndQuery).getSoundingLyLst(); + ppbb = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "PPBB", sndQuery).getSoundingLyLst(); + //ppcc = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "PPCC", sndQuery).getSoundingLyLst(); + ppdd = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "PPDD", sndQuery).getSoundingLyLst(); + wmax_a = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "MAXWIND_A", sndQuery).getSoundingLyLst(); + wmax_c = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "MAXWIND_C", sndQuery).getSoundingLyLst(); + trop_a = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "TROPOPAUSE_A", sndQuery).getSoundingLyLst(); + trop_c = ObservedSoundingQuery.getObservedSndBufruaData(0d, 0d, stn, refTimeCal, "TROPOPAUSE_C", sndQuery).getSoundingLyLst(); + pf = ObservedSoundingQuery.getObservedSndStnInfo(0d, 0d,stn,sndType, refTimeCal,sndQuery); + sls = ms.mergeUairSounding(level,ttaa,ttbb,ttcc,ttdd,ppaa,ppbb,ppcc,ppdd,trop_a,trop_c,wmax_a,wmax_c,pf.getStationElevation()); + pf.setSoundingLyLst(sls); + } + } + else if(sndType.equals(PfcSndType.NAMSND.toString()) || + sndType.equals(PfcSndType.GFSSND.toString()) || + sndType.equals(PfcSndType.RUCPTYPSND.toString()) || + sndType.equals(PfcSndType.RUC2SND.toString())) { + //*System.out.println ( " Processing native model data"); + pf = PfcSoundingQuery.getPfcSndData(0d,0d, stn, refTimeCal, validTimeStartCal, sndType,sndQuery); + ms.nativeModelSounding(pf.getSoundingLyLst(), pf.getStationElevation()); + if ( ms.isNumber (level) == 0 ) { + //level is an integer >=0. It means user request a single level + float rlev = new Integer(Integer.parseInt(level.trim())).floatValue(); + pf.setSoundingLyLst(ms.getSingLevel(rlev, pf.getSoundingLyLst())); + } else if ( ms.isNumber (level) == 1 ) { + //level is an float >=0. It also means user request a single level + float rlev = new Float(Float.parseFloat(level.trim())); + pf.setSoundingLyLst(ms.getSingLevel(rlev, pf.getSoundingLyLst())); + } + + } + else if(sndType.equals(MdlSndType.ANY.toString())) { + //model sounding query by stn is not supported yet + pf = null; + } + else { + + /* + * Invalid sounding type + */ + pf = null; + } + if(pf != null && pf.getSoundingLyLst().size()>0) { + soundingProfileList.add(pf); + pf.setStationId(stn); + + pf = null; + } + } + } + if(soundingProfileList.size() == 0 ) + cube.setRtnStatus(NcSoundingCube.QueryStatus.FAILED); + else + cube.setRtnStatus(NcSoundingCube.QueryStatus.OK); + + cube.setSoundingProfileList(soundingProfileList); + returnedObject = cube; + + + return returnedObject; + } + + public Object getModels() throws Exception { + Object returnedObject = new Object(); + NcSoundingModel mdls = MdlSoundingQuery.getMdls(tableName); + returnedObject = mdls; + return returnedObject; + } +/* + * + * +import NcSoundingDataRequest +sndRq = NcSoundingDataRequest.NcSoundingDataRequest() +sndRq.setSndType('NCUAIR') +sndRq.setDataType('ALLDATA') +sndRq.setRefTime(1320278400000L) +sndRq.setValidTimeStart(1320278400000L) +sndRq.setValidTimeEnd(1320278400000L) +sndRq.setMerge(1) +sndRq.setLevel('500') +sndRq.getSoundingLayer2DataByLatLonArray([32.37,-64.68,47.47,-111.38,53.96,-101.09,60.03,-111.93,28.200000762939453,-87.5999984741211,28.63,-106.08,51.28,-80.59,36.23333,-86.55,34.77556,-76.87917,18.72,-110.95,53.29,-60.36,28.88,-118.3,55.03,-131.57,17.98,-92.92,19.3,-81.35,43.93,-60.01]) +*/ + } diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java index a12d759995..d053d4d049 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/ObservedSoundingQuery.java @@ -1,5 +1,4 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; - /** * * gov.noaa.nws.ncep.edex.uengine.tasks.profile.ObservedSoundingQuery @@ -17,26 +16,24 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; * 11/05/2010 301 Chin Chen Update to support uairSnd query to all data types, except ALLDATA * 12/16/2010 301 Chin Chen add support of BUFRUA observed sounding data * 09/14/2011 457 S. Gurung Renamed h5 to nc - * + * 10/20/2011 S. Gurung Added ncuair changes related to replacing slat/slon/selv with location of type SurfaceObsLocation + * Nov 2011 Chin Chen changed Ncuair table query algorithm for performance improvement + * 01/05/2012 S. Gurung Removed references to UAIR (performed cleanup) * * * @author Chin Chen * @version 1.0 */ -import gov.noaa.nws.ncep.common.dataplugin.h5uair.H5UairRecord; -import gov.noaa.nws.ncep.common.dataplugin.h5uair.dao.H5UairToRecord; -import gov.noaa.nws.ncep.common.dataplugin.uair.MaxWind; -import gov.noaa.nws.ncep.common.dataplugin.uair.ObsLevels; -import gov.noaa.nws.ncep.common.dataplugin.uair.Tropopause; -import gov.noaa.nws.ncep.common.dataplugin.uair.UairRecord; +import gov.noaa.nws.ncep.common.dataplugin.ncuair.NcUairRecord; +import gov.noaa.nws.ncep.common.dataplugin.ncuair.dao.NcUairToRecord; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.ObsSndType; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.SndQueryKeyType; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfo; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingTimeLines; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.ObsSndType; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.SndQueryKeyType; import java.io.File; import java.sql.Timestamp; @@ -51,1933 +48,1603 @@ import javax.measure.unit.NonSI; import javax.measure.unit.SI; import com.raytheon.edex.plugin.bufrua.dao.BufrUADao; -import com.raytheon.uf.common.dataplugin.bufrua.UAObs; import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.Request; import com.raytheon.uf.common.datastorage.records.FloatDataRecord; import com.raytheon.uf.common.datastorage.records.IntegerDataRecord; +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.bufrua.UAObs; import com.raytheon.uf.common.pointdata.PointDataContainer; +import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation; import com.raytheon.uf.edex.database.DataAccessLayerException; import com.raytheon.uf.edex.database.dao.CoreDao; import com.raytheon.uf.edex.database.dao.DaoConfig; import com.raytheon.uf.edex.pointdata.PointDataQuery; +import com.vividsolutions.jts.geom.Coordinate; public class ObservedSoundingQuery { - private static final UnitConverter metersPerSecondToKnots = SI.METERS_PER_SECOND - .getConverterTo(NonSI.KNOT); + private static final UnitConverter metersPerSecondToKnots = SI.METERS_PER_SECOND.getConverterTo(NonSI.KNOT); + private static final UnitConverter kelvinToCelsius = SI.KELVIN.getConverterTo(SI.CELSIUS); + private static final String UAIR_TBL_NAME = "uair"; + private static final String NCUAIR_TBL_NAME = "ncuair"; + private static final String BURFUA_TBL_NAME = "bufrua"; + private static String currentDBTblName = "nil"; + + /* + * This method is for caller to get sounding station's info lat/lon/stn id/stn num/elevation + * key: stn's lat/lon or stn ( either stn id or stn num) + */ + @SuppressWarnings("unchecked") + public static NcSoundingProfile getObservedSndStnInfo(Double lat, Double lon,String stn, String obType,Calendar refTimeCal,SndQueryKeyType queryType ) { + NcSoundingProfile pf = new NcSoundingProfile(); + CoreDao dao; + List fields = new ArrayList(); + List values = new ArrayList(); + if(obType.equals(ObsSndType.NCUAIR.toString())){ + List operands = new ArrayList(); + List lUairRecords = null; + if(queryType==SndQueryKeyType.STNID){ + fields.add("location.stationId");// the location.stationId field name defined in NcUairRecord + values.add(stn); + operands.add("="); + } + else if(queryType==SndQueryKeyType.STNNUM){ + fields.add("stnum");// the stnNum field name defined in NcUairRecord + values.add(stn); + operands.add("="); + } + else if(queryType==SndQueryKeyType.LATLON){ + fields.add("location.latitude"); // the location.latitude field name defined in NcUairRecord + values.add(lat); + operands.add(">="); + fields.add("location.latitude"); + values.add(lat); + operands.add("<="); + fields.add("location.longitude"); // the location.longitude field name defined in NcUairRecord + values.add(lon); + operands.add(">="); + fields.add("location.longitude"); + values.add(lon); + operands.add("<="); + } + else { + //*System.out.println("request query type "+ queryType+ " is not supported in this API" ); + return pf; + } + fields.add("synopticTime");// the synoptic time field name defined in UairRecord + values.add(refTimeCal); + operands.add("="); + dao = new CoreDao(DaoConfig.forClass(NcUairRecord.class)); + try { + lUairRecords = (List) dao.queryByCriteria(fields, values,operands); + System.out.println("Nc uair at lat="+ lat+" lon="+lon+ " recorde size="+lUairRecords.size()); + if(lUairRecords.size() > 0){ + pf.setStationElevation((float)lUairRecords.get(0).getElevation()); + pf.setStationId(lUairRecords.get(0).getStationId()); + if(lUairRecords.get(0).getStnum() != null && lUairRecords.get(0).getStnum().length()>0) + pf.setStationNum(Integer.parseInt(lUairRecords.get(0).getStnum())); + pf.setStationLatitude((float)lUairRecords.get(0).getLatitude()); + pf.setStationLongitude((float)lUairRecords.get(0).getLongitude()); + } + }catch (DataAccessLayerException e) { + //*System.out.println("obs sounding query exception"); + e.printStackTrace(); + } + } + else if(obType.equals(ObsSndType.BUFRUA.toString())) { + List lUairRecords = null; + if(queryType==SndQueryKeyType.STNID){ + fields.add("stationName");// the stationName String field name defined in UAObs, dont be confused with UAIRRecord definition + values.add(stn); + } + else if(queryType==SndQueryKeyType.STNNUM){ + fields.add("location.stationId");// the location.stationId String field name defined in UAObs. dont be confused with UAIRRecord definition + values.add(stn); + } + else if(queryType==SndQueryKeyType.LATLON){ + fields.add("location.latitude");// the location.latitude field name defined in UAObs + values.add(lat); + fields.add("location.longitude");// the location.longitude field name defined in UAObs + values.add(lon); - private static final UnitConverter kelvinToCelsius = SI.KELVIN - .getConverterTo(SI.CELSIUS); + } + else { + return pf; + } + fields.add("validTime");// the synoptic time field name defined in UAObs + values.add(refTimeCal); + dao = new CoreDao(DaoConfig.forClass(UAObs.class)); + try { + lUairRecords = (List) dao.queryByCriteria(fields, values); + if(lUairRecords.size() > 0){ + pf.setStationLatitude((float)lUairRecords.get(0).getLatitude()); + pf.setStationLongitude((float)lUairRecords.get(0).getLongitude()); + pf.setStationElevation((float)lUairRecords.get(0).getElevation()); + if(lUairRecords.get(0).getStationId()!=null && lUairRecords.get(0).getStationId().length()>0) + pf.setStationNum(Integer.parseInt(lUairRecords.get(0).getStationId())); + pf.setStationId(lUairRecords.get(0).getStationName()); + } + }catch (DataAccessLayerException e) { + //*System.out.println("obs sounding query exception"); + e.printStackTrace(); + } + } + return pf; + } + public static NcSoundingStnInfoCollection getObservedSndStnInfoCol(String obType, String selectedSndTime) { + NcSoundingStnInfoCollection stnInfoCol = new NcSoundingStnInfoCollection(); + List stationInfoList= new ArrayList(); + String queryStr, queryStr1; + Object [] rtnobjArray, rtnobjArray1; + CoreDao dao; + if(obType.equals(ObsSndType.BUFRUA.toString())){ + currentDBTblName = BURFUA_TBL_NAME; + queryStr = new String("Select Distinct latitude, longitude, id, stationname, elevation, reftime FROM "+ currentDBTblName + " where reftime='" + + selectedSndTime+"' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); + queryStr1 = new String("Select Distinct latitude, longitude FROM "+ currentDBTblName + " where reftime='" + + selectedSndTime+"' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); + dao = new CoreDao(DaoConfig.forClass(UAObs.class)); + + } + else if(obType.equals(ObsSndType.NCUAIR.toString())){ + currentDBTblName = NCUAIR_TBL_NAME; + queryStr = new String("Select Distinct latitude, longitude, id, stationId, elevation, synoptictime FROM "+ currentDBTblName + " where nil='FALSE' AND synoptictime='" + + selectedSndTime+"' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); + queryStr1 = new String("Select Distinct latitude, longitude FROM "+ currentDBTblName + " where nil='FALSE' AND synoptictime='" + + selectedSndTime+"' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); + dao = new CoreDao(DaoConfig.forClass(NcUairRecord.class)); + } + else { + return stnInfoCol; + } + rtnobjArray = dao.executeSQLQuery(queryStr); - private static final String UAIR_TBL_NAME = "uair"; + //*System.out.println("size of rtnobjArray " + rtnobjArray.length); + /* + Object[] obj; + for (int i =0; i 0) && (rtnobjArray.length > 0)){ + double lat, lon, elv; + String stnInfo; - private static String currentDBTblName = "nil"; + //System.out.println("queryAndMarkStn called mapresource = "+ nsharpMapResource.toString()); + //Note: A same station may have many reports and at some reports they dont provide elv and or stnid + // this implementation is "try" to make sure we get those info. + //If, all reports does not have elv or stnid, then we still can not report it. + for (int i =0; i fields = new ArrayList(); - List values = new ArrayList(); - if (obType.equals(ObsSndType.UAIR.toString())) { - List lUairRecords = null; - if (queryType == SndQueryKeyType.STNID) { - fields.add("stationId");// the stnId field name defined in - // UairRecord - values.add(stn); - } else if (queryType == SndQueryKeyType.STNNUM) { - fields.add("stationNumber");// the stnNum field name defined in - // UairRecord - values.add(stn); - } else if (queryType == SndQueryKeyType.LATLON) { - fields.add("slat");// the lat field name defined in UairRecord - values.add(lat); - fields.add("slon");// the lon field name defined in UairRecord - values.add(lon); + } + + NcSoundingStnInfo stn = stnInfoCol.getNewStnInfo(); + stn.setStnId(stnInfo); + stn.setStationLongitude((float)lon); + stn.setStationLatitude((float)lat); + stn.setStationElevation((float)elv); + stn.setSynopTime(synoptictime); + stationInfoList.add((NcSoundingStnInfo)stn); + //System.out.println("stn "+ stnInfo + " lon "+ lon + " lat "+ lat); + } + } - } else { - // *System.out.println("request query type "+ queryType+ - // " is not supported in this API" ); - return pf; - } - fields.add("synopticTime");// the synoptic time field name defined - // in UairRecord - values.add(refTimeCal); - dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - try { - lUairRecords = (List) dao.queryByCriteria(fields, - values); - if (lUairRecords.size() > 0) { - System.out.println("Uair recorde size=" - + lUairRecords.size()); - pf.setStationElevation((float) lUairRecords.get(0) - .getSelv()); - pf.setStationId(lUairRecords.get(0).getStationId()); - if (lUairRecords.get(0).getStationNumber() != null - && lUairRecords.get(0).getStationNumber().length() > 0) - pf.setStationNum(Integer.parseInt(lUairRecords.get(0) - .getStationNumber())); - pf.setStationLatitude((float) lUairRecords.get(0).getSlat()); - pf.setStationLongitude((float) lUairRecords.get(0) - .getSlon()); - } - } catch (DataAccessLayerException e) { - // *System.out.println("obs sounding query exception"); - e.printStackTrace(); - } - } else if (obType.equals(ObsSndType.H5UAIR.toString())) { - List operands = new ArrayList(); - List lUairRecords = null; - if (queryType == SndQueryKeyType.STNID) { - fields.add("stid");// the stnId field name defined in - // H5UairRecord - values.add(stn); - operands.add("="); - } else if (queryType == SndQueryKeyType.STNNUM) { - fields.add("stnum");// the stnNum field name defined in - // H5UairRecord - values.add(stn); - operands.add("="); - } else if (queryType == SndQueryKeyType.LATLON) { - fields.add("slat"); - values.add(lat.floatValue() - 0.1f); - operands.add(">="); - fields.add("slat"); - values.add(lat.floatValue() + 0.1f); - operands.add("<="); - fields.add("slon"); - values.add(lon.floatValue() - 0.1f); - operands.add(">="); - fields.add("slon"); - values.add(lon.floatValue() + 0.1f); - operands.add("<="); - } else { - // *System.out.println("request query type "+ queryType+ - // " is not supported in this API" ); - return pf; - } - fields.add("synopticTime");// the synoptic time field name defined - // in UairRecord - values.add(refTimeCal); - operands.add("="); - dao = new CoreDao(DaoConfig.forClass(H5UairRecord.class)); - try { - lUairRecords = (List) dao.queryByCriteria(fields, - values, operands); - System.out.println("H5 uair at lat=" + lat + " lon=" + lon - + " recorde size=" + lUairRecords.size()); - if (lUairRecords.size() > 0) { - pf.setStationElevation((float) lUairRecords.get(0) - .getSelv()); - pf.setStationId(lUairRecords.get(0).getStid()); - if (lUairRecords.get(0).getStnum() != null - && lUairRecords.get(0).getStnum().length() > 0) - pf.setStationNum(Integer.parseInt(lUairRecords.get(0) - .getStnum())); - pf.setStationLatitude((float) lUairRecords.get(0).getSlat()); - pf.setStationLongitude((float) lUairRecords.get(0) - .getSlon()); - } - } catch (DataAccessLayerException e) { - // *System.out.println("obs sounding query exception"); - e.printStackTrace(); - } - } else if (obType.equals(ObsSndType.BUFRUA.toString())) { - List lUairRecords = null; - if (queryType == SndQueryKeyType.STNID) { - fields.add("stationName");// the stationName String field name - // defined in UAObs, dont be confused - // with UAIRRecord definition - values.add(stn); - } else if (queryType == SndQueryKeyType.STNNUM) { - fields.add("location.stationId");// the location.stationId - // String field name defined in - // UAObs. dont be confused with - // UAIRRecord definition - values.add(stn); - } else if (queryType == SndQueryKeyType.LATLON) { - fields.add("location.latitude");// the location.latitude field - // name defined in UAObs - values.add(lat); - fields.add("location.longitude");// the location.longitude field - // name defined in UAObs - values.add(lon); + + NcSoundingStnInfo [] stationInfoAry = new NcSoundingStnInfo [stationInfoList.size()] ; + stnInfoCol.setStationInfo(stationInfoList.toArray(stationInfoAry)); + //*System.out.println("stn size = "+ stnInfoCol.getStationInfo().length); + return stnInfoCol; + } + public static NcSoundingTimeLines getObservedSndTimeLine(String obType) { + Object[] synopTimeAry = null; + NcSoundingTimeLines tl = new NcSoundingTimeLines(); + String queryStr; + CoreDao dao; + if(obType.equals(ObsSndType.BUFRUA.toString())) { + currentDBTblName = BURFUA_TBL_NAME; + queryStr = new String("Select Distinct reftime FROM "+ currentDBTblName + " ORDER BY reftime DESC"); + dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - } else { - return pf; - } - fields.add("validTime");// the synoptic time field name defined in - // UAObs - values.add(refTimeCal); - dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - try { - lUairRecords = (List) dao - .queryByCriteria(fields, values); - if (lUairRecords.size() > 0) { - pf.setStationLatitude((float) lUairRecords.get(0) - .getLatitude()); - pf.setStationLongitude((float) lUairRecords.get(0) - .getLongitude()); - pf.setStationElevation((float) lUairRecords.get(0) - .getElevation()); - if (lUairRecords.get(0).getStationId() != null - && lUairRecords.get(0).getStationId().length() > 0) - pf.setStationNum(Integer.parseInt(lUairRecords.get(0) - .getStationId())); - pf.setStationId(lUairRecords.get(0).getStationName()); - } - } catch (DataAccessLayerException e) { - // *System.out.println("obs sounding query exception"); - e.printStackTrace(); - } - } - return pf; - } + } + else if(obType.equals(ObsSndType.NCUAIR.toString())){ + currentDBTblName = NCUAIR_TBL_NAME; + queryStr = new String("Select Distinct synoptictime FROM "+ currentDBTblName + " where nil='FALSE' ORDER BY synoptictime DESC"); + dao = new CoreDao(DaoConfig.forClass(NcUairRecord.class)); + } + else{ + return tl; + } + synopTimeAry = (Object[]) dao.executeSQLQuery(queryStr); + //*System.out.println("size of synoptictime " + synopTimeAry.length); - public static NcSoundingStnInfoCollection getObservedSndStnInfoCol( - String obType, String selectedSndTime) { - NcSoundingStnInfoCollection stnInfoCol = new NcSoundingStnInfoCollection(); - List stationInfoList = new ArrayList(); - String queryStr, queryStr1; - Object[] rtnobjArray, rtnobjArray1; - CoreDao dao; - // obType = ObsSndType.UAIR.toString(); // currently assume all uair - // sounding type - if (obType.equals(ObsSndType.UAIR.toString())) { - currentDBTblName = UAIR_TBL_NAME; - queryStr = new String( - "Select Distinct slat, slon, id, stationid, selv, synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime='" - + selectedSndTime - + "' AND slat BETWEEN -89.9 AND 89.9 AND slon BETWEEN -179.9 AND 179.9"); - queryStr1 = new String( - "Select Distinct slat, slon FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime='" - + selectedSndTime - + "' AND slat BETWEEN -89.9 AND 89.9 AND slon BETWEEN -179.9 AND 179.9"); - dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - } else if (obType.equals(ObsSndType.BUFRUA.toString())) { - currentDBTblName = BURFUA_TBL_NAME; - queryStr = new String( - "Select Distinct latitude, longitude, id, stationname, elevation, reftime FROM " - + currentDBTblName - + " where reftime='" - + selectedSndTime - + "' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); - queryStr1 = new String( - "Select Distinct latitude, longitude FROM " - + currentDBTblName - + " where reftime='" - + selectedSndTime - + "' AND latitude BETWEEN -89.9 AND 89.9 AND longitude BETWEEN -179.9 AND 179.9"); - dao = new CoreDao(DaoConfig.forClass(UAObs.class)); + //for(int i=0; i < synopTimeAry.length; i++){ + // if(synopTimeAry[i] != null) + // System.out.println("synoptictime ="+synopTimeAry[i] ); + //} + tl.setTimeLines(synopTimeAry); - } else if (obType.equals(ObsSndType.H5UAIR.toString())) { - currentDBTblName = H5UAIR_TBL_NAME; - queryStr = new String( - "Select Distinct slat, slon, id, stid, selv, synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime='" - + selectedSndTime - + "' AND slat BETWEEN -89.9 AND 89.9 AND slon BETWEEN -179.9 AND 179.9"); - queryStr1 = new String( - "Select Distinct slat, slon FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime='" - + selectedSndTime - + "' AND slat BETWEEN -89.9 AND 89.9 AND slon BETWEEN -179.9 AND 179.9"); - dao = new CoreDao(DaoConfig.forClass(H5UairRecord.class)); - } else { - return stnInfoCol; - } - rtnobjArray = dao.executeSQLQuery(queryStr); + return tl; + } + public static List getObservedSndTimeRangeList(String obType,Calendar startTime, Calendar endTime) { + Object[] synopTimeAry = null; + String startTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime.getTime()); + String endTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTime.getTime()); + String queryStr; + CoreDao dao; + if(obType.equals(ObsSndType.BUFRUA.toString())) { + currentDBTblName = BURFUA_TBL_NAME; + queryStr = new String("Select Distinct reftime FROM "+ currentDBTblName + " ORDER BY reftime DESC"); + dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - // *System.out.println("size of rtnobjArray " + rtnobjArray.length); - /* - * Object[] obj; for (int i =0; i = '"+ startTimeStr+"' AND synoptictime <= '"+endTimeStr+"' ORDER BY synoptictime DESC"); + dao = new CoreDao(DaoConfig.forClass(NcUairRecord.class)); + } + else{ + return null; + } + synopTimeAry = (Object[]) dao.executeSQLQuery(queryStr); + List timeLst = new ArrayList(); + //*System.out.println("size of synoptictime " + synopTimeAry.length); - rtnobjArray1 = dao.executeSQLQuery(queryStr1); + for(int i=0; i < synopTimeAry.length; i++){ + if(synopTimeAry[i] != null){ + System.out.println("synoptictime ="+synopTimeAry[i] ); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTimeInMillis(((Timestamp)synopTimeAry[i]).getTime()); + //String gmtTimeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", cal); + timeLst.add(cal); + } + } - // *System.out.println("size of rtnobjArray1 " + rtnobjArray1.length); - if ((rtnobjArray1.length > 0) && (rtnobjArray.length > 0)) { - double lat, lon, elv; - String stnInfo; - - // System.out.println("queryAndMarkStn called mapresource = "+ - // nsharpMapResource.toString()); - // Note: A same station may have many reports and at some reports - // they dont provide elv and or stnid - // this implementation is "try" to make sure we get those info. - // If, all reports does not have elv or stnid, then we still can not - // report it. - for (int i = 0; i < rtnobjArray1.length; i++) { - Object[] objArray1 = (Object[]) rtnobjArray1[i]; - Timestamp synoptictime = null; - stnInfo = ""; - elv = -999; - if (obType.equals(ObsSndType.H5UAIR.toString())) { - lat = (Float) objArray1[0]; - lon = (Float) objArray1[1]; - } else { - lat = (Double) objArray1[0]; - lon = (Double) objArray1[1]; - } - // System.out.println("lat = "+ lat +" lon= "+lon+"\n\n"); - for (int j = 0; j < rtnobjArray.length; j++) { - Object[] objArray = (Object[]) rtnobjArray[j]; - if ((obType.equals(ObsSndType.H5UAIR.toString()) - && (lat == (Float) objArray[0]) && (lon == (Float) objArray[1])) - || ((obType.equals(ObsSndType.UAIR.toString()) || obType - .equals(ObsSndType.BUFRUA.toString())) - && (lat == (Double) objArray[0]) && (lon == (Double) objArray[1]))) { - // ids.add(((Integer)objArray[2])); - // System.out.println("id=" + (Integer)objArray[2]); - if (stnInfo == "") - stnInfo = (String) objArray[3]; - if (elv == -999) { - if (obType.equals(ObsSndType.UAIR.toString())) - elv = (Double) objArray[4]; - else if (obType - .equals(ObsSndType.H5UAIR.toString())) - elv = (Float) objArray[4]; - else if (obType - .equals(ObsSndType.BUFRUA.toString())) - elv = (Integer) objArray[4]; - } - synoptictime = (Timestamp) objArray[5]; - } - - } - - NcSoundingStnInfo stn = stnInfoCol.getNewStnInfo(); - stn.setStnId(stnInfo); - stn.setStationLongitude((float) lon); - stn.setStationLatitude((float) lat); - stn.setStationElevation((float) elv); - stn.setSynopTime(synoptictime); - stationInfoList.add((NcSoundingStnInfo) stn); - // System.out.println("stn "+ stnInfo + " lon "+ lon + " lat "+ - // lat); - } - } - - NcSoundingStnInfo[] stationInfoAry = new NcSoundingStnInfo[stationInfoList - .size()]; - stnInfoCol.setStationInfo(stationInfoList.toArray(stationInfoAry)); - // *System.out.println("stn size = "+ - // stnInfoCol.getStationInfo().length); - return stnInfoCol; - } - - public static NcSoundingTimeLines getObservedSndTimeLine(String obType) { - Object[] synopTimeAry = null; - NcSoundingTimeLines tl = new NcSoundingTimeLines(); - String queryStr; - CoreDao dao; - // obType = ObsSndType.UAIR.toString(); // currently assume all uair - // sounding type - if (obType.equals(ObsSndType.UAIR.toString())) { - currentDBTblName = UAIR_TBL_NAME; - // query "uair" table in metadata db - queryStr = new String("Select Distinct synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' ORDER BY synoptictime DESC"); - dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - } else if (obType.equals(ObsSndType.BUFRUA.toString())) { - currentDBTblName = BURFUA_TBL_NAME; - queryStr = new String("Select Distinct reftime FROM " - + currentDBTblName + " ORDER BY reftime DESC"); - dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - - } else if (obType.equals(ObsSndType.H5UAIR.toString())) { - currentDBTblName = H5UAIR_TBL_NAME; - queryStr = new String("Select Distinct synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' ORDER BY synoptictime DESC"); - dao = new CoreDao(DaoConfig.forClass(H5UairRecord.class)); - } else { - return tl; - } - synopTimeAry = (Object[]) dao.executeSQLQuery(queryStr); - // *System.out.println("size of synoptictime " + synopTimeAry.length); - - // for(int i=0; i < synopTimeAry.length; i++){ - // if(synopTimeAry[i] != null) - // System.out.println("synoptictime ="+synopTimeAry[i] ); - // } - tl.setTimeLines(synopTimeAry); - - return tl; - } - - public static List getObservedSndTimeRangeList(String obType, - Calendar startTime, Calendar endTime) { - Object[] synopTimeAry = null; - String startTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - .format(startTime.getTime()); - String endTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - .format(endTime.getTime()); - String queryStr; - CoreDao dao; - // obType = ObsSndType.UAIR.toString(); // currently assume all uair - // sounding type - if (obType.equals(ObsSndType.UAIR.toString())) { - currentDBTblName = UAIR_TBL_NAME; - // query "uair" table in metadata db - queryStr = new String("Select Distinct synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime >= '" + startTimeStr - + "' AND synoptictime <= '" + endTimeStr - + "' ORDER BY synoptictime DESC"); - dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - } else if (obType.equals(ObsSndType.BUFRUA.toString())) { - currentDBTblName = BURFUA_TBL_NAME; - queryStr = new String("Select Distinct reftime FROM " - + currentDBTblName + " ORDER BY reftime DESC"); - dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - - } else if (obType.equals(ObsSndType.H5UAIR.toString())) { - currentDBTblName = H5UAIR_TBL_NAME; - queryStr = new String("Select Distinct synoptictime FROM " - + currentDBTblName - + " where nil='FALSE' AND synoptictime >= '" + startTimeStr - + "' AND synoptictime <= '" + endTimeStr - + "' ORDER BY synoptictime DESC"); - dao = new CoreDao(DaoConfig.forClass(H5UairRecord.class)); - } else { - return null; - } - synopTimeAry = (Object[]) dao.executeSQLQuery(queryStr); - List timeLst = new ArrayList(); - // *System.out.println("size of synoptictime " + synopTimeAry.length); - - for (int i = 0; i < synopTimeAry.length; i++) { - if (synopTimeAry[i] != null) { - System.out.println("synoptictime =" + synopTimeAry[i]); - Calendar cal = Calendar - .getInstance(TimeZone.getTimeZone("GMT")); - cal.setTimeInMillis(((Timestamp) synopTimeAry[i]).getTime()); - // String gmtTimeStr = - // String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", cal); - timeLst.add(cal); - } - } - - return timeLst; - } - - public static NcSoundingProfile getObservedSndH5UairAllData(Double lat, - Double lon, String stn, long refTimeL, String dataType, - SndQueryKeyType queryType) { - Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - refTimeCal.setTimeInMillis(refTimeL); - String refTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - .format(refTimeCal.getTime()); - return getObservedSndH5UairAllData(lat, lon, stn, refTime, dataType, - queryType); - } - - public static NcSoundingProfile getObservedSndH5UairAllData(Double lat, - Double lon, String stn, String refTime, String dataType, - SndQueryKeyType queryType) { - NcSoundingProfile pfAll = new NcSoundingProfile(); - PointDataQuery request = null; + return timeLst; + } + //static long totalRqTime=0; + /* + * Chin: Note: get NcUair based on stn is NOT supported yet!!! + * NEW: This function requests ONE station's all dataTypes data at once + * Nsharp is using this metod...dont remove it without consulting Nsharp developer + */ + public static NcUairRecord[] getObservedSndNcUairData(Double lat, Double lon, String stn, String refTime){ + + PointDataQuery request = null; PointDataContainer result = null; - + NcUairRecord[] h5Records=null; + + List pickedH5Records = new ArrayList(); try { - request = new PointDataQuery("h5uair"); - - request.requestAllLevels(); - request.addParameter("slat", String.valueOf(lat - 0.1), ">="); - request.addParameter("slat", String.valueOf(lat + 0.1), "<="); - request.addParameter("slon", String.valueOf(lon - 0.1), ">="); - request.addParameter("slon", String.valueOf(lon + 0.1), "<="); - - request.addParameter("dataTime.refTime", refTime, "="); - System.out.println("Get H5: lat=" + lat + " lon=" + lon - + " refTime=" + refTime); - request.addParameter("nil", String.valueOf(false), "="); - // request.addParameter("dataType", dataType, "="); - request.setParameters(H5UairToRecord.HDR_PARAMS_LIST); - result = request.execute(); + request = new PointDataQuery("ncuair"); + request.setParameters(NcUairToRecord.MAN_PARAMS_LIST); + request.addParameter("location.latitude", String.valueOf(lat), "="); + request.addParameter("location.longitude", String.valueOf(lon), "="); + /*request.addParameter("location.latitude", String.valueOf(lat-0.1), ">="); + request.addParameter("location.latitude", String.valueOf(lat+0.1), "<="); + request.addParameter("location.longitude", String.valueOf(lon-0.1), ">="); + request.addParameter("location.longitude", String.valueOf(lon+0.1), "<=");*/ + request.addParameter("dataTime.refTime",refTime, "="); + request.addParameter("nil", String.valueOf(false), "="); + //Chin newQ request.addParameter("dataType", dataType, "="); + //long t001 = System.currentTimeMillis(); + request.requestAllLevels(); + result = request.execute(); + //long t002 = System.currentTimeMillis(); + //totalRqTime=totalRqTime+(t002-t001); + //System.out.println("getObservedSndNcUairData request at lat="+ lat+ " lon="+lon+" took "+(t002-t001)+"ms total Qtime="+totalRqTime); if (result != null) { - System.out - .println("Get H5: result is not null, getAllocatedSz= " - + result.getAllocatedSz()); - - H5UairRecord[] h5Records = H5UairToRecord - .toH5UairRecords(result); - - System.out.println("Get H5: number of records = " - + h5Records.length); + //System.out.println("getObservedSndNcUairData: result is not null, getAllocatedSz= "+ result.getAllocatedSz()); + //System.out.println("getObservedSndNcUairData:getting "+dataType); + h5Records = NcUairToRecord.toNcUairRecords(result); + + if(h5Records!= null && h5Records.length > 0){ + // Chin: need to search through record list and keep one record for each record type + // If a record type comes with more than one record, then make decision to keep one based on + // its "issuetime" and "corr" columns in the ncuair table, then keep one record only + NcUairRecord orignalRd; + boolean addToList = true; + for(int i=0; i< h5Records.length; i++){ + orignalRd = h5Records[i]; + addToList = true; + for(NcUairRecord pickedRd: pickedH5Records){ + if(orignalRd.getDataType().equals( pickedRd.getDataType())){ + //the two records have same data type + //this records will either replace the one in list or be dropped + addToList = false; + if ((pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())<0) || + (pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())==0 && orignalRd.getCorr()!=null && pickedRd.getCorr() != null && pickedRd.getCorr().compareTo(orignalRd.getCorr())<0 )|| + (pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())==0 && orignalRd.getCorr()!=null && pickedRd.getCorr() == null) + ) + { + // decide to replace picked with original record, based on the following cases, in (priority) order + //case 1: original record has "later" issue time than picked record + //case 2: original record has "larger" correction "corr" than picked record + //case 3: original record has correction "corr", picked record does not have + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " ori= " + orignalRd.getDataURI()+ + // " picked="+ pickedRd.getDataURI()); + int pickedIndex = pickedH5Records.indexOf(pickedRd); + pickedH5Records.set(pickedIndex, orignalRd); + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " afterreplaced picked record ="+pickedH5Records.get(pickedIndex).getDataURI()); + + } + break; + } + } + if(addToList==true){ + // add this original record to picked list + pickedH5Records.add(orignalRd); + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " add ori to picked record ="+orignalRd.getDataURI()); + + } + } + + } + } } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(); } - return pfAll; - } - - /* - * Chin: Note: get H5Uair based on stn is NOT supported yet!!! - */ - public static H5UairRecord getObservedSndH5UairData(Double lat, Double lon, - String stn, String refTime, String dataType, - SndQueryKeyType queryType) { - H5UairRecord effectRecord = null; - PointDataQuery request = null; + if(pickedH5Records.size()>0){ + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " number of picked records = "+pickedH5Records.size()); + return pickedH5Records.toArray(new NcUairRecord[pickedH5Records.size()]); + } + return null; + } + /* + * Chin: Note: get NcUair based on stn is NOT supported yet!!! + * NEW: This function requests ALL stn with all dataTypes and returns all good ("corrected")records at once to improve performance + */ + public static List getAllStnObservedSndNcUairData(float[][] latLonArray, String stn, String refTime){ + //List soundingProfileList= new ArrayList(); + PointDataQuery request = null; PointDataContainer result = null; + //NcUairRecord[] h5Records=null; + Double maxLat, minLat, maxLon, minLon, lat, lon; + List returnedDbRecords = new ArrayList(); + List finalRecordArrayList = new ArrayList(); + maxLat=minLat=0.0; + maxLon=minLon=0.0; + for ( int i=0; i < latLonArray.length ; i++) + { + //make sure we have right precision... + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + if(i==0){ + maxLat=minLat=lat; + maxLon=minLon=lon; + } + maxLat = Math.max(lat, maxLat); + minLat = Math.min(lat, minLat); + maxLon = Math.max(lon, maxLon); + minLon = Math.min(lon, minLon); + } try { - request = new PointDataQuery("h5uair"); - request.setParameters(H5UairToRecord.MAN_PARAMS_LIST); - request.addParameter("slat", String.valueOf(lat - 0.1), ">="); - request.addParameter("slat", String.valueOf(lat + 0.1), "<="); - request.addParameter("slon", String.valueOf(lon - 0.1), ">="); - request.addParameter("slon", String.valueOf(lon + 0.1), "<="); - request.addParameter("dataTime.refTime", refTime, "="); - // System.out.println("getObservedSndNcUairData: lat="+lat+ - // " lon="+lon + " refTime="+refTime); - request.addParameter("nil", String.valueOf(false), "="); - request.addParameter("dataType", dataType, "="); + request = new PointDataQuery("ncuair"); + request.setParameters(NcUairToRecord.MAN_PARAMS_LIST); - request.requestAllLevels(); - result = request.execute(); + request.addParameter("location.latitude", String.valueOf(minLat-0.1), ">="); + request.addParameter("location.latitude", String.valueOf(maxLat+0.1), "<="); + request.addParameter("location.longitude", String.valueOf(minLon-0.1), ">="); + request.addParameter("location.longitude", String.valueOf(maxLon+0.1), "<="); + request.addParameter("dataTime.refTime",refTime, "="); + request.addParameter("nil", String.valueOf(false), "="); + request.requestAllLevels(); + result = request.execute(); + //long t002 = System.currentTimeMillis(); + //totalRqTime=totalRqTime+(t002-t001); + //System.out.println("getObservedSndNcUairData request at lat="+ lat+ " lon="+lon+" took "+(t002-t001)+"ms total Qtime="+totalRqTime); + if (result != null) { + returnedDbRecords = NcUairToRecord.toNcUairRecordsList(result); + + if(returnedDbRecords!= null && returnedDbRecords.size() > 0){ + + //Chin: keep list of records for same station + //search through all returned records and keep same staion's records in one list + for ( int i=0; i < latLonArray.length ; i++) + { + //for each station + lat = Double.parseDouble(Float.toString(latLonArray[i][0])); + lon = Double.parseDouble(Float.toString(latLonArray[i][1])); + NcUairRecord record; + List stnRecords = new ArrayList(); + //System.out.println("Before loop: Number of records in returnedDbRecords="+returnedDbRecords.size()); + for(int j=returnedDbRecords.size()-1; j >=0; j--){ + record =returnedDbRecords.get(j); + if(record.getLatitude() >= lat - 0.1 && record.getLatitude() <= lat + 0.1 && record.getLongitude() >= lon-0.1&& record.getLongitude() <= lon+0.1){ + //remove this record from return list and add it to this stn list + stnRecords.add(returnedDbRecords.remove(j)); + } + } + if(stnRecords.size()>0){ + //System.out.println("Before checking:stn lat="+lat +"stn record size="+stnRecords.size()); + List pickedUairRecords = new ArrayList(); + NcUairRecord orignalRd; + boolean addToList = true; + for(int ii=0; ii< stnRecords.size(); ii++){ + orignalRd = stnRecords.get(ii); + addToList = true; + for(NcUairRecord pickedRd: pickedUairRecords){ + if(orignalRd.getDataType().equals( pickedRd.getDataType())){ + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " find a same datatype="+pickedRd.getDataType()+ " orignalRd corr="+orignalRd.getCorr()+ + // " pickedRd Corr="+pickedRd.getCorr()); + + //the two records have same data type + //this records will either replace the one in list or be dropped + addToList = false; + if ((pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())<0) || + (pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())==0 && orignalRd.getCorr()!=null && pickedRd.getCorr() != null && pickedRd.getCorr().compareTo(orignalRd.getCorr())<0 )|| + (pickedRd.getIssueTime().compareTo(orignalRd.getIssueTime())==0 && orignalRd.getCorr()!=null && pickedRd.getCorr() == null) + ) + { + // decide to replace picked with original record, based on the following cases, in (priority) order + //case 1: original record has "later" issue time than picked record + //case 2: original record has "larger" correction "corr" than picked record + //case 3: original record has correction "corr", picked record does not have + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " ori= " + orignalRd.getDataURI()+ + // " picked="+ pickedRd.getDataURI()); + int pickedIndex = pickedUairRecords.indexOf(pickedRd); + pickedUairRecords.set(pickedIndex, orignalRd); + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " afterreplaced picked record ="+pickedH5Records.get(pickedIndex).getDataURI()); + } + break; + } + } + if(addToList==true){ + // add this original record to picked list + pickedUairRecords.add(orignalRd); + //System.out.println("getObservedSndNcUairData: at lat="+ lat+ " lon="+lon+ " add ori to picked record ="+orignalRd.getDataURI()); + + } + } + //pickedUairRecords.get(0).setNil(false); // set for special handling for its caller + finalRecordArrayList.add(pickedUairRecords.toArray(new NcUairRecord[pickedUairRecords.size()])); + //System.out.println("After checking: stn record size="+pickedUairRecords.size()); + }/*Chin: If caller need all query stns returned (no matter there is no data), then we may need to add this code... + else { + //just add a null record array + NcUairRecord dummy = new NcUairRecord(); + dummy.setNil(true);// set for special handling for its caller + SurfaceObsLocation location = new SurfaceObsLocation(); + location.setLatitude(lat); + location.setLongitude(lon); + dummy.setLocation(location); + + NcUairRecord[] dummys= new NcUairRecord[1]; + dummys[0] = dummy; + finalRecordArrayList.add(dummys); + }*/ + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return finalRecordArrayList; + } + /* + * This method query ONE station's specific one dataType data only + */ + public static NcUairRecord getObservedSndNcUairData(Double lat, Double lon, String stn, String refTime, String dataType, SndQueryKeyType queryType){ + NcUairRecord effectRecord=null; + PointDataQuery request = null; + PointDataContainer result = null; + + try { + request = new PointDataQuery("ncuair"); + request.setParameters(NcUairToRecord.MAN_PARAMS_LIST); + request.addParameter("location.latitude", String.valueOf(lat-0.1), ">="); + request.addParameter("location.latitude", String.valueOf(lat+0.1), "<="); + request.addParameter("location.longitude", String.valueOf(lon-0.1), ">="); + request.addParameter("location.longitude", String.valueOf(lon+0.1), "<="); + request.addParameter("dataTime.refTime",refTime, "="); + //System.out.println("getObservedSndNcUairData: lat="+lat+ " lon="+lon + " refTime="+refTime); + request.addParameter("nil", String.valueOf(false), "="); + request.addParameter("dataType", dataType, "="); + + request.requestAllLevels(); + result = request.execute(); if (result != null) { - // System.out.println("getObservedSndNcUairData: result is not null, getAllocatedSz= "+ - // result.getAllocatedSz()); - // System.out.println("getObservedSndNcUairData:getting "+dataType); - H5UairRecord[] h5Records = H5UairToRecord - .toH5UairRecords(result); - // System.out.println("getObservedSndNcUairData: number of "+dataType+" records = "+h5Records.length); - - if (h5Records.length == 1) { - // effectRecord = h5Records[0]; - // System.out.println("getObservedSndNcUairData: real dataType =" - // + h5Records[0].getDataType()); - return h5Records[0]; - } else if (h5Records.length > 1) { - // need to find out the latest corrected record - int lastCorrectedRecord = 0; - String currentCorInd = ""; - Calendar curIssueTime = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - // set init time - curIssueTime.setTimeInMillis(0); - for (int i = 0; i < h5Records.length; i++) { - // System.out.println("getObservedSndNcUairData2: real dataType =" - // + h5Records[i].getDataType()); - if ((curIssueTime - .compareTo(h5Records[i].getIssueTime()) == 0 - && h5Records[i].getCorr() != null && currentCorInd - .compareTo(h5Records[i].getCorr()) < 0) - || (curIssueTime.compareTo(h5Records[i] - .getIssueTime()) < 0)) { - currentCorInd = h5Records[i].getCorr(); - curIssueTime = h5Records[i].getIssueTime(); - lastCorrectedRecord = i; - // System.out.println("getObservedSndNcUairData: corr=" - // + h5Records[i].getCorr()); - } - } - // effectRecord = h5Records[lastCorrectedRecord]; - return h5Records[lastCorrectedRecord]; - } - + //System.out.println("getObservedSndNcUairData: result is not null, getAllocatedSz= "+ result.getAllocatedSz()); + //System.out.println("getObservedSndNcUairData:getting "+dataType); + NcUairRecord[] h5Records = NcUairToRecord.toNcUairRecords(result); + //System.out.println("getObservedSndNcUairData: number of "+dataType+" records = "+h5Records.length); + + if(h5Records.length == 1){ + //effectRecord = h5Records[0]; + //System.out.println("getObservedSndNcUairData: real dataType =" + h5Records[0].getDataType()); + return h5Records[0]; + } + else if (h5Records.length > 1){ + // need to find out the latest corrected record + int lastCorrectedRecord=0; + String currentCorInd = ""; + Calendar curIssueTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // set init time + curIssueTime.setTimeInMillis(0); + for(int i=0; i< h5Records.length; i++){ + //System.out.println("getObservedSndNcUairData2: real dataType =" + h5Records[i].getDataType()); + if( ( curIssueTime.compareTo(h5Records[i].getIssueTime())<0 ) || + (curIssueTime.compareTo(h5Records[i].getIssueTime())==0 && h5Records[i].getCorr()!= null && currentCorInd.compareTo(h5Records[i].getCorr()) < 0 ) + ) + { + currentCorInd = h5Records[i].getCorr(); + curIssueTime = h5Records[i].getIssueTime(); + lastCorrectedRecord = i; + //System.out.println("getObservedSndNcUairData: corr=" + h5Records[i].getCorr()); + } + } + //effectRecord = h5Records[lastCorrectedRecord]; + return h5Records[lastCorrectedRecord]; + } + } } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(); } - return effectRecord; - } + return effectRecord; + } - /* - * this api is provided for applications and for testing to retrieve - * observed uair data from PostgreSql DB dataType should use "enum DataType" - * defined in NcSoundingLayer.java Support "ALLDATA" data type only + /* + * this api is provided for applications and for testing to retrieve observed uair data from PostgreSql DB + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support "ALLDATA" data type only */ - public static NcSoundingProfile getObservedSndAllData(Double lat, - Double lon, String stn, long refTimeL, String obType, - SndQueryKeyType queryType) { - Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // for testing ...refTimeCal.setTimeInMillis(1276581600000L); - // refTimeCal.setTimeInMillis(refTime.getTime()); - refTimeCal.setTimeInMillis(refTimeL); - return getObservedSndAllData(lat, lon, stn, refTimeCal, obType, - queryType); - } - - /* - * this api is provided for applications and for testing to retrieve - * observed uair data from PostgreSql DB dataType should use "enum DataType" - * defined in NcSoundingLayer.java Support "ALLDATA" data type only + public static NcSoundingProfile getObservedSndAllData(Double lat, Double lon, String stn, long refTimeL, String obType, SndQueryKeyType queryType){ + Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // for testing ...refTimeCal.setTimeInMillis(1276581600000L); + //refTimeCal.setTimeInMillis(refTime.getTime()); + refTimeCal.setTimeInMillis(refTimeL); + return getObservedSndAllData(lat, lon, stn, refTimeCal, obType, queryType); + } + + /* + * this api is provided for applications and for testing to retrieve observed uair data from PostgreSql DB + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support "ALLDATA" data type only */ - public static NcSoundingProfile getObservedSndAllData(Double lat, - Double lon, String stn, Calendar refTimeCal, String obType, - SndQueryKeyType queryType) { - NcSoundingProfile pfAll = new NcSoundingProfile(); - List soundingLyLst, finalsoundingLyLst; - if (obType.equals(ObsSndType.UAIR.toString())) { - NcSoundingProfile pf = getObservedSndData(lat, lon, stn, - refTimeCal, obType, "TTAA", queryType); - pfAll.setStationElevation(pf.getStationElevation()); - finalsoundingLyLst = pf.getSoundingLyLst(); - if (finalsoundingLyLst.size() == 0) { - finalsoundingLyLst = getObservedSndData(lat, lon, stn, - refTimeCal, obType, "UUAA", queryType) - .getSoundingLyLst(); - } - - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "TTBB", queryType).getSoundingLyLst(); - if (soundingLyLst.size() == 0) { - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "UUBB", queryType).getSoundingLyLst(); - } - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "TTCC", queryType).getSoundingLyLst(); - if (soundingLyLst.size() == 0) { - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "UUCC", queryType).getSoundingLyLst(); - } - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "TTDD", queryType).getSoundingLyLst(); - if (soundingLyLst.size() == 0) { - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "UUDD", queryType).getSoundingLyLst(); - } - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "PPAA", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "PPBB", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "PPCC", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "PPDD", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "MAXWIND_A", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "MAXWIND_C", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "TROPOPAUSE_A", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndData(lat, lon, stn, refTimeCal, - obType, "TROPOPAUSE_C", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - pfAll.setSoundingLyLst(finalsoundingLyLst); - } - - return pfAll; - } + public static NcSoundingProfile getObservedSndAllData(Double lat, Double lon, String stn, Calendar refTimeCal, String obType, SndQueryKeyType queryType){ + NcSoundingProfile pfAll= new NcSoundingProfile(); + List soundingLyLst, finalsoundingLyLst; + /*if(obType.equals(ObsSndType.UAIR.toString())){ + NcSoundingProfile pf = getObservedSndData(lat, lon, stn, refTimeCal, obType, "TTAA", queryType); + pfAll.setStationElevation(pf.getStationElevation()); + finalsoundingLyLst = pf.getSoundingLyLst(); + if (finalsoundingLyLst.size() == 0) { + finalsoundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "UUAA", queryType).getSoundingLyLst(); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "TTBB", queryType).getSoundingLyLst(); + if (soundingLyLst.size() == 0) { + soundingLyLst = getObservedSndData(lat, lon,stn, refTimeCal, obType, "UUBB", queryType).getSoundingLyLst(); + } + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "TTCC", queryType).getSoundingLyLst(); + if (soundingLyLst.size() == 0) { + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "UUCC", queryType).getSoundingLyLst(); + } + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "TTDD", queryType).getSoundingLyLst(); + if (soundingLyLst.size() == 0) { + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "UUDD", queryType).getSoundingLyLst(); + } + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "PPAA", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "PPBB", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "PPCC", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "PPDD", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon,stn, refTimeCal, obType, "MAXWIND_A", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "MAXWIND_C", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "TROPOPAUSE_A", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndData(lat, lon, stn,refTimeCal, obType, "TROPOPAUSE_C", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + pfAll.setSoundingLyLst(finalsoundingLyLst); + } + */ + return pfAll; + } /* - * this api is provided for applications and for testing to retrieve - * observed uair data from PostgreSql DB dataType should use "enum DataType" - * defined in NcSoundingLayer.java Support all dataType except "ALLDATA" - * data type using either lat/lon, stnId or stnNum and synopticTime as key + * this api is provided for applications and for testing to retrieve observed uair data from PostgreSql DB + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support all dataType except "ALLDATA" data type + * using either lat/lon, stnId or stnNum and synopticTime as key * refTime is with unit of msec as input */ - public static NcSoundingProfile getObservedSndData(Double lat, Double lon, - String stn, long refTimeL, String obType, String dataType, - SndQueryKeyType queryType) { - Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // for testing ...refTimeCal.setTimeInMillis(1276581600000L); - // refTimeCal.setTimeInMillis(refTime.getTime()); - refTimeCal.setTimeInMillis(refTimeL); - return getObservedSndData(lat, lon, stn, refTimeCal, obType, dataType, - queryType); - } - + public static NcSoundingProfile getObservedSndData(Double lat, Double lon,String stn, long refTimeL, String obType, String dataType, SndQueryKeyType queryType){ + Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // for testing ...refTimeCal.setTimeInMillis(1276581600000L); + //refTimeCal.setTimeInMillis(refTime.getTime()); + refTimeCal.setTimeInMillis(refTimeL); + return getObservedSndData(lat, lon, stn, refTimeCal, obType, dataType, queryType); + } /* - * this api is provided for applications and for testing to retrieve - * observed uair data from PostgreSql DB dataType should use "enum DataType" - * defined in NcSoundingLayer.java Support all dataType except "ALLDATA" - * data type using either lat/lon, stnId or stnNum and synopticTime as key - * reference time is with Calendar data type as input - */ - @SuppressWarnings("unchecked") - public static NcSoundingProfile getObservedSndData(Double lat, Double lon, - String stn, Calendar refTimeCal, String obType, String dataType, - SndQueryKeyType queryType) { - NcSoundingProfile pf = new NcSoundingProfile(); - // one StnPt represent one data time line - List soundLyLst = new ArrayList(); - NcSoundingLayer soundingLy; - soundLyLst.clear(); - - // String gmtTimeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM", - // refTimeCal); - // *System.out.println("sndType= "+ obType+" data type="+ dataType+ - // " lat " + lat+ " lon "+ lon+" GMT time " + gmtTimeStr ); - - obType = ObsSndType.UAIR.toString(); // currently assume all uair - // sounding type - if (obType.equals(ObsSndType.UAIR.toString())) { - if (dataType.equals(NcSoundingLayer.DataType.ALLDATA.toString())) { - // *System.out.println("request all data is not supported in this API"); - } else { - List fields = new ArrayList(); - List values = new ArrayList(); - List operands = new ArrayList(); - List lUairRecords = null; - if (queryType == SndQueryKeyType.STNID) { - fields.add("stationId");// the stnId field name defined in - // UairRecord - values.add(stn); - operands.add("="); - } else if (queryType == SndQueryKeyType.STNNUM) { - fields.add("stationNumber");// the stnNum field name defined - // in UairRecord - values.add(stn); - operands.add("="); - } else if (queryType == SndQueryKeyType.LATLON) { - fields.add("slat");// the lat field name defined in - // UairRecord - values.add(lat - 0.1); - operands.add(">="); - fields.add("slat");// the lat field name defined in - // UairRecord - values.add(lat + 0.1); - operands.add("<="); - fields.add("slon");// the lon field name defined in - // UairRecord - values.add(lon - 0.1); - operands.add(">="); - fields.add("slon");// the lon field name defined in - // UairRecord - values.add(lon + 0.1); - operands.add("<="); - - } else { - // *System.out.println("request query type "+ queryType+ - // " is not supported in this API" ); - return pf; - } - fields.add("dataTime.refTime");// the synoptic time field name - // defined in UairRecord - // fields.add("synopticTime");// the synoptic time field name - // defined in UairRecord - values.add(refTimeCal.getTime()); - operands.add("="); - fields.add("nil");// nil field name defined in UairRecord - values.add(false); - operands.add("="); - fields.add("dataType");// the record dataType field name defined - // in UairRecord - String realDataType; // when query, need to use TTAA for - // MAXWIND_A, or TROPOPAUSE_A, and TTCC for - // MAXWIND_C, or TROPOPAUSE_C - if (dataType.equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString())) { - realDataType = NcSoundingLayer.DataType.TTAA.toString(); - } else if (dataType.equals(NcSoundingLayer.DataType.MAXWIND_C - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_C - .toString())) { - realDataType = NcSoundingLayer.DataType.TTCC.toString(); - } else - realDataType = dataType; - values.add(realDataType); - operands.add("="); - - CoreDao dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - try { - lUairRecords = (List) dao.queryByCriteria( - fields, values, operands); - if (lUairRecords.size() > 0) { - // *System.out.println("size of uairrecord " + - // lUairRecords.size()); - int lastCorrectedRecord = 0; - String currentCorInd = ""; - Calendar curIssueTime = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - // set init time - curIssueTime.setTimeInMillis(0); - - if (lUairRecords.size() > 1) { - for (int i = 0; i < lUairRecords.size(); i++) { - // Since we are using lat/lon/refTime to query - // uair table. We may have several records - // returned for - // one query. It indicates there is a correction - // report, then we should use the newest one - // report. - // we compare corIndicator to find the latest - // record. - // System.out.println("id ="+lUairRecords.get(i).getId() - // + " datauri=" - // +lUairRecords.get(i).getDataURI()); - // System.out.println("size of ObsLevels ="+lUairRecords.get(i).getObsLevels().size() - // ); - // System.out.println("size of maxWind ="+lUairRecords.get(i).getMaxWind().size() - // ); - // System.out.println("size of Tropopause ="+lUairRecords.get(i).getTropopause().size() - // ); - // System.out.println("correction ind ="+lUairRecords.get(i).getCorIndicator() - // ); - if ((curIssueTime.compareTo(lUairRecords.get(i) - .getIssueTime()) == 0 - && lUairRecords.get(i) - .getCorIndicator() != null && currentCorInd - .compareTo(lUairRecords.get(i) - .getCorIndicator()) < 0) - || (curIssueTime.compareTo(lUairRecords - .get(i).getIssueTime()) < 0)) { - currentCorInd = lUairRecords.get(i) - .getCorIndicator(); - curIssueTime = lUairRecords.get(i) - .getIssueTime(); - lastCorrectedRecord = i; - } - } - } - pf.setStationElevation((float) lUairRecords.get( - lastCorrectedRecord).getSelv()); - pf.setStationId(lUairRecords.get(lastCorrectedRecord) - .getStationId()); - if (lUairRecords.get(lastCorrectedRecord) - .getStationNumber() != null - && lUairRecords.get(lastCorrectedRecord) - .getStationNumber().length() > 0) { - // System.out.println("stn num = "+ - // lUairRecords.get(lastCorrectedRecord).getStationNumber()); - pf.setStationNum(Integer.parseInt(lUairRecords.get( - lastCorrectedRecord).getStationNumber())); - } else { - pf.setStationNum(-1); - } - pf.setStationLatitude((float) lUairRecords.get( - lastCorrectedRecord).getSlat()); - pf.setStationLongitude((float) lUairRecords.get( - lastCorrectedRecord).getSlon()); - // System.out.println("stn elevation ="+ - // pf.getStationElevation() ); - - if ((lUairRecords.get(lastCorrectedRecord) - .getObsLevels().size() > 0) - && !dataType - .equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) - && !dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString()) - && !dataType - .equals(NcSoundingLayer.DataType.MAXWIND_C - .toString()) - && !dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_C - .toString())) { - // *System.out.println("getting "+ dataType); - - java.util.Iterator it = lUairRecords - .get(lastCorrectedRecord).getObsLevels() - .iterator(); - while (it.hasNext()) { - ObsLevels value = (ObsLevels) it.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setGeoHeight(value.getGeoHeight()); - soundingLy.setTemperature(value.getTemp()); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - } - soundingLy.setDewpoint(value.getDwpt()); - // System.out.println("pressure :"+value.getPressure() - // + " temp:" + value.getTemp() + - // " H:"+value.getGeoHeight() + " D:" + - // value.getWindDirection() + " F: " + - // value.getWindSpeed()); - soundLyLst.add(soundingLy); - } - } else if (lUairRecords.get(lastCorrectedRecord) - .getMaxWind().size() > 0 - && (dataType - .equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) || dataType - .equals(NcSoundingLayer.DataType.MAXWIND_C - .toString()))) { - // *System.out.println("getting "+ dataType); - java.util.Iterator itWind = lUairRecords - .get(lastCorrectedRecord).getMaxWind() - .iterator(); - - while (itWind.hasNext()) { - MaxWind value = (MaxWind) itWind.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - } - // *System.out.println("WIND pressure :"+value.getPressure() - // + " WD:" + value.getWindDirection() + - // " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); - soundLyLst.add(soundingLy); - } - } else if (lUairRecords.get(lastCorrectedRecord) - .getTropopause().size() > 0 - && (dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString()) || dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_C - .toString()))) { - // *System.out.println("getting "+ dataType); - java.util.Iterator it = lUairRecords - .get(lastCorrectedRecord).getTropopause() - .iterator(); - while (it.hasNext()) { - Tropopause value = (Tropopause) it.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setTemperature(value.getTemp()); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - // *System.out.println("Tropopause pressure :"+value.getPressure() - // + " temp:" + value.getTemp()+" WD:" + - // value.getWindDirection() + - // " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); - - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - // *System.out.println("Tropopause pressure :"+value.getPressure() - // + " temp:" + value.getTemp()+" WD:" + - // value.getWindDirection() + - // " WS:"+(float)value.getWindSpeed()); - - } - soundingLy.setDewpoint(value.getDwpt()); - soundLyLst.add(soundingLy); - } - } - } - - } catch (DataAccessLayerException e) { - // *System.out.println("obs sounding query exception"); - // e.printStackTrace(); - } - } - - }// end ObsSndType.UAIR - - pf.setSoundingLyLst(soundLyLst); - return pf; - - } - - /* - * NOT used currently - * - * obsType: UAIR, TAMDAR or DROP, dataType: ALLDATA ONLY - */ - @SuppressWarnings("unchecked") - public static NcSoundingProfile getObservedSndData(int[] parentIds, - String obType, String dataType) { - NcSoundingProfile pf = new NcSoundingProfile(); - // one StnPt represent one data time line - List soundLyLst = new ArrayList(); - NcSoundingLayer soundingLy; - soundLyLst.clear(); - obType = ObsSndType.UAIR.toString(); // currently assume all uair - // sounding type - if (obType.equals(ObsSndType.UAIR.toString())) { - // *System.out.println("parentIds length = " + parentIds.length ); - for (int i = 0; i < parentIds.length; i++) { - int id = parentIds[i]; - List fields = new ArrayList(); - List values = new ArrayList(); - List lObsLevels = null; - fields.add("id");// the record id field name defined in - // UairRecord - values.add(id); // testing 994872); - if (!dataType.equals(NcSoundingLayer.DataType.ALLDATA - .toString()) - && !dataType.equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) - && !dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString())) { - fields.add("dataType");// the record dataType field name - // defined in UairRecord - values.add(dataType); // testing "TTAA" - - } - CoreDao dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); - try { - lObsLevels = (List) dao.queryByCriteria(fields, - values); - if (lObsLevels.size() > 0) { - // since we are using Records id to query uair table. - // lObsLevels.size() should always be one. - // *System.out.println("size of uairrecord " + - // lObsLevels.size()); - // *System.out.println("id ="+lObsLevels.get(0).getId() - // + " datauri=" +lObsLevels.get(0).getDataURI()); - // *System.out.println("size of ObsLevels ="+lObsLevels.get(0).getObsLevels().size() - // ); - // *System.out.println("size of maxWind ="+lObsLevels.get(0).getMaxWind().size() - // ); - // *System.out.println("size of Tropopause ="+lObsLevels.get(0).getTropopause().size() - // ); - if ((lObsLevels.get(0).getObsLevels().size() > 0) - && !dataType - .equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) - && !dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString())) { - java.util.Iterator it = lObsLevels - .get(0).getObsLevels().iterator(); - while (it.hasNext()) { - ObsLevels value = (ObsLevels) it.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setGeoHeight(value.getGeoHeight()); - soundingLy.setTemperature(value.getTemp()); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - } - soundingLy.setDewpoint(value.getDwpt()); - // *System.out.println("pressure :"+value.getPressure() - // + " temp:" + value.getTemp() + - // " H:"+value.getGeoHeight() ); - soundLyLst.add(soundingLy); - } - } - } - - if (lObsLevels.get(0).getMaxWind().size() > 0 - && !dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString())) { - java.util.Iterator itWind = lObsLevels.get(0) - .getMaxWind().iterator(); - - while (itWind.hasNext()) { - MaxWind value = (MaxWind) itWind.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - } - - soundLyLst.add(soundingLy); - } - } - - if (lObsLevels.get(0).getTropopause().size() > 0 - && !dataType - .equals(NcSoundingLayer.DataType.MAXWIND_A - .toString())) { - java.util.Iterator it = lObsLevels.get(0) - .getTropopause().iterator(); - while (it.hasNext()) { - Tropopause value = (Tropopause) it.next(); - soundingLy = new NcSoundingLayer(); - soundingLy.setTemperature(value.getTemp()); - soundingLy.setPressure(value.getPressure()); - soundingLy.setWindDirection(value - .getWindDirection()); - if (value.getWindSpeed() != NcSoundingLayer.MISSING) { - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) value - .getWindSpeed())); - // *System.out.println("Tropopause pressure :"+value.getPressure() - // + " temp:" + value.getTemp()+" WD:" + - // value.getWindDirection() + - // " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); - - } else { - soundingLy.setWindSpeed((float) value - .getWindSpeed()); - // *System.out.println("Tropopause pressure :"+value.getPressure() - // + " temp:" + value.getTemp()+" WD:" + - // value.getWindDirection() + - // " WS:"+(float)value.getWindSpeed()); - - } - - soundingLy.setDewpoint(value.getDwpt()); - - soundLyLst.add(soundingLy); - - } - } - } catch (DataAccessLayerException e) { - // *System.out.println("obs sounding query exception"); - // e.printStackTrace(); - } - - } - } - pf.setSoundingLyLst(soundLyLst); - return pf; - - } - - /* - * this api is provided for applications and for testing to retrieve - * observed bufruair data from PostgreSql DB & HDF5 dataType should use - * "enum DataType" defined in NcSoundingLayer.java Support "ALLDATA" data - * type only - */ - public static NcSoundingProfile getObservedSndBufruaAllData(Double lat, - Double lon, String stn, long refTimeL, SndQueryKeyType queryType) { - Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // for testing ...refTimeCal.setTimeInMillis(1276581600000L); - // refTimeCal.setTimeInMillis(refTime.getTime()); - refTimeCal.setTimeInMillis(refTimeL); - return getObservedSndBufruaAllData(lat, lon, stn, refTimeCal, queryType); - } - - /* - * this api is provided for applications and for testing to retrieve - * observed bufruair data from PostgreSql DB & HDF5 dataType should use - * "enum DataType" defined in NcSoundingLayer.java Support "ALLDATA" data - * type only - */ - public static NcSoundingProfile getObservedSndBufruaAllData(Double lat, - Double lon, String stn, Calendar refTimeCal, - SndQueryKeyType queryType) { - NcSoundingProfile pfAll = new NcSoundingProfile(); - List soundingLyLst, finalsoundingLyLst; - NcSoundingProfile pf = getObservedSndBufruaData(lat, lon, stn, - refTimeCal, "TTAA", queryType); - pfAll.setStationElevation(pf.getStationElevation()); - finalsoundingLyLst = pf.getSoundingLyLst(); - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "TTBB", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "TTCC", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "TTDD", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - // soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, - // "PPAA", queryType).getSoundingLyLst(); - // if (soundingLyLst.size() >= 0){ - // finalsoundingLyLst.addAll(soundingLyLst); - // } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "PPBB", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - // soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, - // "PPCC", queryType).getSoundingLyLst(); - // if (soundingLyLst.size() >= 0){ - // finalsoundingLyLst.addAll(soundingLyLst); - // } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "PPDD", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "MAXWIND_A", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "MAXWIND_C", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "TROPOPAUSE_A", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - soundingLyLst = getObservedSndBufruaData(lat, lon, stn, refTimeCal, - "TROPOPAUSE_C", queryType).getSoundingLyLst(); - if (soundingLyLst.size() >= 0) { - finalsoundingLyLst.addAll(soundingLyLst); - } - pfAll.setSoundingLyLst(finalsoundingLyLst); - return pfAll; - } - - /* - * this api is provided for applications and for testing to retrieve - * observed BufrUA data from PostgreSql DB and HDF5 dataType should use - * "enum DataType" defined in NcSoundingLayer.java Support all dataType - * except "ALLDATA" data type using either lat/lon, stnId or stnNum and - * validTime as key refTime is with unit of msec as input - */ - public static NcSoundingProfile getObservedSndBufruaData(Double lat, - Double lon, String stn, long refTimeL, String dataType, - SndQueryKeyType queryType) { - Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // for testing ...refTimeCal.setTimeInMillis(1276581600000L); - // refTimeCal.setTimeInMillis(refTime.getTime()); - refTimeCal.setTimeInMillis(refTimeL); - return getObservedSndBufruaData(lat, lon, stn, refTimeCal, dataType, - queryType); - } - - /* - * This API is provided for retrieving bufrUA data from PostgresSQL and HDF5 + * this api is provided for applications and for testing to retrieve observed uair data from PostgreSql DB * dataType should use "enum DataType" defined in NcSoundingLayer.java - * Support all dataType except "ALLDATA" data type using either lat/lon, - * stnId or stnNum and synopticTime as key reference time is with Calendar - * data type as input + * Support all dataType except "ALLDATA" data type + * using either lat/lon, stnId or stnNum and synopticTime as key + * reference time is with Calendar data type as input */ - @SuppressWarnings("unchecked") - public static NcSoundingProfile getObservedSndBufruaData(Double lat, - Double lon, String stn, Calendar refTimeCal, String dataType, - SndQueryKeyType queryType) { - // *System.out.println("getObservedSndBufruaData lat= " + - // lat+" lon="+lon+" refTime="+refTimeCal ); - // Timestamp refTime = new Timestamp(refTimeL); - // System.out.println("GMT ref time = "+ refTime.toGMTString()); - NcSoundingProfile pf = new NcSoundingProfile(); - List soundLyList = new ArrayList(); - if (dataType.equals(NcSoundingLayer.DataType.ALLDATA.toString())) { - // *System.out.println("request all data is not supported in this API"); - return pf; - } else { - List fields = new ArrayList(); - List values = new ArrayList(); - List lUairRecords = null; - if (queryType == SndQueryKeyType.STNID) { - fields.add("stationName");// the stationName String field name - // defined in UAObs, dont be confused - // with UAIRRecord definition - values.add(stn); - } else if (queryType == SndQueryKeyType.STNNUM) { - fields.add("location.stationId");// the location.stationId - // String field name defined in - // UAObs. dont be confused with - // UAIRRecord definition - values.add(stn); - } else if (queryType == SndQueryKeyType.LATLON) { - fields.add("location.latitude");// the location.latitude field - // name defined in UAObs - values.add(lat); - fields.add("location.longitude");// the location.longitude field - // name defined in UAObs - values.add(lon); + @SuppressWarnings("unchecked") + public static NcSoundingProfile getObservedSndData(Double lat, Double lon,String stn, Calendar refTimeCal, String obType, String dataType, SndQueryKeyType queryType){ + NcSoundingProfile pf = new NcSoundingProfile(); + //one StnPt represent one data time line + List soundLyLst = new ArrayList(); + NcSoundingLayer soundingLy; + soundLyLst.clear(); + + //String gmtTimeStr = String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM", refTimeCal); + //*System.out.println("sndType= "+ obType+" data type="+ dataType+ " lat " + lat+ " lon "+ lon+" GMT time " + gmtTimeStr ); - } else { - System.out.println("request query type " + queryType - + " is not supported in this API"); - return pf; - } - fields.add("dataTime.refTime");// the synoptic time field name - // defined in UAObs - // fields.add("validTime");// the synoptic time field name defined - // in UAObs - values.add(refTimeCal.getTime()); - fields.add("reportType");// the record dataType field name defined - // in UAObs - int intDataType = NcSoundingLayer.dataTypeMap.get(dataType); - values.add(intDataType); + /*obType = ObsSndType.UAIR.toString(); // currently assume all uair sounding type + if(obType.equals(ObsSndType.UAIR.toString())){ + if(dataType.equals(NcSoundingLayer.DataType.ALLDATA.toString())){ + //System.out.println("request all data is not supported in this API"); + } + else { + List fields = new ArrayList(); + List values = new ArrayList(); + List operands = new ArrayList(); + List lUairRecords = null; + if(queryType==SndQueryKeyType.STNID){ + fields.add("stationId");// the stnId field name defined in UairRecord + values.add(stn); + operands.add("="); + } + else if(queryType==SndQueryKeyType.STNNUM){ + fields.add("stationNumber");// the stnNum field name defined in UairRecord + values.add(stn); + operands.add("="); + } + else if(queryType==SndQueryKeyType.LATLON){ + fields.add("slat");// the lat field name defined in UairRecord + values.add(lat-0.1); + operands.add(">="); + fields.add("slat");// the lat field name defined in UairRecord + values.add(lat+0.1); + operands.add("<="); + fields.add("slon");// the lon field name defined in UairRecord + values.add(lon-0.1); + operands.add(">="); + fields.add("slon");// the lon field name defined in UairRecord + values.add(lon+0.1); + operands.add("<="); + + } + else { + //System.out.println("request query type "+ queryType+ " is not supported in this API" ); + return pf; + } + fields.add("dataTime.refTime");// the synoptic time field name defined in UairRecord + //fields.add("synopticTime");// the synoptic time field name defined in UairRecord + values.add(refTimeCal.getTime()); + operands.add("="); + fields.add("nil");// nil field name defined in UairRecord + values.add(false); + operands.add("="); + fields.add("dataType");// the record dataType field name defined in UairRecord + String realDataType; //when query, need to use TTAA for MAXWIND_A, or TROPOPAUSE_A, and TTCC for MAXWIND_C, or TROPOPAUSE_C + if(dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString()) || + dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString())){ + realDataType = NcSoundingLayer.DataType.TTAA.toString(); + } else if(dataType.equals(NcSoundingLayer.DataType.MAXWIND_C.toString()) || + dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_C.toString())){ + realDataType = NcSoundingLayer.DataType.TTCC.toString(); + } else + realDataType = dataType; + values.add(realDataType); + operands.add("="); - // for (int i=0; i < fields.size(); i++) { - // System.out.println("field "+ fields.get(i) + " value "+ - // values.get(i)); - // } - CoreDao dao = new CoreDao(DaoConfig.forClass(UAObs.class)); - try { - lUairRecords = (List) dao - .queryByCriteria(fields, values); - if (lUairRecords.size() > 0) { - // set pf data - // System.out.println("record size = "+ lUairRecords.size() - // + " reportType="+dataType); + CoreDao dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); + try { + lUairRecords = (List) dao.queryByCriteria(fields, values, operands); + if(lUairRecords.size() > 0){ + //*System.out.println("size of uairrecord " + lUairRecords.size()); + int lastCorrectedRecord=0; + String currentCorInd = ""; + Calendar curIssueTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // set init time + curIssueTime.setTimeInMillis(0); + + if(lUairRecords.size() > 1){ + for(int i=0; i< lUairRecords.size(); i++){ + //Since we are using lat/lon/refTime to query uair table. We may have several records returned for + // one query. It indicates there is a correction report, then we should use the newest one report. + // we compare corIndicator to find the latest record. + //System.out.println("id ="+lUairRecords.get(i).getId() + " datauri=" +lUairRecords.get(i).getDataURI()); + //System.out.println("size of ObsLevels ="+lUairRecords.get(i).getObsLevels().size() ); + //System.out.println("size of maxWind ="+lUairRecords.get(i).getMaxWind().size() ); + //System.out.println("size of Tropopause ="+lUairRecords.get(i).getTropopause().size() ); + //System.out.println("correction ind ="+lUairRecords.get(i).getCorIndicator() ); + if((curIssueTime.compareTo(lUairRecords.get(i).getIssueTime())==0 && lUairRecords.get(i).getCorIndicator()!= null && currentCorInd.compareTo(lUairRecords.get(i).getCorIndicator()) < 0)|| + (curIssueTime.compareTo(lUairRecords.get(i).getIssueTime())<0)) { + currentCorInd = lUairRecords.get(i).getCorIndicator(); + curIssueTime = lUairRecords.get(i).getIssueTime(); + lastCorrectedRecord = i; + } + } + } + pf.setStationElevation((float)lUairRecords.get(lastCorrectedRecord).getSelv()); + pf.setStationId(lUairRecords.get(lastCorrectedRecord).getStationId()); + if(lUairRecords.get(lastCorrectedRecord).getStationNumber()!= null && lUairRecords.get(lastCorrectedRecord).getStationNumber().length() >0){ + //System.out.println("stn num = "+ lUairRecords.get(lastCorrectedRecord).getStationNumber()); + pf.setStationNum(Integer.parseInt(lUairRecords.get(lastCorrectedRecord).getStationNumber())); + }else{ + pf.setStationNum(-1); + } + pf.setStationLatitude((float)lUairRecords.get(lastCorrectedRecord).getSlat()); + pf.setStationLongitude((float)lUairRecords.get(lastCorrectedRecord).getSlon()); + //System.out.println("stn elevation ="+ pf.getStationElevation() ); - int lastCorrectedRecord = 0; - String currentCorInd = ""; - if (lUairRecords.size() > 1) { -// for (int i = 0; i < lUairRecords.size(); i++) { -// // Since we are using lat/lon/refTime to query uair -// // table. We may have several records returned for -// // one query. It indicates there is a correction -// // report, then we should use the newest one report. -// // we compare corIndicator to find the latest -// // record. -// -// if (lUairRecords.get(i).getCorIndicator() != null -// && currentCorInd.compareTo(lUairRecords -// .get(i).getCorIndicator()) < 0) { -// currentCorInd = lUairRecords.get(i) -// .getCorIndicator(); -// lastCorrectedRecord = i; -// } -// } - lUairRecords = UAObs.sortByCorrection(lUairRecords); - } - UAObs uairRecord = lUairRecords.get(0); - pf.setStationLatitude((float) uairRecord.getLatitude()); - pf.setStationLongitude((float) uairRecord.getLongitude()); - pf.setStationElevation((float) uairRecord.getElevation()); - if (uairRecord.getStationId() != null - && uairRecord.getStationId().length() > 0) - pf.setStationNum(Integer.parseInt(uairRecord - .getStationId())); - pf.setStationId(uairRecord.getStationName()); - int hdfIndex = uairRecord.getIdx(); - if (hdfIndex >= 0) { - // System.out.println("selected stn lon= " + lon + - // " lat = "+ lat + " elv = "+ pf.getStationElevation() - // + " h5 table Y index ="+ hdfIndex); - BufrUADao uadao = new BufrUADao("bufrua"); - uairRecord.setPluginName("bufrua"); - File hdf5loc = uadao.getFullFilePath(uairRecord); - // System.out.println("hdf5 path = " + - // hdf5loc.getAbsolutePath()); - IDataStore dataStore = DataStoreFactory - .getDataStore(hdf5loc); + if((lUairRecords.get(lastCorrectedRecord).getObsLevels().size()>0) && + !dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString()) && + !dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString()) && + !dataType.equals(NcSoundingLayer.DataType.MAXWIND_C.toString()) && + !dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_C.toString())){ + //*System.out.println("getting "+ dataType); - FloatDataRecord sfcPressurefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "sfcPressure", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] sfcPressuredata = sfcPressurefloatData - .getFloatData(); - if (sfcPressuredata.length > 0) - pf.setSfcPress(sfcPressuredata[0] / 100F); + java.util.Iterator it=lUairRecords.get(lastCorrectedRecord).getObsLevels().iterator(); + while(it.hasNext()) + { + ObsLevels value=(ObsLevels)it.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setGeoHeight(value.getGeoHeight()); + soundingLy.setTemperature(value.getTemp()); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + } + soundingLy.setDewpoint(value.getDwpt()); + // System.out.println("pressure :"+value.getPressure() + " temp:" + value.getTemp() + " H:"+value.getGeoHeight() + " D:" + + // value.getWindDirection() + " F: " + value.getWindSpeed()); + soundLyLst.add(soundingLy); + } + } + else if(lUairRecords.get(lastCorrectedRecord).getMaxWind().size() >0 && + (dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString())|| + dataType.equals(NcSoundingLayer.DataType.MAXWIND_C.toString()))){ + //*System.out.println("getting "+ dataType); + java.util.Iterator itWind=lUairRecords.get(lastCorrectedRecord).getMaxWind().iterator(); - NcSoundingLayer soundingLy; - // based on requested data type: - // get temp, dew point, pressure, wind u/v components, - // and height - // they are 2-D tables - if (dataType.equals(NcSoundingLayer.DataType.TTAA - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.TTCC - .toString())) { - // get mandatory data size - IntegerDataRecord numManIntData = (IntegerDataRecord) dataStore - .retrieve( - "/", - "numMand", - Request.buildYLineRequest(new int[] { hdfIndex })); - int[] sizes = numManIntData.getIntData(); - // sizes is a 1x1 2d table. Only first (0) element - // is valid. - if (sizes[0] > 0) { - FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "prMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] pressuredata = pressurefloatData - .getFloatData(); - FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tpMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] temperaturedata = temperaturefloatData - .getFloatData(); - FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tdMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] dewptdata = dewptfloatData - .getFloatData(); - FloatDataRecord windDfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wdMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windDdata = windDfloatData - .getFloatData(); - FloatDataRecord windSfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wsMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windSdata = windSfloatData - .getFloatData(); - FloatDataRecord htfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "htMan", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] htdata = htfloatData.getFloatData(); - for (int i = 0; i < sizes[0]; i++) { - soundingLy = new NcSoundingLayer(); - // if data is not available, dont convert it - // and just use default setting data - if (temperaturedata[i] != NcSoundingLayer.MISSING) - soundingLy - .setTemperature((float) kelvinToCelsius - .convert(temperaturedata[i])); - if (pressuredata[i] != NcSoundingLayer.MISSING) - soundingLy - .setPressure(pressuredata[i] / 100F); - if (windSdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) windSdata[i])); - soundingLy.setWindDirection(windDdata[i]); - if (dewptdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setDewpoint((float) kelvinToCelsius - .convert(dewptdata[i])); - soundingLy.setGeoHeight(htdata[i]); - soundLyList.add(soundingLy); - } - // debug - // for(NcSoundingLayer ly: soundLyList){ - // System.out.println("Mandatory "+ dataType + - // ":: Pre= "+ly.getPressure()+ " Dew= "+ - // ly.getDewpoint()+ " T= "+ ly.getTemperature() - // + " WS= " + ly.getWindSpeed() + " WD= " + - // ly.getWindDirection()); - // } - } else { - System.out - .println("Mandatory data is not available! request data tye is " - + dataType); - } - } else if (dataType - .equals(NcSoundingLayer.DataType.TTBB - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.TTDD - .toString())) { - // get significantT data size - IntegerDataRecord numSigtIntData = (IntegerDataRecord) dataStore - .retrieve( - "/", - "numSigT", - Request.buildYLineRequest(new int[] { hdfIndex })); - int[] sizes = numSigtIntData.getIntData(); - // sizes is a 1x1 2d table. Only first (0) element - // is valid. - if (sizes[0] > 0) { - FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "prSigT", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] pressuredata = pressurefloatData - .getFloatData(); - FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tpSigT", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] temperaturedata = temperaturefloatData - .getFloatData(); - FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tdSigT", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] dewptdata = dewptfloatData - .getFloatData(); - for (int i = 0; i < sizes[0]; i++) { - soundingLy = new NcSoundingLayer(); - // if data is not available, dont convert it - // and just use default setting data - if (temperaturedata[i] != NcSoundingLayer.MISSING) - soundingLy - .setTemperature((float) kelvinToCelsius - .convert(temperaturedata[i])); - if (pressuredata[i] != NcSoundingLayer.MISSING) - soundingLy - .setPressure(pressuredata[i] / 100F); - if (dewptdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setDewpoint((float) kelvinToCelsius - .convert(dewptdata[i])); - soundLyList.add(soundingLy); - } - // for(NcSoundingLayer ly: soundLyList){ - // System.out.println("SigT "+ dataType + - // ":: Pre= "+ly.getPressure()+ " Dew= "+ - // ly.getDewpoint()+ " T= "+ - // ly.getTemperature()); - // } - } else { - System.out - .println("SigT data is not available! request data tye is " - + dataType); - } + while(itWind.hasNext()) + { + MaxWind value=(MaxWind)itWind.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + } + //*System.out.println("WIND pressure :"+value.getPressure() + " WD:" + value.getWindDirection() + " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + soundLyLst.add(soundingLy); + } + } + else if(lUairRecords.get(lastCorrectedRecord).getTropopause().size() >0 && + (dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString())|| + dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_C.toString()))){ + //*System.out.println("getting "+ dataType); + java.util.Iterator it=lUairRecords.get(lastCorrectedRecord).getTropopause().iterator(); + while(it.hasNext()) + { + Tropopause value=(Tropopause)it.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setTemperature(value.getTemp()); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + //*System.out.println("Tropopause pressure :"+value.getPressure() + " temp:" + value.getTemp()+" WD:" + value.getWindDirection() + " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); - } else if (dataType - .equals(NcSoundingLayer.DataType.PPBB - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.PPDD - .toString())) { - // get significantW data size - IntegerDataRecord numSigwIntData = (IntegerDataRecord) dataStore - .retrieve( - "/", - "numSigW", - Request.buildYLineRequest(new int[] { hdfIndex })); - int[] sizes = numSigwIntData.getIntData(); - // sizes is a 1x1 2d table. Only first (0) element - // is valid. - if (sizes[0] > 0) { - FloatDataRecord htfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "htSigW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] htdata = htfloatData.getFloatData(); - FloatDataRecord windDfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wdSigW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windDdata = windDfloatData - .getFloatData(); - FloatDataRecord windSfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wsSigW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windSdata = windSfloatData - .getFloatData(); - for (int i = 0; i < sizes[0]; i++) { - soundingLy = new NcSoundingLayer(); - // if data is not available, dont convert it - // and just use default setting data - soundingLy.setGeoHeight(htdata[i]); - if (windSdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) windSdata[i])); - soundingLy.setWindDirection(windDdata[i]); - soundLyList.add(soundingLy); - } - // for(NcSoundingLayer ly: soundLyList){ - // System.out.println("SigW "+ dataType + - // ":: Ht= "+ly.getGeoHeight()+" WS= " + - // ly.getWindSpeed() + " WD= " + - // ly.getWindDirection()); - // } - } else { - System.out - .println("SigW data is not available! request data tye is " - + dataType); - } - } else if (dataType - .equals(NcSoundingLayer.DataType.MAXWIND_A - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.MAXWIND_C - .toString())) { - // get max wind data size - IntegerDataRecord numMwndIntData = (IntegerDataRecord) dataStore - .retrieve( - "/", - "numMwnd", - Request.buildYLineRequest(new int[] { hdfIndex })); - int[] sizes = numMwndIntData.getIntData(); - // sizes is a 1x1 2d table. Only first (0) element - // is valid. - if (sizes[0] > 0) { - FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "prMaxW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] pressuredata = pressurefloatData - .getFloatData(); - FloatDataRecord windDfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wdMaxW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windDdata = windDfloatData - .getFloatData(); - FloatDataRecord windSfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wsMaxW", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windSdata = windSfloatData - .getFloatData(); - for (int i = 0; i < sizes[0]; i++) { - soundingLy = new NcSoundingLayer(); - // if data is not available, dont convert it - // and just use default setting data - if (pressuredata[i] != NcSoundingLayer.MISSING) - soundingLy - .setPressure(pressuredata[i] / 100F); - if (windSdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) windSdata[i])); - soundingLy.setWindDirection(windDdata[i]); - soundLyList.add(soundingLy); - } - // for(NcSoundingLayer ly: soundLyList){ - // System.out.println("MAXwind "+ dataType + - // ":: Pre= "+ly.getPressure()+ " WS= " + - // ly.getWindSpeed() + " WD= " + - // ly.getWindDirection()); - // } - } else { - System.out - .println("max wind data is not available! request data tye is " - + dataType); - } - } else if (dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_A - .toString()) - || dataType - .equals(NcSoundingLayer.DataType.TROPOPAUSE_C - .toString())) { - // get troppause data size - IntegerDataRecord numTropIntData = (IntegerDataRecord) dataStore - .retrieve( - "/", - "numTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - int[] sizes = numTropIntData.getIntData(); - // sizes is a 1x1 2d table. Only first (0) element - // is valid. - if (sizes[0] > 0) { - FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "prTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] pressuredata = pressurefloatData - .getFloatData(); - FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tpTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] temperaturedata = temperaturefloatData - .getFloatData(); - FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "tdTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] dewptdata = dewptfloatData - .getFloatData(); - FloatDataRecord windDfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wdTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windDdata = windDfloatData - .getFloatData(); - FloatDataRecord windSfloatData = (FloatDataRecord) dataStore - .retrieve( - "/", - "wsTrop", - Request.buildYLineRequest(new int[] { hdfIndex })); - float[] windSdata = windSfloatData - .getFloatData(); - for (int i = 0; i < sizes[0]; i++) { - soundingLy = new NcSoundingLayer(); - // if data is not available, dont convert it - // and just use default setting data - if (temperaturedata[i] != NcSoundingLayer.MISSING) - soundingLy - .setTemperature((float) kelvinToCelsius - .convert(temperaturedata[i])); - if (pressuredata[i] != NcSoundingLayer.MISSING) - soundingLy - .setPressure(pressuredata[i] / 100F); - if (windSdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setWindSpeed((float) metersPerSecondToKnots - .convert((float) windSdata[i])); - soundingLy.setWindDirection(windDdata[i]); - if (dewptdata[i] != NcSoundingLayer.MISSING) - soundingLy - .setDewpoint((float) kelvinToCelsius - .convert(dewptdata[i])); - soundLyList.add(soundingLy); - } - // debug - // for(NcSoundingLayer ly: soundLyList){ - // System.out.println("Troppause "+ dataType + - // ":: Pre= "+ly.getPressure()+ " Dew= "+ - // ly.getDewpoint()+ " T= "+ ly.getTemperature() - // + " WS= " + ly.getWindSpeed() + " WD= " + - // ly.getWindDirection()); - // } - } else { - System.out - .println("Troppause data is not available! request data tye is " - + dataType); - } - } + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + //*System.out.println("Tropopause pressure :"+value.getPressure() + " temp:" + value.getTemp()+" WD:" + value.getWindDirection() + " WS:"+(float)value.getWindSpeed()); - } else { - System.out - .println("hdf5 index (idx) is less than 0!!!"); - return pf; - } - } else { - System.out - .println("buffrua (UAOb) record is not available!! request type " - + dataType); - return pf; - } + } + soundingLy.setDewpoint(value.getDwpt()); + soundLyLst.add(soundingLy); + } + } + } - } catch (Exception e) { - // *System.out.println("exception=" + e ); - e.printStackTrace(); - return pf; - } - // *System.out.println("sounding layer size = "+ - // soundLyList.size()); + } catch (DataAccessLayerException e) { + //*System.out.println("obs sounding query exception"); + //e.printStackTrace(); + } + } - pf.setSoundingLyLst(soundLyList); + }//end ObsSndType.UAIR +*/ + + pf.setSoundingLyLst(soundLyLst); + return pf; + + } - return pf; - /* - * List soundLyList = new - * ArrayList(); UAObs uaRecord = new UAObs(); - * uaRecord.setPluginName("bufrua"); - * - * - * - * // refTimeCal = - * Calendar.getInstance(TimeZone.getTimeZone("GMT")); // for testing - * ...refTimeCal.setTimeInMillis(1276581600000L); - * - * //refTimeCal.setTimeInMillis(refTime.getTime()); DataTime - * refTimeDataTime = new DataTime(refTimeCal); - * uaRecord.setDataTime(refTimeDataTime); - * - * // for testing ... validTime = new Timestamp(1277013600000L); - * //validTime.setTime(1277013600000L); - * - * try { BufrUADao uadao = new BufrUADao("bufrua"); File hdf5loc = - * uadao.getFullFilePath(lUairRecords.get(0)); - * System.out.println("hdf5 path = " + hdf5loc.getAbsolutePath()); - * IDataStore dataStore = DataStoreFactory.getDataStore(hdf5loc); - * - * try { LongDataRecord longData = (LongDataRecord) - * dataStore.retrieve( "/", "validTime", Request.ALL); long[] - * validtimedata = longData.getLongData(); - * - * FloatDataRecord latfloatData = (FloatDataRecord) - * dataStore.retrieve( "/", "latitude", Request.ALL); float[] - * latdata = latfloatData.getFloatData(); - * - * FloatDataRecord lonfloatData = (FloatDataRecord) - * dataStore.retrieve( "/", "longitude", Request.ALL); float[] - * londata = lonfloatData.getFloatData(); - * - * FloatDataRecord elvfloatData = (FloatDataRecord) - * dataStore.retrieve( "/", "staElev", Request.ALL); float[] elvdata - * = elvfloatData.getFloatData(); - * - * StringDataRecord stnIdStrData = (StringDataRecord) - * dataStore.retrieve( "/", "staName", Request.ALL); String[] - * stnIddata = stnIdStrData.getStringData(); - * - * IntegerDataRecord stnNumIntData = (IntegerDataRecord) - * dataStore.retrieve( "/", "wmoStaNum", Request.ALL); int[] - * stnNumdata = stnNumIntData.getIntData(); - * - * IntegerDataRecord rptIntData = (IntegerDataRecord) - * dataStore.retrieve( "/", "rptType", Request.ALL); int[] rptData = - * rptIntData.getIntData(); - * - * int selectedTimeIndex=-1; - * - * for (int j=0; j0) - * pf.setSfcPress(sfcPressuredata[0]/100F); - * - * NcSoundingLayer soundingLy; - * - * // get temp, dew point, pressure, wind u/v components, and height - * //they are 2-D tables FloatDataRecord pressurefloatData = - * (FloatDataRecord) dataStore.retrieve( "/", "prMan", - * Request.buildYLineRequest(new int[] {selectedTimeIndex})); - * float[] pressuredata = pressurefloatData.getFloatData(); - * FloatDataRecord temperaturefloatData = (FloatDataRecord) - * dataStore.retrieve( "/", "tpMan", Request.buildYLineRequest(new - * int[] {selectedTimeIndex})); float[] temperaturedata = - * temperaturefloatData.getFloatData(); FloatDataRecord - * dewptfloatData = (FloatDataRecord) dataStore.retrieve( "/", - * "tdMan", Request.buildYLineRequest(new int[] - * {selectedTimeIndex})); float[] dewptdata = - * dewptfloatData.getFloatData(); FloatDataRecord windDfloatData = - * (FloatDataRecord) dataStore.retrieve( "/", "wdMan", - * Request.buildYLineRequest(new int[] {selectedTimeIndex})); - * float[] windDdata = windDfloatData.getFloatData(); - * FloatDataRecord windSfloatData = (FloatDataRecord) - * dataStore.retrieve( "/", "wsMan", Request.buildYLineRequest(new - * int[] {selectedTimeIndex})); float[] windSdata = - * windSfloatData.getFloatData(); FloatDataRecord htfloatData = - * (FloatDataRecord) dataStore.retrieve( "/", "htMan", - * Request.buildYLineRequest(new int[] {selectedTimeIndex})); - * float[] htdata = htfloatData.getFloatData(); long[] sizes = - * pressurefloatData.getSizes(); //int dim = - * pressurefloatData.getDimension(); for (int i=0; i soundLyLst = new ArrayList(); + NcSoundingLayer soundingLy; + soundLyLst.clear(); + + obType = ObsSndType.UAIR.toString(); // currently assume all uair sounding type + if(obType.equals(ObsSndType.UAIR.toString())){ + //*System.out.println("parentIds length = " + parentIds.length ); + for(int i=0; i fields = new ArrayList(); + List values = new ArrayList(); + List lObsLevels = null; + fields.add("id");// the record id field name defined in UairRecord + values.add(id); //testing 994872); + if(!dataType.equals(NcSoundingLayer.DataType.ALLDATA.toString()) && + !dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString()) && + !dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString())){ + fields.add("dataType");// the record dataType field name defined in UairRecord + values.add(dataType); //testing "TTAA" - } - } + } + CoreDao dao = new CoreDao(DaoConfig.forClass(UairRecord.class)); + try { + lObsLevels = (List) dao.queryByCriteria(fields, values); + if(lObsLevels.size() > 0){ + //since we are using Records id to query uair table. lObsLevels.size() should always be one. + //*System.out.println("size of uairrecord " + lObsLevels.size()); + //*System.out.println("id ="+lObsLevels.get(0).getId() + " datauri=" +lObsLevels.get(0).getDataURI()); + //*System.out.println("size of ObsLevels ="+lObsLevels.get(0).getObsLevels().size() ); + //*System.out.println("size of maxWind ="+lObsLevels.get(0).getMaxWind().size() ); + //*System.out.println("size of Tropopause ="+lObsLevels.get(0).getTropopause().size() ); + if((lObsLevels.get(0).getObsLevels().size()>0) && + !dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString()) && + !dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString())){ + java.util.Iterator it=lObsLevels.get(0).getObsLevels().iterator(); + while(it.hasNext()) + { + ObsLevels value=(ObsLevels)it.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setGeoHeight(value.getGeoHeight()); + soundingLy.setTemperature(value.getTemp()); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + } + soundingLy.setDewpoint(value.getDwpt()); + //*System.out.println("pressure :"+value.getPressure() + " temp:" + value.getTemp() + " H:"+value.getGeoHeight() ); + soundLyLst.add(soundingLy); + } + } + } + + if(lObsLevels.get(0).getMaxWind().size() >0 && + !dataType.equals(NcSoundingLayer.DataType.TROPOPAUSE_A.toString())){ + java.util.Iterator itWind=lObsLevels.get(0).getMaxWind().iterator(); + + while(itWind.hasNext()) + { + MaxWind value=(MaxWind)itWind.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + } + + soundLyLst.add(soundingLy); + } + } + + if(lObsLevels.get(0).getTropopause().size() >0 && + !dataType.equals(NcSoundingLayer.DataType.MAXWIND_A.toString())){ + java.util.Iterator it=lObsLevels.get(0).getTropopause().iterator(); + while(it.hasNext()) + { + Tropopause value=(Tropopause)it.next(); + soundingLy = new NcSoundingLayer(); + soundingLy.setTemperature(value.getTemp()); + soundingLy.setPressure(value.getPressure()); + soundingLy.setWindDirection(value.getWindDirection()); + if ( value.getWindSpeed() != NcSoundingLayer.MISSING ) { + soundingLy.setWindSpeed((float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + //*System.out.println("Tropopause pressure :"+value.getPressure() + " temp:" + value.getTemp()+" WD:" + value.getWindDirection() + " WS:"+(float)metersPerSecondToKnots.convert((float)value.getWindSpeed())); + + } else { + soundingLy.setWindSpeed((float)value.getWindSpeed()); + //*System.out.println("Tropopause pressure :"+value.getPressure() + " temp:" + value.getTemp()+" WD:" + value.getWindDirection() + " WS:"+(float)value.getWindSpeed()); + + } + + soundingLy.setDewpoint(value.getDwpt()); + + soundLyLst.add(soundingLy); + + } + } + } catch (DataAccessLayerException e) { + //*System.out.println("obs sounding query exception"); + //e.printStackTrace(); + } + + } + } + pf.setSoundingLyLst(soundLyLst); + return pf; + + } + */ + /* + * this api is provided for applications and for testing to retrieve observed bufruair data from PostgreSql DB & HDF5 + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support "ALLDATA" data type only + */ + public static NcSoundingProfile getObservedSndBufruaAllData(Double lat, Double lon, String stn, long refTimeL, SndQueryKeyType queryType){ + Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // for testing ...refTimeCal.setTimeInMillis(1276581600000L); + //refTimeCal.setTimeInMillis(refTime.getTime()); + refTimeCal.setTimeInMillis(refTimeL); + return getObservedSndBufruaAllData(lat, lon, stn, refTimeCal, queryType); + } + + /* + * this api is provided for applications and for testing to retrieve observed bufruair data from PostgreSql DB & HDF5 + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support "ALLDATA" data type only + */ + public static NcSoundingProfile getObservedSndBufruaAllData(Double lat, Double lon, String stn, Calendar refTimeCal, SndQueryKeyType queryType){ + NcSoundingProfile pfAll= new NcSoundingProfile(); + List soundingLyLst, finalsoundingLyLst; + NcSoundingProfile pf = getObservedSndBufruaData(lat, lon, stn, refTimeCal, "TTAA", queryType); + pfAll.setStationElevation(pf.getStationElevation()); + finalsoundingLyLst = pf.getSoundingLyLst(); + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "TTBB", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "TTCC", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "TTDD", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + //soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "PPAA", queryType).getSoundingLyLst(); + //if (soundingLyLst.size() >= 0){ + // finalsoundingLyLst.addAll(soundingLyLst); + //} + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "PPBB", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + //soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "PPCC", queryType).getSoundingLyLst(); + //if (soundingLyLst.size() >= 0){ + // finalsoundingLyLst.addAll(soundingLyLst); + //} + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "PPDD", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon,stn, refTimeCal, "MAXWIND_A", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "MAXWIND_C", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "TROPOPAUSE_A", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + soundingLyLst = getObservedSndBufruaData(lat, lon, stn,refTimeCal, "TROPOPAUSE_C", queryType).getSoundingLyLst(); + if (soundingLyLst.size() >= 0){ + finalsoundingLyLst.addAll(soundingLyLst); + } + pfAll.setSoundingLyLst(finalsoundingLyLst); + return pfAll; + } + + /* + * this api is provided for applications and for testing to retrieve observed BufrUA data from PostgreSql DB and HDF5 + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support all dataType except "ALLDATA" data type + * using either lat/lon, stnId or stnNum and validTime as key + * refTime is with unit of msec as input + */ + public static NcSoundingProfile getObservedSndBufruaData(Double lat, Double lon,String stn, long refTimeL, String dataType, SndQueryKeyType queryType){ + Calendar refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // for testing ...refTimeCal.setTimeInMillis(1276581600000L); + //refTimeCal.setTimeInMillis(refTime.getTime()); + refTimeCal.setTimeInMillis(refTimeL); + return getObservedSndBufruaData(lat, lon, stn, refTimeCal, dataType, queryType); + } + + /* + * This API is provided for retrieving bufrUA data from PostgresSQL and HDF5 + * dataType should use "enum DataType" defined in NcSoundingLayer.java + * Support all dataType except "ALLDATA" data type + * using either lat/lon, stnId or stnNum and synopticTime as key + * reference time is with Calendar data type as input + */ + @SuppressWarnings("unchecked") + public static NcSoundingProfile getObservedSndBufruaData(Double lat, Double lon, String stn, Calendar refTimeCal, String dataType,SndQueryKeyType queryType){ + //*System.out.println("getObservedSndBufruaData lat= " + lat+" lon="+lon+" refTime="+refTimeCal ); + //Timestamp refTime = new Timestamp(refTimeL); + //System.out.println("GMT ref time = "+ refTime.toGMTString()); + NcSoundingProfile pf = new NcSoundingProfile(); + List soundLyList = new ArrayList(); + if(dataType.equals(NcSoundingLayer.DataType.ALLDATA.toString())){ + //*System.out.println("request all data is not supported in this API"); + return pf; + } + else { + List fields = new ArrayList(); + List values = new ArrayList(); + List lUairRecords = null; + if(queryType==SndQueryKeyType.STNID){ + fields.add("stationName");// the stationName String field name defined in UAObs, dont be confused with UAIRRecord definition + values.add(stn); + } + else if(queryType==SndQueryKeyType.STNNUM){ + fields.add("location.stationId");// the location.stationId String field name defined in UAObs. dont be confused with UAIRRecord definition + values.add(stn); + } + else if(queryType==SndQueryKeyType.LATLON){ + fields.add("location.latitude");// the location.latitude field name defined in UAObs + values.add(lat); + fields.add("location.longitude");// the location.longitude field name defined in UAObs + values.add(lon); + + } + else { + System.out.println("request query type "+ queryType+ " is not supported in this API" ); + return pf; + } + fields.add("dataTime.refTime");// the synoptic time field name defined in UAObs + //fields.add("validTime");// the synoptic time field name defined in UAObs + values.add(refTimeCal.getTime()); + fields.add("reportType");// the record dataType field name defined in UAObs + int intDataType = NcSoundingLayer.dataTypeMap.get(dataType); + values.add(intDataType); + + //for (int i=0; i < fields.size(); i++) { + // System.out.println("field "+ fields.get(i) + " value "+ values.get(i)); + //} + CoreDao dao = new CoreDao(DaoConfig.forClass(UAObs.class)); + try { + lUairRecords = (List) dao.queryByCriteria(fields, values); + if(lUairRecords.size() > 0){ + //set pf data + //System.out.println("record size = "+ lUairRecords.size() + " reportType="+dataType); + + int lastCorrectedRecord=0; + String currentCorInd = ""; + + if(lUairRecords.size() > 1){ + for(int i=0; i< lUairRecords.size(); i++){ + //Since we are using lat/lon/refTime to query uair table. We may have several records returned for + // one query. It indicates there is a correction report, then we should use the newest one report. + // we compare corIndicator to find the latest record. + + if(lUairRecords.get(i).getCorIndicator()!= null && currentCorInd.compareTo(lUairRecords.get(i).getCorIndicator()) < 0){ + currentCorInd = lUairRecords.get(i).getCorIndicator(); + lastCorrectedRecord = i; + } + } + } + UAObs uairRecord = lUairRecords.get(lastCorrectedRecord); + pf.setStationLatitude((float)uairRecord.getLatitude()); + pf.setStationLongitude((float)uairRecord.getLongitude()); + pf.setStationElevation((float)uairRecord.getElevation()); + if(uairRecord.getStationId()!= null && uairRecord.getStationId().length()>0) + pf.setStationNum(Integer.parseInt(uairRecord.getStationId())); + pf.setStationId(uairRecord.getStationName()); + int hdfIndex = uairRecord.getIdx(); + if(hdfIndex >= 0) { + //System.out.println("selected stn lon= " + lon + + // " lat = "+ lat + " elv = "+ pf.getStationElevation() + " h5 table Y index ="+ hdfIndex); + BufrUADao uadao = new BufrUADao("bufrua"); + uairRecord.setPluginName("bufrua"); + File hdf5loc = uadao.getFullFilePath(uairRecord); + //System.out.println("hdf5 path = " + hdf5loc.getAbsolutePath()); + IDataStore dataStore = DataStoreFactory.getDataStore(hdf5loc); + + FloatDataRecord sfcPressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "sfcPressure", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] sfcPressuredata = sfcPressurefloatData.getFloatData(); + if(sfcPressuredata.length>0) + pf.setSfcPress(sfcPressuredata[0]/100F); + + NcSoundingLayer soundingLy; + //based on requested data type: + // get temp, dew point, pressure, wind u/v components, and height + //they are 2-D tables + if(dataType.equals(NcSoundingLayer.DataType.TTAA.toString()) || + dataType.equals(NcSoundingLayer.DataType.TTCC.toString())) + { + //get mandatory data size + IntegerDataRecord numManIntData = (IntegerDataRecord) dataStore.retrieve( + "/", "numMand", Request.buildYLineRequest(new int[] {hdfIndex})); + int[] sizes = numManIntData.getIntData(); + // sizes is a 1x1 2d table. Only first (0) element is valid. + if(sizes[0] >0){ + FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "prMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] pressuredata = pressurefloatData.getFloatData(); + FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tpMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] temperaturedata = temperaturefloatData.getFloatData(); + FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tdMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] dewptdata = dewptfloatData.getFloatData(); + FloatDataRecord windDfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wdMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windDdata = windDfloatData.getFloatData(); + FloatDataRecord windSfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wsMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windSdata = windSfloatData.getFloatData(); + FloatDataRecord htfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "htMan", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] htdata = htfloatData.getFloatData(); + for (int i=0; i0){ + FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "prSigT", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] pressuredata = pressurefloatData.getFloatData(); + FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tpSigT", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] temperaturedata = temperaturefloatData.getFloatData(); + FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tdSigT", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] dewptdata = dewptfloatData.getFloatData(); + for (int i=0; i0){ + FloatDataRecord htfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "htSigW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] htdata = htfloatData.getFloatData(); + FloatDataRecord windDfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wdSigW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windDdata = windDfloatData.getFloatData(); + FloatDataRecord windSfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wsSigW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windSdata = windSfloatData.getFloatData(); + for (int i=0; i0){ + FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "prMaxW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] pressuredata = pressurefloatData.getFloatData(); + FloatDataRecord windDfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wdMaxW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windDdata = windDfloatData.getFloatData(); + FloatDataRecord windSfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wsMaxW", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windSdata = windSfloatData.getFloatData(); + for (int i=0; i0){ + FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "prTrop", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] pressuredata = pressurefloatData.getFloatData(); + FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tpTrop", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] temperaturedata = temperaturefloatData.getFloatData(); + FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tdTrop", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] dewptdata = dewptfloatData.getFloatData(); + FloatDataRecord windDfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wdTrop", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windDdata = windDfloatData.getFloatData(); + FloatDataRecord windSfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wsTrop", Request.buildYLineRequest(new int[] {hdfIndex})); + float[] windSdata = windSfloatData.getFloatData(); + for (int i=0; i0) + pf.setSfcPress(sfcPressuredata[0]/100F); + + NcSoundingLayer soundingLy; + + // get temp, dew point, pressure, wind u/v components, and height + //they are 2-D tables + FloatDataRecord pressurefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "prMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] pressuredata = pressurefloatData.getFloatData(); + FloatDataRecord temperaturefloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tpMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] temperaturedata = temperaturefloatData.getFloatData(); + FloatDataRecord dewptfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "tdMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] dewptdata = dewptfloatData.getFloatData(); + FloatDataRecord windDfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wdMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] windDdata = windDfloatData.getFloatData(); + FloatDataRecord windSfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "wsMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] windSdata = windSfloatData.getFloatData(); + FloatDataRecord htfloatData = (FloatDataRecord) dataStore.retrieve( + "/", "htMan", Request.buildYLineRequest(new int[] {selectedTimeIndex})); + float[] htdata = htfloatData.getFloatData(); + long[] sizes = pressurefloatData.getSizes(); + //int dim = pressurefloatData.getDimension(); + for (int i=0; i 0){ double lat, lon, elv; //System.out.println("queryAndMarkStn called mapresource = "+ nsharpMapResource.toString()); @@ -336,14 +336,14 @@ public class PfcSoundingQuery { soundingLy.setSpecHumidity(specHumdata[i]); soundLyList.add(soundingLy); } - System.out.println("sounding layer size = "+ soundLyList.size()); + //System.out.println("sounding layer size = "+ soundLyList.size()); //debug - int k=1; - for(NcSoundingLayer lvl: soundLyList){ - System.out.println("Sounding Level "+ k + " pres="+lvl.getPressure()+ " temp="+ - lvl.getTemperature()+ " u="+lvl.getWindU() + " SH="+ lvl.getSpecHumidity()); - k++; - } + //int k=1; + //for(NcSoundingLayer lvl: soundLyList){ + // System.out.println("Sounding Level "+ k + " pres="+lvl.getPressure()+ " temp="+ + // lvl.getTemperature()+ " u="+lvl.getWindU() + " SH="+ lvl.getSpecHumidity()); + // k++; + //} } } @@ -652,7 +652,7 @@ public class PfcSoundingQuery { soundingLy.setSpecHumidity(level.getSpecificHumidity().floatValue()); soundLyList.add(soundingLy); } - System.out.println("sounding layer size = "+ soundLyList.size()); + //System.out.println("sounding layer size = "+ soundLyList.size()); //debug //for(NcSoundingLayer ly: soundLyList){ //*System.out.println("P= "+ly.getPressure()+ " Hm= "+ ly.getSpecHumidity()+ " T= "+ ly.getTemperature()); @@ -678,8 +678,8 @@ public class PfcSoundingQuery { k++; }*/ pf.setSoundingLyLst(soundLyList); - long t02 = System.currentTimeMillis(); - System.out.println("getPfcSndData2 PFC profile retreival took " + (t02 - t01)); + //long t02 = System.currentTimeMillis(); + //System.out.println("getPfcSndData2 PFC profile retreival took " + (t02 - t01)); return pf; } private static Comparator reversePressureComparator() { diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py b/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py index 6353aa13c8..0570f0c596 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py @@ -76,9 +76,11 @@ class NcSoundingDataRequest(): def makeResponse(self): - return ResponseMessageGeneric(self.result) +# print 'Before calling the constructor for ResponseMessageGeneric with NcSoundingCube' + return ResponseMessageGeneric(self.result) def makeNullResponse(self): +# print 'from makeNullResponse' return ResponseMessageGeneric("No data is available") @@ -130,6 +132,40 @@ class NcSoundingDataRequest(): return self.makeNullResponse() else: return self.makeResponse() + + def getSoundingLayer2DataByLatLonArray(self, LatLonArr): +# print'from NcSoundingDataRequest.getSoundingLayer2DataByLatLonArray' + self.NcSoundingDrv.setQueryType("LATLON") + from jep import jarray, JFLOAT_ID + jA = jarray(len(LatLonArr), JFLOAT_ID) + for i in range(len(LatLonArr)): + jA[i] = float(LatLonArr[i]) + self.NcSoundingDrv.setLatLons(jA) +# print'just before calling self.NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray()' + self.result = self.NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray() + if self.result is None: +# print 'unable to get the sounding cube back' + return self.makeNullResponse() + else: +# print 'Got the sounding cube back' + return self.makeResponse() + + def getSoundingLayer2DataByLatLonArray1(self, LatLonArr): +# This method calling per station base algorithm. It is not used for production. + self.NcSoundingDrv.setQueryType("LATLON") + from jep import jarray, JFLOAT_ID + jA = jarray(len(LatLonArr), JFLOAT_ID) + for i in range(len(LatLonArr)): + jA[i] = float(LatLonArr[i]) + self.NcSoundingDrv.setLatLons(jA) +# print'just before calling self.NcSoundingDrv.getSoundingLayer2DataUsingLatLonArray()' + self.result = self.NcSoundingDrv.getSoundingLayer2DataUsingLatLonArrayPerStn() + if self.result is None: +# print 'unable to get the sounding cube back' + return self.makeNullResponse() + else: +# print 'Got the sounding cube back' + return self.makeResponse() def getSoundingDataByStnIdArray(self, StnIdArr): self.NcSoundingDrv.setQueryType("STNID") @@ -204,4 +240,4 @@ class NcSoundingDataRequest(): return self.makeNullResponse() else: return self.makeResponse() - + \ No newline at end of file