将 StreamingRenderer 与 GeotiffReader 结合使用

问题描述 投票:0回答:1

我在使用 geotools

StreamingRenderer
来正确显示来自 Geotiff 的图像时遇到了困难。我正在使用来自 NASA 的 visible Earth geotiff ,但我在其他 EPSGE:4326 geotiff 中看到了这个问题。 非 EPSG:4326 的 Geotiff 没有这个问题,并且渲染得很漂亮。 Geotools版本是31.1

这是来自

GeotiffReader
CRS
toWKT()
方法的 CRS WKT:

GEOGCS["WGS 84", 
  DATUM["World Geodetic System 1984",
    SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],
    AUTHORITY["EPSG","6326"]],
  PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],
  UNIT["degree", 0.017453292519943295],
  AXIS["Geodetic latitude", NORTH],
  AXIS["Geodetic longitude", EAST],
  AUTHORITY["EPSG","4326"]]

我的理解是

StreamingRenderer
应该从给定的读取器读取并重新投影/重新采样到视口边界和图像尺寸,但它最多会生成一个侧面翻转的图像,或者最坏的情况下会生成一个没有数据的图像请求整个 EPSG:4326 边界。

    @Test
    public void testGeotiffReader() throws IOException, FactoryException {
        Path path = TestSupport.classPathResourceAsFile("/testdata/grids/eo_base.tif").toPath();    
        GridCoverage2DReader reader = GridFormatFinder.findFormat(path.toFile()).getReader(path.toFile());

        ParameterValue bands = GeoTiffFormat.BANDS.createValue();
        bands.setValue(new int[]{0});

        GridCoverage2D coverage = reader.read(new GeneralParameterValue[]{bands});

        //at this point the coverage is rendered in the correct orientation
        Path out = Paths.get("rendered-coverage.png");
        try(FileOutputStream fos= new FileOutputStream(out.toFile())) {
           ImageIO.write(coverage.getRenderedImage(),"PNG",fos);
        }

        ReferencedEnvelope envelope = new ReferencedEnvelope(-180,0,0,90,CRS.decode("EPSG:4326"));
        Rectangle imageDim = new Rectangle(0, 0, 1200, 800);

        MapViewport viewport = new MapViewport(envelope,false);
        MapContent content = new MapContent();
        content.setViewport(viewport);

        StyleFactory sf = CommonFactoryFinder.getStyleFactory();
        FilterFactory ff = CommonFactoryFinder.getFilterFactory();
        ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NORMALIZE);
        SelectedChannelType sct = sf.createSelectedChannelType(String.valueOf(1), ce);
        RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
        ChannelSelection sel = sf.channelSelection(sct);
        sym.setChannelSelection(sel);
        Style style = SLD.wrapSymbolizers(sym);

        GridReaderLayer layer = new GridReaderLayer(reader, style);
        content.addLayer(layer);

        StreamingRenderer renderer = new StreamingRenderer();
        renderer.setMapContent(content);

        final BufferedImage image = 
              new BufferedImage(imageDim.width, imageDim.height, BufferedImage.TYPE_INT_ARGB);
        final Graphics2D graphics = image.createGraphics();
        renderer.paint(graphics, imageDim, envelope);

        final ImageWorker iw = new ImageWorker(image);
        iw.prepareForRendering();

        out = Paths.get("streaming-renderer.png");

        /**
         * At this point, the image will be flipped on it's side
         */
        try(FileOutputStream fos = new FileOutputStream(out.toFile())) {
            iw.writePNG(fos, null, 0, false, false);
        }
       
    }
没有

rendered-coverage.png

 渲染的 
StreamingRenderer
就可以了: enter image description here

但是当使用

StreamingRenderer
渲染到视口时: enter image description here

如果需要完整范围,则可以是完全空白的图像。 我尝试过forceXY,在引用的信封中交换坐标顺序,似乎没有任何效果。我缺少什么? 如何让 EPSG:4326 geotiffs 正确渲染?我确信我在这里遗漏了一些明显的东西。

我尝试过不同的 EPSG:4326 geotiffs、forceXY 系统属性、交换坐标

ReferencedEnvelope

gis geotools geotiff
1个回答
0
投票

我不能发誓,但我怀疑这是使用 GeoTiffReader 的一个众所周知的问题。我这样说是因为我们的图像教程包含以下代码:

    AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
    // this is a bit hacky but does make more geotiffs work
    Hints hints = new Hints();
    if (format instanceof GeoTiffFormat) {
        hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
    }
    reader = format.getReader(rasterFile, hints);

说实话,每当我要处理4326时,我都觉得需要去洗澡才能再次干净。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.