001: package it.geosolutions.imageio.plugins.jhdf.aps;
002:
003: import it.geosolutions.imageio.plugins.jhdf.BaseHDFStreamMetadata;
004: import it.geosolutions.imageio.plugins.jhdf.HDFUtilities;
005:
006: import java.util.ArrayList;
007: import java.util.Collections;
008: import java.util.Iterator;
009: import java.util.LinkedHashMap;
010: import java.util.Map;
011: import java.util.Set;
012:
013: import javax.imageio.metadata.IIOInvalidTreeException;
014: import javax.imageio.metadata.IIOMetadataNode;
015:
016: import ncsa.hdf.object.Attribute;
017: import ncsa.hdf.object.Dataset;
018: import ncsa.hdf.object.Datatype;
019: import ncsa.hdf.object.Group;
020: import ncsa.hdf.object.HObject;
021: import ncsa.hdf.object.ScalarDS;
022:
023: import org.w3c.dom.Node;
024:
025: public class APSStreamMetadata extends BaseHDFStreamMetadata {
026: public static final String nativeMetadataFormatName = "it.geosolutions.imageio.plugins.jhdf.aps.APSStreamMetadata_1.0";
027:
028: //TODO: Provides to build a proper structure to get CP_Pixels, CP_Lines, CP_Latitudes, CP_Longitudes information
029:
030: protected Map stdFileAttribMap = Collections
031: .synchronizedMap(new LinkedHashMap(11));
032:
033: protected Map stdTimeAttribMap = Collections
034: .synchronizedMap(new LinkedHashMap(9));
035:
036: protected Map stdSensorAttribMap = Collections
037: .synchronizedMap(new LinkedHashMap(13));
038:
039: protected Map fileInputParamAttribMap = Collections
040: .synchronizedMap(new LinkedHashMap(6));
041:
042: protected Map fileNavAttribMap = Collections
043: .synchronizedMap(new LinkedHashMap(7));
044:
045: protected Map fileInGeoCovAttribMap = Collections
046: .synchronizedMap(new LinkedHashMap(8));
047:
048: protected Map genericAttribMap = Collections
049: .synchronizedMap(new LinkedHashMap(15));
050:
051: protected Map projectionMap = null;
052:
053: protected Map productsMap = null;
054:
055: protected String[] prodList = null;
056:
057: private final int[] mapMutex = new int[] { 0 };
058:
059: private int prodListNum;
060:
061: private String projectionDatasetName;
062:
063: public APSStreamMetadata() {
064: super (false, nativeMetadataFormatName, null, null, null);
065: }
066:
067: public APSStreamMetadata(HObject root) {
068: this ();
069: buildMetadata(root);
070: }
071:
072: public Node getAsTree(String formatName) {
073: if (formatName.equals(nativeMetadataFormatName)) {
074: return getNativeTree();
075: } else {
076: throw new IllegalArgumentException(
077: "Not a recognized format!");
078: }
079: }
080:
081: private Node getNativeTree() {
082: final IIOMetadataNode root = new IIOMetadataNode(
083: nativeMetadataFormatName);
084:
085: synchronized (mapMutex) {
086:
087: ///////////////////////////////////////////////////////////////
088: //
089: // Attributes Node
090: //
091: ///////////////////////////////////////////////////////////////
092: IIOMetadataNode attribNode = new IIOMetadataNode(
093: "Attributes");
094:
095: ///////////////////////////////////////////////////////////////
096: // Standard APS Attributes
097: ///////////////////////////////////////////////////////////////
098: IIOMetadataNode stdNode = new IIOMetadataNode(
099: "StandardAPSAttributes");
100:
101: // File Attributes
102: IIOMetadataNode stdFaNode = buildAttributesNodeFromMap(
103: stdFileAttribMap, "FileAttributes");
104: stdNode.appendChild(stdFaNode);
105:
106: // Time Attributes
107: IIOMetadataNode stdTaNode = buildAttributesNodeFromMap(
108: stdTimeAttribMap, "TimeAttributes");
109: stdNode.appendChild(stdTaNode);
110:
111: // Sensor Attributes
112: IIOMetadataNode stdSaNode = buildAttributesNodeFromMap(
113: stdSensorAttribMap, "SensorAttributes");
114: stdNode.appendChild(stdSaNode);
115:
116: attribNode.appendChild(stdNode);
117:
118: //////////////////////////////////////////////////////////////////
119: // File Products Attributes
120: //////////////////////////////////////////////////////////////////
121: IIOMetadataNode fpaNode = new IIOMetadataNode(
122: "FileProductsAttributes");
123:
124: // Input Parameter Attributes
125: IIOMetadataNode fpIpaNode = buildAttributesNodeFromMap(
126: fileInputParamAttribMap, "InputParameterAttributes");
127: fpaNode.appendChild(fpIpaNode);
128:
129: // Navigation Attributes
130: IIOMetadataNode fpNaNode = buildAttributesNodeFromMap(
131: fileNavAttribMap, "NavigationAttributes");
132: fpaNode.appendChild(fpNaNode);
133:
134: // Input Geographical Coverage Attributes
135: IIOMetadataNode fpIgcaNode = buildAttributesNodeFromMap(
136: fileInGeoCovAttribMap,
137: "InputGeographicalCoverageAttributes");
138: fpaNode.appendChild(fpIgcaNode);
139:
140: attribNode.appendChild(fpaNode);
141:
142: //////////////////////////////////////////////////////////////////
143: // Generic Attributes
144: //////////////////////////////////////////////////////////////////
145: IIOMetadataNode genericNode = buildAttributesNodeFromMap(
146: genericAttribMap, "GenericAttributes");
147: attribNode.appendChild(genericNode);
148: root.appendChild(attribNode);
149:
150: IIOMetadataNode productsNode = new IIOMetadataNode(
151: "Products");
152: productsNode.setAttribute("numberOfProducts", Integer
153: .toString(prodListNum));
154:
155: final Set set = productsMap.keySet();
156: final Iterator productsIt = set.iterator();
157:
158: while (productsIt.hasNext()) {
159: IIOMetadataNode productNode = new IIOMetadataNode(
160: "Product");
161: final String name = (String) productsIt.next();
162: productNode.setAttribute("name", name);
163: final ArrayList attribs = (ArrayList) productsMap
164: .get(name);
165:
166: final Map pdsaAttribMap = (LinkedHashMap) attribs
167: .get(0);
168: IIOMetadataNode pdsaAttribNode = buildAttributesNodeFromMap(
169: pdsaAttribMap, "ProductDatasetAttributes");
170: productNode.appendChild(pdsaAttribNode);
171:
172: final Map genericAttribMap = (LinkedHashMap) attribs
173: .get(1);
174: IIOMetadataNode genericPdsaNode = buildAttributesNodeFromMap(
175: genericAttribMap, "ProductGenericAttributes");
176: productNode.appendChild(genericPdsaNode);
177:
178: productsNode.appendChild(productNode);
179: }
180:
181: root.appendChild(productsNode);
182: IIOMetadataNode referencingNode = new IIOMetadataNode(
183: "Referencing");
184: IIOMetadataNode projectionNode = buildAttributesNodeFromMap(
185: projectionMap, "Projection");
186:
187: referencingNode.appendChild(projectionNode);
188: root.appendChild(referencingNode);
189: }
190: return root;
191: }
192:
193: public boolean isReadOnly() {
194: // TODO Auto-generated method stub
195: return false;
196: }
197:
198: public void mergeTree(String formatName, Node root)
199: throws IIOInvalidTreeException {
200: // TODO Auto-generated method stub
201:
202: }
203:
204: public void reset() {
205: // TODO Auto-generated method stub
206:
207: }
208:
209: public void buildMetadata(HObject root) {
210: Iterator metadataIt;
211: try {
212: metadataIt = root.getMetadata().iterator();
213:
214: // number of supported attributes
215: final int nStdFileAttribMap = APSProperties.STD_FA_ATTRIB.length;
216: final int nStdTimeAttribMap = APSProperties.STD_TA_ATTRIB.length;
217: final int nStdSensorAttribMap = APSProperties.STD_SA_ATTRIB.length;
218: final int nFileInputParamAttribMap = APSProperties.PFA_IPA_ATTRIB.length;
219: final int nFileNavAttribMap = APSProperties.PFA_NA_ATTRIB.length;
220: final int nFileInGeoCovAttribMap = APSProperties.PFA_IGCA_ATTRIB.length;
221:
222: synchronized (mapMutex) {
223: while (metadataIt.hasNext()) {
224: // get Attributes
225: final Attribute att = (Attribute) metadataIt.next();
226:
227: // get Attribute Name
228: final String attribName = att.getName();
229: final String attribValue = HDFUtilities
230: .buildAttributeString(att);
231:
232: // checks if the attribute name matches one of the supported
233: // attributes
234:
235: boolean found = false;
236: for (int k = 0; k < nStdFileAttribMap && !found; k++) {
237: // if matched
238: if (attribName
239: .equals(APSProperties.STD_FA_ATTRIB[k])) {
240: stdFileAttribMap.put((String) attribName,
241: attribValue);
242: found = true;
243: }
244: }
245:
246: for (int k = 0; k < nStdTimeAttribMap && !found; k++) {
247: // if matched
248: if (attribName
249: .equals(APSProperties.STD_TA_ATTRIB[k])) {
250: stdTimeAttribMap.put((String) attribName,
251: attribValue);
252: found = true;
253: }
254: }
255:
256: for (int k = 0; k < nStdSensorAttribMap && !found; k++) {
257: // if matched
258: if (attribName
259: .equals(APSProperties.STD_SA_ATTRIB[k])) {
260: stdSensorAttribMap.put((String) attribName,
261: attribValue);
262: found = true;
263: }
264: }
265:
266: for (int k = 0; k < nFileInputParamAttribMap
267: && !found; k++) {
268: // if matched
269: if (attribName
270: .equals(APSProperties.PFA_IPA_ATTRIB[k])) {
271: fileInputParamAttribMap.put(
272: (String) attribName, attribValue);
273: if (attribName
274: .equals(APSProperties.PFA_IPA_PRODLIST))
275: prodList = attribValue.split(",");
276: found = true;
277: }
278: }
279:
280: for (int k = 0; k < nFileNavAttribMap && !found; k++) {
281: // if matched
282: if (attribName
283: .equals(APSProperties.PFA_NA_ATTRIB[k])) {
284: fileNavAttribMap.put((String) attribName,
285: attribValue);
286: if (attribName
287: .equals(APSProperties.PFA_NA_MAPPROJECTION))
288: projectionDatasetName = attribValue;
289: found = true;
290: }
291: }
292:
293: for (int k = 0; k < nFileInGeoCovAttribMap
294: && !found; k++) {
295: // if matched
296: if (attribName
297: .equals(APSProperties.PFA_IGCA_ATTRIB[k])) {
298: fileInGeoCovAttribMap.put(
299: (String) attribName, attribValue);
300: found = true;
301: }
302: }
303:
304: if (!found)
305: genericAttribMap.put((String) attribName,
306: attribValue);
307: }
308:
309: // //////////////////////////////////
310: // Retrieving products metadata
311: // //////////////////////////////////
312:
313: prodListNum = prodList.length;
314: if (productsMap == null)
315: productsMap = Collections
316: .synchronizedMap(new LinkedHashMap(
317: prodListNum));
318:
319: Iterator datasetIt = ((Group) root).getMemberList()
320: .iterator();
321: while (datasetIt.hasNext()) {
322: // get member dataset
323: final HObject memberDS = (HObject) datasetIt.next();
324: if (memberDS instanceof ScalarDS) {
325: final String name = memberDS.getName();
326: boolean productFound = false;
327: for (int j = 0; j < prodListNum
328: && !productFound; j++) {
329: if (name.equals(prodList[j])) {
330: productFound = true;
331:
332: //get dataset metadata
333: Iterator metadataDsIt = memberDS
334: .getMetadata().iterator();
335:
336: final int nPdsAttrib = APSProperties.PDSA_ATTRIB.length;
337: final LinkedHashMap pdsAttribMap = new LinkedHashMap(
338: nPdsAttrib);
339: final LinkedHashMap pdsGenericAttribMap = new LinkedHashMap(
340: 10);
341:
342: while (metadataDsIt.hasNext()) {
343:
344: // get Attributes
345: final Attribute att = (Attribute) metadataDsIt
346: .next();
347:
348: // get Attribute Name
349: final String attribName = att
350: .getName();
351:
352: // get Attribute Value
353: final String attribValue = HDFUtilities
354: .buildAttributeString(att);
355: boolean attributeFound = false;
356: for (int k = 0; k < nPdsAttrib
357: && !attributeFound; k++) {
358: // if matched
359: if (attribName
360: .equals(APSProperties.PDSA_ATTRIB[k])) {
361: // putting the <attribut Name, attribute value>
362: // couple in the map
363: pdsAttribMap
364: .put(
365: (String) attribName,
366: attribValue);
367:
368: attributeFound = true;
369: }
370: }
371:
372: if (!attributeFound) {
373: // putting the <attribut Name, attribute value>
374: // couple in the map
375: pdsGenericAttribMap.put(
376: (String) attribName,
377: attribValue);
378:
379: }
380:
381: }
382: final ArrayList productAttribs = new ArrayList(
383: 2);
384: // putting pdsaAttribMap and genericAttribMap
385: // in the arrayList
386: productAttribs.add(pdsAttribMap);
387: productAttribs.add(pdsGenericAttribMap);
388: productsMap.put(name, productAttribs);
389: }
390: }
391:
392: if (!productFound
393: && name.equals(projectionDatasetName)) {
394: //TODO: All projection share the same dataset structure??
395: Object data = ((Dataset) memberDS)
396: .getData();
397: final Datatype datatype = ((Dataset) memberDS)
398: .getDatatype();
399: if (projectionMap == null)
400: projectionMap = buildMedeastProjectionAttributesMap(
401: data, datatype);
402: }
403: }
404: }
405: }
406:
407: } catch (Exception e) {
408: // TODO Auto-generated catch block
409:
410: }
411: }
412:
413: private Map buildMedeastProjectionAttributesMap(final Object data,
414: Datatype datatype) {
415: final Map projMap = Collections
416: .synchronizedMap(new LinkedHashMap(29));
417: final int datatypeClass = datatype.getDatatypeClass();
418: final int datatypeSize = datatype.getDatatypeSize();
419:
420: if (datatypeClass == Datatype.CLASS_FLOAT && datatypeSize == 8) {
421: double[] values = (double[]) data;
422: // synchronized (projMap) {
423: //TODO: I need to build a parser or a formatter to properly interprete
424: // these settings
425: projMap.put("Code", Double.toString(values[0]));
426: projMap.put("Projection", Double.toString(values[1]));
427: projMap.put("Zone", Double.toString(values[2]));
428: projMap.put("Datum", Double.toString(values[3]));
429: projMap.put("Param0", Double.toString(values[4]));
430: projMap.put("Param1", Double.toString(values[5]));
431: projMap.put("Param2", Double.toString(values[6]));
432: projMap.put("Param3", Double.toString(values[7]));
433: projMap.put("Param4", Double.toString(values[8]));
434: projMap.put("Param5", Double.toString(values[9]));
435: projMap.put("Param6", Double.toString(values[10]));
436: projMap.put("Param7", Double.toString(values[11]));
437: projMap.put("Param8", Double.toString(values[12]));
438: projMap.put("Param9", Double.toString(values[13]));
439: projMap.put("Param10", Double.toString(values[14]));
440: projMap.put("Param11", Double.toString(values[15]));
441: projMap.put("Param12", Double.toString(values[16]));
442: projMap.put("Param13", Double.toString(values[17]));
443: projMap.put("Param14", Double.toString(values[18]));
444: projMap.put("Width", Double.toString(values[19]));
445: projMap.put("Height", Double.toString(values[20]));
446: projMap.put("Longitude_1", Double.toString(values[21]));
447: projMap.put("Latitude_1", Double.toString(values[22]));
448: projMap.put("Pixel_1", Double.toString(values[23]));
449: projMap.put("Line_1", Double.toString(values[24]));
450: projMap.put("Longitude_2", Double.toString(values[25]));
451: projMap.put("Latitude_2", Double.toString(values[26]));
452: projMap.put("Delta", Double.toString(values[27]));
453: projMap.put("Aspect", Double.toString(values[28]));
454: // }
455: }
456: return projMap;
457: }
458:
459: }
|