From c54869cd29c87c01c0e08427986c8f68b59a2f39 Mon Sep 17 00:00:00 2001 From: yaqiang Date: Wed, 27 Nov 2024 09:20:05 +0800 Subject: [PATCH] Enhance Bufr data support including multi-category messages in a single data file, so that prepbufr was supported. Also CMA bufr tables were added. --- .../java/ucar/nc2/iosp/bufr/BufrConfig.java | 6 + .../java/ucar/nc2/iosp/bufr/BufrIosp2.java | 128 ++- .../ucar/nc2/iosp/bufr/BufrIospBuilder.java | 76 +- .../ucar/nc2/iosp/bufr/BufrTableLookup.java | 5 +- .../ucar/nc2/iosp/bufr/EmbeddedTable.java | 60 +- .../java/ucar/nc2/iosp/bufr/TableLookup.java | 27 + .../ucar/nc2/iosp/bufr/tables/TableA.java | 109 ++- .../bufrTables/local/cma/cma_bufr_tableb.csv | 97 ++ .../bufrTables/local/cma/cma_bufr_tabled.csv | 916 ++++++++++++++++++ .../bufrTables/local/tablelookup.csv | 4 + .../src/main/java/ucar/ma2/ArraySequence.java | 19 + cdm/core/src/main/java/ucar/nc2/Variable.java | 61 +- 12 files changed, 1472 insertions(+), 36 deletions(-) create mode 100644 bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tableb.csv create mode 100644 bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tabled.csv diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrConfig.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrConfig.java index 542e73260d..ad318f96b3 100755 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrConfig.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrConfig.java @@ -45,6 +45,7 @@ static BufrConfig openFromMessage(RandomAccessFile raf, Message m, Element iospP } private String filename; + private Message message; private StandardFields.StandardFieldsFromMessage standardFields; private FieldConverter rootConverter; private int messHash; @@ -86,6 +87,7 @@ private BufrConfig(RandomAccessFile raf) { private BufrConfig(RandomAccessFile raf, Message m) throws IOException { this.filename = raf.getLocation(); + this.message = m; this.messHash = m.hashCode(); this.rootConverter = new FieldConverter(m.ids.getCenterId(), m.getRootDataDescriptor()); standardFields = StandardFields.extract(m); @@ -95,6 +97,10 @@ public String getFilename() { return filename; } + public Message getMessage() { + return this.message; + } + public FieldConverter getRootConverter() { return rootConverter; } diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIosp2.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIosp2.java index ae1b7272ea..8663de99e0 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIosp2.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIosp2.java @@ -5,10 +5,8 @@ package ucar.nc2.iosp.bufr; import java.io.IOException; -import java.util.Formatter; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; +import java.util.*; + import org.jdom2.Element; import ucar.ma2.Array; import ucar.ma2.ArraySequence; @@ -46,9 +44,11 @@ public static void setDebugFlags(ucar.nc2.util.DebugFlags debugFlag) { debugIter = debugFlag.isSet("Bufr/iter"); } - private Structure obsStructure; - private Message protoMessage; // prototypical message: all messages in the file must be the same. + //private Structure obsStructure; + //private Message protoMessage; // prototypical message: all messages in the file must be the same. private MessageScanner scanner; + private List protoMessages; // prototypical messages: the messages with different category. + private List rootVariables; private HashSet messHash; private boolean isSingle; private BufrConfig config; @@ -69,25 +69,57 @@ public void build(RandomAccessFile raf, Group.Builder rootGroup, CancelTask canc super.open(raf, rootGroup.getNcfile(), cancelTask); scanner = new MessageScanner(raf); - protoMessage = scanner.getFirstDataMessage(); + Message protoMessage = scanner.getFirstDataMessage(); if (protoMessage == null) throw new IOException("No data messages in the file= " + raf.getLocation()); if (!protoMessage.isTablesComplete()) throw new IllegalStateException("BUFR file has incomplete tables"); + // get all prototype messages - contains different message category in a Bufr data file + protoMessages = new ArrayList<>(); + protoMessages.add(protoMessage); + int category = protoMessage.ids.getCategory(); + while (scanner.hasNext()) { + Message message = scanner.next(); + if (message.ids.getCategory() != category) { + protoMessages.add(message); + category = message.ids.getCategory(); + } + } + // just get the fields config = BufrConfig.openFromMessage(raf, protoMessage, iospParam); // this fills the netcdf object - new BufrIospBuilder(protoMessage, config, rootGroup, raf.getLocation()); + if (this.protoMessages.size() == 1) { + new BufrIospBuilder(protoMessage, config, rootGroup, raf.getLocation()); + } else { + List configs = new ArrayList<>(); + for (Message message : protoMessages) { + configs.add(BufrConfig.openFromMessage(raf, message, iospParam)); + } + new BufrIospBuilder(protoMessage, configs, rootGroup, raf.getLocation()); + } isSingle = false; } @Override public void buildFinish(NetcdfFile ncfile) { - obsStructure = (Structure) ncfile.findVariable(obsRecordName); - // The proto DataDescriptor must have a link to the Sequence object to read nested Sequences. - connectSequences(obsStructure.getVariables(), protoMessage.getRootDataDescriptor().getSubKeys()); + // support multiple root variables in one Bufr data file + this.rootVariables = new ArrayList<>(); + if (this.protoMessages.size() == 1) { + Structure obsStructure = (Structure) ncfile.findVariable(obsRecordName); + // The proto DataDescriptor must have a link to the Sequence object to read nested Sequences. + connectSequences(obsStructure.getVariables(), protoMessages.get(0).getRootDataDescriptor().getSubKeys()); + this.rootVariables.add(new RootVariable(protoMessages.get(0), obsStructure)); + } else { + for (int i = 0; i < this.protoMessages.size(); i++) { + Structure variable = (Structure) ncfile.getVariables().get(i); + Message message = protoMessages.get(i); + connectSequences(variable.getVariables(), message.getRootDataDescriptor().getSubKeys()); + this.rootVariables.add(new RootVariable(message, variable)); + } + } } private void connectSequences(List variables, List dataDescriptors) { @@ -116,7 +148,7 @@ public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) super.open(raf, ncfile, cancelTask); scanner = new MessageScanner(raf); - protoMessage = scanner.getFirstDataMessage(); + Message protoMessage = scanner.getFirstDataMessage(); if (protoMessage == null) throw new IOException("No data messages in the file= " + ncfile.getLocation()); if (!protoMessage.isTablesComplete()) @@ -127,7 +159,7 @@ public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) // this fills the netcdf object Construct2 construct = new Construct2(protoMessage, config, ncfile); - obsStructure = construct.getObsStructure(); + Structure obsStructure = construct.getObsStructure(); ncfile.finish(); isSingle = false; } @@ -136,7 +168,7 @@ public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) public void open(RandomAccessFile raf, NetcdfFile ncfile, Message single) throws IOException { this.raf = raf; - protoMessage = single; + Message protoMessage = single; protoMessage.getRootDataDescriptor(); // construct the data descriptors, check for complete tables if (!protoMessage.isTablesComplete()) throw new IllegalStateException("BUFR file has incomplete tables"); @@ -145,7 +177,7 @@ public void open(RandomAccessFile raf, NetcdfFile ncfile, Message single) throws // this fills the netcdf object Construct2 construct = new Construct2(protoMessage, config, ncfile); - obsStructure = construct.getObsStructure(); + Structure obsStructure = construct.getObsStructure(); isSingle = true; ncfile.finish(); @@ -175,28 +207,67 @@ public Element getElem() { @Override public Array readData(Variable v2, Section section) { - findRootSequence(); - return new ArraySequence(obsStructure.makeStructureMembers(), new SeqIter(), nelems); + RootVariable rootVariable = findRootSequence(v2); + Structure obsStructure = rootVariable.getVariable(); + return new ArraySequence(obsStructure.makeStructureMembers(), new SeqIter(rootVariable), nelems); } @Override public StructureDataIterator getStructureIterator(Structure s, int bufferSize) { - findRootSequence(); - return isSingle ? new SeqIterSingle() : new SeqIter(); + RootVariable rootVariable = findRootSequence(s); + return isSingle ? new SeqIterSingle(rootVariable) : new SeqIter(rootVariable); + } + + private Structure findRootSequence() { + return (Structure) this.ncfile.findVariable(BufrIosp2.obsRecordName); + } + + // find root sequence from root variable list + private RootVariable findRootSequence(Variable var) { + for (RootVariable rootVariable : this.rootVariables) { + if (rootVariable.getVariable().getShortName().equals(var.getShortName())) { + return rootVariable; + } + } + return null; } - private void findRootSequence() { - this.obsStructure = (Structure) this.ncfile.findVariable(BufrIosp2.obsRecordName); + // root variable contains prototype message and corresponding variable + private class RootVariable { + private Message protoMessage; + private Structure variable; + + public RootVariable(Message message, Structure variable) { + this.protoMessage = message; + this.variable = variable; + } + + public Message getProtoMessage() { + return this.protoMessage; + } + + public Structure getVariable() { + return this.variable; + } } private class SeqIter implements StructureDataIterator { StructureDataIterator currIter; int recnum; + // add its own prototype message and observation structure + Message protoMessage; + Structure obsStructure; - SeqIter() { + SeqIter(Message message, Structure structure) { + this.protoMessage = message; + this.obsStructure = structure; reset(); } + SeqIter(RootVariable rootVariable) { + this(rootVariable.protoMessage, rootVariable.variable); + } + @Override public StructureDataIterator reset() { recnum = 0; @@ -286,11 +357,20 @@ public void close() { private class SeqIterSingle implements StructureDataIterator { StructureDataIterator currIter; int recnum; + // add its own prototype message and observation structure + Message protoMessage; + Structure obsStructure; - SeqIterSingle() { + SeqIterSingle(Message message, Structure structure) { + protoMessage = message; + obsStructure = structure; reset(); } + SeqIterSingle(RootVariable rootVariable) { + this(rootVariable.protoMessage, rootVariable.variable); + } + @Override public StructureDataIterator reset() { recnum = 0; @@ -350,7 +430,7 @@ public void close() { public String getDetailInfo() { Formatter ff = new Formatter(); ff.format("%s", super.getDetailInfo()); - protoMessage.dump(ff); + protoMessages.get(0).dump(ff); ff.format("%n"); config.show(ff); return ff.toString(); diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIospBuilder.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIospBuilder.java index b680f26fe4..e58cd99d3d 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIospBuilder.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrIospBuilder.java @@ -30,7 +30,7 @@ class BufrIospBuilder { private static final boolean warnUnits = false; private final Group.Builder rootGroup; - private final Sequence.Builder recordStructure; + private Sequence.Builder recordStructure; private final Formatter coordinates = new Formatter(); private int tempNo = 1; // fishy @@ -75,6 +75,42 @@ class BufrIospBuilder { } } + BufrIospBuilder(Message proto, List bufrConfigs, Group.Builder root, String location) { + this.rootGroup = root; + + // global Attributes + AttributeContainerMutable atts = root.getAttributeContainer(); + atts.addAttribute(CDM.HISTORY, "Read using CDM BufrIosp2"); + atts.addAttribute("location", location); + + atts.addAttribute("BUFR:categoryName", proto.getLookup().getCategoryName()); + atts.addAttribute("BUFR:subCategoryName", proto.getLookup().getSubCategoryName()); + atts.addAttribute("BUFR:centerName", proto.getLookup().getCenterName()); + atts.addAttribute(BufrIosp2.centerId, proto.ids.getCenterId()); + atts.addAttribute("BUFR:subCenter", proto.ids.getSubCenterId()); + atts.addAttribute("BUFR:table", proto.ids.getMasterTableId()); + atts.addAttribute("BUFR:tableVersion", proto.ids.getMasterTableVersion()); + atts.addAttribute("BUFR:localTableVersion", proto.ids.getLocalTableVersion()); + atts.addAttribute("Conventions", "BUFR/CDM"); + atts.addAttribute("BUFR:edition", proto.is.getBufrEdition()); + + String header = proto.getHeader(); + if (header != null && !header.isEmpty()) { + atts.addAttribute("WMO Header", header); + } + + for (BufrConfig bufrConfig : bufrConfigs) { + String varName = proto.getLookup().getCategoryName(bufrConfig.getMessage().ids.getCategory()); + Sequence.Builder rs = Sequence.builder().setName(varName); + this.rootGroup.addVariable(rs); + makeObsRecord(bufrConfig, rs); + String coordS = coordinates.toString(); + if (!coordS.isEmpty()) { + rs.addAttribute(new Attribute("coordinates", coordS)); + } + } + } + Sequence.Builder getObsStructure() { return recordStructure; } @@ -117,6 +153,44 @@ private void makeObsRecord(BufrConfig bufrConfig) { } } + private void makeObsRecord(BufrConfig bufrConfig, Sequence.Builder rs) { + BufrConfig.FieldConverter root = bufrConfig.getRootConverter(); + for (BufrConfig.FieldConverter fld : root.flds) { + DataDescriptor dkey = fld.dds; + if (!dkey.isOkForVariable()) { + continue; + } + + if (dkey.replication == 0) { + addSequence(rootGroup, rs, fld); + + } else if (dkey.replication > 1) { + + List subFlds = fld.flds; + List subKeys = dkey.subKeys; + if (subKeys.size() == 1) { // only one member + DataDescriptor subDds = dkey.subKeys.get(0); + BufrConfig.FieldConverter subFld = subFlds.get(0); + if (subDds.dpi != null) { + addDpiStructure(rs, fld, subFld); + + } else if (subDds.replication == 1) { // one member not a replication + Variable.Builder v = addVariable(rootGroup, rs, subFld, dkey.replication); + v.setSPobject(fld); // set the replicating field as SPI object + + } else { // one member is a replication (two replications in a row) + addStructure(rootGroup, rs, fld, dkey.replication); + } + } else if (subKeys.size() > 1) { + addStructure(rootGroup, rs, fld, dkey.replication); + } + + } else { // replication == 1 + addVariable(rootGroup, rs, fld, dkey.replication); + } + } + } + private void addStructure(Group.Builder group, Structure.Builder parent, BufrConfig.FieldConverter fld, int count) { DataDescriptor dkey = fld.dds; String uname = findUniqueName(parent, fld.getName(), "struct"); diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrTableLookup.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrTableLookup.java index 80064a3294..ad2c3ba332 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrTableLookup.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/BufrTableLookup.java @@ -127,11 +127,14 @@ public String getSubCategoryName() { // throws IOException { return subcatName; } - public String getCategoryName() { return TableA.getDataCategory(getCategory()); } + public String getCategoryName(int cat) { + return TableA.getDataCategoryName(cat); + } + public String getCategoryNo() { String result = getCategory() + "." + getSubCategory(); if (getLocalSubCategory() >= 0) diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/EmbeddedTable.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/EmbeddedTable.java index fb27353c03..de0b293dc8 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/EmbeddedTable.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/EmbeddedTable.java @@ -7,6 +7,7 @@ import ucar.ma2.*; import ucar.nc2.*; +import ucar.nc2.iosp.bufr.tables.TableA; import ucar.nc2.iosp.bufr.tables.TableB; import ucar.nc2.iosp.bufr.tables.TableD; import ucar.nc2.iosp.bufr.tables.WmoXmlReader; @@ -33,14 +34,16 @@ public class EmbeddedTable { private List messages = new ArrayList<>(); private boolean tableRead; + private TableA a; private TableB b; private TableD d; - private Structure seq2, seq3, seq4; + private Structure seq1, seq2, seq3, seq4; private TableLookup tlookup; EmbeddedTable(Message m, RandomAccessFile raf) { this.raf = raf; this.ids = m.ids; + a = new TableA("embed", raf.getLocation()); b = new TableB("embed", raf.getLocation()); d = new TableD("embed", raf.getLocation()); } @@ -51,10 +54,19 @@ public void addTable(Message m) { private void read2() throws IOException { Message proto = messages.get(0); + + // make root sub key data descriptors name as null, so the following construct + // will have seq2 and seq3 variables + DataDescriptor root = proto.getRootDataDescriptor(); + for (DataDescriptor ds : root.subKeys) { + ds.name = null; + } + BufrConfig config = BufrConfig.openFromMessage(raf, proto, null); Construct2 construct = new Construct2(proto, config, new NetcdfFileSubclass()); Sequence obs = construct.getObsStructure(); + seq1 = (Structure) obs.findVariable("seq1"); seq2 = (Structure) obs.findVariable("seq2"); seq3 = (Structure) obs.findVariable("seq3"); seq4 = (Structure) seq3.findVariable("seq4"); @@ -81,7 +93,12 @@ private void add(StructureData data) throws IOException { if (showB) System.out.printf("%s%n", m); if (m.getDataType() == DataType.SEQUENCE) { - if (m.getName().equals("seq2")) { + if (m.getName().equals("seq1")) { + ArraySequence seq = data.getArraySequence(m); + StructureDataIterator iter = seq.getStructureDataIterator(); + while (iter.hasNext()) + addTableEntryA(iter.next()); + } else if (m.getName().equals("seq2")) { ArraySequence seq = data.getArraySequence(m); StructureDataIterator iter = seq.getStructureDataIterator(); while (iter.hasNext()) @@ -96,6 +113,43 @@ private void add(StructureData data) throws IOException { } } + private void addTableEntryA(StructureData sdata) { + int scale = 0, refVal = 0, width = 0; + String entry = "", line1 = "", line2 = ""; + List members = sdata.getMembers(); + List vars = seq1.getVariables(); + for (int i = 0; i < vars.size(); i++) { + Variable v = vars.get(i); + StructureMembers.Member m = members.get(i); + String data = sdata.getScalarString(m); + Attribute att = v.attributes().findAttribute(BufrIosp2.fxyAttName); + switch (att.getStringValue()) { + case "0-0-1": + entry = sdata.getScalarString(m); + break; + case "0-0-2": + line1 = sdata.getScalarString(m); + break; + case "0-0-3": + line2 = sdata.getScalarString(m); + break; + } + } + + int code = Integer.parseInt(entry); + + // split name and description from appended line 1 and 2 + String desc = (line1 + line2).trim(); + String name = ""; + int pos = desc.indexOf(' '); + if (pos > 0) { + name = desc.substring(0, pos); + } + + TableA.Descriptor d = a.addDescriptor(code, desc); + d.setName(name); + } + private void addTableEntryB(StructureData sdata) { String name = "", units = "", signScale = null, signRef = null; int scale = 0, refVal = 0, width = 0; @@ -255,7 +309,7 @@ TableLookup getTableLookup() throws IOException { if (!tableRead) { read2(); tableRead = true; - tlookup = new TableLookup(ids, b, d); + tlookup = new TableLookup(ids, a, b, d); } return tlookup; } diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/TableLookup.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/TableLookup.java index ed519da619..2f5ed1c42c 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/TableLookup.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/TableLookup.java @@ -5,6 +5,7 @@ package ucar.nc2.iosp.bufr; import ucar.nc2.iosp.bufr.tables.BufrTables; +import ucar.nc2.iosp.bufr.tables.TableA; import ucar.nc2.iosp.bufr.tables.TableB; import ucar.nc2.iosp.bufr.tables.TableD; import javax.annotation.concurrent.Immutable; @@ -22,6 +23,7 @@ public class TableLookup { private static final boolean showErrors = false; ///////////////////////////////////////// + private TableA localTableA = null; private final TableB localTableB; private final TableD localTableD; @@ -53,10 +55,23 @@ public TableLookup(BufrIdentificationSection ids, TableB b, TableD d) throws IOE this.mode = BufrTables.Mode.localOverride; } + public TableLookup(BufrIdentificationSection ids, TableA a, TableB b, TableD d) throws IOException { + this.wmoTableB = BufrTables.getWmoTableB(ids.getMasterTableVersion()); + this.wmoTableD = BufrTables.getWmoTableD(ids.getMasterTableVersion()); + this.localTableA = a; + this.localTableB = b; + this.localTableD = d; + this.mode = BufrTables.Mode.localOverride; + } + public String getWmoTableBName() { return wmoTableB.getName(); } + public String getLocalTableAName() { + return localTableA == null ? "none" : localTableA.getName(); + } + public String getLocalTableBName() { return localTableB == null ? "none" : localTableB.getName(); } @@ -73,6 +88,10 @@ public BufrTables.Mode getMode() { return mode; } + public TableA getLocalTableA() { + return localTableA; + } + public TableB getLocalTableB() { return localTableB; } @@ -81,6 +100,14 @@ public TableD getLocalTableD() { return localTableD; } + public TableA.Descriptor getDescriptorTableA(int code) { + if (localTableA != null) { + return localTableA.getDescriptor(code); + } else { + return null; + } + } + public TableB.Descriptor getDescriptorTableB(short fxy) { TableB.Descriptor b = null; boolean isWmoRange = Descriptor.isWmoRange(fxy); diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/tables/TableA.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/tables/TableA.java index 08d0bb0d1d..c5a7d6e43b 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/tables/TableA.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/tables/TableA.java @@ -16,7 +16,9 @@ public class TableA { private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TableA.class); private static final String TABLEA_FILENAME = "wmo/BUFR_37_0_0_TableA_en.xml"; - private static Map tableA; + private static Map tableA; + private final String name; + private final String location; /* * @@ -37,7 +39,7 @@ private static void init() { String filename = BufrTables.RESOURCE_PATH + TABLEA_FILENAME; try (InputStream is = CodeFlagTables.class.getResourceAsStream(filename)) { - HashMap map = new HashMap<>(100); + HashMap map = new HashMap<>(100); SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(false); org.jdom2.Document tdoc = builder.build(is); @@ -51,7 +53,8 @@ private static void init() { try { int code = Integer.parseInt(codeS); - map.put(code, desc); + Descriptor descriptor = new Descriptor(code, desc); + map.put(code, descriptor); } catch (NumberFormatException e) { log.debug("NumberFormatException on line " + line + " in " + codeS); } @@ -64,6 +67,18 @@ private static void init() { } } + public TableA(String name, String location) { + this.name = name; + this.location = location; + tableA = new HashMap<>(); + } + + public Descriptor getDescriptor(int code) { + if (tableA == null) + init(); + return tableA.get(code); + } + /** * data category name, from table A * @@ -73,8 +88,92 @@ private static void init() { public static String getDataCategory(int cat) { if (tableA == null) init(); - String result = tableA.get(cat); - return result != null ? result : "Unknown category=" + cat; + Descriptor descriptor = tableA.get(cat); + return descriptor != null ? descriptor.getDescription() : "Unknown category=" + cat; + } + + /** + * data category name, from table A + * + * @param cat data category + * @return category name, or null if not found + */ + public static String getDataCategoryName(int cat) { + if (tableA == null) + init(); + Descriptor descriptor = tableA.get(cat); + return descriptor != null ? descriptor.getName() : "obs_" + cat; + } + + public String getName() { + return name; + } + + public String getLocation() { + return location; + } + + public TableA.Descriptor addDescriptor(int code, String description) { + TableA.Descriptor d = new TableA.Descriptor(code, description); + tableA.put(code, d); + return d; + } + + public static class Descriptor implements Comparable { + private int code; + private String name; + private String description; + private boolean localOverride; + + Descriptor(int code, String description) { + this.code = code; + this.description = description; + this.name = "obs_" + String.valueOf(code); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return this.description; + } + + /** + * Get code + * + * @return Code + */ + public int getCode() { + return this.code; + } + + public String toString() { + return String.valueOf(code) + " " + getName() + " " + + this.description; + } + + @Override + public int compareTo(Descriptor o) { + return code - o.getCode(); + } + + public boolean isLocal() { + return ((code >= 102) && (code <= 239)); + } + + public void setLocalOverride(boolean isOverride) { + this.localOverride = isOverride; + } + + public boolean getLocalOverride() { + return localOverride; + } + } } diff --git a/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tableb.csv b/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tableb.csv new file mode 100644 index 0000000000..431e7c1e27 --- /dev/null +++ b/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tableb.csv @@ -0,0 +1,97 @@ +ClassNo,FXY,ElementName_cn,BUFR_Unit,BUFR_Scale,BUFR_ReferenceValue,BUFR_DataWidth_Bits,ElementName_en,No +1,1192,本地测站标识,CCITT IA5,0,0,72,,1 +2,2192,探空仪生产厂家,Code table,0,0,7,,2 +2,2200,气压的计算方法,Code table,0,0,4,,3 +2,2193,施放计数,Numeric,0,0,8,,4 +2,2194,附加物重量,kg,3,0,14,,5 +2,2195,球与探空仪间实际绳长,m,1,0,10,,6 +2,2196,总举力,kg,3,0,14,,7 +2,2197,净举力,kg,3,0,14,,8 +2,2198,平均升速,m/min,1,0,14,,9 +10,10192,气压基测值,Pa,-1,0,14,,10 +10,10193,气压仪器值,Pa,-1,0,14,,11 +10,10194,气压偏差,Pa,-1,0,14,,12 +12,12192,温度基测值,K,2,0,16,,13 +12,12193,温度仪器值,K,2,0,16,,14 +12,12194,温度偏差,K,2,0,16,,15 +13,13192,相对湿度基测值,%,0,0,7,,16 +13,13193,相对湿度仪器值,%,0,0,7,,17 +13,13194,相对湿度偏差,%,0,0,7,,18 +2,2199,仪器检测结论,Code table,0,0,2,,19 +4,4192,时间差,s,0,-86400,18,,20 +8,8192,时间含义标识,Code table,0,0,5,,21 +20,20192,国内观测天气现象,Code table,0,0,7,,22 +28,28192,采样时距离,Code table,0,0,19,,23 +26,26192,国内观测天气现象,Code table,0,0,7,,24 +2,2201,本地地面传感器标识,Code table,0,0,3,,25 +20,20211,连续观测天气现象,CCITT IA5,0,0,960,,26 +2,2207,日照时制方式,Code table,0,0,3,,27 +12,12195,路面温度,K,1,0,12,,28 +12,12196,10cm路基温度,K,1,0,12,,29 +13,13195,雪压,g/cm2,0,0,11,,30 +13,13196,蒸发水位,mm,0,0,6,,31 +20,20193,冻土深度第一层上限值,m,2,0,10,,32 +20,20194,冻土深度第一层下限值,m,2,0,10,,33 +20,20195,冻土深度第二层上限值,m,2,0,10,,34 +20,20196,冻土深度第二层下限值,m,2,0,10,,35 +20,20197,龙卷、尘卷风距测站距离,m,-3,0,8,,36 +20,20198,电线积冰-南北方向直径,m,3,0,10,,37 +20,20199,电线积冰-南北方向厚度,m,3,0,10,,38 +20,20200,电线积冰-南北方向重量,1g/m,0,0,14,,39 +20,20201,电线积冰-东西方向直径,m,3,0,10,,40 +20,20202,电线积冰-东西方向厚度,m,3,0,10,,41 +20,20203,电线积冰-东西方向重量,1g/m,0,0,14,,42 +20,20204,路面状况,Code table,0,0,5,,43 +20,20205,路面雪层厚度,mm,0,0,12,,44 +20,20206,路面水层厚度,mm,1,0,8,,45 +20,20207,路面冰层厚度,mm,1,0,8,,46 +20,20208,融雪剂浓度,%,0,0,5,,47 +26,26195,现象出现时间的时,Hour,0,0,5,,48 +26,26196,现象出现时间的分,Minute,0,0,6,,49 +20,20212,小时连续观测天气现象,CCITT IA5,0,0,3600,,50 +2,2202,本地辐射传感器标识,Code table,0,0,10,,51 +14,14192,直射辐射辐照度,Wm-2,0,0,24,,52 +14,14193,散射辐射辐照度,Wm-2,0,0,24,,53 +14,14194,总辐射辐照度,Wm-2,0,0,24,,54 +14,14195,反射辐射辐照度,Wm-2,0,0,24,,55 +14,14196,大气长波辐射辐照度,Wm-2,0,0,24,,56 +14,14197,地球长波辐射辐照度,Wm-2,0,0,24,,57 +14,14198,紫外辐射(UVA)辐照度,Wm-2,2,0,24,,58 +14,14199,紫外辐射(UVB)辐照度,Wm-2,2,0,24,,59 +14,14200,光合有效辐射辐照度,umol/s.m-2,0,0,24,,60 +14,14201,反射辐射曝辐量,MJm-2,2,0,15,,61 +14,14202,大气长波辐射曝辐量,MJm-2,2,0,15,,62 +14,14203,地球长波辐射曝辐量,MJm-2,2,0,15,,63 +14,14204,紫外辐射(UVA) 曝辐量,MJm-2,3,0,15,,64 +14,14205,紫外辐射(UVB) 曝辐量,MJm-2,3,0,15,,65 +14,14206,净全辐射辐照度,Wm-2,0,-1000,24,,66 +14,14207,紫外辐射辐照度,Wm-2,2,0,24,,67 +14,14208,紫外辐射曝辐量,MJm-2,-3,0,15,,68 +14,14209,大气浑浊度,,2,0,12,,69 +20,20209,作用层情况,Code table,0,0,3,,70 +20,20210,作用层状况,Code table,0,0,4,,71 +2,2203,酸雨复测指示码,Code table,0,0,4,,72 +2,2204,酸雨测量电导率的手动温度补偿功能指示码,Code table,0,0,1,,73 +2,2205,酸雨样品延迟测量指示码,Code table,0,0,4,,74 +2,2206,酸雨降水样品异常状况,Code table,0,0,3,,75 +11,11235,,Code table,0,0,6,Turbulence index,76 +21,21192,,dB,2,-5000,13,Radar back scatter,77 +12,12197,24小时变温,K,1,-2732,12,,78 +15,15192,K=0.4负离子值,个/cm3,-1,0,17,,79 +15,15193,K=0.4正离子值,个/cm3,-1,0,17,,80 +48,48192,计算机通信状态,Code table,0,0,2,,81 +48,48193,设备断电报警,Code table,0,0,2,,82 +49,49192,是否做异常数据剔除与外延,Code table,0,0,2,,83 +49,49193,异常数据判断阈值倍数,Numeric,2,0,10,,84 +33,33192,是否有异常数据,Code table,0,0,2,,85 +33,33193,是否有数据缺失,Code table,0,0,2,,86 +14,14210,太阳直接辐射辐照度,Wm-2,0,0,24,,87 +14,14211,直射辐射曝辐量,MJm-2,2,0,15,,88 +14,14212,散射辐射曝辐量,MJm-2,2,0,15,,89 +14,14213,总辐射曝辐量,MJm-2,2,0,15,,90 +14,14214,净全辐射曝辐量,MJm-2,2,-1000,15,,91 +14,14215,光合有效曝辐量,MJm-2,2,0,15,,92 +13,13205,谱图数据编号,Code table,0,0,12,,93 +13,13206,雨滴个数,Numeric,0,0,16,,94 +2,2240,雨滴谱的设备类型,Code table,0,0,4,,95 +13,13162,Cloud liquid water,kg m-2,2,0,8,Cloud liquid water,96 diff --git a/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tabled.csv b/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tabled.csv new file mode 100644 index 0000000000..c650e38d19 --- /dev/null +++ b/bufr/src/main/resources/resources/bufrTables/local/cma/cma_bufr_tabled.csv @@ -0,0 +1,916 @@ +Category,No,FXY1,ElementName1_en,FXY2,ElementName2_en +#高空,,,, +9,1,309192,A1,301111,A1 +9,2,309192,A2,1101,A2 +9,3,309192,A3,1192,A3 +9,4,309192,A4,101002,A4 +9,5,309192,A5,33035,A5 +9,6,309192,A6,25061,A6 +9,7,309192,A7,2192,A7 +9,8,309192,A8,8041,A8 +9,9,309192,A9,301011,A9 +9,10,309192,A10,1081,A10 +9,11,309192,A11,1082,A11 +9,12,309192,A12,2067,A12 +9,13,309192,A13,2095,A13 +9,14,309192,A14,2096,A14 +9,15,309192,A15,2097,A15 +9,16,309192,A16,2081,A16 +9,17,309192,A17,2082,A17 +9,18,309192,A18,2084,A18 +9,19,309192,A19,2191,A19 +9,20,309192,A20,2200,A20 +9,21,309192,A21,2066,A21 +9,22,309192,A22,2102,A22 +9,23,309192,A23,2193,A23 +9,24,309192,A24,2194,A24 +9,25,309192,A25,2195,A25 +9,26,309192,A26,2196,A26 +9,27,309192,A27,2197,A27 +9,28,309192,A28,2198,A28 +9,29,309192,A29,10192,A29 +9,30,309192,A30,10193,A30 +9,31,309192,A31,10194,A31 +9,32,309192,A32,12192,A32 +9,33,309192,A33,12193,A33 +9,34,309192,A34,12194,A34 +9,35,309192,A35,13192,A35 +9,36,309192,A36,13193,A36 +9,37,309192,A37,13194,A37 +9,38,309192,A38,2199,A38 +9,39,309192,A39,301113,A39 +9,40,309192,A40,8025,A40 +9,41,309192,A41,4192,A41 +9,42,309192,A42,106002,A42 +9,43,309192,A43,8192,A43 +9,44,309192,A44,301011,A44 +9,45,309192,A45,301013,A45 +9,46,309192,A46,35035,A46 +9,47,309192,A47,7007,A47 +9,48,309192,A48,7022,A48 +9,49,309192,A49,301114,A49 +9,50,309192,A50,10004,A50 +9,51,309192,A51,302032,A51 +9,52,309192,A52,7032,A52 +9,53,309192,A53,7032,A53 +9,54,309192,A54,2002,A54 +9,55,309192,A55,8021,A55 +9,56,309192,A56,4025,A56 +9,57,309192,A57,11001,A57 +9,58,309192,A58,11002,A58 +9,59,309192,A59,8021,A59 +9,60,309192,A60,7032,A60 +9,61,309192,A61,20003,A61 +9,62,309192,A62,7022,A62 +9,63,309192,A63,20001,A63 +9,64,309192,A64,101003,A64 +9,65,309192,A65,20012,A65 +9,66,309192,A66,20051,A66 +9,67,309192,A67,20010,A67 +9,68,309192,A68,101003,A68 +9,69,309192,A69,20192,A69 +9,70,309192,A70,5021,A70 +9,71,309192,A71,7021,A71 +9,72,309192,A72,6021,A72 +9,73,309192,A73,302049,A73 +9,74,309192,A74,113000,A74 +9,75,309192,A75,31002,A75 +9,76,309192,A76,204008,A76 +9,77,309192,A77,31021,A77 +9,78,309192,A78,4086,A78 +9,79,309192,A79,8042,A79 +9,80,309192,A80,7004,A80 +9,81,309192,A81,10009,A81 +9,82,309192,A82,5015,A82 +9,83,309192,A83,6015,A83 +9,84,309192,A84,12101,A84 +9,85,309192,A85,12103,A85 +9,86,309192,A86,11001,A86 +9,87,309192,A87,11002,A87 +9,88,309192,A88,204000,A88 +9,89,309192,A89,110000,A89 +9,90,309192,A90,31002,A90 +9,91,309192,A91,204008,A91 +9,92,309192,A92,31021,A92 +9,93,309192,A93,4086,A93 +9,94,309192,A94,8042,A94 +9,95,309192,A95,7007,A95 +9,96,309192,A96,5015,A96 +9,97,309192,A97,6015,A97 +9,98,309192,A98,11001,A98 +9,99,309192,A99,11002,A99 +9,100,309192,A100,204000,A100 +9,101,309192,A101,110000,A101 +9,102,309192,A102,31002,A102 +9,103,309192,A103,204008,A103 +9,104,309192,A104,31021,A104 +9,105,309192,A105,4086,A105 +9,106,309192,A106,8042,A106 +9,107,309192,A107,7004,A107 +9,108,309192,A108,5015,A108 +9,109,309192,A109,6015,A109 +9,110,309192,A110,11061,A110 +9,111,309192,A111,11062,A111 +9,112,309192,A112,204000,A112 +9,113,309192,A113,115000,A113 +9,114,309192,A114,31002,A114 +9,115,309192,A115,204008,A115 +9,116,309192,A116,31021,A116 +9,117,309192,A117,4086,A117 +9,118,309192,A118,7004,A118 +9,119,309192,A119,10009,A119 +9,120,309192,A120,5015,A120 +9,121,309192,A121,6015,A121 +9,122,309192,A122,12101,A122 +9,123,309192,A123,13003,A123 +9,124,309192,A124,11001,A124 +9,125,309192,A125,11002,A125 +9,126,309192,A126,7021,A126 +9,127,309192,A127,5021,A127 +9,128,309192,A128,28192,A128 +9,129,309192,A129,204000,A129 +9,130,309192,A130,112000,A130 +9,131,309192,A131,31002,A131 +9,132,309192,A132,204008,A132 +9,133,309192,A133,31021,A133 +9,134,309192,A134,4086,A134 +9,135,309192,A135,10009,A135 +9,136,309192,A136,5015,A136 +9,137,309192,A137,6015,A137 +9,138,309192,A138,11001,A138 +9,139,309192,A139,11002,A139 +9,140,309192,A140,7021,A140 +9,141,309192,A141,5021,A141 +9,142,309192,A142,28192,A142 +9,143,309192,A143,204000,A143 +#地面分钟3.2 307192(最终稿20160509),,,, +#测站基本信息,,,, +7,144,307192,B1,301004,B1 +7,145,307192,B2,1101,B2 +7,146,307192,B3,1192,B3 +7,147,307192,B4,301011,B4 +7,148,307192,B5,301012,B5 +7,149,307192,B6,301021,B6 +7,150,307192,B7,7030,B7 +7,151,307192,B8,7031,B8 +7,152,307192,B9,8010,B9 +7,153,307192,B10,101002,B10 +7,154,307192,B11,33035,B11 +7,155,307192,B12,204008,B12 +7,156,307192,B13,31021,B13 +#气压,,,, +7,157,307192,C1,2201,C1 +7,158,307192,C2,4015,C2 +7,159,307192,C3,4065,C3 +7,160,307192,C4,102000,C4 +7,161,307192,C5,31001,C5 +7,162,307192,C6,10004,C6 +7,163,307192,C7,10051,C7 +#温度和湿度,,,, +7,164,307192,D1,101002,D1 +7,165,307192,D2,2201,D2 +7,166,307192,D3,7032,D3 +7,167,307192,D4,7033,D4 +7,168,307192,D5,4015,D5 +7,169,307192,D6,4065,D6 +7,170,307192,D7,104000,D7 +7,171,307192,D8,31001,D8 +7,172,307192,D9,12001,D9 +7,173,307192,D10,12003,D10 +7,174,307192,D11,13003,D11 +7,175,307192,D12,13004,D12 +7,176,307192,D13,7032,D13 +7,177,307192,D14,7033,D14 +#降水,,,, +7,178,307192,E1,2201,E1 +7,179,307192,E2,7032,E2 +7,180,307192,E3,7033,E3 +7,181,307192,E4,2175,E4 +7,182,307192,E5,101000,E5 +7,183,307192,E6,31001,E6 +7,184,307192,E7,13011,E7 +7,185,307192,E8,7032,E8 +7,186,307192,E9,7033,E9 +#风,,,, +7,187,307192,F1,101002,F1 +7,188,307192,F2,2201,F2 +7,189,307192,F3,7032,F3 +7,190,307192,F4,7033,F4 +7,191,307192,F5,4015,F5 +7,192,307192,F6,4065,F6 +7,193,307192,F7,108000,F7 +7,194,307192,F8,31001,F8 +7,195,307192,F9,8021,F9 +7,196,307192,F10,103003,F10 +7,197,307192,F11,4025,F11 +7,198,307192,F12,11001,F12 +7,199,307192,F13,11002,F13 +7,200,307192,F14,8021,F14 +7,201,307192,F15,11043,F15 +7,202,307192,F16,11041,F16 +7,203,307192,F17,7032,F17 +7,204,307192,F18,7033,F18 +#地表温度、浅层和深层地温,,,, +7,205,307192,G1,101009,G1 +7,206,307192,G2,2201,G2 +7,207,307192,G3,4015,G3 +7,208,307192,G4,4065,G4 +7,209,307192,G5,105000,G5 +7,210,307192,G6,31001,G6 +7,211,307192,G7,12061,G7 +7,212,307192,G8,102008,G8 +7,213,307192,G9,7061,G9 +7,214,307192,G10,12030,G10 +7,215,307192,G11,7061,G11 +#草面(或雪面)温度,,,, +7,216,307192,H1,2201,H1 +7,217,307192,H2,4015,H2 +7,218,307192,H3,4065,H3 +7,219,307192,H4,101000,H4 +7,220,307192,H5,31001,H5 +7,221,307192,H6,12061,H6 +#能见度,,,, +7,222,307192,I1,2201,I1 +7,223,307192,I2,7032,I2 +7,224,307192,I3,7033,I3 +7,225,307192,I4,4015,I4 +7,226,307192,I5,4065,I5 +7,227,307192,I6,109000,I6 +7,228,307192,I7,31001,I7 +7,229,307192,I8,8021,I8 +7,230,307192,I9,106002,I9 +7,231,307192,I10,4025,I10 +7,232,307192,I11,201132,I11 +7,233,307192,I12,202129,I12 +7,234,307192,I13,20001,I13 +7,235,307192,I14,202000,I14 +7,236,307192,I15,201000,I15 +7,237,307192,I16,8021,I16 +7,238,307192,I17,7032,I17 +7,239,307192,I18,7033,I18 +#云数据,,,, +7,240,307192,J1,101002,J1 +7,241,307192,J2,2201,J2 +7,242,307192,J3,2183,J3 +7,243,307192,J4,4015,J4 +7,244,307192,J5,4065,J5 +7,245,307192,J6,102000,J6 +7,246,307192,J7,31001,J7 +7,247,307192,J8,20010,J8 +7,248,307192,J9,20013,J9 +#雪深,,,, +7,249,307192,K1,2201,K1 +7,250,307192,K2,2177,K2 +7,251,307192,K3,4015,K3 +7,252,307192,K4,4065,K4 +7,253,307192,K5,101000,K5 +7,254,307192,K6,31001,K6 +7,255,307192,K7,13013,K7 +#天气现象,,,, +7,256,307192,L1,101004,L1 +7,257,307192,L2,2201,L2 +7,258,307192,L3,2180,L3 +7,259,307192,L4,4015,L4 +7,260,307192,L5,4065,L5 +7,261,307192,L6,101000,L6 +7,262,307192,L7,31001,L7 +7,263,307192,L8,20211,L8 +7,264,307192,L9,204000,L9 +#307193地面小时3.3(最终稿20160509),,,, +#测站基本信息,,,, +7,265,307193,M1,301004,M1 +7,266,307193,M2,1101,M2 +7,267,307193,M3,1192,M3 +7,268,307193,M4,301011,M4 +7,269,307193,M5,301013,M5 +7,270,307193,M6,301021,M6 +7,271,307193,M7,7030,M7 +7,272,307193,M8,7031,M8 +7,273,307193,M9,8010,M9 +7,274,307193,M10,2207,M10 +7,275,307193,M11,101002,M11 +7,276,307193,M12,33035,M12 +7,277,307193,M13,204008,M13 +7,278,307193,M14,31021,M14 +#气压,,,, +7,279,307193,N1,2201,N1 +7,280,307193,N2,113000,N2 +7,281,307193,N3,31000,N3 +7,282,307193,N4,302031,N4 +7,283,307193,N5,8023,N5 +7,284,307193,N6,4024,N6 +7,285,307193,N7,10004,N7 +7,286,307193,N8,26195,N8 +7,287,307193,N9,26196,N9 +7,288,307193,N10,8023,N10 +7,289,307193,N11,8023,N11 +7,290,307193,N12,4024,N12 +7,291,307193,N13,10004,N13 +7,292,307193,N14,26195,N14 +7,293,307193,N15,26196,N15 +7,294,307193,N16,8023,N16 +#温度和湿度,,,, +7,295,307193,O1,101002,O1 +7,296,307193,O2,2201,O2 +7,297,307193,O3,123000,O3 +7,298,307193,O4,31000,O4 +7,299,307193,O5,7032,O5 +7,300,307193,O6,7033,O6 +7,301,307193,O7,12001,O7 +7,302,307193,O8,12003,O8 +7,303,307193,O9,13003,O9 +7,304,307193,O10,13004,O10 +7,305,307193,O11,4024,O11 +7,306,307193,O12,12011,O12 +7,307,307193,O13,26195,O13 +7,308,307193,O14,26196,O14 +7,309,307193,O15,4024,O15 +7,310,307193,O16,12012,O16 +7,311,307193,O17,26195,O17 +7,312,307193,O18,26196,O18 +7,313,307193,O19,4024,O19 +7,314,307193,O20,13007,O20 +7,315,307193,O21,26195,O21 +7,316,307193,O22,26196,O22 +7,317,307193,O23,12197,O23 +7,318,307193,O24,12016,O24 +7,319,307193,O25,12017,O25 +7,320,307193,O26,7032,O26 +7,321,307193,O27,7033,O27 +#降水,,,, +7,322,307193,P1,2201,P1 +7,323,307193,P2,112000,P2 +7,324,307193,P3,31000,P3 +7,325,307193,P4,7032,P4 +7,326,307193,P5,7033,P5 +7,327,307193,P6,2175,P6 +7,328,307193,P7,13019,P7 +7,329,307193,P8,13020,P8 +7,330,307193,P9,13021,P9 +7,331,307193,P10,13022,P10 +7,332,307193,P11,13023,P11 +7,333,307193,P12,4024,P12 +7,334,307193,P13,13011,P13 +7,335,307193,P14,7032,P14 +7,336,307193,P15,7033,P15 +#蒸发,,,, +7,337,307193,Q1,2201,Q1 +7,338,307193,Q2,102000,Q2 +7,339,307193,Q3,31000,Q3 +7,340,307193,Q4,302044,Q4 +7,341,307193,Q1,13196,Q1 +7,342,307193,Q2,4024,Q2 +7,343,307193,Q3,13033,Q3 +#风,,,, +7,344,307193,R1,101002,R1 +7,345,307193,R2,2201,R2 +7,346,307193,R3,125000,R3 +7,347,307193,R4,31000,R4 +7,348,307193,R5,7032,R5 +7,349,307193,R6,7033,R6 +#瞬时风,,,, +7,350,307193,S1,11001,S1 +7,351,307193,S2,11002,S2 +#2分钟平均和10分钟平均风,,,, +7,352,307193,T1,8021,T1 +7,353,307193,T2,103002,T2 +7,354,307193,T3,4025,T3 +7,355,307193,T4,11001,T4 +7,356,307193,T5,11002,T5 +7,357,307193,T6,8021,T6 +#最大风和极大风,,,, +7,358,307193,U1,4024,U1 +7,359,307193,U2,11010,U2 +7,360,307193,U3,11042,U3 +7,361,307193,U4,26195,U4 +7,362,307193,U5,26196,U5 +7,363,307193,U6,11010,U6 +7,364,307193,U7,11046,U7 +7,365,307193,U8,26195,U8 +7,366,307193,U9,26196,U9 +#过去6小时和12小时极大风,,,, +7,367,307193,V1,103002,V1 +7,368,307193,V2,4024,V2 +7,369,307193,V3,11010,V3 +7,370,307193,V4,11046,V4 +7,371,307193,V5,7032,V5 +7,372,307193,V6,7033,V6 +#地表温度、浅层地温和深层地温,,V7,,V7 +7,373,307193,V8,101009,V8 +7,374,307193,V9,2201,V9 +7,375,307193,V10,118000,V10 +7,376,307193,V11,31000,V11 +7,377,307193,V12,12061,V12 +7,378,307193,V13,12013,V13 +7,379,307193,V14,102008,V14 +7,380,307193,V15,7061,V15 +7,381,307193,V16,12030,V16 +7,382,307193,V17,7061,V17 +7,383,307193,V18,8023,V18 +7,384,307193,V19,4024,V19 +7,385,307193,V20,12061,V20 +7,386,307193,V21,26195,V21 +7,387,307193,V22,26196,V22 +7,388,307193,V23,8023,V23 +7,389,307193,V24,8023,V24 +7,390,307193,V25,4024,V25 +7,391,307193,V26,12061,V26 +7,392,307193,V27,26195,V27 +7,393,307193,V28,26196,V28 +7,394,307193,V29,8023,V29 +#草面或雪面温度,,V30,,V30 +7,395,307193,V31,2201,V31 +7,396,307193,V32,113000,V32 +7,397,307193,V33,31000,V33 +7,398,307193,V34,12061,V34 +7,399,307193,V35,8023,V35 +7,400,307193,V36,4024,V36 +7,401,307193,V37,12061,V37 +7,402,307193,V38,26195,V38 +7,403,307193,V39,26196,V39 +7,404,307193,V40,8023,V40 +7,405,307193,V41,8023,V41 +7,406,307193,V42,4024,V42 +7,407,307193,V43,12061,V43 +7,408,307193,V44,26195,V44 +7,409,307193,V45,26196,V45 +7,410,307193,V46,8023,V46 +#路面温度,,V47,,V47 +7,411,307193,V48,2201,V48 +7,412,307193,V49,112000,V49 +7,413,307193,V50,31000,V50 +7,414,307193,V51,12195,V51 +7,415,307193,V52,12196,V52 +7,416,307193,V53,8023,V53 +7,417,307193,V54,12195,V54 +7,418,307193,V55,26195,V55 +7,419,307193,V56,26196,V56 +7,420,307193,V57,8023,V57 +7,421,307193,V58,8023,V58 +7,422,307193,V59,12195,V59 +7,423,307193,V60,26195,V60 +7,424,307193,V61,26196,V61 +7,425,307193,V62,8023,V62 +#能见度数据,,V63,,V63 +7,426,307193,V64,2201,V64 +7,427,307193,V65,129000,V65 +7,428,307193,V66,31000,V66 +7,429,307193,V67,7032,V67 +7,430,307193,V68,7033,V68 +7,431,307193,V69,33041,V69 +7,432,307193,V70,201132,V70 +7,433,307193,V71,202129,V71 +7,434,307193,V72,20001,V72 +7,435,307193,V73,202000,V73 +7,436,307193,V74,201000,V74 +#1分钟平均和10分钟平均水平能见度,,V75,,V75 +7,437,307193,V76,8021,V76 +7,438,307193,V77,106002,V77 +7,439,307193,V78,4025,V78 +7,440,307193,V79,201132,V79 +7,441,307193,V80,202129,V80 +7,442,307193,V81,20001,V81 +7,443,307193,V82,202000,V82 +7,444,307193,V83,201000,V83 +7,445,307193,V84,8021,V84 +#小时内最小水平能见度,,V85,,V85 +7,446,307193,V86,8023,V86 +7,447,307193,V87,4024,V87 +7,448,307193,V88,201132,V88 +7,449,307193,V89,202129,V89 +7,450,307193,V90,20001,V90 +7,451,307193,V91,202000,V91 +7,452,307193,V92,201000,V92 +7,453,307193,V93,26195,V93 +7,454,307193,V94,26196,V94 +7,455,307193,V95,8023,V95 +7,456,307193,V96,7032,V96 +7,457,307193,V97,7033,V97 +#云数据,,V98,,V98 +7,458,307193,V99,101003,V99 +7,459,307193,V100,2201,V100 +7,460,307193,V101,106000,V101 +7,461,307193,V102,31000,V102 +7,462,307193,V103,2183,V103 +7,463,307193,V104,302004,V104 +7,464,307193,V105,8002,V105 +7,465,307193,V106,20051,V106 +7,466,307193,V107,101008,V107 +7,467,307193,V108,20012,V108 +#地面状态,,V109,,V109 +7,468,307193,V110,2201,V110 +7,469,307193,V111,102000,V111 +7,470,307193,V112,31000,V112 +7,471,307193,V113,2176,V113 +7,472,307193,V114,20062,V114 +#积雪深度、雪压,,V115,,V115 +7,473,307193,V116,2201,V116 +7,474,307193,V117,103000,V117 +7,475,307193,V118,31000,V118 +7,476,307193,V119,2177,V119 +7,477,307193,V120,13013,V120 +7,478,307193,V121,13195,V121 +#冻土深度,,V122,,V122 +7,479,307193,V123,2201,V123 +7,480,307193,V124,104000,V124 +7,481,307193,V125,31000,V125 +7,482,307193,V126,20193,V126 +7,483,307193,V127,20194,V127 +7,484,307193,V128,20195,V128 +7,485,307193,V129,20196,V129 +#电线积冰,,V130,,V130 +7,486,307193,V131,2201,V131 +7,487,307193,V132,111000,V132 +7,488,307193,V133,31000,V133 +7,489,307193,V134,101002,V134 +7,490,307193,V135,20192,V135 +7,491,307193,V136,20198,V136 +7,492,307193,V137,20199,V137 +7,493,307193,V138,20200,V138 +7,494,307193,V139,20201,V139 +7,495,307193,V140,20202,V140 +7,496,307193,V141,20203,V141 +7,497,307193,V142,12001,V142 +7,498,307193,V143,11001,V143 +7,499,307193,V144,11002,V144 +#路面状况,,V145,,V145 +7,500,307193,V146,2201,V146 +7,501,307193,V147,106000,V147 +7,502,307193,V148,31000,V148 +7,503,307193,V149,20204,V149 +7,504,307193,V150,20205,V150 +7,505,307193,V151,20206,V151 +7,506,307193,V152,20207,V152 +7,507,307193,V153,12132,V153 +7,508,307193,V154,20208,V154 +#其它重要天气数据、现在和过去天气、连续观测天气现象记录,,V155,,V155 +7,509,307193,V156,101004,V156 +7,510,307193,V157,2201,V157 +7,511,307193,V158,106000,V158 +7,512,307193,V159,31000,V159 +7,513,307193,V160,2180,V160 +7,514,307193,V161,20197,V161 +7,515,307193,V162,20054,V162 +7,516,307193,V163,20067,V163 +7,517,307193,V164,20066,V164 +7,518,307193,V165,302074,V165 +7,519,307193,V166,20212,V166 +#日照,,V167,,V167 +7,520,307193,V168,2201,V168 +7,521,307193,V169,107000,V169 +7,522,307193,V170,31000,V170 +7,523,307193,V171,301011,V171 +7,524,307193,V172,103024,V172 +7,525,307193,V173,4024,V173 +7,526,307193,V174,4024,V174 +7,527,307193,V175,14031,V175 +7,528,307193,V176,4024,V176 +7,529,307193,V177,14031,V177 +7,530,307193,V178,204000,V178 +#307195辐射分钟(2017/3/16),,V179,,V179 +#测站基本信息和时间,,V180,,V180 +7,531,307195,V181,301004,V181 +7,532,307195,V182,1101,V182 +7,533,307195,V183,1192,V183 +7,534,307195,V184,301011,V184 +7,535,307195,V185,301013,V185 +7,536,307195,V186,301021,V186 +7,537,307195,V187,7030,V187 +7,538,307195,V188,7031,V188 +7,539,307195,V189,102009,V189 +7,540,307195,V190,7032,V190 +7,541,307195,V191,2201,V191 +7,542,307195,V192,25061,V192 +7,543,307195,V193,101002,V193 +7,544,307195,V194,33035,V194 +#观测数据,,V195,,V195 +7,545,307195,V196,4015,V196 +7,546,307195,V197,4065,V197 +7,547,307195,V198,154000,V198 +7,548,307195,V199,31001,V199 +7,549,307195,V200,204008,V200 +7,550,307195,V201,31021,V201 +7,551,307195,V202,8023,V202 +7,552,307195,V203,14192,V203 +7,553,307195,V204,14193,V204 +7,554,307195,V205,14194,V205 +7,555,307195,V206,14195,V206 +7,556,307195,V207,14196,V207 +7,557,307195,V208,14197,V208 +7,558,307195,V209,14198,V209 +7,559,307195,V210,14199,V210 +7,560,307195,V211,14200,V211 +7,561,307195,V212,14206,V212 +7,562,307195,V213,14207,V213 +7,563,307195,V214,8023,V214 +7,564,307195,V215,8023,V215 +7,565,307195,V216,14192,V216 +7,566,307195,V217,14193,V217 +7,567,307195,V218,14194,V218 +7,568,307195,V219,14195,V219 +7,569,307195,V220,14196,V220 +7,570,307195,V221,14197,V221 +7,571,307195,V222,14198,V222 +7,572,307195,V223,14199,V223 +7,573,307195,V224,14200,V224 +7,574,307195,V225,14206,V225 +7,575,307195,V226,14207,V226 +7,576,307195,V227,8023,V227 +7,577,307195,V228,8023,V228 +7,578,307195,V229,14192,V229 +7,579,307195,V230,14193,V230 +7,580,307195,V231,14194,V231 +7,581,307195,V232,14195,V232 +7,582,307195,V233,14196,V233 +7,583,307195,V234,14197,V234 +7,584,307195,V235,14198,V235 +7,585,307195,V236,14199,V236 +7,586,307195,V237,14200,V237 +7,587,307195,V238,14206,V238 +7,588,307195,V239,14207,V239 +7,589,307195,V240,8023,V240 +7,590,307195,V241,8023,V241 +7,591,307195,V242,14192,V242 +7,592,307195,V243,14193,V243 +7,593,307195,V244,14194,V244 +7,594,307195,V245,14195,V245 +7,595,307195,V246,14196,V246 +7,596,307195,V247,14197,V247 +7,597,307195,V248,14198,V248 +7,598,307195,V249,14199,V249 +7,599,307195,V250,14200,V250 +7,600,307195,V251,14206,V251 +7,601,307195,V252,14207,V252 +7,602,307195,V253,8023,V253 +7,603,307195,V254,101005,V254 +7,604,307195,V255,11002,V255 +7,605,307195,V256,101006,V256 +7,606,307195,V257,12002,V257 +7,607,307195,V258,204000,V258 +#307196辐射小时3.1(最终稿20160509),,V259,,V259 +#测站基本信息和时间,,V260,,V260 +7,608,307196,V261,301004,V261 +7,609,307196,V262,1101,V262 +7,610,307196,V263,1192,V263 +7,611,307196,V264,301011,V264 +7,612,307196,V265,301013,V265 +7,613,307196,V266,301021,V266 +7,614,307196,V267,7030,V267 +7,615,307196,V268,7031,V268 +7,616,307196,V269,102009,V269 +7,617,307196,V270,7032,V270 +7,618,307196,V271,2201,V271 +7,619,307196,V272,25061,V272 +7,620,307196,V273,101002,V273 +7,621,307196,V274,33035,V274 +#观测数据,,V275,,V275 +7,622,307196,V276,204008,V276 +7,623,307196,V277,31021,V277 +7,624,307196,V278,8023,V278 +7,625,307196,V279,14192,V279 +7,626,307196,V280,14193,V280 +7,627,307196,V281,14194,V281 +7,628,307196,V282,14195,V282 +7,629,307196,V283,14196,V283 +7,630,307196,V284,14197,V284 +7,631,307196,V285,14198,V285 +7,632,307196,V286,14199,V286 +7,633,307196,V287,14200,V287 +7,634,307196,V288,14206,V288 +7,635,307196,V289,14207,V289 +7,636,307196,V290,14210,V290 +7,637,307196,V291,8023,V291 +7,638,307196,V292,14211,V292 +7,639,307196,V293,14212,V293 +7,640,307196,V294,14213,V294 +7,641,307196,V295,14201,V295 +7,642,307196,V296,14202,V296 +7,643,307196,V297,14203,V297 +7,644,307196,V298,14204,V298 +7,645,307196,V299,14205,V299 +7,646,307196,V300,14215,V300 +7,647,307196,V301,14214,V301 +7,648,307196,V302,14208,V302 +7,649,307196,V303,8023,V303 +7,650,307196,V304,14196,V304 +7,651,307196,V305,301012,V305 +7,652,307196,V306,14197,V306 +7,653,307196,V307,301012,V307 +7,654,307196,V308,14206,V308 +7,655,307196,V309,301012,V309 +7,656,307196,V310,8023,V310 +7,657,307196,V311,8023,V311 +7,658,307196,V312,14192,V312 +7,659,307196,V313,301012,V313 +7,660,307196,V314,14193,V314 +7,661,307196,V315,301012,V315 +7,662,307196,V316,14194,V316 +7,663,307196,V317,301012,V317 +7,664,307196,V318,14195,V318 +7,665,307196,V319,301012,V319 +7,666,307196,V320,14196,V320 +7,667,307196,V321,301012,V321 +7,668,307196,V322,14197,V322 +7,669,307196,V323,301012,V323 +7,670,307196,V324,14198,V324 +7,671,307196,V325,301012,V325 +7,672,307196,V326,14199,V326 +7,673,307196,V327,301012,V327 +7,674,307196,V328,14200,V328 +7,675,307196,V329,301012,V329 +7,676,307196,V330,14206,V330 +7,677,307196,V331,301012,V331 +7,678,307196,V332,14207,V332 +7,679,307196,V333,301012,V333 +7,680,307196,V334,8023,V334 +7,681,307196,V335,14031,V335 +7,682,307196,V336,14210,V336 +7,683,307196,V337,14209,V337 +7,684,307196,V338,20209,V338 +7,685,307196,V339,20210,V339 +7,686,307196,V340,204000,V340 +#322192酸雨1.1,2017/8/4,V341,,V341 +#测站信息,,V342,,V342 +22,687,322192,V343,301004,V343 +22,688,322192,V344,1101,V344 +22,689,322192,V345,1192,V345 +22,690,322192,V346,301021,V346 +22,691,322192,V347,7030,V347 +22,692,322192,V348,101002,V348 +22,693,322192,V349,33035,V349 +#时间要素信息,,V350,,V350 +22,694,322192,V351,301011,V351 +22,695,322192,V352,140000,V352 +22,696,322192,V353,31000,V353 +22,697,322192,V354,138000,V354 +22,698,322192,V355,31000,V355 +22,699,322192,V356,105002,V356 +22,700,322192,V357,4001,V357 +22,701,322192,V358,4002,V358 +22,702,322192,V359,4003,V359 +22,703,322192,V360,4004,V360 +22,704,322192,V361,4005,V361 +#辅助观测数据,,V362,,V362 +22,705,322192,V363,13011,V363 +22,706,322192,V364,101000,V364 +22,707,322192,V365,31001,V365 +22,708,322192,V366,20192,V366 +22,709,322192,V367,102004,V367 +22,710,322192,V368,11001,V368 +22,711,322192,V369,11002,V369 +#观测数据,,V370,,V370 +22,712,322192,V371,118000,V371 +22,713,322192,V372,31001,V372 +22,714,322192,V373,204008,V373 +22,715,322192,V374,31021,V374 +22,716,322192,V375,12001,V375 +22,726,322192,V376,202129,V376 +22,717,322192,V377,101003,V377 +22,718,322192,V378,13080,V378 +22,719,322192,V379,8023,V379 +22,720,322192,V380,13080,V380 +22,721,322192,V381,8023,V381 +22,726,322192,V382,202000,V382 +22,726,322192,V383,202130,V383 +22,722,322192,V384,101003,V384 +22,723,322192,V385,13081,V385 +22,724,322192,V386,8023,V386 +22,725,322192,V387,13081,V387 +22,726,322192,V388,8023,V388 +22,726,322192,V389,202000,V389 +22,727,322192,V390,204000,V390 +#酸雨观测备注信息,,V391,,V391 +22,728,322192,V392,2203,V392 +22,729,322192,V393,2204,V393 +22,730,322192,V394,2205,V394 +22,731,322192,V395,101002,V395 +22,732,322192,V396,2206,V396 +#......................,,V397,,V397 +#322193大气负离子1.0,,V398,,V398 +#测站基本信息,,V399,,V399 +22,733,322193,V400,301001,V400 +22,734,322193,V401,1015,V401 +22,735,322193,V402,1101,V402 +22,736,322193,V403,1192,V403 +22,737,322193,V404,301011,V404 +22,738,322193,V405,301013,V405 +22,739,322193,V406,301021,V406 +22,740,322193,V407,7030,V407 +22,741,322193,V408,101003,V408 +22,742,322193,V409,33035,V409 +#大气负离子浓度观测数据、运行状态及质控信息,,V410,,V410 +22,743,322193,V411,116000,V411 +22,744,322193,V412,31000,V412 +22,745,322193,V413,7032,V413 +22,746,322193,V414,204012,V414 +22,747,322193,V415,31021,V415 +22,748,322193,V416,15192,V416 +22,749,322193,V417,15193,V417 +22,750,322193,V418,12001,V418 +22,751,322193,V419,13003,V419 +22,752,322193,V420,204000,V420 +22,753,322193,V421,48192,V421 +22,754,322193,V422,25025,V422 +22,755,322193,V423,48193,V423 +22,756,322193,V424,49192,V424 +22,757,322193,V425,49193,V425 +22,758,322193,V426,33192,V426 +22,759,322193,V427,33193,V427 +22,760,322193,V428,7032,V428 +########################,,V429,,V429 +#雨滴谱模板1.0,,V430,,V430 +########################,,V431,,V431 +#测站基本信息和时间,,V432,,V432 +7,761,307194,V433,301004,V433 +7,762,307194,V434,1101,V434 +7,763,307194,V435,1192,V435 +7,764,307194,V436,301011,V436 +7,765,307194,V437,301012,V437 +7,766,307194,V438,301021,V438 +#天气现象雨滴谱谱图,,V439,,V439 +7,767,307194,V440,2201,V440 +7,768,307194,V441,2240,V441 +7,769,307194,V442,111000,V442 +7,770,307194,V443,31000,V443 +7,771,307194,V444,4015,V444 +7,772,307194,V445,4065,V445 +7,773,307194,V446,107000,V446 +7,774,307194,V447,31001,V447 +7,775,307194,V448,105000,V448 +7,776,307194,V449,31002,V449 +7,777,307194,V450,13205,V450 +7,778,307194,V451,204008,V451 +7,779,307194,V452,31021,V452 +7,780,307194,V453,13206,V453 +7,781,307194,V454,204000,V454 +#FY3-C视场变量序列20170625,,V455,,V455 +10,782,310068,V456,8070,V456 +10,783,310068,V457,1033,V457 +10,784,310068,V458,1034,V458 +10,785,310068,V459,1007,V459 +10,785,310068,V460,2019,V460 +10,785,310068,V461,12064,V461 +10,786,310068,V462,5040,V462 +10,787,310068,V463,201136,V463 +10,788,310068,V464,5041,V464 +10,789,310068,V465,201000,V465 +10,790,310068,V466,5043,V466 +10,791,310068,V467,301011,V467 +10,794,310068,V468,301012,V468 +10,803,310068,V469,201138,V469 +10,803,310068,V470,202131,V470 +10,798,310068,V471,4006,V471 +10,803,310068,V472,202000,V472 +10,803,310068,V473,201000,V473 +10,801,310068,V474,5001,V474 +10,802,310068,V475,6001,V475 +10,803,310068,V476,202126,V476 +10,804,310068,V477,7001,V477 +10,805,310068,V478,202000,V478 +10,810,310068,V479,10007,V479 +10,806,310068,V480,7024,V480 +10,807,310068,V481,5021,V481 +10,808,310068,V482,7025,V482 +10,809,310068,V483,5022,V483 +10,811,310068,V484,13040,V484 +10,811,310068,V485,12101,V485 +10,811,310068,V486,201131,V486 +10,811,310068,V487,202129,V487 +10,811,310068,V488,11011,V488 +10,811,310068,V489,202000,V489 +10,811,310068,V490,201000,V490 +10,811,310068,V491,201130,V491 +10,811,310068,V492,202129,V492 +10,811,310068,V493,11012,V493 +10,811,310068,V494,202000,V494 +10,811,310068,V495,201000,V495 +10,811,310068,V496,20029,V496 +10,812,310068,V497,20010,V497 +10,812,310068,V498,20014,V498 +10,813,310068,V499,13162,V499 +10,814,310068,V500,14050,V500 +#FY3-C通道变量序列20170625,,V501,,V501 +10,816,310069,V502,5042,V502 +10,817,310069,V503,201139,V503 +10,817,310069,V504,2155,V504 +10,817,310069,V505,201000,V505 +10,818,310069,V506,25077,V506 +10,819,310069,V507,25078,V507 +10,819,310069,V508,33007,V508 +10,820,310069,V509,201132,V509 +10,821,310069,V510,202129,V510 +10,822,310069,V511,12063,V511 +10,823,310069,V512,202000,V512 +10,824,310069,V513,201000,V513 +#FY3-C MWTS,,V514,,V514 +10,824,310070,V515,310068,V515 +10,824,310070,V516,101013,V516 +10,824,310070,V517,310069,V517 +#FY3-C MWHS,,V518,,V518 +10,824,310071,V519,310068,V519 +10,824,310071,V520,101015,V520 +10,824,310071,V521,310069,V521 +#FY3-C IRAS,,V522,,V522 +10,824,310072,V523,310068,V523 +10,824,310072,V524,101026,V524 +10,824,310072,V525,310069,V525 diff --git a/bufr/src/main/resources/resources/bufrTables/local/tablelookup.csv b/bufr/src/main/resources/resources/bufrTables/local/tablelookup.csv index 22efae83f9..5686055049 100644 --- a/bufr/src/main/resources/resources/bufrTables/local/tablelookup.csv +++ b/bufr/src/main/resources/resources/bufrTables/local/tablelookup.csv @@ -71,3 +71,7 @@ EUMETSAT.19, 254, -1, -1, -1, -1, resource:/resources/bufrTables/l # # EUMETNET OPERA - using -1 !!!! #255, 255, -1, 5, -1, resource:/resources/bufrTables/local/opera/localtabb_65535_5.csv, opera, resource:/resources/bufrTables/local/opera/localtabd_65535_5.csv, opera, +# +# CMA +# CMA Bufr table +CMA.23, 38, 0, 23, -1, -1, resource:/resources/bufrTables/local/cma/cma_bufr_tableb.csv, wmo_csv, resource:/resources/bufrTables/local/cma/cma_bufr_tabled.csv, wmo_csv diff --git a/cdm/core/src/main/java/ucar/ma2/ArraySequence.java b/cdm/core/src/main/java/ucar/ma2/ArraySequence.java index 779726c4be..fd36be6684 100644 --- a/cdm/core/src/main/java/ucar/ma2/ArraySequence.java +++ b/cdm/core/src/main/java/ucar/ma2/ArraySequence.java @@ -4,6 +4,7 @@ */ package ucar.ma2; +import ucar.nc2.Sequence; import ucar.nc2.util.Indent; import java.io.IOException; import java.util.ArrayList; @@ -361,6 +362,24 @@ private Array extractMemberArrayFromIteration(StructureMembers.Member proxym, in StructureMembers membersw = proxym.getStructureMembers().toBuilder(false).build(); return new ArrayStructureW(membersw, rshape, result.toArray(new StructureData[0])); } + + // add SEQUENCE data type + case SEQUENCE: { + ArrayList result = new ArrayList<>(initial); + while (sdataIter.hasNext()) { + StructureData sdata = sdataIter.next(); + StructureMembers.Member realm = sdata.getStructureMembers().findMember(proxym.getName()); + ArraySequence as = sdata.getArraySequence(realm); + result.add(as); + count++; + } + ArraySequence[] da = new ArraySequence[result.size()]; + int i = 0; + for (ArraySequence d : result) + da[i++] = d; + dataArray = da; + break; + } } } diff --git a/cdm/core/src/main/java/ucar/nc2/Variable.java b/cdm/core/src/main/java/ucar/nc2/Variable.java index a872f50088..7f89fb6413 100644 --- a/cdm/core/src/main/java/ucar/nc2/Variable.java +++ b/cdm/core/src/main/java/ucar/nc2/Variable.java @@ -789,8 +789,65 @@ public Array reallyRead(Variable client, CancelTask cancelTask) throws IOExcepti List memList = new ArrayList<>(); memList.add(this.getShortName()); Structure s = getParentStructure().select(memList); - ArrayStructure as = (ArrayStructure) s.read(); - return as.extractMemberArray(as.findMember(getShortName())); + + // s.read() may return an ArrayObject with sequence data type when the client is sequence. + // That's way we need the code to read the data array from it. + Array a = s.read(); + if (a instanceof ArrayStructure) { + ArrayStructure as = (ArrayStructure) a; + return as.extractMemberArray(as.findMember(getShortName())); + } else { + IndexIterator iter = a.getIndexIterator(); + List arrays = new ArrayList<>(); + int len = 0; + DataType dataType1 = DataType.SEQUENCE; + while (iter.hasNext()) { + ArrayStructure as = (ArrayStructure) iter.getObjectNext(); + if (as == null) { + arrays.add(null); + } else { + Array array = as.extractMemberArray(as.findMember(getShortName())); + if (len == 0) { + dataType1 = array.getDataType(); + } + arrays.add(array); + len += (int) array.getSize(); + } + } + + if (arrays.size() == 1) { + return arrays.get(0); + } else { + Array r; + IndexIterator rIter; + switch (dataType1) { + case SEQUENCE: + case STRUCTURE: + len = arrays.size(); + r = Array.factory(dataType1, new int[]{len}); + for (int i = 0; i < len; i++) { + if (arrays.get(i).getSize() > 0) + r.setObject(i, arrays.get(i).getObject(0)); + } + break; + default: + r = Array.factory(dataType1, new int[]{len}); + rIter = r.getIndexIterator(); + for (Array array : arrays) { + if (array != null) { + IndexIterator aIter = array.getIndexIterator(); + while (aIter.hasNext()) { + if (rIter.hasNext()) { + rIter.setObjectNext(aIter.getObjectNext()); + } + } + } + } + break; + } + return r; + } + } } try {