All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.ft2.coverage.writer.CoverageDatasetCapabilities Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
 * See LICENSE for license information.
 */
package ucar.nc2.ft2.coverage.writer;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.ma2.IndexIterator;
import ucar.nc2.Attribute;
import ucar.nc2.constants.AxisType;
import ucar.nc2.ft2.coverage.CoordSysSet;
import ucar.nc2.ft2.coverage.Coverage;
import ucar.nc2.ft2.coverage.CoverageCoordAxis;
import ucar.nc2.ft2.coverage.CoverageCoordSys;
import ucar.nc2.ft2.coverage.CoverageCollection;
import ucar.nc2.ft2.coverage.CoverageTransform;
import ucar.nc2.ncml.NcMLWriter;
import ucar.nc2.time.CalendarDateRange;
import ucar.nc2.util.Misc;
import ucar.unidata.geoloc.LatLonRect;
import ucar.unidata.geoloc.ProjectionRect;

/**
 * Helper class to create a DatasetCapabilities XML document for CoverageDataset
 *
 * @author caron
 * @since 5/7/2015
 */
public class CoverageDatasetCapabilities {
  private CoverageCollection gcd;
  private String path;

  private final NcMLWriter ncmlWriter = new NcMLWriter();

  public CoverageDatasetCapabilities(CoverageCollection gds, String path) {
    this.gcd = gds;
    this.path = path;
  }

  /**
   * Write the information as an XML document
   *
   * @param doc write XML for this Document
   * @return String output
   */
  public String writeXML(Document doc) {
    XMLOutputter fmt = new XMLOutputter(Format.getPrettyFormat());
    return fmt.outputString(doc);
  }

  /**
   * Write the information as an XML document
   *
   * @param doc write XML for this Document
   * @param os  write to this output stream
   * @throws java.io.IOException on write error
   */
  public void writeXML(Document doc, OutputStream os) throws IOException {
    XMLOutputter fmt = new XMLOutputter(Format.getPrettyFormat());
    fmt.output(doc, os);
  }

  /**
   * Create the "Dataset Description" XML document from this GridDataset
   *
   * @return a JDOM Document
   */
  public Document makeDatasetDescription() throws IOException {
    Element rootElem = new Element("gridDataset");
    Document doc = new Document(rootElem);
    rootElem.setAttribute("location", gcd.getName());
    if (null != path)
      rootElem.setAttribute("path", path);

    // coordinate axes
    for (CoverageCoordAxis axis : gcd.getCoordAxes()) {
      rootElem.addContent(writeAxis(axis));
    }

    // gridSets
    for (CoordSysSet gridset : gcd.getCoverageSets()) {
      rootElem.addContent(writeCoverageSet(gridset.getCoordSys(), gridset.getCoverages(), gcd.getProjBoundingBox()));
    }

    // coordinate transforms
    for (CoverageTransform ct : gcd.getCoordTransforms()) {
      rootElem.addContent(writeCoordTransform(ct));
    }

 		/* global attributes
     Iterator atts = gds.getGlobalAttributes().iterator();
     while (atts.hasNext()) {
       ucar.nc2.Attribute att = (ucar.nc2.Attribute) atts.next();
       rootElem.addContent(ucar.nc2.ncml.NcMLWriter.writeAttribute(att, "attribute", null));
     } */

    // add lat/lon bounding box
    LatLonRect bb = gcd.getLatlonBoundingBox();
    if (bb != null)
      rootElem.addContent(writeBoundingBox(bb));

    // add date range
    CalendarDateRange calDateRange = gcd.getCalendarDateRange();
    if (calDateRange != null) {
      Element dateRange = new Element("TimeSpan");
      dateRange.addContent(new Element("begin").addContent(calDateRange.getStart().toString()));
      dateRange.addContent(new Element("end").addContent(calDateRange.getEnd().toString()));
      rootElem.addContent(dateRange);
    }

    return doc;
  }

