/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.data.util;
import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.factory.Hints;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.parameter.DefaultParameterDescriptor;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.BufferedCoordinateOperationFactory;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.OperationNotFoundException;
/**
* DOCUMENT ME!
*
* @author $Author: Alessio Fabiani (alessio.fabiani@geo-solutions.it)
* @author $Author: Simone Giannecchini (simone.giannecchini@geo-solutions.it)
*/
public class CoverageUtils {
private final static Logger LOGGER = org.geotools.util.logging.Logging.getLogger(CoverageUtils.class.toString());
public static final int TRANSPARENT = 0;
public static final int OPAQUE = 1;
public static GeneralParameterValue[] getParameters(ParameterValueGroup params) {
final List parameters = new ArrayList();
final String readGeometryKey = AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString();
if ((params != null) && (params.values().size() > 0)) {
List list = params.values();
final Iterator it = list.iterator();
while (it.hasNext()) {
final ParameterValue val = (ParameterValue) it.next();
if (val != null) {
final ParameterDescriptor descr = (ParameterDescriptor) val.getDescriptor();
final String _key = descr.getName().toString();
if ("namespace".equals(_key)) {
// skip namespace as it is *magic* and
// appears to be an entry used in all dataformats?
//
continue;
}
// /////////////////////////////////////////////////////////
//
// request param for better management of coverage
//
// /////////////////////////////////////////////////////////
if (_key.equalsIgnoreCase(readGeometryKey)) {
// IGNORING READ_GRIDGEOMETRY2D param
continue;
}
final Object value = val.getValue();
parameters.add(new DefaultParameterDescriptor(_key, value.getClass(), null,
value).createValue());
}
}
return (!parameters.isEmpty())
? (GeneralParameterValue[]) parameters.toArray(new GeneralParameterValue[parameters.size()])
: null;
} else {
return null;
}
}
public static GeneralParameterValue[] getParameters(ParameterValueGroup params, Map values) {
return getParameters(params, values, false);
}
public static GeneralParameterValue[] getParameters(ParameterValueGroup params, Map values,
boolean readGeom) {
final List<ParameterValue<?>> parameters = new ArrayList<ParameterValue<?>>();
final String readGeometryKey = AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString();
if ((params != null) && (params.values().size() > 0)) {
final List<GeneralParameterValue> elements = params.values();
for (GeneralParameterValue elem: elements) {
final ParameterValue<?> val = (ParameterValue<?>)elem;
if (val != null) {
final ParameterDescriptor<?> descr = val.getDescriptor();
final String _key = descr.getName().toString();
if ("namespace".equals(_key)) {
// skip namespace as it is *magic* and
// appears to be an entry used in all dataformats?
//
continue;
}
// /////////////////////////////////////////////////////////
//
// request param for better management of coverage
//
// /////////////////////////////////////////////////////////
if (_key.equalsIgnoreCase(readGeometryKey) && !readGeom) {
// IGNORING READ_GRIDGEOMETRY2D param
continue;
}
// /////////////////////////////////////////////////////////
//
// format specific params
//
// /////////////////////////////////////////////////////////
final Object value = CoverageUtils.getCvParamValue(_key, val, values);
parameters.add(new DefaultParameterDescriptor(_key, descr.getValueClass(), null, value).createValue());
}
}
return (!parameters.isEmpty())?
(GeneralParameterValue[]) parameters.toArray(new GeneralParameterValue[parameters.size()]): null;
} else {
return null;
}
}
public static Map getParametersKVP(ParameterValueGroup params) {
final Map parameters = new HashMap();
final String readGeometryKey = AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString();
if ((params != null) && (params.values().size() > 0)) {
final List list = params.values();
final Iterator it = list.iterator();
while (it.hasNext()) {
final ParameterValue val = (ParameterValue) it.next();
if (val != null) {
final ParameterDescriptor descr = (ParameterDescriptor) val.getDescriptor();
final String _key = descr.getName().toString();
if ("namespace".equals(_key)) {
// skip namespace as it is *magic* and
// appears to be an entry used in all dataformats?
//
continue;
}
// /////////////////////////////////////////////////////////
//
// request param for better management of coverage
//
// /////////////////////////////////////////////////////////
if (_key.equalsIgnoreCase(readGeometryKey)) {
// IGNORING READ_GRIDGEOMETRY2D param
continue;
}
Object value = val.getValue();
String text = "";
if (value == null) {
text = null;
} else if (value instanceof String) {
text = (String) value;
} else {
text = value.toString();
}
parameters.put(_key, (text != null) ? text : "");
}
}
return parameters;
} else {
return parameters;
}
}
/**
* @param paramValues
* @param key
* @param param
* @return
*/
public static Object getCvParamValue(final String key, ParameterValue param,
final List paramValues, final int index) {
Object value = null;
try {
if (key.equalsIgnoreCase("crs")) {
if ((getParamValue(paramValues, index) != null)
&& (((String) getParamValue(paramValues, index)).length() > 0)) {
if ((paramValues.get(index) != null)
&& (((String) paramValues.get(index)).length() > 0)) {
value = CRS.parseWKT((String) paramValues.get(index));
}
} else {
LOGGER.info("Unable to find a crs for the coverage param, using EPSG:4326");
value = CRS.decode("EPSG:4326");
}
} else if (key.equalsIgnoreCase("envelope")) {
if ((getParamValue(paramValues, index) != null)
&& (((String) getParamValue(paramValues, index)).length() > 0)) {
String tmp = (String) getParamValue(paramValues, index);
if ((tmp.indexOf("[") > 0) && (tmp.indexOf("]") > tmp.indexOf("["))) {
tmp = tmp.substring(tmp.indexOf("[") + 1, tmp.indexOf("]")).trim();
tmp = tmp.replaceAll(",", "");
String[] strCoords = tmp.split(" ");
double[] coords = new double[strCoords.length];
if (strCoords.length == 4) {
for (int iT = 0; iT < 4; iT++) {
coords[iT] = Double.parseDouble(strCoords[iT].trim());
}
value = (org.opengis.geometry.Envelope) new GeneralEnvelope(new double[] {
coords[0], coords[1]
}, new double[] { coords[2], coords[3] });
}
}
}
} else {
Class[] clArray = { getParamValue(paramValues, index).getClass() };
Object[] inArray = { getParamValue(paramValues, index) };
value = param.getValue().getClass().getConstructor(clArray).newInstance(inArray);
}
// Intentionally generic exception catched
} catch (Exception e) {
value = null;
// errors.add("paramValue[" + i + "]",
// new ActionError("error.dataFormatEditor.param.parse", key,
// getParamValue(i).getClass(), e));
}
return value;
}
private static String getParamValue(final List paramValues, final int index) {
return (String) paramValues.get(index);
}
/**
* @param params
* @param key
* @param param
* @return
*/
public static Object getCvParamValue(final String key, ParameterValue param, final Map params) {
Object value = null;
try {
if (key.equalsIgnoreCase("crs")) {
if ((params.get(key) != null) && (((String) params.get(key)).length() > 0)) {
value = CRS.parseWKT((String) params.get(key));
} else {
LOGGER.info("Unable to find a crs for the coverage param, using EPSG:4326");
value = CRS.decode("EPSG:4326");
}
} else if (key.equalsIgnoreCase("envelope")) {
if ((params.get(key) != null) && (((String) params.get(key)).length() > 0)) {
String tmp = (String) params.get(key);
if ((tmp.indexOf("[") > 0) && (tmp.indexOf("]") > tmp.indexOf("["))) {
tmp = tmp.substring(tmp.indexOf("[") + 1, tmp.indexOf("]")).trim();
tmp = tmp.replaceAll(",", "");
String[] strCoords = tmp.split(" ");
double[] coords = new double[strCoords.length];
if (strCoords.length == 4) {
for (int iT = 0; iT < 4; iT++) {
coords[iT] = Double.parseDouble(strCoords[iT].trim());
}
value = (org.opengis.geometry.Envelope) new GeneralEnvelope(new double[] {
coords[0], coords[1]
}, new double[] { coords[2], coords[3] });
}
}
}
} else if (key.equalsIgnoreCase(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName()
.toString())) {
if ((params.get(key) != null) && params.get(key) instanceof String
&& (((String) params.get(key)).length() > 0)) {
String tmp = (String) params.get(key);
if ((tmp.indexOf("[") > 0) && (tmp.indexOf("]") > tmp.indexOf("["))) {
tmp = tmp.substring(tmp.indexOf("[") + 1, tmp.indexOf("]")).trim();
tmp = tmp.replaceAll(",", "");
String[] strCoords = tmp.split(" ");
double[] coords = new double[strCoords.length];
if (strCoords.length == 4) {
for (int iT = 0; iT < 4; iT++) {
coords[iT] = Double.parseDouble(strCoords[iT].trim());
}
value = (org.opengis.geometry.Envelope) new GeneralEnvelope(new double[] {
coords[0], coords[1]
}, new double[] { coords[2], coords[3] });
}
}
} else if ((params.get(key) != null)
&& params.get(key) instanceof GeneralGridGeometry) {
value = params.get(key);
}
} else if (key.equalsIgnoreCase("InputTransparentColor")
|| key.equalsIgnoreCase("OutputTransparentColor")) {
if (params.get(key) != null) {
value = Color.decode((String) params.get(key));
} else {
Class[] clArray = { Color.class };
Object[] inArray = { params.get(key) };
value = param.getValue().getClass().getConstructor(clArray).newInstance(inArray);
}
}else if (key.equalsIgnoreCase("BackgroundValues")) {
if (params.get(key) != null) {
String temp = (String) params.get(key);
String[] elements = temp.split(",");
final double[] backgroundValues = new double[elements.length];
for(int i=0;i<elements.length;i++)
backgroundValues[i]=Double.valueOf(elements[i]);
value=backgroundValues;
}
}
else if (key.equalsIgnoreCase("InputImageThresholdValue")) {
if (params.get(key) != null) {
String temp = (String) params.get(key);
value=Double.valueOf(temp);
}
}
else {
Class[] clArray = { String.class };
Object[] inArray = { params.get(key) };
value = param.getValue().getClass().getConstructor(clArray).newInstance(inArray);
}
} catch (Exception e) {
value = param.getValue();
}
return value;
}
/**
* Returns the grid sample dimensions out of a reader by reading a sample of the coverage
* @param reader
* @return
*/
public static GridSampleDimension[] getCoverageDimensions(AbstractGridCoverage2DReader reader)
throws IOException {
/**
* Now reading a fake small GridCoverage just to retrieve meta information:
* - calculating a new envelope which is 1/20 of the original one
* - reading the GridCoverage subset
*/
final ParameterValueGroup readParams = reader.getFormat().getReadParameters();
final Map parameters = getParametersKVP(readParams);
final GeneralEnvelope envelope = reader.getOriginalEnvelope();
double[] minCP = envelope.getLowerCorner().getCoordinates();
double[] maxCP = new double[] {
minCP[0] + (envelope.getLength(0) / 20.0),
minCP[1] + (envelope.getLength(1) / 20.0)
};
final GeneralEnvelope subEnvelope = new GeneralEnvelope(minCP, maxCP);
subEnvelope.setCoordinateReferenceSystem(reader.getCrs());
parameters.put(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString(),
new GridGeometry2D(reader.getOriginalGridRange(), subEnvelope));
GridCoverage2D gc = (GridCoverage2D) reader.read(getParameters(readParams, parameters,
true));
return gc.getSampleDimensions();
}
}