1

In GeoTools, GridCoverage2D.evaluate(DirectPosition coord, int[] dest) can get the raster data in specified location. It's powerful, but I want to get some raster data in a spatial range.

I try to use the

RenderedImage ri=GridCoverage2D.getRenderedImage() ;

ri.getData(Rectangle rect);

to get the raster data in a rectangle, but class Rectangle can't represent the other spatial range like circular or other polygon. It seems to have this function in ArcGIS.

Has any method in Java to get the data in a specified range of the TIFF file ?

0

You could load the image in QGIS and with PyQGIS (Python) access the data like this:

image = gdal.Open(directory)                   #directory is a string with the path to the file
band = image.GetRasterBand(1)                  #integer is the number of the band
array = band.ReadAsArray().astype(np.float)    #now you have all the image as an array

You can now iterate over this array saving only the pixels on the positions you want and creating a new image with GDAL. More on this is found here. Don't forget that for this to work you have to import numpy at the beginning of your code.

  • Maybe the question I have described is not very clear, I want to designate a polygon as range on a TIFF file and I prefer achieve it in Java code. I noticed that GDAL also support Java, but the document is too curt , I can not read it fluently. Does GDAL has the function that I have mentioned above? – leomessi Sep 29 at 2:58
  • @leomessi I think GDAL has gdalwarp for your purpose. It has crop to cutline. Here is an example of how GDAL commands are formatted in Python which may be similiar to how you'll have to construct it in Java: subprocess.call(["gdal_translate.exe","-co", "TILED=NO", "-co", "COMPRESS=LZW", "-ot", "Int16", "-scale", image_in, image_out ]) – Arturo Mendes Sep 30 at 6:42
0

Thanks for Arturo Mendes's answer,but I barely know GDAL and prefer use Geotools. If someone is like me,you can refer to this question:How to crop an image based on a shapefile using GeoTools

and the code,the key code is line 213-218,you can compare it to the code of the above question

the follow code can achieve the purpose

/***
     *Crop the GeoTiff base on geometric range
     * @param tifURL  
     * @param tfwURL 
     * @param range geometric range
     * @return GridCoverage of cropped tiff file
     * @throws Exception
     */

public static GridCoverage cropGeoTiff(String tifURL, String tfwURL, Geometry range) throws Exception {
    //tiff
    File tiff = new File(tifURL);
    //twf
    File twf = new File(tfwURL);
    TIFFImageReader tiffImageReader =
            (it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReader)
                    new TIFFImageReaderSpi().createReaderInstance();
    tiffImageReader.setInput(ImageIO.createImageInputStream(tiff));
    BufferedImage image = tiffImageReader.read(0);
    tiffImageReader.dispose();

    MathTransform transform = new WorldFileReader(twf).getTransform();
    GridCoverage2D coverage2D =
            CoverageFactoryFinder.getGridCoverageFactory(null)
                    .create(
                            "coverage",
                            image,
                            new GridGeometry2D(
                                    new GridEnvelope2D(
                                            PlanarImage.wrapRenderedImage(image).getBounds()),
                                    transform,
                                    DefaultGeographicCRS.WGS84),
                            new GridSampleDimension[]{new GridSampleDimension("coverage")},
                            null,
                            null);

    GridCoverage clippedCoverage = null;

    List<Geometry> geometryList = new ArrayList<Geometry>();
    geometryList.add(range);
    if (geometryList.size() > 0) {
        CoverageProcessor processor = new CoverageProcessor();
        //define the crop operation
        ParameterValueGroup params = processor.getOperation("CoverageCrop")
                .getParameters();
        //the GridCoverage which you want to crop
        params.parameter("Source").setValue(coverage2D);
        GeometryFactory factory = JTSFactoryFinder.getGeometryFactory(null);
        Geometry[] a = geometryList.toArray(new Geometry[0]);
        GeometryCollection c = new GeometryCollection(a, factory);
        //params.parameter("ENVELOPE").setValue(bounds);
        params.parameter("ROI").setValue(c);
        params.parameter("ForceMosaic").setValue(true);
        clippedCoverage = (GridCoverage) processor.doOperation(params);
        return clippedCoverage;
    }
    return null;
}
  • Please don't post link-only answers, but provide context and the relevant code-snippets by editing your answer. Links may get deleted and thus your answer would be useless. – Erik Oct 28 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.