I'm working in Geotools with Java. So far, I have a GridCoverage2D and a List of Geometries. The GridCoverage2D is a digital elevation model, originating from a geotiff. Everything works fine till here.
Now I want to get the area for each polygon where the elevation has a certain value. For example for this Geometry, I want to know the total area where the elevation is 27 m. How can I achieve this?
I have no clue how to start :(
Two options I have in mind:
This turned out to be harder than I expected, which probably means I've missed something obvious. You can solve the question by creating a histogram of the coverage and then selecting the bin which contains your value. The all you need to do is multiply the total number of cells by the area of a cell.
So assuming you've read in or created a coverage:
private double selectCells(GridCoverage2D cov, int value) {
GridGeometry2D geom = cov.getGridGeometry();
// cov.show();
final OperationJAI op = new OperationJAI("Histogram");
ParameterValueGroup params = op.getParameters();
GridCoverage2D coverage;
params.parameter("Source").setValue(cov);
coverage = (GridCoverage2D) op.doOperation(params, null);
javax.media.jai.Histogram hist = (Histogram) coverage
.getProperty("histogram");
int total = hist.getSubTotal(0, value, value);
double area = calcAreaOfCell(geom);
Unit<?> unit = cov.getCoordinateReferenceSystem().getCoordinateSystem()
.getAxis(0).getUnit();
System.out.println("which gives " + (area * total) + " " + unit
+ "^2 area with value " + value);
return area * total;
}
private double calcAreaOfCell(GridGeometry2D geom) {
GridEnvelope gridRange = geom.getGridRange();
int width = gridRange.getHigh(0) - gridRange.getLow(0) + 1; // allow for the
int height = gridRange.getHigh(1) - gridRange.getLow(1) + 1;// 0th row/col
Envelope envelope = geom.getEnvelope();
double dWidth = envelope.getMaximum(0) - envelope.getMinimum(0);
double dHeight = envelope.getMaximum(1) - envelope.getMinimum(1);
double cellWidth = dWidth / width;
double cellHeight = dHeight / height;
return cellWidth * cellHeight;
}
Obviously if you plan on calling it more than once you can cache the histogram and the cellsize.