001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.wfs.xml.gml3;
006:
007: import com.vividsolutions.jts.geom.Coordinate;
008: import com.vividsolutions.jts.geom.Geometry;
009: import org.geoserver.wfs.WFSException;
010: import org.geotools.geometry.jts.JTS;
011: import org.geotools.gml2.bindings.GML2ParsingUtils;
012: import org.geotools.referencing.CRS;
013: import org.geotools.referencing.operation.projection.PointOutsideEnvelopeException;
014: import org.geotools.xml.ElementInstance;
015: import org.geotools.xml.Node;
016: import org.opengis.referencing.NoSuchAuthorityCodeException;
017: import org.opengis.referencing.crs.CoordinateReferenceSystem;
018: import org.opengis.referencing.cs.CoordinateSystemAxis;
019: import org.picocontainer.MutablePicoContainer;
020: import org.vfny.geoserver.global.Data;
021:
022: /**
023: * Subclass of {@link org.geotools.gml3.bindings.AbstractGeometryTypeBinding} which performs some
024: * addtional validation checks.
025: * <p>
026: * Checks include:
027: * <ul>
028: * <li>All geometries have a crs, when not specified, the server default is used.
029: * <li>If a crs is specified it has a valid authority
030: * <li>Points defined on geometries fall into the valid coordinate space defined by crs.
031: * </ul>
032: * </p>
033: * @author Justin Deoliveira, The Open Planning Project
034: *
035: */
036: public class AbstractGeometryTypeBinding extends
037: org.geotools.gml3.bindings.AbstractGeometryTypeBinding {
038:
039: CoordinateReferenceSystem crs;
040:
041: public void setCRS(CoordinateReferenceSystem crs) {
042: this .crs = crs;
043: }
044:
045: public void initializeChildContext(ElementInstance childInstance,
046: Node node, MutablePicoContainer context) {
047: //if an srsName is set for this geometry, put it in the context for
048: // children, so they can use it as well
049: if (node.hasAttribute("srsName")) {
050: try {
051: CoordinateReferenceSystem crs = GML2ParsingUtils
052: .crs(node);
053: if (crs != null) {
054: context.registerComponentInstance(
055: CoordinateReferenceSystem.class, crs);
056: }
057: } catch (Exception e) {
058: throw new WFSException(e, "InvalidParameterValue");
059: }
060: }
061: }
062:
063: public Object parse(ElementInstance instance, Node node,
064: Object value) throws Exception {
065: try {
066: if (node.hasAttribute("srsName")) {
067: CRS
068: .decode(node.getAttributeValue("srsName")
069: .toString());
070: }
071: } catch (NoSuchAuthorityCodeException e) {
072: throw new WFSException("Invalid Authority Code: "
073: + e.getAuthorityCode(), "InvalidParameterValue");
074: }
075:
076: Geometry geometry = (Geometry) super .parse(instance, node,
077: value);
078:
079: if (geometry != null) {
080: //1. ensure a crs is set
081: if (geometry.getUserData() == null) {
082: //no crs set for the geometry, did we inherit one from a parent?
083: if (crs != null) {
084: geometry.setUserData(crs);
085: } else {
086: // for the moment we don't do anything since we miss the information
087: // to infer the CRS from the feature type
088: }
089: }
090:
091: //2. ensure the coordinates of the geometry fall into valid space defined by crs
092: CoordinateReferenceSystem crs = (CoordinateReferenceSystem) geometry
093: .getUserData();
094: if (crs != null)
095: try {
096: JTS.checkCoordinatesRange(geometry, crs);
097: } catch (PointOutsideEnvelopeException e) {
098: throw new WFSException(e, "InvalidParameterValue");
099: }
100: }
101:
102: return geometry;
103: }
104: }
|