visad/src/main/java/ucar/nc2/iosp/gempak/GempakSurfaceIOSP.java
private Array readShipData(Variable v2, Section section)
          throws IOException {

    Array array = null;
    if (v2 instanceof Structure) {
      List<GempakParameter> params =
              gemreader.getParameters(GempakSurfaceFileReader.SFDT);
      Structure pdata = (Structure) v2;
      StructureMembers members = pdata.makeStructureMembers();
      List<StructureMembers.Member> mbers = members.getMembers();
      int ssize = 0;
      //int stnVarNum = 0;
      List<String> stnKeyNames = gemreader.getStationKeyNames();
      for (StructureMembers.Member member : mbers) {
        if (stnKeyNames.contains(member.getName())) {
          int varSize = getStnVarSize(member.getName());
          member.setDataParam(ssize);
          ssize += varSize;
        } else if (member.getName().equals(TIME_VAR)) {
          member.setDataParam(ssize);
          ssize += 8;
        } else if (member.getName().equals(MISSING_VAR)) {
          member.setDataParam(ssize);
          ssize += 1;
        } else {
          member.setDataParam(ssize);
          ssize += 4;
        }
      }
      members.setStructureSize(ssize);

      // TODO:  figure out how to get the missing value for data
      //float[] missing = new float[mbers.size()];
      //int     missnum = 0;
      //for (Variable v : pdata.getVariables()) {
      //    Attribute att = v.findAttribute("missing_value");
      //    missing[missnum++] = (att == null)
      //                         ? GempakConstants.RMISSD
      //                         : att.getNumericValue().floatValue();
      //}


      Range recordRange = section.getRange(0);
      int size = recordRange.length();
      // Create a ByteBuffer using a byte array
      byte[] bytes = new byte[ssize * size];
      ByteBuffer buf = ByteBuffer.wrap(bytes);
      array = new ArrayStructureBB(members, new int[]{size}, buf, 0);
      List<GempakStation> stationList = gemreader.getStations();
      List<Date> dateList = gemreader.getDates();
      boolean needToReadData = !pdata.isSubset();
      if (!needToReadData) {  // subset, see if we need some param data
        for (GempakParameter param : params) {
          if (members.findMember(param.getName()) != null) {
            needToReadData = true;
            break;
          }
        }
      }
      //boolean hasTime = (members.findMember(TIME_VAR) != null);

      // fill out the station information
      for (int recIdx : recordRange) {
        GempakStation stn = stationList.get(recIdx);
        for (String varname : stnKeyNames) {
          if (members.findMember(varname) == null) {
            continue;
          }
          String temp = null;
          switch (varname) {
            case GempakStation.STID:
              temp = StringUtil2.padRight(stn.getName(), 8);
              break;
            case GempakStation.STNM:
              buf.putInt(stn.getSTNM());
              break;
            case GempakStation.SLAT:
              buf.putFloat((float) stn.getLatitude());
              break;
            case GempakStation.SLON:
              buf.putFloat((float) stn.getLongitude());
              break;
            case GempakStation.SELV:
              buf.putFloat((float) stn.getAltitude());
              break;
            case GempakStation.STAT:
              temp = StringUtil2.padRight(stn.getSTAT(), 2);
              break;
            case GempakStation.COUN:
              temp = StringUtil2.padRight(stn.getCOUN(), 2);
              break;
            case GempakStation.STD2:
              temp = StringUtil2.padRight(stn.getSTD2(), 4);
              break;
            case GempakStation.SPRI:
              buf.putInt(stn.getSPRI());
              break;
            case GempakStation.SWFO:
              temp = StringUtil2.padRight(stn.getSWFO(), 4);
              break;
            case GempakStation.WFO2:
              temp = StringUtil2.padRight(stn.getWFO2(), 4);
              break;
          }
          if (temp != null) {
            buf.put(temp.getBytes(CDM.utf8Charset));
          }
        }
        if (members.findMember(TIME_VAR) != null) {
          // put in the time
          Date time = dateList.get( recIdx);
          buf.putDouble(time.getTime() / 1000.d);
        }

        if (needToReadData) {
          int column = stn.getIndex();
          GempakFileReader.RData vals =
                  gemreader.DM_RDTR(1, column,
                          GempakSurfaceFileReader.SFDT);
          if (vals == null) {
            for (GempakParameter param : params) {
              if (members.findMember(param.getName()) != null) {
                buf.putFloat(GempakConstants.RMISSD);
              }
            }
            buf.put((byte) 1);
          } else {
            float[] reals = vals.data;
            int var = 0;
            for (GempakParameter param : params) {
              if (members.findMember(param.getName()) != null) {
                buf.putFloat(reals[var]);
              }
              var++;
            }
            buf.put((byte) 0);
          }
        }
      }
      //Trace.call2("GEMPAKSIOSP: readShipData");
    }
    return array;
  }
