MeteoInfo-Micaps绘制色斑图

本文介绍如何使用MeteoInfo工具包将Micaps文件转换为色斑图,并通过添加城市边界来提高可读性。文中详细记录了从基本色斑图生成到最终优化过程中的代码实现。

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值