NetCDF Java Library - dump to JSON (Draft)

NetCDF Java Library - data to JSON

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());
    }

}



本文連結