Micaps转色斑图
1 MeteoInfo工具包是专门处理气象数据的工具,目前工作上遇到了micaps文件转色斑图,在网上找了很久,总结如下:
MeteoDataInfo meteoDataInfo = new MeteoDataInfo();
meteoDataInfo.openMICAPSData("C:\\Users\\zhang\\Desktop\\xxxx\\micaps\\bjtp\\2022112812.000");
GridData gridData = meteoDataInfo.getGridData();
VectorLayer shadedLayer = DrawMeteoData.createShadedLayer(gridData, "","");
MapView view = new MapView();
view.addLayer(shadedLayer);
MapLayout layout = new MapLayout();
layout.getActiveMapFrame().setMapView(view);
try {
layout.exportToPicture("C:\\Users\\zhang\\Desktop\\1.png");
} catch (PrintException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
以上方法是不经过任何处理形成的色斑图,外形比较丑陋,相信大部分人也不会用该图片给客户展示这种图片吧!

形成的图片如上图所示(ps:这只是展示了隔点数据,不同颜色代表该地区的隔点数据时不同的)
2 于是我们发现需要城市的行政边界图,才知道色斑图绘制的是哪个地方的嘛
String fileFullName = "C:\\Users\\zhang\\Desktop\\xxxxx\\micaps\\bjtp\\2022112812.000";
MeteoDataInfo meteoDataInfo = new MeteoDataInfo();
meteoDataInfo.openMICAPSData(fileFullName);
GridData grid = meteoDataInfo.getGridData();
//创建图例
double[] values = new double[]{
5,
7,
9,
11,
13,
15,
17};
Color[] colors = new Color[]{
Color.decode(String.valueOf(Integer.parseInt("6959CD",16))),
Color.decode(String.valueOf(Integer.parseInt("FFC1C1",16))),
Color.decode(String.valueOf(Integer.parseInt("8B008B",16))),
Color.decode(String.valueOf(Integer.parseInt("5D478B",16))),
Color.decode(String.valueOf(Integer.parseInt("7EC0EE",16))),
Color.decode(String.valueOf(Integer.parseInt("00688B",16))),
Color.decode(String.valueOf(Integer.parseInt("0000EE",16))),
Color.decode(String.valueOf(Integer.parseInt("FFDAB9",16)))};
double minData =0;
double maxData =0;
double[] maxMin = new double[2];
if(!grid.getMaxMinValue(maxMin))
{
maxData = maxMin[0];
minData = maxMin[1];
}
if(values[0] < minData)
{
minData = values[0];
}
if(values[values.length-1] > maxData)
{
maxData = values[values.length-1];
}
//渐变值
LegendScheme aLS = LegendManage.createGraduatedLegendScheme(values, colors,
ShapeTypes.IMAGE, minData, maxData, false, grid.getDoubleMissingValue());
//绘制图层
VectorLayer layer = DrawMeteoData.createShadedLayer(grid,aLS,"Shaded_var","var",true);
layer.setFileName("a1");
//对绘制的图层进行裁剪
VectorLayer clipShp = MapDataManage.readMapFile_ShapeFile("G:\\BaiduNetdiskDownload\\省市\\北京市.shp");
PolygonBreak pb = (PolygonBreak) clipShp.getLegendScheme().getLegendBreak(0);
pb.setDrawFill(false);
pb.setDrawOutline(true);
pb.setOutlineSize(1);
pb.setOutlineColor(Color.gray);
clipShp.setFileName("test");
//VectorLayer newlayer = layer.clip(clipShp);
//创建视图
MapView view = new MapView();
view.setAntiAlias(true);
view.addLayer(layer);
view.addLayer(clipShp);
MaskOut maskOut = view.getMaskOut();
maskOut.setMask(true);
maskOut.setMaskLayer("test");
view.setMaskOut(maskOut);
//视图设置
MapLayout layout = new MapLayout();
layout.setAntiAlias(true);
//设置页面边界 画布大小
layout.setPageBounds(new Rectangle(0, 0, 900, 800));
layout.getActiveMapFrame().setMapView(view);
//根据视图计算视图的宽高
Extent extent = view.getExtent();
int widthSize = 800;
//放缩比率
Double rate = 1D;
//按宽度比例设置高度
Rectangle rectangle = new Rectangle(
widthSize,
(int) Math.ceil(widthSize * 1D / extent.getWidth() * extent.getHeight()));
//设置地图区域大小和外边距
int width = rectangle.width;
int height = rectangle.height;
int left = 50;
int top = 50;
//获取地图框
MapFrame frame = layout.getActiveMapFrame();
//设置布局边界 色斑图位置及大小
frame.setLayoutBounds(new Rectangle(left, top, width, height));
//导出
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyMMddHHmmss");
layout.exportToPicture("C:\\Users\\zhang\\Desktop\\shp\\"+ LocalDateTime.now().format(format)+".png");
上述代码运行后的色斑图贴在下方

这里我们可以看出这是某个地区的色斑图了,对比之前确实好了许多,至少知道该色斑图描述的是某个省气温的色斑图了,但是我们主体突出的不是很明显,若是想要显示该地区的色斑图,其他多余的区域裁减掉,则需要添加额外方法处理
3 经过区域边界裁剪后的色斑图,代码如下
MeteoDataInfo meteoDataInfo = new MeteoDataInfo();
meteoDataInfo.openMICAPSData("C:\\Users\\zhang\\Desktop\\xxxxx\\micaps\\bjtp\\2022112812.000");
GridData grid = meteoDataInfo.getGridData();
//读取地图A
VectorLayer scmap = MapDataManage.readMapFile_ShapeFile("C:\\Users\\zhang\\Desktop\\shp\\界限shp\\beijing.shp");
//读取地图B
VectorLayer qgmap = MapDataManage.readMapFile_ShapeFile("G:\\BaiduNetdiskDownload\\省市\\北京市.shp");
//描述地图边界线
PolygonBreak pb = (PolygonBreak) qgmap.getLegendScheme().getLegendBreak(0);
//是否设置填充
pb.setDrawFill(false);
//设置轮廓大小
pb.setOutlineSize(2f);
//设置轮廓颜色
pb.setOutlineColor(Color.black);
//创建图例
double[] values = new double[]{
5,
7,
9,
11,
13,
15,
17};
Color[] colors = new Color[]{
Color.decode(String.valueOf(Integer.parseInt("6959CD",16))),
Color.decode(String.valueOf(Integer.parseInt("FFC1C1",16))),
Color.decode(String.valueOf(Integer.parseInt("8B008B",16))),
Color.decode(String.valueOf(Integer.parseInt("5D478B",16))),
Color.decode(String.valueOf(Integer.parseInt("7EC0EE",16))),
Color.decode(String.valueOf(Integer.parseInt("00688B",16))),
Color.decode(String.valueOf(Integer.parseInt("0000EE",16))),
Color.decode(String.valueOf(Integer.parseInt("FFDAB9",16)))};
double minData =0;
double maxData =0;
double[] maxMin = new double[2];
if(!grid.getMaxMinValue(maxMin))
{
maxData = maxMin[0];
minData = maxMin[1];
}
if(values[0] < minData)
{
minData = values[0];
}
if(values[values.length-1] > maxData)
{
maxData = values[values.length-1];
}
//渐变值
LegendScheme aLS = LegendManage.createGraduatedLegendScheme(values, colors,
ShapeTypes.IMAGE, minData, maxData, false, grid.getDoubleMissingValue());
//als.importFromXMLFile("");
//绘制图层
VectorLayer shadedLayer = DrawMeteoData.createShadedLayer(grid,aLS,"","",true);
//创建视图
MapView view = new MapView();
shadedLayer = shadedLayer.clip(scmap);
//叠加图层
view.addLayer(shadedLayer);
view.addLayer(qgmap);
MapLayout layout = new MapLayout();
//去除图形边框
layout.getActiveMapFrame().setDrawNeatLine(false);
//区域边界
Extent extent = view.getExtent();
//设置矩形的宽和高
Rectangle bounds = new Rectangle(800, (int) (800 * 1D / extent.getWidth() * extent.getHeight()));
//设置地图边框
layout.setPageBounds(new Rectangle(0, 0, bounds.width, bounds.height));
//设置页面边框
layout.getActiveMapFrame().setLayoutBounds(new Rectangle(0, 0, bounds.width, bounds.height));
layout.getActiveMapFrame().setMapView(view);
//图片存放地址
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyMMddHHmmss");
String imagePath = "C:\\Users\\zhang\\Desktop\\shp\\"+ LocalDateTime.now().format(format)+".png";
layout.exportToPicture(imagePath);
//透明处理
//读取图片
BufferedImage bi = ImageIO.read(new File(imagePath));
//类型转换
BufferedImage img = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
g.drawImage(bi, null, 0, 0);
//透明处理
int alpha = 0;
for(int i=img.getMinY(); i<img.getHeight(); i++){
for(int j=img.getMinX(); j<img.getWidth(); j++){
int rgb = img.getRGB(j, i);
//透明部分不需要处理
if(rgb < 0){
int R = (rgb & 0xff0000) >> 16;
int G = (rgb & 0xff00) >> 8;
int B = (rgb & 0xff);
//将白色剔除
Color color = Color.white;
if(color.getRed() == R && color.getGreen() == G && color.getBlue() == B){
alpha = 0;
}
else {
alpha = 255;
}
rgb = (alpha << 24) | (rgb & 0x00ffffff);
img.setRGB(j, i, rgb);
}
}
}
//释放资源
g.dispose();
ImageIO.write(img, "png", new File(imagePath));
本文介绍如何使用MeteoInfo工具包将Micaps文件转换为色斑图,并通过添加城市边界来提高可读性。文中详细记录了从基本色斑图生成到最终优化过程中的代码实现。

8713

被折叠的 条评论
为什么被折叠?



