MeteoInfo-Java解析与绘图教程(四)
上文我们说到,将地图叠加在色斑图上,但大部分都是卫星绘图,现在开始讲解micaps数据绘图,同样也是更多自定义配置
首先我们解析micaps数据,将之前学到的东西拿过来绘图
MeteoDataInfo meteoDataInfo = new MeteoDataInfo();
meteoDataInfo.openMICAPSData("D:\\解析数据\\cldas\\cldas\\TEM\\20081000.000");
GridData grid = meteoDataInfo.getGridData();
//读取地图A
VectorLayer scmap = MapDataManage.readMapFile_ShapeFile("E:\\shp\\四川\\四川省(3)_市界.shp");
//描述地图边界线
PolygonBreak pb = (PolygonBreak) scmap.getLegendScheme().getLegendBreak(0);
//是否设置填充
pb.setDrawFill(false);
//设置轮廓大小
pb.setOutlineSize(2f);
//设置轮廓颜色
pb.setOutlineColor(Color.black);
//读取色阶
LegendScheme als = LgsUtil.readFromLgs("D:\\apache-tomcat-8.0.50\\alt色阶\\color\\ECMWF_HR\\TMP.lgs");
//绘制图层
VectorLayer layer = DrawMeteoData.createShadedLayer(grid,als,"","",true);
//创建视图
MapView view = new MapView();
//叠加图层
view.addLayer(layer);
view.addLayer(scmap);
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);
layout.exportToPicture(PathUtil.getDeskPath()+"/1.png");
可以看出来,micaps绘图和卫星绘图的区别只在解析数据openData的方法上,以及绘制图层createShadedLayer上,这个方法是绘制色斑图(等值图),而createContourLayer是绘制等值线,可以切换试一试
当然实际使用的时候,图一定是不需要这种的,例如四川的数据就应该只在四川区域呈现,其他区域就为空白,这里就涉及到了地图切割,可以将图层按照地图边界切割掉
MeteoDataInfo meteoDataInfo = new MeteoDataInfo(); meteoDataInfo.openMICAPSData("D:\\解析数据\\cldas\\cldas\\TEM\\20081000.000"); GridData grid = meteoDataInfo.getGridData(); //读取地图A VectorLayer scmap = MapDataManage.readMapFile_ShapeFile("C:\\Users\\Administrator\\Downloads\\好例子网_全国省、县界线shp格式矢量图(精确到县区域)\\全国省、县界线shp格式矢量图(精确到县区域)\\sichuan.shp"); //读取色阶 LegendScheme als = LgsUtil.readFromLgs("D:\\apache-tomcat-8.0.50\\alt色阶\\color\\ECMWF_HR\\TMP.lgs"); //绘制图层 VectorLayer layer = DrawMeteoData.createShadedLayer(grid,als,"","",true); //创建视图 MapView view = new MapView(); layer = layer.clip(scmap); //叠加图层 view.addLayer(layer); 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); //图片存放地址 String imagePath = PathUtil.getDeskPath()+"/1.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));
首先我们需要注意到的是shp文件,如果不知道如何下载shp,可以直接去好例子网下载shp,现成的,很方便,这个shp文件我们需要的是省界,文件里面不要有市的信息,否则无法截个边缘
第二点,我们将白色做了透明处理,这样就成为了气象行业需要的贴图了,透明处理可以集成一个方法,我单纯是为了方便才这样写
有一些时候我们需要在图上看到城市边界,此时我们就可以在加一个市界图层,将图层叠上去
MeteoDataInfo meteoDataInfo = new MeteoDataInfo(); meteoDataInfo.openMICAPSData("D:\\解析数据\\cldas\\cldas\\TEM\\20081000.000"); GridData grid = meteoDataInfo.getGridData(); //读取地图A VectorLayer scmap = MapDataManage.readMapFile_ShapeFile("C:\\Users\\Administrator\\Downloads\\好例子网_全国省、县界线shp格式矢量图(精确到县区域)\\全国省、县界线shp格式矢量图(精确到县区域)\\sichuan.shp"); //读取地图B VectorLayer qgmap = MapDataManage.readMapFile_ShapeFile("E:\\shp\\四川\\四川省(3)_市界.shp"); //描述地图边界线 PolygonBreak pb = (PolygonBreak) qgmap.getLegendScheme().getLegendBreak(0); //是否设置填充 pb.setDrawFill(false); //设置轮廓大小 pb.setOutlineSize(2f); //设置轮廓颜色 pb.setOutlineColor(Color.black); //读取色阶 LegendScheme als = LgsUtil.readFromLgs("D:\\apache-tomcat-8.0.50\\alt色阶\\color\\ECMWF_HR\\TMP.lgs"); //绘制图层 VectorLayer layer = DrawMeteoData.createShadedLayer(grid,als,"","",true); //创建视图 MapView view = new MapView(); layer = layer.clip(scmap); //叠加图层 view.addLayer(layer); 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); //图片存放地址 String imagePath = PathUtil.getDeskPath()+"/1.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));
补充工具类说明:
public static LegendScheme readFromLgs(String path) throws Exception { LegendScheme scheme = new LegendScheme(); scheme.importFromXMLFile(path, false); return scheme; }