001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.gml;
017:
018: import java.util.Collection;
019: import java.util.List;
020: import java.util.Vector;
021: import java.util.logging.Logger;
022:
023: import com.vividsolutions.jts.geom.Coordinate;
024: import com.vividsolutions.jts.geom.Geometry;
025: import com.vividsolutions.jts.geom.GeometryFactory;
026: import com.vividsolutions.jts.geom.LineString;
027: import com.vividsolutions.jts.geom.MultiLineString;
028: import com.vividsolutions.jts.geom.MultiPoint;
029: import com.vividsolutions.jts.geom.MultiPolygon;
030: import com.vividsolutions.jts.geom.Point;
031: import com.vividsolutions.jts.geom.Polygon;
032:
033: /**
034: * Creates a MultiPoint, MultiLineString, or MultiPolygon geometry as required
035: * by the internal functions.
036: *
037: * @author Ian Turton, CCG
038: * @author Rob Hranac, Vision for New York
039: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/gml/SubHandlerMulti.java $
040: * @version $Id: SubHandlerMulti.java 27862 2007-11-12 19:51:19Z desruisseaux $
041: */
042: public class SubHandlerMulti extends SubHandler {
043: /** The logger for the GML module. */
044: private static final Logger LOGGER = org.geotools.util.logging.Logging
045: .getLogger("org.geotools.gml");
046:
047: /**
048: * Remembers the list of all possible sub (base) types for this multi type.
049: */
050: private static final Collection BASE_GEOMETRY_TYPES = new Vector(
051: java.util.Arrays.asList(new String[] { "Point",
052: "LineString", "Polygon" }));
053:
054: /** Geometry factory to return the multi type. */
055: private GeometryFactory geometryFactory = new GeometryFactory();
056:
057: /** Handler factory to return the sub type. */
058: private SubHandlerFactory handlerFactory = new SubHandlerFactory();
059:
060: /** Creates a SubHandler for the current sub type. */
061: private SubHandler currentHandler;
062:
063: /** Stores list of all sub types. */
064: private List geometries = new Vector();
065:
066: /** Remembers the current sub type (ie. Line, Polygon, Point). */
067: private String internalType;
068:
069: /** Remembers whether or not the internal type is set already. */
070: private boolean internalTypeSet = false;
071:
072: /**
073: * Empty constructor.
074: */
075: public SubHandlerMulti() {
076: }
077:
078: /**
079: * Handles all internal (sub) geometries.
080: *
081: * @param message The sub geometry type found.
082: * @param type Whether or not it is at a start or end.
083: */
084: public void subGeometry(String message, int type) {
085: LOGGER.fine("subGeometry message = " + message + " type = "
086: + type);
087:
088: // if the internal type is not yet set, set it
089: if (!internalTypeSet) {
090: if (BASE_GEOMETRY_TYPES.contains(message)) {
091: internalType = message;
092: internalTypeSet = true;
093: LOGGER.fine("Internal type set to " + message);
094: }
095: }
096:
097: // if the internal type is already set, then either:
098: // create a new handler, if at start of geometry, or
099: // return the completed geometry, if at the end of it
100: if (message.equals(internalType)) {
101: if (type == GEOMETRY_START) {
102: currentHandler = handlerFactory.create(internalType);
103: } else if (type == GEOMETRY_END) {
104: geometries.add(currentHandler.create(geometryFactory));
105: } else if (type == GEOMETRY_SUB) {
106: currentHandler.subGeometry(message, type);
107: }
108: } else {
109: currentHandler.subGeometry(message, type);
110: LOGGER.fine(internalType + " != " + message);
111: }
112: }
113:
114: /**
115: * Adds a coordinate to the current internal (sub) geometry.
116: *
117: * @param coordinate The coordinate.
118: */
119: public void addCoordinate(Coordinate coordinate) {
120: currentHandler.addCoordinate(coordinate);
121: }
122:
123: /**
124: * Determines whether or not it is time to return this geometry.
125: *
126: * @param message The geometry element that prompted this check.
127: *
128: * @return DOCUMENT ME!
129: */
130: public boolean isComplete(String message) {
131: if (message.equals("Multi" + internalType)) {
132: return true;
133: } else {
134: return false;
135: }
136: }
137:
138: /**
139: * Returns a completed multi type.
140: *
141: * @param geometryFactory The factory this method should use to create the
142: * multi type.
143: *
144: * @return Appropriate multi geometry type.
145: */
146: public Geometry create(GeometryFactory geometryFactory) {
147: if (internalType.equals("Point")) {
148: Point[] pointArray = geometryFactory
149: .toPointArray(geometries);
150: MultiPoint multiPoint = geometryFactory
151: .createMultiPoint(pointArray);
152: multiPoint.setUserData(getSRS());
153: multiPoint.setSRID(getSRID());
154: LOGGER.fine("created " + multiPoint);
155:
156: return multiPoint;
157: } else if (internalType.equals("LineString")) {
158: LineString[] lineStringArray = geometryFactory
159: .toLineStringArray(geometries);
160: MultiLineString multiLineString = geometryFactory
161: .createMultiLineString(lineStringArray);
162: multiLineString.setUserData(getSRS());
163: multiLineString.setSRID(getSRID());
164: LOGGER.fine("created " + multiLineString);
165:
166: return multiLineString;
167: } else if (internalType.equals("Polygon")) {
168: Polygon[] polygonArray = geometryFactory
169: .toPolygonArray(geometries);
170: MultiPolygon multiPolygon = geometryFactory
171: .createMultiPolygon(polygonArray);
172: multiPolygon.setUserData(getSRS());
173: multiPolygon.setSRID(getSRID());
174: LOGGER.fine("created " + multiPolygon);
175:
176: return multiPolygon;
177: } else {
178: return null;
179: }
180: }
181: }
|