Merge branch 'unidata_18.2.1' of github.com:Unidata/awips2 into docChanges
This commit is contained in:
commit
a9c71e58f6
4 changed files with 106 additions and 139 deletions
|
@ -1,3 +1,2 @@
|
|||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
utility/
|
||||
|
|
|
@ -2,5 +2,4 @@ source.. = src/
|
|||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
res/,\
|
||||
utility/
|
||||
res/
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
/**
|
||||
* 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 com.raytheon.uf.edex.plugin.modelsounding.decoder;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -26,12 +27,11 @@ import com.raytheon.uf.common.dataplugin.modelsounding.SoundingLevel;
|
|||
import com.raytheon.uf.common.dataplugin.modelsounding.SoundingSite;
|
||||
import com.raytheon.uf.common.geospatial.spi.SPIContainer;
|
||||
import com.raytheon.uf.common.geospatial.spi.SPIEntry;
|
||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
||||
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.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationUtil;
|
||||
import com.raytheon.uf.common.localization.PathManager;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.pointdata.PointDataContainer;
|
||||
import com.raytheon.uf.common.pointdata.PointDataDescription;
|
||||
|
@ -43,6 +43,7 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
import com.raytheon.uf.common.wmo.WMOHeader;
|
||||
import com.raytheon.uf.edex.bufrtools.BUFRDataDocument;
|
||||
import com.raytheon.uf.edex.bufrtools.descriptors.BUFRDescriptor;
|
||||
import com.raytheon.uf.edex.bufrtools.packets.BUFRStringPacket;
|
||||
import com.raytheon.uf.edex.bufrtools.packets.BUFRSublistPacket;
|
||||
import com.raytheon.uf.edex.bufrtools.packets.DataPacketTypes;
|
||||
import com.raytheon.uf.edex.bufrtools.packets.IBUFRDataPacket;
|
||||
|
@ -53,7 +54,7 @@ import com.raytheon.uf.edex.plugin.modelsounding.common.SoundingModels;
|
|||
/**
|
||||
* This class contains several utility methods that construct a ProfilerObs
|
||||
* instance from the BUFR decoded data.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
|
@ -68,11 +69,13 @@ import com.raytheon.uf.edex.plugin.modelsounding.common.SoundingModels;
|
|||
* Sep 16, 2014 3628 mapeters Replaced static imports.
|
||||
* Jul 12, 2016 5744 mapeters SoundingStations constructor no longer takes
|
||||
* path parameter
|
||||
* Jan 04, 2018 7100 dgilling Code cleanup, read SPI file from
|
||||
* CONFIGURED level.
|
||||
*
|
||||
* Sep 05, 2018 mjames@ucar Remove modelBufr filter.
|
||||
*
|
||||
* May 19, 2021 22629 mgamazaychikov Fixed the header issue for GFS v16 update
|
||||
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author jkorman
|
||||
*/
|
||||
public class ModelSoundingDataAdapter {
|
||||
|
@ -82,48 +85,13 @@ public class ModelSoundingDataAdapter {
|
|||
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
public static final String SPI_FILE = LocalizationUtil.join("basemaps",
|
||||
"modelBufr.spi");
|
||||
|
||||
public static final String MODEL_STATION_LIST_FILENAME = "modelBufrStationList.txt";
|
||||
|
||||
public static final String MODEL_STATION_LIST_PATH = LocalizationUtil
|
||||
.join("modelsounding", MODEL_STATION_LIST_FILENAME);
|
||||
public static final String MODEL_STATION_LIST = "modelBufrStationList.txt";
|
||||
|
||||
private static SoundingStations stationsList = new SoundingStations();
|
||||
|
||||
private static SPIContainer SPI_DATA = populateSPIData();
|
||||
|
||||
public static void updateSPIData() {
|
||||
SPIContainer spi = populateSPIData();
|
||||
synchronized (LOCK) {
|
||||
if ((spi != null) && (spi.isLoaded())) {
|
||||
SPI_DATA = spi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateStationList() {
|
||||
SoundingStations ss = new SoundingStations();
|
||||
synchronized (LOCK) {
|
||||
stationsList = ss;
|
||||
}
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
SoundingStations ss = new SoundingStations();
|
||||
SPIContainer spi = populateSPIData();
|
||||
synchronized (LOCK) {
|
||||
stationsList = ss;
|
||||
if ((spi != null) && (spi.isLoaded())) {
|
||||
SPI_DATA = spi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the temporal and model information.
|
||||
*
|
||||
*
|
||||
* @param dataDoc
|
||||
* @param wmoHeader
|
||||
* @return
|
||||
|
@ -169,7 +137,7 @@ public class ModelSoundingDataAdapter {
|
|||
/**
|
||||
* Construct a ProfilerObs instance from the BUFR decoded data contained in
|
||||
* the specified separator.
|
||||
*
|
||||
*
|
||||
* @param iterator
|
||||
* A iterator containing decoded BUFR data.
|
||||
* @param wmoHeader
|
||||
|
@ -223,7 +191,7 @@ public class ModelSoundingDataAdapter {
|
|||
|
||||
/**
|
||||
* Extract all header data from the "main" observation list.
|
||||
*
|
||||
*
|
||||
* @param dataList
|
||||
* List of data packets to get data from.
|
||||
* @return The ProfilerObs with primary data populated.
|
||||
|
@ -241,57 +209,57 @@ public class ModelSoundingDataAdapter {
|
|||
obsData = new SoundingSite();
|
||||
SurfaceObsLocation location = new SurfaceObsLocation();
|
||||
|
||||
IBUFRDataPacket dp = dataList.get(index);
|
||||
index++;
|
||||
IBUFRDataPacket dp = dataList.get(index++);
|
||||
/*
|
||||
* dp is forecastHr packet, already handled in
|
||||
* SoundingModelTemporalData
|
||||
*/
|
||||
|
||||
int wmoStaNum = getInt(dataList.get(index), -9999);
|
||||
index++;
|
||||
int wmoStaNum = getInt(dataList.get(index++), -9999);
|
||||
view.setInt("wmoStaNum", wmoStaNum);
|
||||
// Map the WMO station number to a station Id
|
||||
String stationId = stationsList.mapId(String.format("%010d",
|
||||
wmoStaNum));
|
||||
// Now determine if the station Id is in this localization list.
|
||||
SPIEntry s = SPI_DATA.getEntryById(stationId);
|
||||
if (s != null) {
|
||||
if (stationId != null) {
|
||||
location.setStationId(stationId);
|
||||
obsData.setSiteId(String.format("%06d", wmoStaNum));
|
||||
}
|
||||
if (model.equals(SoundingModels.MODEL_ETA)) {
|
||||
if (stationId != null) {
|
||||
location.setStationId(stationId);
|
||||
obsData.setSiteId(String.format("%06d", wmoStaNum));
|
||||
}
|
||||
|
||||
if (model.equals(SoundingModels.MODEL_ETA)) {
|
||||
index++;
|
||||
} else if (model.equals(SoundingModels.MODEL_GFS)) {
|
||||
// GFS v16 data headers have station ID just like MODEL_ETA headers
|
||||
// For that type of data index needs to be incremented so the
|
||||
// reading of station ID is skipped.
|
||||
dp = dataList.get(index);
|
||||
if (dp instanceof BUFRStringPacket) {
|
||||
index++;
|
||||
}
|
||||
Double lat = null;
|
||||
dp = dataList.get(index);
|
||||
index++;
|
||||
int d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 5, 2)) {
|
||||
lat = (Double) dp.getValue();
|
||||
}
|
||||
Double lon = null;
|
||||
dp = dataList.get(index);
|
||||
index++;
|
||||
d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 6, 2)) {
|
||||
lon = (Double) dp.getValue();
|
||||
}
|
||||
location.assignLocation(lat.floatValue(), lon.floatValue());
|
||||
dp = dataList.get(index);
|
||||
d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 10, 194)) {
|
||||
stationHeight = (dp.getValue() != null) ? ((Double) dp
|
||||
.getValue()).intValue() : null;
|
||||
location.setElevation(stationHeight);
|
||||
}
|
||||
obsData.setLocation(location);
|
||||
|
||||
obsData.setPointDataView(view);
|
||||
} else {
|
||||
obsData = null;
|
||||
}
|
||||
|
||||
Double lat = null;
|
||||
dp = dataList.get(index++);
|
||||
int d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 5, 2)) {
|
||||
lat = (Double) dp.getValue();
|
||||
}
|
||||
Double lon = null;
|
||||
dp = dataList.get(index++);
|
||||
d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 6, 2)) {
|
||||
lon = (Double) dp.getValue();
|
||||
}
|
||||
location.assignLocation(lat.floatValue(), lon.floatValue());
|
||||
dp = dataList.get(index);
|
||||
d = dp.getReferencingDescriptor().getDescriptor();
|
||||
if (d == BUFRDescriptor.createDescriptor(0, 10, 194)) {
|
||||
stationHeight = (dp.getValue() != null) ? ((Double) dp
|
||||
.getValue()).intValue() : null;
|
||||
location.setElevation(stationHeight);
|
||||
}
|
||||
obsData.setLocation(location);
|
||||
obsData.setPointDataView(view);
|
||||
}
|
||||
|
||||
return obsData;
|
||||
|
@ -299,7 +267,7 @@ public class ModelSoundingDataAdapter {
|
|||
|
||||
/**
|
||||
* Extract all header data from the "main" observation list.
|
||||
*
|
||||
*
|
||||
* @param siteData
|
||||
* List of data packets to get data from.
|
||||
* @return The ProfilerObs with primary data populated.
|
||||
|
@ -310,7 +278,16 @@ public class ModelSoundingDataAdapter {
|
|||
if ((dataList != null) && (siteData != null)) {
|
||||
|
||||
// get the replication sublist for the sounding data
|
||||
IBUFRDataPacket p = dataList.get(5);
|
||||
// istart is the number of header fields in the packet
|
||||
// in the pre v16 GFS the header has 5 fields
|
||||
// in the v16 upgrade the header has 6 fields
|
||||
// use 3rd IBUFRDataPacket to determine the version
|
||||
IBUFRDataPacket dp = dataList.get(2);
|
||||
int istart = 6;
|
||||
if (!(dp instanceof BUFRStringPacket)) {
|
||||
istart = 5;
|
||||
}
|
||||
IBUFRDataPacket p = dataList.get(istart);
|
||||
if ((p instanceof BUFRSublistPacket)
|
||||
&& (DataPacketTypes.RepSubList.getPacketType().equals(p
|
||||
.getUnits()))) {
|
||||
|
@ -359,7 +336,7 @@ public class ModelSoundingDataAdapter {
|
|||
|
||||
/**
|
||||
* Creates individual level data from level "sublists" that were decoded.
|
||||
*
|
||||
*
|
||||
* @param levelList
|
||||
* A sublist containing level data.
|
||||
* @param level
|
||||
|
@ -387,7 +364,7 @@ public class ModelSoundingDataAdapter {
|
|||
|
||||
/**
|
||||
* Extract all header data from the "main" observation list.
|
||||
*
|
||||
*
|
||||
* @param siteData
|
||||
* List of data packets to get data from.
|
||||
* @return The ProfilerObs with primary data populated.
|
||||
|
@ -526,26 +503,4 @@ public class ModelSoundingDataAdapter {
|
|||
return retValue;
|
||||
}
|
||||
|
||||
private static SPIContainer populateSPIData() {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext ctx = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.CONFIGURED);
|
||||
String site = ctx.getContextName();
|
||||
|
||||
logger.info("Loading " + SPI_FILE + " for site [" + site + "]");
|
||||
|
||||
ILocalizationFile srcFile = pathMgr.getLocalizationFile(ctx, SPI_FILE);
|
||||
|
||||
SPIContainer container = new SPIContainer(srcFile);
|
||||
if (container.isLoaded()) {
|
||||
logger.info("Loading " + SPI_FILE + " for site [" + site
|
||||
+ "] Successful");
|
||||
} else {
|
||||
logger.error("Loading " + SPI_FILE + " for site [" + site
|
||||
+ "] failed");
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* 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.
|
||||
**/
|
||||
|
@ -27,57 +27,70 @@ import java.util.Map;
|
|||
|
||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
||||
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.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
||||
/**
|
||||
* Loads a map from a file (modelBufrStationList.txt) for mapping wmo numbers to
|
||||
* icaos.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------------------------
|
||||
* Aug 10, 2009 jkorman Initial creation
|
||||
* Dec 02, 2013 2537 bsteffen Switch logger to ufstatus.
|
||||
* Jul 08, 2016 5744 mapeters Config file moved from edex_static to
|
||||
* common_static, cleanup
|
||||
* Jan 04, 2018 7100 dgilling Code cleanup, read from CONFIGURED level.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author jkorman
|
||||
*/
|
||||
|
||||
public class SoundingStations {
|
||||
|
||||
private static final String STATION_LIST = ModelSoundingDataAdapter.MODEL_STATION_LIST;
|
||||
|
||||
private static final IUFStatusHandler logger = UFStatus
|
||||
.getHandler(SoundingStations.class);
|
||||
|
||||
private static final String STATION_LIST = ModelSoundingDataAdapter.MODEL_STATION_LIST_FILENAME;
|
||||
|
||||
private static final String STATION_LIST_PATH = ModelSoundingDataAdapter.MODEL_STATION_LIST_PATH;
|
||||
|
||||
private final Map<String, String> stationMap;
|
||||
private static Map<String, String> stationMap;
|
||||
|
||||
public SoundingStations() {
|
||||
this.stationMap = new HashMap<>();
|
||||
stationMap = new HashMap<>();
|
||||
populateMap();
|
||||
}
|
||||
|
||||
private void populateMap() {
|
||||
try {
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
ILocalizationFile locFile = pm.getStaticLocalizationFile(
|
||||
LocalizationType.COMMON_STATIC, STATION_LIST_PATH);
|
||||
String fullLocPath = "modelsounding" + IPathManager.SEPARATOR
|
||||
+ STATION_LIST;
|
||||
|
||||
if (locFile != null) {
|
||||
/*
|
||||
* Check SITE first, as the updated config file is stored there when
|
||||
* NDM files are ingested. If not found, use default BASE file.
|
||||
*/
|
||||
LocalizationContext context = pm.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
|
||||
ILocalizationFile srcFile = pm.getLocalizationFile(context,
|
||||
fullLocPath);
|
||||
if (srcFile == null || !srcFile.exists()) {
|
||||
context = pm.getContext(LocalizationType.COMMON_STATIC,
|
||||
LocalizationLevel.BASE);
|
||||
srcFile = pm.getLocalizationFile(context, fullLocPath);
|
||||
}
|
||||
if (srcFile != null && srcFile.exists()) {
|
||||
try (BufferedReader bf = new BufferedReader(
|
||||
new InputStreamReader(locFile.openInputStream()))) {
|
||||
new InputStreamReader(srcFile.openInputStream()))) {
|
||||
int count = 0;
|
||||
String line = null;
|
||||
while ((line = bf.readLine()) != null) {
|
||||
|
@ -92,13 +105,14 @@ public class SoundingStations {
|
|||
logger.debug(String.format("Read %d stationIds from %s.",
|
||||
count, STATION_LIST));
|
||||
} catch (IOException ioe) {
|
||||
logger.error("Unable to read sounding stations from ["
|
||||
+ locFile + "].", ioe);
|
||||
logger.handle(Priority.PROBLEM, ioe.getLocalizedMessage(),
|
||||
ioe);
|
||||
}
|
||||
} else {
|
||||
logger.error("Localization file " + STATION_LIST_PATH
|
||||
logger.error("Localization file " + fullLocPath
|
||||
+ " does not exist");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Error reading model sounding station list", e);
|
||||
}
|
||||
|
@ -106,7 +120,7 @@ public class SoundingStations {
|
|||
|
||||
/**
|
||||
* Map a modelsounding wmoId to a pseudoICAO identifier.
|
||||
*
|
||||
*
|
||||
* @param stationId
|
||||
* @return
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue