/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.ppio;
import java.util.Arrays;
import java.util.List;
import net.opengis.ows11.BoundingBoxType;
import net.opengis.ows11.Ows11Factory;
import org.geoserver.wps.WPSException;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.opengis.geometry.BoundingBox;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Envelope;
/**
* Process parameter input / output for bounding boxes
*
* @author Andrea Aime, OpenGeo
*/
public class BoundingBoxPPIO extends ProcessParameterIO {
public BoundingBoxPPIO(Class type) {
super(type, type);
}
/**
* Decodes the parameter from an external source or input stream.
* <p>
* This method should parse the input stream into its "internal" representation.
* </p>
*
* @param input
* The input stream.
*
* @return An object of type {@link #getType()}.
*/
public Object decode(BoundingBoxType boundingBoxType) throws Exception {
if (boundingBoxType == null) {
return null;
} else {
return toTargetType(boundingBoxType);
}
}
private Object toTargetType(BoundingBoxType bbox) throws Exception {
CoordinateReferenceSystem crs = null;
if(bbox.getCrs() != null) {
crs = CRS.decode(bbox.getCrs());
}
double[] lower = ordinates(bbox.getLowerCorner());
double[] upper = ordinates(bbox.getUpperCorner());
if(ReferencedEnvelope.class.isAssignableFrom(getType()) ||
BoundingBox.class.isAssignableFrom(getType())) {
return new ReferencedEnvelope(lower[0], upper[0], lower[1], upper[1], crs);
} else if(Envelope.class.isAssignableFrom(getType())) {
return new Envelope(lower[0], upper[0], lower[1], upper[1]);
} else if(org.opengis.geometry.Envelope.class.isAssignableFrom(getType())) {
GeneralEnvelope ge = new GeneralEnvelope(lower, upper);
ge.setCoordinateReferenceSystem(crs);
return ge;
} else {
throw new WPSException("Failed to convert from OWS 1.1 Bounding box type "
+ "to the internal representation: " + getType());
}
}
double[] ordinates(List<Double> corner) {
Double[] objects = (Double[]) corner.toArray(new Double[corner.size()]);
double[] result = new double[objects.length];
for (int i = 0; i < result.length; i++) {
result[i] = objects[i];
}
return result;
}
/**
* Encodes the internal representation of the object to an XML stream.
*
* @param object
* An object of type {@link #getType()}.
* @param handler
* An XML content handler.
*/
public BoundingBoxType encode(Object object) throws WPSException {
if (object == null) {
throw new IllegalArgumentException("Cannot encode a null bounding box");
}
return fromTargetType(object);
}
BoundingBoxType fromTargetType(Object object) throws WPSException {
Ows11Factory factory = Ows11Factory.eINSTANCE;
BoundingBoxType bbox = factory.createBoundingBoxType();
// basic conversion and collect the crs
CoordinateReferenceSystem crs = null;
if (object instanceof Envelope) {
Envelope env = (Envelope) object;
if(object instanceof ReferencedEnvelope) {
ReferencedEnvelope re = (ReferencedEnvelope) object;
crs = re.getCoordinateReferenceSystem();
}
bbox.setLowerCorner(Arrays.asList(env.getMinX(), env.getMinY()));
bbox.setUpperCorner(Arrays.asList(env.getMaxX(), env.getMaxY()));
} else if (org.opengis.geometry.Envelope.class.isAssignableFrom(getType())) {
org.opengis.geometry.Envelope env = (org.opengis.geometry.Envelope) object;
crs = env.getCoordinateReferenceSystem();
bbox.setLowerCorner(Arrays.asList(env.getLowerCorner().getCoordinate()));
bbox.setUpperCorner(Arrays.asList(env.getUpperCorner().getCoordinate()));
} else {
throw new WPSException("Failed to convert from " + object
+ " to an OWS 1.1 Bounding box type");
}
// handle the EPSG code
if(crs != null) {
try {
Integer code = CRS.lookupEpsgCode(crs, false);
if(code != null) {
bbox.setCrs("EPSG:" + code);
}
} catch(Exception e) {
throw new WPSException("Could not lookup epsg code for " + crs, e);
}
}
return bbox;
}
}