private Array readShipData(Variable v2, Section section)
          throws IOException {

    Array array = null;
    if (v2 instanceof Structure) {
      List<GempakParameter> params =
              gemreader.getParameters(GempakSurfaceFileReader.SFDT);
      Structure pdata = (Structure) v2;
      StructureMembers members = pdata.makeStructureMembers();
      List<StructureMembers.Member> mbers = members.getMembers();
      int ssize = 0;
      //int stnVarNum = 0;
      List<String> stnKeyNames = gemreader.getStationKeyNames();
      for (StructureMembers.Member member : mbers) {
        if (stnKeyNames.contains(member.getName())) {
          int varSize = getStnVarSize(member.getName());
          member.setDataParam(ssize);
          ssize += varSize;
        } else if (member.getName().equals(TIME_VAR)) {
          member.setDataParam(ssize);
          ssize += 8;
        } else if (member.getName().equals(MISSING_VAR)) {
          member.setDataParam(ssize);
          ssize += 1;
        } else {
          member.setDataParam(ssize);
          ssize += 4;
        }
      }
      members.setStructureSize(ssize);

      // TODO:  figure out how to get the missing value for data
      //float[] missing = new float[mbers.size()];
      //int     missnum = 0;
      //for (Variable v : pdata.getVariables()) {
      //    Attribute att = v.findAttribute("missing_value");
      //    missing[missnum++] = (att == null)
      //                         ? GempakConstants.RMISSD
      //                         : att.getNumericValue().floatValue();
      //}


      Range recordRange = section.getRange(0);
      int size = recordRange.length();
      // Create a ByteBuffer using a byte array
      byte[] bytes = new byte[ssize * size];
      ByteBuffer buf = ByteBuffer.wrap(bytes);
      array = new ArrayStructureBB(members, new int[]{size}, buf, 0);
      List<GempakStation> stationList = gemreader.getStations();
      List<Date> dateList = gemreader.getDates();
      boolean needToReadData = !pdata.isSubset();
      if (!needToReadData) {  // subset, see if we need some param data
        for (GempakParameter param : params) {
          if (members.findMember(param.getName()) != null) {
            needToReadData = true;
            break;
          }
        }
      }
      //boolean hasTime = (members.findMember(TIME_VAR) != null);

      // fill out the station information
      for (int recIdx : recordRange) {
        GempakStation stn = stationList.get(recIdx);
        for (String varname : stnKeyNames) {
          if (members.findMember(varname) == null) {
            continue;
          }
          String temp = null;
          switch (varname) {
            case GempakStation.STID:
              temp = StringUtil2.padRight(stn.getName(), 8);
              break;
            case GempakStation.STNM:
              buf.putInt(stn.getSTNM());
              break;
            case GempakStation.SLAT:
              buf.putFloat((float) stn.getLatitude());
              break;
            case GempakStation.SLON:
              buf.putFloat((float) stn.getLongitude());
              break;
            case GempakStation.SELV:
              buf.putFloat((float) stn.getAltitude());
              break;
            case GempakStation.STAT:
              temp = StringUtil2.padRight(stn.getSTAT(), 2);
              break;
            case GempakStation.COUN:
              temp = StringUtil2.padRight(stn.getCOUN(), 2);
              break;
            case GempakStation.STD2:
              temp = StringUtil2.padRight(stn.getSTD2(), 4);
              break;
            case GempakStation.SPRI:
              buf.putInt(stn.getSPRI());
              break;
            case GempakStation.SWFO:
              temp = StringUtil2.padRight(stn.getSWFO(), 4);
              break;
            case GempakStation.WFO2:
              temp = StringUtil2.padRight(stn.getWFO2(), 4);
              break;
          }
          if (temp != null) {
            buf.put(temp.getBytes(CDM.utf8Charset));
          }
        }
        if (members.findMember(TIME_VAR) != null) {
          // put in the time
          Date time = dateList.get( recIdx);
          buf.putDouble(time.getTime() / 1000.d);
        }

        if (needToReadData) {
          int column = stn.getIndex();
          GempakFileReader.RData vals =
                  gemreader.DM_RDTR(1, column,
                          GempakSurfaceFileReader.SFDT);
          if (vals == null) {
            for (GempakParameter param : params) {
              if (members.findMember(param.getName()) != null) {
                buf.putFloat(GempakConstants.RMISSD);
              }
            }
            buf.put((byte) 1);
          } else {
            float[] reals = vals.data;
            int var = 0;
            for (GempakParameter param : params) {
              if (members.findMember(param.getName()) != null) {
                buf.putFloat(reals[var]);
              }
              var++;
            }
            buf.put((byte) 0);
          }
        }
      }
      //Trace.call2("GEMPAKSIOSP: readShipData");
    }
    return array;
  }
Read in the data for the record variable.  In this case, it should be
a Structure of record dimension.  We can handle a subset of the
variables in a structure.

@param v2      variable to read
@param section section of the variable
@return the array of data
@throws IOException problem reading the file