  private Element writeAxis(CoverageCoordAxis axis) throws IOException {
    Element varElem = new Element("axis");
    varElem.setAttribute("name", axis.getName());
    varElem.setAttribute("shape", Misc.showInts(axis.getShape()));

    DataType dt = axis.getDataType();
    varElem.setAttribute("type", dt.toString());

    AxisType axisType = axis.getAxisType();
    if (null != axisType)
      varElem.setAttribute("axisType", axisType.toString());

    if (axis.getDependsOn() != null && axis.getDependsOn().trim().length() > 0)
      varElem.setAttribute("dependsOn", axis.getDependsOn().trim());

    // attributes
    for (Attribute att : axis.getAttributes()) {
      varElem.addContent(ncmlWriter.makeAttributeElement(att));
    }

		/*
        f.format("%s  npts: %d [%f,%f] spacing=%s", indent, ncoords, startValue, endValue, spacing);
    if (getResolution() != 0.0)
      f.format(" resolution=%f", resolution);
    f.format(" %s :", getDependenceType());
    for (String s : dependsOn)
		 */

    Element values = new Element("values");
    if (!axis.isRegular()) {
      Array array = axis.getCoordsAsArray();
      boolean isRealType = (array.getDataType() == DataType.DOUBLE) || (array.getDataType() == DataType.FLOAT);
      IndexIterator iter = array.getIndexIterator();

      StringBuilder buff = new StringBuilder();
      buff.append(isRealType ? iter.getDoubleNext() : iter.getIntNext());

      while (iter.hasNext()) {
        buff.append(" ");
        buff.append(isRealType ? iter.getDoubleNext() : iter.getIntNext());
      }

      values.setText(buff.toString());
    }

    values.setAttribute("spacing", axis.getSpacing().toString());
    values.setAttribute("npts", Long.toString(axis.getNcoords()));
    values.setAttribute("start", Double.toString(axis.getStartValue()));
    values.setAttribute("end", Double.toString(axis.getEndValue()));
    if (axis.getResolution() != 0.0)
      values.setAttribute("resolution", Double.toString(axis.getResolution()));

    varElem.addContent(values);
    return varElem;
  }


  // display name plus the dimensions
  private String getShapeString(int[] shape) {
    StringBuilder buf = new StringBuilder();
    for (int i = 0; i < shape.length; i++) {
      if (i != 0) buf.append(" ");
      buf.append(shape[i]);
    }
    return buf.toString();
  }


  private Element writeBoundingBox(LatLonRect bb) {

    Element bbElem = new Element("LatLonBox");
    //LatLonPoint llpt = bb.getLowerLeftPoint();
    //LatLonPoint urpt = bb.getUpperRightPoint();

    //bbElem.addContent(new Element("west").addContent(ucar.unidata.util.Format.dfrac(llpt.getLongitude(), 4)));
    bbElem.addContent(new Element("west").addContent(ucar.unidata.util.Format.dfrac(bb.getLonMin(), 4)));
    //bbElem.addContent(new Element("east").addContent(ucar.unidata.util.Format.dfrac(urpt.getLongitude(), 4)));
    bbElem.addContent(new Element("east").addContent(ucar.unidata.util.Format.dfrac(bb.getLonMax(), 4)));
    //bbElem.addContent(new Element("south").addContent(ucar.unidata.util.Format.dfrac(llpt.getLatitude(), 4)));
    bbElem.addContent(new Element("south").addContent(ucar.unidata.util.Format.dfrac(bb.getLatMin(), 4)));
    //bbElem.addContent(new Element("north").addContent(ucar.unidata.util.Format.dfrac(urpt.getLatitude(), 4)));
    bbElem.addContent(new Element("north").addContent(ucar.unidata.util.Format.dfrac(bb.getLatMax(), 4)));

    return bbElem;

  }

