|
|
@@ -0,0 +1,415 @@
|
|
|
+package com.ph.grib2tools.grib2file;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.nio.ByteBuffer;
|
|
|
+import java.util.logging.Logger;
|
|
|
+
|
|
|
+import com.ph.grib2tools.grib2file.datarepresentation.DataRepresentationTemplate50;
|
|
|
+import com.ph.grib2tools.grib2file.griddefinition.GridDefinitionTemplate30;
|
|
|
+
|
|
|
+// A representation of a GRIB file containing all meta data and allowing a random
|
|
|
+// access to the data of the GRIB file. While the random access allows great flexibility
|
|
|
+// it requires that the complete data is held in memory
|
|
|
+public class RandomAccessGribFile extends GribFile {
|
|
|
+
|
|
|
+ private static final long serialVersionUID = 100L;
|
|
|
+
|
|
|
+ private static final Logger log = Logger.getLogger(RandomAccessGribFile.class.getName());
|
|
|
+
|
|
|
+
|
|
|
+ public RandomAccessGribFile(String typeid, String source) {
|
|
|
+ super(typeid, source);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void importFromStream(InputStream gribfile, int numskip) throws IOException {
|
|
|
+
|
|
|
+ if (gribfile == null) return;
|
|
|
+
|
|
|
+ // By overwriting the section variables, the first numskip GRIB file data structures
|
|
|
+ // within a stream or a file can be skipped
|
|
|
+ for (int t=0; t<numskip+1; t++) {
|
|
|
+
|
|
|
+ gridcnt = 0;
|
|
|
+
|
|
|
+ //while (true) {
|
|
|
+ while (gridcnt < 1) {
|
|
|
+
|
|
|
+ // Read all meta data but not the data itself in Section 7
|
|
|
+ importMetadatFromStream(gribfile);
|
|
|
+
|
|
|
+ // Read the data of Section 7 into memory
|
|
|
+ GribSection nextsection = new GribSection(gribfile).initSection();
|
|
|
+ if (nextsection.sectionnumber == 7) {
|
|
|
+ section7[gridcnt] = (GribSection7)nextsection;
|
|
|
+ //section7[gridcnt].setDataRepresentation(section5[gridcnt].numberDataPoints, section5[gridcnt].dataRepresentationTemplate);
|
|
|
+ section7[gridcnt].setDataRepresentation(section5[gridcnt].numberValues, section5[gridcnt].dataRepresentationTemplate);
|
|
|
+ section7[gridcnt].readData(gribfile);
|
|
|
+
|
|
|
+ // Decode bit map to expand sparse data grid to full data grid
|
|
|
+ section7[gridcnt].setBitmapDecodedData(decodeDataBitmap(gridcnt));
|
|
|
+
|
|
|
+ gridcnt++;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ log.warning("Section " + nextsection.sectionnumber + " found while Section 7 expected. aborting.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ finalizeImport(gribfile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] decodeDataBitmap(int gridcnt) {
|
|
|
+
|
|
|
+ //GribSection6 section6 = gribFile.getSection6(0);
|
|
|
+ if (section6[gridcnt].bitMapIndicator == 0) {
|
|
|
+
|
|
|
+ GridDefinitionTemplate30 gridDefinition = (GridDefinitionTemplate30) this.getGridDefinitionTemplate();
|
|
|
+ DataRepresentationTemplate50 dataRepresentation = (DataRepresentationTemplate50) this.getDataRepresentationTemplate(gridcnt);
|
|
|
+ int numbits = dataRepresentation.numberBits;
|
|
|
+ int baseMask = (int)(Math.pow(2, numbits) - 1);
|
|
|
+
|
|
|
+ byte valuesArray[] = section7[gridcnt].sectiondata;
|
|
|
+ byte decodedGridData[] = new byte[gridDefinition.numberPointsLat*gridDefinition.numberPointsLon*2];
|
|
|
+
|
|
|
+ if ((gridDefinition.scanningMode & 0x04) == 0x00) {
|
|
|
+
|
|
|
+ // Holds the index of the next value in the value array of Section 7
|
|
|
+ int sourcevaluecnt = 0;
|
|
|
+
|
|
|
+ for (int j=0; j<gridDefinition.numberPointsLat; j++) {
|
|
|
+ for (int i=0; i<gridDefinition.numberPointsLon; i++) {
|
|
|
+
|
|
|
+ // Index of the bit map
|
|
|
+ int bitmapIdx;
|
|
|
+ bitmapIdx = j*gridDefinition.numberPointsLon + i;
|
|
|
+
|
|
|
+ // Position of byte and bit of the bit map
|
|
|
+ int bitmapBytePos = (int)Math.floor(bitmapIdx/8);
|
|
|
+ int bitmapBitPos = bitmapIdx % 8;
|
|
|
+ byte bitmapByte = section6[gridcnt].bitMap[bitmapBytePos];
|
|
|
+
|
|
|
+ int rawValue;
|
|
|
+
|
|
|
+ // Grid point without value, here we set this to zero. Depending on the data, this is
|
|
|
+ // not the best value. Maybe value for empty grid pos should be made configurable
|
|
|
+ if ((bitmapByte & (1 << (7-bitmapBitPos))) == 0) rawValue = 0;
|
|
|
+
|
|
|
+ // Grid point with value
|
|
|
+ else {
|
|
|
+
|
|
|
+ // Position of the value in the array of values of Section 7
|
|
|
+ int sourcebitpos = sourcevaluecnt * numbits;
|
|
|
+
|
|
|
+ // Position of byte and bit of the value array
|
|
|
+ int valstartbyte = (int)Math.floor(sourcebitpos/8);
|
|
|
+ int valstartbit = sourcebitpos % 8;
|
|
|
+
|
|
|
+ // Retrieve value from value array
|
|
|
+ if (numbits <= 8) {
|
|
|
+
|
|
|
+ // Adapt value array access to align to array end
|
|
|
+ int readstartbyte;
|
|
|
+ int rawValueBitLength;
|
|
|
+ if (valstartbyte < valuesArray.length-2) {
|
|
|
+ readstartbyte = valstartbyte;
|
|
|
+ rawValueBitLength = 16;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ readstartbyte = valuesArray.length-2;
|
|
|
+ rawValueBitLength = 16 + ((valuesArray.length-2) - valstartbyte) * 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get data from values array
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.wrap(valuesArray, readstartbyte, 2);
|
|
|
+ rawValue = byteBuffer.getShort();
|
|
|
+
|
|
|
+ // Adjust for correct position in bit stream
|
|
|
+ rawValue = (byte) (rawValue >> (rawValueBitLength-numbits-valstartbit));
|
|
|
+ rawValue = (byte) (rawValue & baseMask);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ // Adapt value array access to align to array end
|
|
|
+ int readstartbyte;
|
|
|
+ int rawValueBitLength;
|
|
|
+ if (valstartbyte < valuesArray.length-4) {
|
|
|
+ readstartbyte = valstartbyte;
|
|
|
+ rawValueBitLength = 32;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ readstartbyte = valuesArray.length-4;
|
|
|
+ rawValueBitLength = 32 + ((valuesArray.length-4) - valstartbyte) * 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get data from values array
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.wrap(valuesArray, readstartbyte, 4);
|
|
|
+ rawValue = byteBuffer.getInt();
|
|
|
+
|
|
|
+ // Adjust for correct position in bit stream
|
|
|
+ rawValue = (int) (rawValue >> (rawValueBitLength-numbits-valstartbit));
|
|
|
+ rawValue = (int) (rawValue & baseMask);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Increase the index of the next value in the value array of Section 7
|
|
|
+ sourcevaluecnt++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Position of the value in the array of values of Section 7
|
|
|
+ int targetbitpos = bitmapIdx * numbits;
|
|
|
+
|
|
|
+ // Position of byte and bit of the value array
|
|
|
+ int targetstartbyte = (int)Math.floor(targetbitpos/8);
|
|
|
+ int targetstartbit = targetbitpos % 8;
|
|
|
+
|
|
|
+ // Write value in the full grid data array
|
|
|
+ if (numbits <= 8) {
|
|
|
+
|
|
|
+ // Adapt target data array access to align to array end
|
|
|
+ int readstartbyte;
|
|
|
+ int rawValueBitLength;
|
|
|
+ if (targetstartbyte < decodedGridData.length-2) {
|
|
|
+ readstartbyte = targetstartbyte;
|
|
|
+ rawValueBitLength = 16;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ readstartbyte = decodedGridData.length-2;
|
|
|
+ rawValueBitLength = 16 + ((decodedGridData.length-2) - targetstartbyte) * 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create bit mask of length numbits shifted to have the alignment of
|
|
|
+ // the data in the bit stream
|
|
|
+ short mask = (short)(baseMask << (rawValueBitLength-numbits-targetstartbit));
|
|
|
+
|
|
|
+ // Blend data into right position of the existing data stream
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.wrap(decodedGridData, readstartbyte, 2);
|
|
|
+ short curData = byteBuffer.getShort();
|
|
|
+ short data = (short)(curData & (~mask));
|
|
|
+ data = (short)(data | (rawValue << (rawValueBitLength-numbits-targetstartbit)));
|
|
|
+
|
|
|
+ decodedGridData[readstartbyte] = (byte) ((data >> 8) & 0xFF);
|
|
|
+ decodedGridData[readstartbyte+1] = (byte) (data & 0xFF);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ // Adapt target data array access to align to array end
|
|
|
+ int readstartbyte;
|
|
|
+ int rawValueBitLength;
|
|
|
+ if (targetstartbyte < decodedGridData.length-4) {
|
|
|
+ readstartbyte = targetstartbyte;
|
|
|
+ rawValueBitLength = 32;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ readstartbyte = decodedGridData.length-4;
|
|
|
+ rawValueBitLength = 32 + ((decodedGridData.length-4) - targetstartbyte) * 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create bit mask of length numbits shifted to have the alignment of
|
|
|
+ // the data in the bit stream
|
|
|
+ int mask = (int)(baseMask << (rawValueBitLength-numbits-targetstartbit));
|
|
|
+
|
|
|
+ // Blend data into right position of the existing data stream
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.wrap(decodedGridData, readstartbyte, 4);
|
|
|
+ int curData = byteBuffer.getInt();
|
|
|
+ int data = (int)(curData & (~mask));
|
|
|
+ data = (int)(data | (rawValue << (rawValueBitLength-numbits-targetstartbit)));
|
|
|
+
|
|
|
+ decodedGridData[readstartbyte] = (byte) (data >> 24);
|
|
|
+ decodedGridData[readstartbyte+1] = (byte) ((data >> 16) & 0xFF);
|
|
|
+ decodedGridData[readstartbyte+2] = (byte) ((data >> 8) & 0xFF);
|
|
|
+ decodedGridData[readstartbyte+3] = (byte) (data & 0xFF);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return decodedGridData;
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ return section7[gridcnt].sectiondata;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extracts the data belonging to the passed coordinate (lat, lon) in degrees and returns the
|
|
|
+ // value represented by this data. If the passed coordinate is not a grid point of the
|
|
|
+ // data grid, the data belonging to the grid point closest to the passed position
|
|
|
+ // is considered.
|
|
|
+ public float getValueAtLocation(int grididx, double lat, double lon) {
|
|
|
+ return getValueAt(grididx, GribFile.degToUnits(lat), GribFile.degToUnits(lon));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extracts the data belonging to the passed coordinate (lat, lon) in units and returns the
|
|
|
+ // value represented by this data. If the passed coordinate is not a grid point of the
|
|
|
+ // data grid, the data belonging to the grid point closest to the passed position
|
|
|
+ // is considered.
|
|
|
+ public float getValueAt(int grididx, int lat, int lon) {
|
|
|
+
|
|
|
+ GribSection5 sec5 = getSection5(grididx);
|
|
|
+ GribSection7 sec7 = getSection7(grididx);
|
|
|
+
|
|
|
+ float val = 0;
|
|
|
+
|
|
|
+// if (sec5.dataRepresentationTemplateNumber == 0) {
|
|
|
+
|
|
|
+ if (section3.gridDefinitionTemplateNumber == 0) {
|
|
|
+
|
|
|
+ GridDefinitionTemplate30 gridDefinition = (GridDefinitionTemplate30)section3.gridDefinitionTemplate;
|
|
|
+
|
|
|
+ int deltaj = 0;
|
|
|
+/*
|
|
|
+ // Implementation of Scanning Modes
|
|
|
+// if ((gridDefinition.scanningMode & 0x01) == 0x01) log.warning("Scanning mode " + 0x01 + " not supported");
|
|
|
+// if ((gridDefinition.scanningMode & 0x02) == 0x02) log.warning("Scanning mode " + 0x02 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x04) == 0x04) log.warning("Scanning mode " + 0x04 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x08) == 0x08) log.warning("Scanning mode " + 0x08 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x10) == 0x10) log.warning("Scanning mode " + 0x10 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x20) == 0x20) log.warning("Scanning mode " + 0x20 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x40) == 0x40) deltaj = gridDefinition.jDirectionIncrement / 2;
|
|
|
+ if ((gridDefinition.scanningMode & 0x80) == 0x80) log.warning("Scanning mode " + 0x80 + " not supported");
|
|
|
+*/
|
|
|
+ deltaj = gridDefinition.getDeltaJ();
|
|
|
+
|
|
|
+ // Calculate j index of the matrix containing the data the contains the data of the
|
|
|
+ // passed latitude lat
|
|
|
+ int deltalat = lat - (gridDefinition.firstPointLat + deltaj);
|
|
|
+ //int jidx = Math.round((float)deltalat / (float)gridDefinition.jDirectionIncrement);
|
|
|
+// int jidx = Math.round((float)deltalat / (float)gridDefinition.getStepJ());
|
|
|
+ int jidx = (int)Math.floor((float)deltalat / (float)gridDefinition.getStepJ());
|
|
|
+
|
|
|
+ // Calculate i index of the matrix containing the data the contains the data of the
|
|
|
+ // passed longitude lon
|
|
|
+ int firstPointLon = gridDefinition.firstPointLon + 0;
|
|
|
+ if (firstPointLon >= GribFile.degToUnits(180)) firstPointLon -= GribFile.degToUnits(360);
|
|
|
+ int deltalon = lon - firstPointLon;
|
|
|
+ //int iidx = Math.round((float)deltalon / (float)gridDefinition.iDirectionIncrement);
|
|
|
+ int iidx = Math.round((float)deltalon / (float)gridDefinition.getStepI());
|
|
|
+
|
|
|
+ // Extract data belonging to the referred location and calculate the value represented by the data
|
|
|
+ byte data[] = sec7.bitmapDecodedData;
|
|
|
+ val = sec5.calcValue(data, jidx*gridDefinition.numberPointsLon+iidx);
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ log.warning("Grid Definition Template Number 3." + section3.gridDefinitionTemplateNumber + " not implemented.");
|
|
|
+ }
|
|
|
+/*
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ log.warning("Data Representation Template Number 5." + sec5.dataRepresentationTemplateNumber + " not implemented.");
|
|
|
+ }
|
|
|
+*/
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extracts the data belonging to the passed coordinate (lat, lon) in degrees and returns the
|
|
|
+ // value represented by this data. If the passed coordinate is not a grid point of the
|
|
|
+ // data grid, the data belonging to the neighbored grid points is interpolated and used
|
|
|
+ // to calculate the value belonging to the passed position.
|
|
|
+ public float interpolateValueAtLocation(int grididx, double lat, double lon) {
|
|
|
+ return interpolateValueAt(grididx, GribFile.degToUnits(lat), GribFile.degToUnits(lon));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Extracts the data belonging to the passed coordinate (lat, lon) in units and returns the
|
|
|
+ // value represented by this data. If the passed coordinate is not a grid point of the
|
|
|
+ // data grid, the data belonging to the neighbored grid points is interpolated and used
|
|
|
+ // to calculate the value belonging to the passed position.
|
|
|
+ public float interpolateValueAt(int grididx, int lat, int lon) {
|
|
|
+
|
|
|
+ GribSection5 sec5 = getSection5(grididx);
|
|
|
+ GribSection7 sec7 = getSection7(grididx);
|
|
|
+
|
|
|
+ float val = 0;
|
|
|
+
|
|
|
+// if (sec5.dataRepresentationTemplateNumber == 0) {
|
|
|
+
|
|
|
+ if (section3.gridDefinitionTemplateNumber == 0) {
|
|
|
+
|
|
|
+ GridDefinitionTemplate30 gridDefinition = (GridDefinitionTemplate30)section3.gridDefinitionTemplate;
|
|
|
+
|
|
|
+ int deltaj = 0;
|
|
|
+/*
|
|
|
+ // Implementation of Scanning Modes
|
|
|
+// if ((gridDefinition.scanningMode & 0x01) == 0x01) log.warning("Scanning mode " + 0x01 + " not supported");
|
|
|
+// if ((gridDefinition.scanningMode & 0x02) == 0x02) log.warning("Scanning mode " + 0x02 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x04) == 0x04) log.warning("Scanning mode " + 0x04 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x08) == 0x08) log.warning("Scanning mode " + 0x08 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x10) == 0x10) log.warning("Scanning mode " + 0x10 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x20) == 0x20) log.warning("Scanning mode " + 0x20 + " not supported");
|
|
|
+ if ((gridDefinition.scanningMode & 0x40) == 0x40) deltaj = gridDefinition.jDirectionIncrement / 2;
|
|
|
+ if ((gridDefinition.scanningMode & 0x80) == 0x80) log.warning("Scanning mode " + 0x80 + " not supported");
|
|
|
+*/
|
|
|
+ deltaj = gridDefinition.getDeltaJ();
|
|
|
+deltaj = 0;
|
|
|
+ // Find j indices of the grid points of the matrix containing the data that surround the
|
|
|
+ // passed latitude lat
|
|
|
+ int deltalat = lat - (gridDefinition.firstPointLat + deltaj);
|
|
|
+ //int jidx1 = Math.round((float)deltalat / (float)gridDefinition.jDirectionIncrement);
|
|
|
+ //int jidx1 = (int)Math.floor((float)deltalat / (float)gridDefinition.jDirectionIncrement);
|
|
|
+ int jidx1 = (int)Math.floor((float)deltalat / (float)gridDefinition.getStepJ());
|
|
|
+
|
|
|
+ // Correct indices when end of the array dimension is reached
|
|
|
+ if (jidx1 >= gridDefinition.numberPointsLat-1) jidx1--;
|
|
|
+ int jidx2 = jidx1 + 1;
|
|
|
+
|
|
|
+ // Find i indices of the grid points of the matrix containing the data that surround the
|
|
|
+ // passed longitude lon
|
|
|
+ int firstPointLon = gridDefinition.firstPointLon + 0;
|
|
|
+// 17.10.21
|
|
|
+// if (firstPointLon >= GribFile.degToUnits(180)) firstPointLon -= GribFile.degToUnits(360);
|
|
|
+ int deltalon = lon - firstPointLon;
|
|
|
+ //int iidx1 = Math.round((float)deltalon / (float)gridDefinition.iDirectionIncrement);
|
|
|
+ //int iidx1 = (int)Math.floor((float)deltalon / (float)gridDefinition.iDirectionIncrement);
|
|
|
+ int iidx1 = (int)Math.floor((float)deltalon / (float)gridDefinition.getStepI());
|
|
|
+
|
|
|
+ // Correct indices when end of the array dimension is reached
|
|
|
+ if (iidx1 >= gridDefinition.numberPointsLon-1) iidx1--;
|
|
|
+ int iidx2 = iidx1 + 1;
|
|
|
+
|
|
|
+
|
|
|
+ //byte data[] = sec7.sectiondata;
|
|
|
+ byte data[] = sec7.bitmapDecodedData;
|
|
|
+
|
|
|
+ // Extract data of the four grid points surrounding the passed coordinate and calculate the
|
|
|
+ // values represented by the data
|
|
|
+ float val11 = sec5.calcValue(data, jidx1*gridDefinition.numberPointsLon+iidx1);
|
|
|
+ float val12 = sec5.calcValue(data, jidx1*gridDefinition.numberPointsLon+iidx2);
|
|
|
+
|
|
|
+ float val21 = sec5.calcValue(data, jidx2*gridDefinition.numberPointsLon+iidx1);
|
|
|
+ float val22 = sec5.calcValue(data, jidx2*gridDefinition.numberPointsLon+iidx2);
|
|
|
+
|
|
|
+
|
|
|
+ // Find latitudes of the grid points of the matrix containing the data that surround the
|
|
|
+ // passed latitude lat
|
|
|
+ //int lat1 = (gridDefinition.firstPointLat + deltaj) + jidx1 * gridDefinition.jDirectionIncrement;
|
|
|
+ //int lat2 = lat1 + gridDefinition.jDirectionIncrement;
|
|
|
+ int lat1 = (gridDefinition.firstPointLat + deltaj) + jidx1 * gridDefinition.getStepJ();
|
|
|
+ int lat2 = lat1 + gridDefinition.getStepJ();
|
|
|
+
|
|
|
+ // Find longitudes of the grid points of the matrix containing the data that surround the
|
|
|
+ // passed longitude lon
|
|
|
+ int lon1 = firstPointLon + iidx1 * gridDefinition.getStepI();
|
|
|
+ int lon2 = lon1 + gridDefinition.getStepI();
|
|
|
+
|
|
|
+ // Interpolate value belonging to the passed location
|
|
|
+ float val1x = val11 + (val12-val11) * (lon-lon1) / (lon2-lon1);
|
|
|
+ float val2x = val21 + (val22-val21) * (lon-lon1) / (lon2-lon1);
|
|
|
+ val = val1x + (val2x-val1x) * (lat-lat1) / (lat2-lat1);
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ log.warning("Grid Definition Template Number 3." + section3.gridDefinitionTemplateNumber + " not implemented.");
|
|
|
+ }
|
|
|
+/*
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ log.warning("Data Representation Template Number 5." + sec5.dataRepresentationTemplateNumber + " not implemented.");
|
|
|
+ }
|
|
|
+*/
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+}
|