cdm/src/main/java/ucar/nc2/ft2/coverage/remote/CdmrfWriter.java
CdmrFeatureProto.CoordAxis.Builder encodeCoordAxis(CoverageCoordAxis axis) {
    CdmrFeatureProto.CoordAxis.Builder builder = CdmrFeatureProto.CoordAxis.newBuilder();
    builder.setName(axis.getName());
    builder.setDataType(NcStream.convertDataType(axis.getDataType()));
    builder.setAxisType(convertAxisType(axis.getAxisType()));
    builder.setNvalues(axis.getNcoords());
    if (axis.getUnits() != null) builder.setUnits(axis.getUnits());
    if (axis.getDescription() != null) builder.setDescription(axis.getDescription());
    builder.setDepend(convertDependenceType(axis.getDependenceType()));
    for (String s : axis.getDependsOnList())
      builder.addDependsOn(s);

    if (axis instanceof LatLonAxis2D) {
      LatLonAxis2D latlon2D = (LatLonAxis2D) axis;
      for (int shape : latlon2D.getShape())
       builder.addShape(shape);
    }

    for (Attribute att : axis.getAttributes())
      builder.addAtts(NcStream.encodeAtt(att));

    builder.setSpacing(convertSpacing(axis.getSpacing()));
    builder.setStartValue(axis.getStartValue());
    builder.setEndValue(axis.getEndValue());
    builder.setResolution(axis.getResolution());

    if (!axis.isRegular() && axis.getNcoords() < MAX_INLINE_NVALUES) {
      double[] values = axis.getValues();
      ByteBuffer bb = ByteBuffer.allocate(8 * values.length);
      DoubleBuffer db = bb.asDoubleBuffer();
      db.put(values);
      builder.setValues(ByteString.copyFrom(bb.array()));
    }

    return builder;
  }
CdmrFeatureProto.CoordAxis.Builder encodeCoordAxis(CoverageCoordAxis axis) {
    CdmrFeatureProto.CoordAxis.Builder builder = CdmrFeatureProto.CoordAxis.newBuilder();
    builder.setName(axis.getName());
    builder.setDataType(NcStream.convertDataType(axis.getDataType()));
    builder.setAxisType(convertAxisType(axis.getAxisType()));
    builder.setNvalues(axis.getNcoords());
    if (axis.getUnits() != null) builder.setUnits(axis.getUnits());
    if (axis.getDescription() != null) builder.setDescription(axis.getDescription());
    builder.setDepend(convertDependenceType(axis.getDependenceType()));
    for (String s : axis.getDependsOnList())
      builder.addDependsOn(s);

    if (axis instanceof LatLonAxis2D) {
      LatLonAxis2D latlon2D = (LatLonAxis2D) axis;
      for (int shape : latlon2D.getShape())
       builder.addShape(shape);
    }

    for (Attribute att : axis.getAttributes())
      builder.addAtts(NcStream.encodeAtt(att));

    builder.setSpacing(convertSpacing(axis.getSpacing()));
    builder.setStartValue(axis.getStartValue());
    builder.setEndValue(axis.getEndValue());
    builder.setResolution(axis.getResolution());

    if (!axis.isRegular() && axis.getNcoords() < MAX_INLINE_NVALUES) {
      double[] values = axis.getValues();
      ByteBuffer bb = ByteBuffer.allocate(8 * values.length);
      DoubleBuffer db = bb.asDoubleBuffer();
      db.put(values);
      builder.setValues(ByteString.copyFrom(bb.array()));
    }

    return builder;
  }
/* message CoordAxis {
required string name = 1;
required DataType dataType = 2;
required int32 axisType = 3;    // ucar.nc2.constants.AxisType ordinal
required int64 nvalues = 4;
required string units = 5;
optional bool isRegular = 6;
required double min = 7;        // required ??
required double max = 8;
optional double resolution = 9;
}