  private Element writeCoverageSet(CoverageCoordSys cs, List grids, ProjectionRect rect) {
    Element csElem = new Element("gridSet");
    csElem.setAttribute("name", cs.getName());

    if (rect != null) {
      Element projBBOX = new Element("projectionBox");
      Element minx = new Element("minx");
      minx.addContent(Double.valueOf(rect.getMinX()).toString());
      projBBOX.addContent(minx);
      Element maxx = new Element("maxx");
      maxx.addContent(Double.valueOf(rect.getMaxX()).toString());
      projBBOX.addContent(maxx);
      Element miny = new Element("miny");
      miny.addContent(Double.valueOf(rect.getMinY()).toString());
      projBBOX.addContent(miny);
      Element maxy = new Element("maxy");
      maxy.addContent(Double.valueOf(rect.getMaxY()).toString());
      projBBOX.addContent(maxy);

      csElem.addContent(projBBOX);
    }

    for (String axisName : cs.getAxisNames()) {
      Element axisElem = new Element("axisRef");
      axisElem.setAttribute("name", axisName);
      csElem.addContent(axisElem);
    }

    for (String ctName : cs.getTransformNames()) {
      Element elem = new Element("coordTransRef");
      elem.setAttribute("name", ctName);
      csElem.addContent(elem);
    }

    Collections.sort(grids, new GridCoverageComparator());
    for (Coverage grid : grids) {
      csElem.addContent(writeGrid(grid));
    }

    return csElem;
  }

 	/* private Element writeCoordSys(GridCoordSystem cs) {
     Element csElem = new Element("coordSys");
     csElem.setAttribute("name", cs.getName());
     List axes = cs.getCoordinateAxes();
     for (int i = 0; i < axes.size(); i++) {
       CoordinateAxis axis = (CoordinateAxis) axes.get(i);
       Element axisElem = new Element("axisRef");
       axisElem.setAttribute("name", axis.getName());
       csElem.addContent(axisElem);
     }
     List cts = cs.getCoordinateTransforms();
     for (int j = 0; j < cts.size(); j++) {
       CoordinateTransform ct = (CoordinateTransform) cts.get(j);
       Element elem = new Element("coordTransRef");
       elem.setAttribute("name", ct.getName());
       csElem.addContent(elem);
     }
     return csElem;
   } */

  private Element writeCoordTransform(CoverageTransform ct) {
    Element ctElem = new Element("coordTransform");
    ctElem.setAttribute("name", ct.getName());
    ctElem.setAttribute("transformType", ct.isHoriz() ? "Projection" : "Vertical");
    for (Attribute param : ct.getAttributes()) {
      Element pElem = ncmlWriter.makeAttributeElement(param);
      pElem.setName("parameter");
      ctElem.addContent(pElem);
    }
    return ctElem;
  }

  private Element writeGrid(Coverage grid) {
    Element varElem = new Element("grid");
    varElem.setAttribute("name", grid.getName());

    String desc = grid.getDescription() != null ? grid.getDescription() : "No description";
    varElem.setAttribute("desc", desc);

 		/* StringBuilder buff = new StringBuilder();
 		List dims = grid.getDimensions();
 		for (int i = 0; i < dims.size(); i++) {
 			Dimension dim = (Dimension) dims.get(i);
 			if (i > 0) buff.append(" ");
 			if (dim.isShared())
 				buff.append(dim.getShortName());
 			else
 				buff.append(dim.getLength());
 		}
 		if (buff.length() > 0)
 			varElem.setAttribute("shape", buff.toString()); */

    DataType dt = grid.getDataType();
    if (dt != null)
      varElem.setAttribute("type", dt.toString());

    //GridCoordSystem cs = grid.getCoordinateSystem();
    //varElem.setAttribute("coordSys", cs.getName());

    // attributes
    for (ucar.nc2.Attribute att : grid.getAttributes()) {
      varElem.addContent(ncmlWriter.makeAttributeElement(att));
    }

    return varElem;
  }

  // sort by domain size, then name
  private static class GridCoverageComparator implements Comparator {
    public int compare(Coverage grid1, Coverage grid2) {
      return grid1.getName().compareTo(grid2.getName());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy