爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: zhangbote

Java二次开发出图有偏差

[复制链接]
发表于 5 天前 | 显示全部楼层
zhangbote 发表于 2025-8-27 10:28
老师,还有一个问题。我使用一个json格点数据进行绘图,但是绘制的图和实际对比,出入较大,少很多点位。 ...

代码贴出来看看
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 天前 | 显示全部楼层
本帖最后由 zhangbote 于 2025-8-27 15:36 编辑

先读json,转成GridData
  1. public void createFire() {
  2.         FileReader fileReader = new FileReader("D:\\project\\fire\\1.json");
  3.         FireJsonVO fireJsonVO = JSON.parseObject(fileReader.readString(), FireJsonVO.class);
  4.         GridData gridData = FireJsonVO.toGridData(fireJsonVO);
  5.         gridData.setMissingValue(9999.0);
  6.         try {
  7.             fireForecastUtils.createPngByGrid(getPngInfo(), gridData, "D:\\project\\fire\\png\", "1.png", "1", "1");
  8.         } catch (Exception e) {
  9.             log.error("生成png失败!", e);
  10.         }
  11.     }
复制代码
然后根据GridData进行绘图
  1. public String createPngByGrid(MeteoDataVO info, GridData grid, String outputPath, String outputName, String timeTitle, String publishTitle) throws Exception {
  2.         if (!outputPath.endsWith("/")) {
  3.             outputPath += "/";
  4.         }

  5.         VectorLayer hebeiMap = this.createMapLayer(fileProp.getShpPath() + "hebei(1).shp");
  6.         hebeiMap.setLayerName("jjjMap");
  7.         VectorLayer nameMap = MapDataManage.readMapFile_ShapeFile(fileProp.getShpPath() + "county.shp");
  8.         // 描述地图边界线
  9.         PolygonBreak pb = (PolygonBreak) nameMap.getLegendScheme().getLegendBreak(0);
  10.         // 是否设置填充
  11.         pb.setDrawFill(false);
  12.         pb.setDrawOutline(false);
  13.         // 读取色阶
  14.         LegendScheme als = this.createLegendScheme(info.getLegendValues(), info.getColorStrArr(), grid.getDoubleMissingValue());
  15.         // 绘制图层
  16.         VectorLayer layer = DrawMeteoData.createShadedLayer(grid, als, "", "", false);
  17.         layer.setMaskout(true);
  18.         // 创建视图
  19.         MapView view = new MapView();
  20.         // 叠加图层
  21.         view.addLayer(layer);
  22.         view.addLayer(hebeiMap);

  23.         // 叠加图层
  24.         if (info.getIfZoom()) {
  25.             if (info.getZoomXY() != null && info.getZoomXY().length != 0) {
  26.                 view.zoomToExtentLonLatEx(new Extent(info.getZoomXY()[0], info.getZoomXY()[1], info.getZoomXY()[2], info.getZoomXY()[3]));
  27.             }
  28.         }
  29.         // 改变投影
  30.         String projStr = "+datum=WGS84 +a=6378137.0 +rf=298.257223563 +proj=longlat +ellps=WGS84 ";
  31.         // String projStr = "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +R=6378137 +units=m +no_defs";
  32.         ProjectionInfo aProjInfo = ProjectionInfo.factory(projStr);
  33.         view.projectLayers(aProjInfo);

  34.         // 视图设置
  35.         MapLayout layout = new MapLayout();
  36.         // 获取地图框
  37.         MapFrame frame = layout.getActiveMapFrame();

  38.         frame.setMapView(view);
  39.         view.setAntiAlias(false);
  40.         layout.setAntiAlias(false);
  41.         Extent extent = view.getExtent();
  42.         int rectangleWidth = info.getPngSize() == 0 ? 800 : info.getPngSize();
  43.         int rectangleHeight = (int) (rectangleWidth * 1D / extent.getWidth() * extent.getHeight());
  44.         Rectangle rectangle = new Rectangle(rectangleWidth, rectangleHeight);

  45.         // 设置地图区域大小和外边距
  46.         int width = rectangle.width;
  47.         int height = rectangle.height;

  48.         // 设置页面边界
  49.         int left = 20;
  50.         int right = 20;
  51.         int top = 100;
  52.         int bottom = 100;
  53.         layout.setPageBounds(new Rectangle(0, 0, width + left + right, height + top + bottom));
  54.         MapView mapView = frame.getMapView();
  55.         mapView.getMaskOut().setMask(true);
  56.         mapView.getMaskOut().setMaskLayer(hebeiMap.getLayerName());
  57.         // 图形边框
  58.         frame.setDrawNeatLine(false);
  59.         frame.setDrawGridLabel(false);
  60.         // 设置布局边界
  61.         frame.setLayoutBounds(new Rectangle(left, top, width, height));
  62.         // 绘制网格刻度线
  63.         frame.setDrawGridLine(false);
  64.         // 设置网格间隔值
  65.         frame.setBackColor(new Color(255, 255, 255));
  66.         layout.setPageBackColor(new Color(255, 255, 255));

  67.         this.setLegend(layout, layer, height);

  68.         FileUtils.forceMkdir(new File(outputPath));

  69.         String totalPath = outputPath + outputName;
  70.         // 将字符串路径转换为 Path 对象
  71.         Path path = Paths.get(totalPath);
  72.         if (Files.exists(path)) {
  73.             System.out.println(totalPath + " 文件存在,正在删除...");
  74.             // 删除文件
  75.             Files.delete(path);
  76.         }
  77.         layout.exportToPicture(totalPath);
  78.         this.addBaseInfo(totalPath, timeTitle, publishTitle);
  79.         return totalPath;
  80.     }
复制代码
下面是创建图例的方法
  1. public LegendScheme createLegendScheme(double[] values, String[] colorStrArr, double missValue) {
  2.         // 创建图例
  3.         Color[] colors = Arrays.stream(colorStrArr)
  4.                 .map(str -> Color.decode(String.valueOf(Integer.parseInt(str, 16))))
  5.                 .toArray(Color[]::new);

  6.         List<Color> newList = new ArrayList<>();
  7.         for (Color color : colors) {
  8.             if (color.getRed() == 255 && color.getGreen() == 255 && color.getBlue() == 255) {
  9.                 newList.add(new Color(color.getRed(), color.getGreen(), color.getBlue(), 0));
  10.             } else {
  11.                 newList.add(new Color(color.getRed(), color.getGreen(), color.getBlue()));
  12.             }
  13.         }
  14.         Color[] newColor = newList.toArray(new Color[0]);

  15.         double minData = values[0];
  16.         double maxData = values[values.length - 1];

  17.         // 渐变值
  18.         return LegendManage.createGraduatedLegendScheme(values, newColor, ShapeTypes.POLYGON, minData, maxData, false, missValue);
  19.     }
复制代码



密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

发表于 5 天前 | 显示全部楼层
zhangbote 发表于 2025-8-27 15:35
先读json,转成GridData
然后根据GridData进行绘图
下面是创建图例的方法

这种很离散的数据追踪等值线会有一些问题,比如有效格点不能连成片的话无法追踪出等值线。可以用用栅格图层来显示,省去等值线追踪过程,速度也会快很多。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

 楼主| 发表于 4 天前 | 显示全部楼层
MeteoInfo 发表于 2025-8-27 17:37
这种很离散的数据追踪等值线会有一些问题,比如有效格点不能连成片的话无法追踪出等值线。可以用用栅格图 ...

确实可以了,感谢老师。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表