NetCDF Java Library - dump to JSON (Draft)
This is only a draft, please do not rely on it!
JsonNetCDF.java:
package jsonnetcdf; import com.google.gson.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import ucar.ma2.Array; import ucar.ma2.InvalidRangeException; import ucar.ma2.Range; import ucar.nc2.Dimension; import ucar.nc2.NetcdfFile; import ucar.nc2.Variable; import ucar.nc2.dataset.NetcdfDataset; public class JsonNetCDF { private String queryJSON = ""; public JsonNetCDF() { } public JsonNetCDF(String queryJSON) { this.queryJSON = queryJSON; } public void replaceJson(String queryJSON) { this.queryJSON = queryJSON; } public String toJson() { Gson gson = new Gson(); try { Query query = gson.fromJson(queryJSON, Query.class); NetcdfDataset gid = NetcdfDataset.openDataset(query.file); NetcdfFile gidFile = gid.getReferencedFile(); if (query.searchType.equals("getList")) { return gson.toJson(getList(query, gid, gidFile)); } else if (query.searchType.equals("getData")) { return gson.toJson(getData(query, gid, gidFile)); } } catch (IOException ex) { Logger.getLogger(JsonNetCDF.class.getName()).log(Level.SEVERE, null, ex); } return "Error!"; } private HashMap getList(Query query, NetcdfDataset gid, NetcdfFile gidFile) { List<Variable> variables = null; HashMap response = new HashMap(); ArrayList variablesArray = new ArrayList(); response.put("list", variablesArray); response.put("type", "list"); if ((query.table != null) && (!query.table.equals(""))) { variables = Arrays.asList(gidFile.findVariable(query.table)); } else { variables = gidFile.getVariables(); } for (int i = 0; i < variables.size(); i++) { Variable variable = variables.get(i); HashMap variableHash = new HashMap(); variableHash.put("description", variable.getDescription()); variableHash.put("attributes", variable.getAttributes().toString()); variableHash.put("dataType", variable.getDataType().toString()); variableHash.put("dimensions", variable.getDimensions().toString()); variableHash.put("dimensionsString", variable.getDimensionsString()); variableHash.put("elementSize", variable.getElementSize()); variableHash.put("name", variable.getName()); variableHash.put("nameEscaped", variable.getNameEscaped()); variableHash.put("rank", variable.getRank()); variableHash.put("shapeAsSection", variable.getShapeAsSection().toString()); variableHash.put("shortName", variable.getShortName()); variableHash.put("size", variable.getSize()); variableHash.put("unitString", variable.getUnitsString()); variableHash.put("isCoordinateVariable", variable.isCoordinateVariable()); variableHash.put("isMetadata", variable.isMetadata()); variableHash.put("isScalar", variable.isScalar()); ArrayList dimensionArray = new ArrayList(); for (int j = 0; j < variable.getDimensions().size(); j++) { HashMap dimensionHash = new HashMap(); Dimension dimension = variable.getDimension(j); dimensionHash.put("length", dimension.getLength()); dimensionHash.put("name", dimension.getName()); if ((gidFile.findVariable(dimension.getName()) != null)) { if (gidFile.findVariable(dimension.getName()).findAttribute("_CoordinateAxisType") != null) { dimensionHash.put("dimensionType", gidFile.findVariable(dimension.getName()).findAttribute("_CoordinateAxisType").getStringValue()); } dimensionHash.put("unitString", gidFile.findVariable(dimension.getName()).getUnitsString()); } else { dimensionHash.put("unitString", ""); } dimensionArray.add(dimensionHash); } variableHash.put("dimensionArray", dimensionArray); variablesArray.add(variableHash); } return response; } private HashMap getData(Query query, NetcdfDataset gid, NetcdfFile gidFile) { HashMap response = new HashMap(); response.put("type", "data"); if ((query.table == null) || (query.table.equals(""))) { response.put("status", "Error!"); return response; } Array dataArray; int dimensionTotal = 1; ArrayList dimensionsSequence = new ArrayList(); HashMap dimensionsList = new HashMap(); try { List<Dimension> dimensions = gid.findVariable(query.table).getDimensions(); ArrayList ranges = new ArrayList(); for (int i = 0; i < dimensions.size(); i++) { String dimensionType = gidFile.findVariable(dimensions.get(i).getName()).findAttribute("_CoordinateAxisType").getStringValue(); Array dimensionValues = gidFile.findVariable(dimensions.get(i).getName()).read(); ArrayList<Float> values = new ArrayList(); for (int j = 0; j < dimensionValues.getSize(); j++) { values.add(dimensionValues.getFloat(j)); } int min = 0; int max = values.size() - 1; //check constraint if (query.constraint != null) { for (int j = 0; j < query.constraint.length; j++) { if ((query.constraint[j].min != (float) -999999999) && (query.constraint[j].max != (float) -999999999) && (query.constraint[j].max < query.constraint[j].min)) { response.put("status", "Error!"); return response; } if (query.constraint[j].name.equals(dimensionType)) { boolean hasSetMin = false; boolean hasSetMax = false; if (values.get(values.size() - 1) > values.get(0)) { for (int k = 0; k < values.size(); k++) { if ((query.constraint[j].min != (float) -999999999) && (values.get(k) < query.constraint[j].min)) { min = k + 1; } if ((!hasSetMax) && (query.constraint[j].max != (float) -999999999) && (values.get(k) > query.constraint[j].max)) { max = k - 1; hasSetMax = true; } } } else { for (int k = (values.size() - 1); k >= 0; k--) { if ((!hasSetMin) && (query.constraint[j].min != (float) -999999999) && (values.get(k) < query.constraint[j].min)) { min = k - 1; hasSetMin = true; } if ((query.constraint[j].max != (float) -999999999) && (values.get(k) > query.constraint[j].max)) { max = k + 1; } } } break; } } } ArrayList<Float> newValues = new ArrayList(); for (int j = min; j < (max + 1); j++) { newValues.add(values.get(j)); } dimensionsSequence.add(dimensionType); dimensionsList.put(dimensionType, newValues); try { ranges.add(new Range(min, max)); } catch (InvalidRangeException ex) { Logger.getLogger(JsonNetCDF.class.getName()).log(Level.SEVERE, null, ex); } } System.out.println(dimensionsSequence); System.out.println(dimensionsList); for (int i = 0; i < dimensionsSequence.size(); i++) { ArrayList<Float> values = (ArrayList<Float>) dimensionsList.get(dimensionsSequence.get(i)); dimensionTotal *= values.size(); } try { dataArray = gid.findVariable(query.table).read(ranges); } catch (InvalidRangeException ex) { Logger.getLogger(JsonNetCDF.class.getName()).log(Level.SEVERE, null, ex); response.put("status", "Error!"); return response; } } catch (IOException ex) { Logger.getLogger(JsonNetCDF.class.getName()).log(Level.SEVERE, null, ex); response.put("status", "Error!"); return response; } ArrayList dataList = new ArrayList(); response.put("data", dataList); float[] data = (float[]) dataArray.copyTo1DJavaArray(); for (int i = 0; i < data.length; i++) { HashMap dataMap = new HashMap(); int previousDimensionTotal = dimensionTotal; for (int j = 0; j < dimensionsSequence.size(); j++) { previousDimensionTotal /= ((ArrayList<Float>)dimensionsList.get(dimensionsSequence.get(j))).size(); int arrayNumber = (i / previousDimensionTotal) % ((ArrayList<Float>)dimensionsList.get(dimensionsSequence.get(j))).size(); Float dimensionValue = ((ArrayList<Float>)dimensionsList.get(dimensionsSequence.get(j))).get(arrayNumber); dataMap.put(dimensionsSequence.get(j), dimensionValue); } dataMap.put("value", data[i]); dataList.add(dataMap); } return response; } } class Query { public String searchType; public String file; public String table; public Constraint[] constraint; } class Constraint { public String name; public float min = (float) -999999999; public float max = (float) -999999999; }
Test program: Main.java:
package jsonnetcdf; public class Main { public static void main(String[] args) { JsonNetCDF a = new JsonNetCDF("{file: 'gfs.t06z.mastergrb2f48', " + "searchType: 'getList', table: 'lat'}"); System.out.println(a.toJson()); a = new JsonNetCDF("{file: 'gfs.t06z.mastergrb2f48', " + "searchType: 'getData'," + "table: 'Temperature'," + "constraint: [{name: 'Lat', max: 22.5}, {name: 'Lon', min: 114.5, max: 114.5}]}"); System.out.println(a.toJson()); } }
本文連結