# Finding coordinates of max n values of raster layer using GeoTools

I have a Geotiff file which is published as a raster layer in Geoserver. I need to be able to calculate the coordinates of the max n values that are inside a given polygon.

I have found a WPS called `gs:RasterZonalStatistics` which returns the max value in a raster layer. But I need to modify its code to return the coordinates of the max value. And further more to return the coordinates of the max n values.

I have searched the geotools code, and found the two classes: `org.geotools.process.raster.RasterZonalStatistics` and `org.geotools.process.raster.RasterZonalStatistics2`. I've tried to understand their code and to find the place where I should change but with no success.

Where is the real logic of calculating the max value?

## 1 Answer

As far as I can tell the logic for those classes is down it `org.jaitools.media.jai.zonalstats.ZonalStats` but it is fairly opaque.

For a simpler way to do it have a look at this code:

``````  private double findMax2(int band) throws TransformException {
double max = Double.NEGATIVE_INFINITY;
GridSampleDimension sampleDimension = cov.getSampleDimension(band);
double[] nodataarr = sampleDimension.getNoDataValues();
double[] nodata = nodataarr != null ? nodataarr : new double[] { Double.NaN };
double[] dest = new double[cov.getNumSampleDimensions()];
GridCoordinates2D mCoord = null;
GridEnvelope2D gr = cov.getGridGeometry().getGridRange2D();
for (int i = gr.getLow(0); i < gr.getHigh(0); i++) {
for (int j = gr.getLow(1); j < gr.getHigh(1); j++) {
GridCoordinates2D coord = new GridCoordinates2D(i, j);
cov.evaluate(coord, dest);
// System.out.println("" + i + "," + j + "\t " + dest[band] + " (" + max
// + ")");
if (dest[band] != nodata[0] && dest[band] > max) {
max = dest[band];
mCoord = coord;
}
}
}

System.out.println("" + max + " at " + mCoord + " " + cov.getGridGeometry().gridToWorld(mCoord));
return max;
}
``````

Essentially, you need to loop through the coverage data and compare it to your current max and if it is bigger (and not NODATA) update where your highest point is.