/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.gml;
import org.xml.sax.SAXException;
/**
* LEVEL2 saxGML4j GML filter: translates coordinates and GML events into OGC
* simple types.
*
* <p>
* This filter simply reads in the events and coordinates passed to it by its
* GMLFilterDocument child and converts them into JTS objects. Note that it
* passes through anything not specifically sent to it by GMLFilterDocument
* (i.e. more or less everything not in geometry.xsd). The parent of this
* filter must implement GMLHandlerJTS in order to receive the JTS objects
* passed by this filter.
* </p>
*
* @author Rob Hranac, Vision for New York
* @source $URL$
* @version $Id$
*/
public class GMLFilterGeometry extends org.xml.sax.helpers.XMLFilterImpl
implements GMLHandlerGeometry {
/** Handler for the JTS elements generated by this filter. */
private GMLHandlerJTS parent;
/** Factory for the JTS geometries. */
private com.vividsolutions.jts.geom.GeometryFactory geometryFactory = new com.vividsolutions.jts.geom.GeometryFactory();
/** Factory for the GML geometry type subhandlers. */
private SubHandlerFactory handlerFactory = new SubHandlerFactory();
/** Generic GML geometry type subhandler. */
private SubHandler currentHandler;
/**
* Constructor with parent, which must implement GMLHandlerJTS.
*
* @param parent The parent of this filter.
*/
public GMLFilterGeometry(GMLHandlerJTS parent) {
super();
this.parent = parent;
}
/**
* Manages the start of a new main or sub geometry. This method looks at
* the status of the current handler and either returns a new sub-handler
* (if the last one was successfully returned already) or passes the
* element start notification along to the current handler as a sub
* geometry notice.
*
* @param localName The local name of the geometry, which corresponds to an
* OGC simple feature type.
* @param atts The attributes of the geometry, including SRID, etc.
*
* @throws SAXException parser error.
*/
public void geometryStart(String localName, org.xml.sax.Attributes atts)
throws SAXException {
String srs = null;
for (int i = 0; i < atts.getLength(); i++) {
final String NAME = atts.getQName(i);
if( "srs".equalsIgnoreCase( NAME ) ){
srs = atts.getValue(i);
}
}
if (currentHandler == null) {
currentHandler = handlerFactory.create(localName);
} else {
currentHandler.subGeometry(localName, currentHandler.GEOMETRY_START);
}
currentHandler.setSRS( srs );
}
/**
* Manages the end of a new main or sub geometry. This method looks at the
* status of the current handler and either returns the finished JTS
* object to its parent or passes the element end notification along to
* the current handler as a sub geometry notice.
*
* @param localName The local name of the geometry, which corresponds to an
* OGC simple feature type.
*
* @throws SAXException parser error.
*/
public void geometryEnd(String localName) throws SAXException {
if (currentHandler.isComplete(localName)) {
parent.geometry(currentHandler.create(geometryFactory));
currentHandler = null;
} else {
currentHandler.subGeometry(localName, currentHandler.GEOMETRY_END);
}
}
/**
* Manages a sub geometry, which simply means always pass it to the current
* content handler as a sub.
*
* @param localName The local name of the geometry, which corresponds to an
* OGC simple feature type.
*
* @throws SAXException parser error.
*/
public void geometrySub(String localName) throws SAXException {
currentHandler.subGeometry(localName, currentHandler.GEOMETRY_SUB);
}
/**
* Gets a coordinate from the child and passes it to the current handler as
* an add request.
*
* @param x The X coordinate of the received coordinate.
* @param y The Y coordinate of the received coordinate.
*
* @throws SAXException parser error.
*/
public void gmlCoordinates(double x, double y) throws SAXException {
currentHandler.addCoordinate(new com.vividsolutions.jts.geom.Coordinate(
x, y));
}
/**
* Gets a coordinate from the child and passes it to the current handler as
* an add request.
*
* @param x The X coordinate of the received coordinate.
* @param y The Y coordinate of the received coordinate.
* @param z The Z coordinate of the received coordinate.
*
* @throws SAXException parser error.
*/
public void gmlCoordinates(double x, double y, double z)
throws SAXException {
currentHandler.addCoordinate(new com.vividsolutions.jts.geom.Coordinate(
x, y, z));
}
/**
* Checks for GML element start and - if not a coordinates element - sends
* it directly on down the chain to the appropriate parent handler. If it
* is a coordinates (or coord) element, it uses internal methods to set
* the current state of the coordinates reader appropriately.
*
* @param namespaceURI The namespace of the element.
* @param localName The local name of the element.
* @param qName The full name of the element, including namespace prefix.
* @param atts The element attributes.
*
* @throws SAXException Some parsing error occurred while reading
* coordinates.
*/
public void startElement(String namespaceURI, String localName,
String qName, org.xml.sax.Attributes atts) throws SAXException {
parent.startElement(namespaceURI, localName, qName, atts);
}
/**
* Reads the only internal characters read by pure GML parsers, which are
* coordinates. These coordinates are sent to the coordinates reader
* class which interprets them appropriately, depending on its current
* state.
*
* @param ch Raw coordinate string from the GML document.
* @param start Beginning character position of raw coordinate string.
* @param length Length of the character string.
*
* @throws SAXException Some parsing error occurred while reading
* coordinates.
*/
public void characters(char[] ch, int start, int length)
throws SAXException {
parent.characters(ch, start, length);
}
/**
* Checks for GML element end and - if not a coordinates element - sends it
* directly on down the chain to the appropriate parent handler. If it is
* a coordinates (or coord) element, it uses internal methods to set the
* current state of the coordinates reader appropriately.
*
* @param namespaceURI The namespace of the element.
* @param localName The local name of the element.
* @param qName The full name of the element, including namespace prefix.
*
* @throws SAXException Some parsing error occurred while reading
* coordinates.
*/
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
parent.endElement(namespaceURI, localName, qName);
}
}