/* 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.wfs.xml.gml3;
import org.geoserver.wfs.WFSException;
import org.geotools.geometry.jts.JTS;
import org.geotools.gml2.bindings.GML2ParsingUtils;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.projection.PointOutsideEnvelopeException;
import org.geotools.xml.ElementInstance;
import org.geotools.xml.Node;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.picocontainer.MutablePicoContainer;
import com.vividsolutions.jts.geom.Geometry;
/**
* Subclass of {@link org.geotools.gml3.bindings.AbstractGeometryTypeBinding} which performs some
* addtional validation checks.
* <p>
* Checks include:
* <ul>
* <li>All geometries have a crs, when not specified, the server default is used.
* <li>If a crs is specified it has a valid authority
* <li>Points defined on geometries fall into the valid coordinate space defined by crs.
* </ul>
* </p>
* @author Justin Deoliveira, The Open Planning Project
*
*/
public class AbstractGeometryTypeBinding extends org.geotools.gml3.bindings.AbstractGeometryTypeBinding {
CoordinateReferenceSystem crs;
public void setCRS(CoordinateReferenceSystem crs) {
this.crs = crs;
}
public void initializeChildContext(ElementInstance childInstance,
Node node, MutablePicoContainer context) {
//if an srsName is set for this geometry, put it in the context for
// children, so they can use it as well
if ( node.hasAttribute("srsName") ) {
try {
CoordinateReferenceSystem crs = GML2ParsingUtils.crs(node);
if ( crs != null ) {
context.registerComponentInstance(CoordinateReferenceSystem.class, crs);
}
} catch(Exception e) {
throw new WFSException(e, "InvalidParameterValue");
}
}
}
public Object parse(ElementInstance instance, Node node, Object value)
throws Exception {
try {
if (node.hasAttribute("srsName")) {
CRS.decode(node.getAttributeValue("srsName").toString());
}
} catch (NoSuchAuthorityCodeException e) {
throw new WFSException("Invalid Authority Code: " + e.getAuthorityCode(),
"InvalidParameterValue");
}
Geometry geometry = (Geometry) super.parse(instance, node, value);
if (geometry != null) {
//1. ensure a crs is set
if (geometry.getUserData() == null) {
//no crs set for the geometry, did we inherit one from a parent?
if ( crs != null ) {
geometry.setUserData(crs);
} else {
// for the moment we don't do anything since we miss the information
// to infer the CRS from the feature type
}
}
//2. ensure the coordinates of the geometry fall into valid space defined by crs
CoordinateReferenceSystem crs = (CoordinateReferenceSystem) geometry.getUserData();
if(crs != null)
try {
JTS.checkCoordinatesRange(geometry, crs);
} catch(PointOutsideEnvelopeException e) {
throw new WFSException(e, "InvalidParameterValue");
}
}
return geometry;
}
}