读取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;
}
}