/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geotools.process.raster;
import static org.geotools.filter.capability.FunctionNameImpl.parameter;
import java.util.List;
import org.geotools.coverage.Category;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.filter.FunctionExpressionImpl;
import org.geotools.filter.capability.FunctionNameImpl;
import org.geotools.util.Utilities;
import org.opengis.filter.capability.FunctionName;
/**
* Filter function to retrieve a grid coverage band min/max value
*
* @author Andrea Aime, GeoSolutions SAS
*/
public class FilterFunction_bandStats extends FunctionExpressionImpl {
public static FunctionName NAME = new FunctionNameImpl("bandStats",
parameter("value", Number.class),
parameter("bandIndex", Number.class),
parameter("property", String.class));
public FilterFunction_bandStats() {
super(NAME);
}
public Object evaluate(Object feature) {
try {
Integer bandIndex = (getExpression(0).evaluate(feature,Integer.class));
String propertyName = (getExpression(1).evaluate(feature,String.class));
Object val = null;
if (feature instanceof GridCoverage2D) {
GridCoverage2D coverage = (GridCoverage2D) feature;
val = evaluate (coverage, bandIndex, propertyName);
}
if (val != null) {
return val;
}
throw new IllegalArgumentException("Filter Function problem for function gridCoverageStats: Unable to find the stat "
+ propertyName + " from the input object of type " + feature.getClass());
} catch (Exception e) {
// probably a type error
throw new IllegalArgumentException("Filter Function problem for function gridCoverageStats", e);
}
}
Object evaluate (final GridCoverage2D coverage, final int bandIndex, final String statName) {
Utilities.ensureNonNull("coverage", coverage);
GridSampleDimension sd = coverage.getSampleDimension(bandIndex);
if("minimum".equalsIgnoreCase(statName)) {
return ensureNotNull(sd, bandIndex, statName, getMinimum(sd));
} else if("maximum".equalsIgnoreCase(statName)) {
return ensureNotNull(sd, bandIndex, statName, getMaximum(sd));
} else {
throw new IllegalArgumentException("Invalid property " + statName + ", supported values are 'minimum' and 'maximum'");
}
}
private double ensureNotNull(GridSampleDimension sd, int bandIndex, String statName,
Double value) {
if(value != null) {
return value;
} else {
throw new RuntimeException("Could not find the " + statName + " from " + sd + " of band " + bandIndex);
}
}
private Double getMaximum(GridSampleDimension sd) {
for (Category cat : sd.getCategories()) {
final double result = cat.getRange().getMaximum();
if(!Category.NODATA.getName().equals(cat.getName()) && !Double.isNaN(result)) {
return result;
}
}
return null;
}
private Double getMinimum(GridSampleDimension sd) {
final List<Category> categories = sd.getCategories();
for(int i = categories.size() - 1; i >= 0; i--) {
Category cat = categories.get(i);
final double result = cat.getRange().getMinimum();
if(!Category.NODATA.getName().equals(cat.getName()) && !Double.isNaN(result)) {
return result;
}
}
return null;
}
}