读取netCdf的依赖
<dependency><groupId>ucar</groupId><artifactId>netcdfAll</artifactId><version>5.5.3</version><scope>system</scope><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>spi</artifactId></exclusion></exclusions><systemPath>${basedir}/libs/netcdfAll-5.5.3.jar</systemPath></dependency>
读取文件入库
import cn.iscas.eneity.*;
import cn.iscas.picture.HeatPictureGenerator;
import cn.iscas.util.DateAddition;
import cn.iscas.util.GzipCompressUtil;
import cn.iscas.util.LogUtil;
import cn.iscas.util.PropertiesUtil;
import com.google.common.collect.ImmutableList;
import com.iscas.datasong.client.DataSongClient;
import com.iscas.datasong.client.DataSongHttpClient;
import com.iscas.datasong.client.domain.DataSongSearchResult;
import com.iscas.datasong.lib.common.DataSongException;
import com.iscas.datasong.lib.request.SearchDataRequest;
import com.iscas.datasong.lib.request.search.builder.ConditionBuilder;
import com.iscas.datasong.lib.request.search.condition.search.TermSearchCondition;
import com.iscas.datasong.lib.util.DataSongJsonUtils;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import java.io.IOException;
import java.util.*;public static void salinitySaveDataSong(String fileName) throws IOException, DataSongException {NetcdfFile file = NetcdfFile.open(fileName);Map map = new HashMap<>();ImmutableList<Variable> variables = file.getVariables();for (Variable var : variables) {String varName = var.getFullName();Object o = var.read().copyToNDJavaArray();map.put(varName, o);}List<Salinity> salinityList = new ArrayList<>();int[] time = (int[]) map.get("time");float[] lev = (float[]) map.get("lev");float[][][][] ss = (float[][][][]) map.get("ss");float[] lat = (float[]) map.get("lat");float[] lon = (float[]) map.get("lon");for (int i = 0; i < time.length; i++) {for (int j = 0; j < lev.length; j++) {Salinity salinity = new Salinity();salinity.setTime(DateAddition.addDays365(time[i]));salinity.setLev(lev[j]);salinity.setLat(Arrays.toString(lat));salinity.setLon(Arrays.toString(lon));salinity.setNetCdfPath(fileName);String compress = GzipCompressUtil.compress(DataSongJsonUtils.toJson(ss[i][j]));salinity.setSs(compress);salinityList.add(salinity);}}DataSongClient dataSongClient = DataSongHttpClient.getInstance(dataSongIp, dataSongPort);dataSongClient.setDatabaseName(dataSongDatabase);dataSongClient.getDataService().batchSaveData(salinityList).toString();LogUtil.debug(fileName + "入库解析完成");}
读取入库数据
public static void salinityGeneratorPicture(String netCdfPath) throws DataSongException {DataSongClient dataSongClient = DataSongHttpClient.getInstance(dataSongIp,dataSongPort);dataSongClient.setDatabaseName(dataSongDatabase);TermSearchCondition levTermSearchCondition = ConditionBuilder.termCondition("netCdfPath", netCdfPath);SearchDataRequest searchDataRequest = new SearchDataRequest();searchDataRequest.setSearch(levTermSearchCondition);DataSongSearchResult<Salinity> salinityDataSongSearchResult = dataSongClient.getDataService().searchData(Salinity.class, searchDataRequest);List<Salinity> items = salinityDataSongSearchResult.getItems();String ss = "";String lat = "";String lon = "";String pictureName = "";for (Salinity salinity : items) {salinity.setSs(GzipCompressUtil.decompress(salinity.getSs()));ss = salinity.getSs();lat = salinity.getLat();lon = salinity.getLon();pictureName = "salinity" + "_" + salinity.getTime() + "_" + Float.valueOf(salinity.getLev()).intValue();float[] latitudes = DataSongJsonUtils.fromJson(lat, float[].class);float[] longitudes = DataSongJsonUtils.fromJson(lon, float[].class);double[][] values = DataSongJsonUtils.fromJson(ss, double[][].class);String pictureFile = HeatPictureGenerator.pictureGenerator(pictureName, latitudes, longitudes, values);if (pictureFile != null) {salinity.setPicturePath(pictureFile);dataSongClient.getDataService().updateData(salinity);salinity.setSs("");LogUtil.debug("记录一条"+salinity);}}}
绘制热力图
import javax.imageio.ImageIO;
import cn.iscas.util.LogUtil;
import cn.iscas.util.PropertiesUtil;
import com.iscas.datasong.lib.common.DataSongException;
import java.awt.*;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public static String pictureGenerator(String pictureName, float[] latitudes, float[] longitudes, double[][] values) {
int messageHeight = 100;int width = 1486;int height = 910 + messageHeight;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = image.createGraphics();g2d.setColor(Color.WHITE);g2d.fillRect(0, 0, width, height);double minValue = Double.MAX_VALUE;double maxValue = Double.MIN_VALUE;for (int i = 0; i < latitudes.length; i++) {for (int j = 0; j < longitudes.length; j++) {if (values[i][j] != 1.0E35 && !Double.isNaN(values[i][j]) && !Double.isInfinite(values[i][j])) {if (values[i][j] < minValue) {minValue = values[i][j];}if (values[i][j] > maxValue) {maxValue = values[i][j];}}}}float minLongitude = Float.MAX_VALUE;float maxLongitude = Float.MIN_VALUE;float minLatitude = Float.MAX_VALUE;float maxLatitude = Float.MIN_VALUE;for (float longitude : longitudes) {if (longitude < minLongitude) minLongitude = longitude;if (longitude > maxLongitude) maxLongitude = longitude;}for (float latitude : latitudes) {if (latitude < minLatitude) minLatitude = latitude;if (latitude > maxLatitude) maxLatitude = latitude;}for (int i = 0; i < latitudes.length; i++) {for (int j = 0; j < longitudes.length; j++) {int x = Math.round((longitudes[j] - minLongitude) / (maxLongitude - minLongitude) * (width - 1));
int y = Math.round(height - messageHeight - 1 - ((latitudes[i] - minLatitude) / (maxLatitude - minLatitude) * (height - messageHeight - 1)));if (values[i][j] == 1.0E35 || Double.isNaN(values[i][j]) || Double.isInfinite(values[i][j])) {g2d.setColor(Color.GRAY);g2d.fillRect(x, y, 2, 2);} else {float value = (float) ((values[i][j] - minValue) / (maxValue - minValue));
float hue = (float) (240.0 - value * 240.0); float saturation = 1.0f; float brightness = 1.0f; Color color = Color.getHSBColor(hue / 360f, saturation, brightness);g2d.setColor(color);g2d.fillOval(x, y, 2, 2); }}}int colorbarHeight = 50; int colorbarY = height - colorbarHeight; int colorbarWidth = width - 200; double valuePerPixel = (maxValue - minValue) / (colorbarWidth - 1);g2d.setColor(Color.BLACK); g2d.fillRect(0 + 80, colorbarY, colorbarWidth, colorbarHeight);for (int b = 0; b < colorbarWidth; b++) {double currentValue = minValue + b * valuePerPixel;float hueValue = 240f - (float) ((currentValue - minValue) / (maxValue - minValue) * 240);Color color = Color.getHSBColor(hueValue / 360f, 1.0f, 1.0f); g2d.setColor(color);g2d.fillRect(b + 80, colorbarY, 1, colorbarHeight);}int tickSpacing = colorbarWidth / 10; int tickLength = 10;int labelSpacing = tickSpacing; String format = "%.2f"; for (int x = 0; x <= colorbarWidth; x += tickSpacing) {g2d.setColor(Color.BLACK);g2d.drawLine(x + 80, colorbarY, x + 80, colorbarY + tickLength);double currentValue = minValue + x * valuePerPixel;if (x % labelSpacing == 0) {String label = String.format(format, currentValue);FontMetrics fm = g2d.getFontMetrics();int labelX = x - fm.stringWidth(label) / 2 + 80;int labelY = colorbarY + colorbarHeight + 15; g2d.setColor(Color.BLACK);g2d.setFont(new Font("Default", Font.PLAIN, 20));g2d.drawString(label, labelX, labelY - 30);}}g2d.setColor(Color.BLACK);g2d.drawString("Max: " + maxValue + " " + "Min: " + minValue, 10, colorbarY + colorbarHeight - 60);g2d.dispose();try {File output = new File(picturePath + pictureName + ".tiff");ImageIO.write(image, "TIFF", output);LogUtil.debug("PNG图像已成功保存到 " + output.getAbsolutePath());return output.getAbsolutePath();} catch (IOException e) {e.printStackTrace();LogUtil.error("图片生成异常" + LogUtil.getStackTraceAsString(e));return null;}}