java使用geotool完成geotiff文件的读写

1.配置maven

<properties>
    <java.version>1.8</java.version>
    <geotools.version>28.0</geotools.version>
</properties>
 
 
<dependencies>
    <!--必须,内置了基础的地理坐标系 不配置会导致读写tiff时找不到坐标系-->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>
 
 
    <!--必须,读写tiff的具体api-->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-geotiff</artifactId>
        <version>${geotools.version}</version>
    </dependency>
</dependencies>
 
<repositories>
    <!--必须 geotools依赖的仓库, 常用的仓库中无geotools依赖-->
    <repository>
        <id>osgeo</id>
        <name>OSGeo Release Repository</name>
        <url>https://repo.osgeo.org/repository/release/</url>
        <snapshots><enabled>false</enabled></snapshots>
        <releases><enabled>true</enabled></releases>
    </repository>
</repositories>

2.生成tiff文件

    public static String tiffWrite() throws FactoryException, IOException {
        int[][] matrix = new int[256][256];
        Random r = new Random();

        for (int i = 0; i < matrix.length; i++) {
            int[] row = matrix[i];
            for (int j = 0; j < row.length; j++) {
                matrix[i][j] = Math.abs(r.nextInt() % Byte.MAX_VALUE);
                //System.out.println(i + "," + j + "," + matrix[i][j]);
            }
        }

        double tile = 6378137 * 2 * Math.PI / (1 << 16);
        Envelope2D envelope = new Envelope2D( CRS.decode("EPSG:3857"),12923543.888468, 4852595.145082 - tile, tile, tile);

        WritableRaster raster = createWritableRaster(4);
        addBound(matrix, raster, 0);
        addBound(matrix, raster, 1);
        addBound(matrix, raster, 2);
        addBound(matrix, raster, 3);
        GridCoverageFactory f = new GridCoverageFactory();
        GridCoverage2D coverage = f.create("tiffTest", raster, envelope);
        GeoTiffFormat format = new GeoTiffFormat();

        /*ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ImageOutputStream ios = ImageIO.createImageOutputStream(bao);
        GridCoverageWriter writer = format.getWriter(ios);*/

        File out = new File("/Users/didi/Desktop/data/test4.tiff");
        GridCoverageWriter writer = format.getWriter(out);
        writer.write(coverage, createWriteParameters());
        writer.dispose();
        coverage.dispose(true);
        return "test";
    }

    public static WritableRaster createWritableRaster(int boundNum) {
        WritableRaster raster = RasterFactory.createBandedRaster(2, 256, 256, boundNum, (Point) null);
        return raster;
    }

    public static void addBound(int[][] matrix, WritableRaster raster, int boundIndex) {
        for (int i = 0; i < 256; i++) {
            for (int j = 0; j < 256; j++) {
                raster.setSample(i, j, boundIndex, matrix[i][j]);
            }
        }
    }

    public static GeneralParameterValue[] createWriteParameters() {

        GeoTiffFormat format = new GeoTiffFormat();
        GeoTiffWriteParams wp = new GeoTiffWriteParams();
        wp.setCompressionMode(GeoTiffWriteParams.MODE_EXPLICIT);
        wp.setCompressionType("Deflate");
        ParameterValueGroup params = format.getWriteParameters();
        params.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp);
        GeneralParameterValue[] writeParameters = params.values().toArray(new GeneralParameterValue[1]);
        return writeParameters;
    }

3.读取tiff文件 并重新写入

    public static void tiffRead(byte[] tiff) throws IOException, FactoryException {

        ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(tiff);
        ImageInputStream stream =  ImageIO.createImageInputStream(arrayInputStream);

        GeoTiffReader reader = new GeoTiffReader(stream);
        GridCoverage2D coverage = reader.read(null);

        Envelope2D envelope = coverage.getEnvelope2D();
        RenderedImage image = coverage.getRenderedImage();

        double height = envelope.getHeight();
        double width = envelope.getWidth();
        double minx = envelope.getMinX();
        double miny = envelope.getMinY();
        String crs = CRS.toSRS(envelope.getCoordinateReferenceSystem());
        int type = image.getSampleModel().getDataType();
        int bandNum = image.getSampleModel().getNumBands();
        int matrixW = image.getWidth();
        //int matrixW2 = image.getTileWidth();
        int matrixH = image.getHeight();
        //int matrixH2 = image.getTileHeight();

        int[][][] matrix = new int[bandNum][matrixW][matrixH];
        Raster raster = image.getData();
        for (int b = 0; b < bandNum; b++) {
            for (int i = 0; i < matrixW; i++) {
                for (int j = 0; j < matrixH; j++) {
                    int value = raster.getSample(i, j, b);
                    matrix[b][i][j] = value;
                    if (value > 0){
                        System.out.println(i + "," + j + "," + b + "," + value);
                    }
                }
            }
        }

        //tiffWrite2(crs,minx,miny,width,height,type,bandNum,matrixW,matrixH,matrix);
        tiffWrite3(coverage);
    }

    public static void tiffWrite3(GridCoverage2D coverage) throws IOException {
        File out2 = new File("/Users/didi/Desktop/data/"+ UUID.randomUUID().toString().substring(0,4)+".tiff");
        GeoTiffFormat format = new GeoTiffFormat();
        GridCoverageWriter writer2 = format.getWriter(out2);
        writer2.write(coverage, createWriteParameters());
        writer2.dispose();
        coverage.dispose(true);
    }

geotools版本问题,尽量使用高版本(推荐28.0,不建议使用30.0 因为需要jdk版本大于11)低版本geotools生成的tiff文件会存在以下问题

  • 低版本geotools 读取时不能使用 ImageInputStream 必须要新建feil文件才能完成读取,读取的coverage重新写成tiff qgis看不到band(原因未确定,可能是colormodel的问题)
  • 高版本geotools读取低版本geotools的产出tiff时 band只要大于3就会出现异常,原因是高版本的geotool默认创建的colorModel只有3个band 与raster的band数无法匹配
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值