001: /*
002: * Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
003: * This code is licensed under the GPL 2.0 license, availible at the root
004: * application directory.
005: */
006: package org.geoserver.wfs.response;
007:
008: import com.vividsolutions.jts.geom.Coordinate;
009: import com.vividsolutions.jts.geom.Envelope;
010: import com.vividsolutions.jts.geom.Geometry;
011: import com.vividsolutions.jts.geom.GeometryCollection;
012: import com.vividsolutions.jts.geom.LineString;
013: import com.vividsolutions.jts.geom.MultiLineString;
014: import com.vividsolutions.jts.geom.MultiPoint;
015: import com.vividsolutions.jts.geom.MultiPolygon;
016: import com.vividsolutions.jts.geom.Point;
017: import com.vividsolutions.jts.geom.Polygon;
018: import net.sf.json.JSONException;
019: import net.sf.json.util.JSONBuilder;
020: import java.io.Writer;
021:
022: /**
023: * This class extends the JSONBuilder to be able to write out geometric types. It is coded
024: * against the draft 5 version of the spec on http://geojson.org
025: *
026: * @author Chris Holmes, The Open Planning Project
027: * @version $Id$
028: *
029: */
030: public class GeoJSONBuilder extends JSONBuilder {
031: public GeoJSONBuilder(Writer w) {
032: super (w);
033: }
034:
035: /**
036: * Writes any geometry object. This class figures out which geometry representation to write
037: * and calls subclasses to actually write the object.
038: * @param geometry The geoemtry be encoded
039: * @return The JSONBuilder with the new geoemtry
040: * @throws JSONException If anything goes wrong
041: */
042: public JSONBuilder writeGeom(Geometry geometry)
043: throws JSONException {
044: this .object();
045: this .key("type");
046: this .value(getGeometryName(geometry));
047:
048: int geometryType = getGeometryType(geometry);
049:
050: if (geometryType != MULTIGEOMETRY) {
051: this .key("coordinates");
052:
053: switch (geometryType) {
054: case POINT:
055: writeCoordinate(geometry.getCoordinate());
056:
057: break;
058:
059: case LINESTRING:
060: case MULTIPOINT:
061: writeCoordinates(geometry.getCoordinates());
062:
063: break;
064:
065: case POLYGON:
066: writePolygon((Polygon) geometry);
067:
068: break;
069:
070: case MULTILINESTRING:
071: this .array();
072:
073: for (int i = 0, n = geometry.getNumGeometries(); i < n; i++) {
074: writeCoordinates(geometry.getGeometryN(i)
075: .getCoordinates());
076: }
077:
078: this .endArray();
079:
080: break;
081:
082: case MULTIPOLYGON:
083: this .array();
084:
085: for (int i = 0, n = geometry.getNumGeometries(); i < n; i++) {
086: writePolygon((Polygon) geometry.getGeometryN(i));
087: }
088:
089: this .endArray();
090:
091: break;
092: }
093: } else {
094: writeGeomCollection((GeometryCollection) geometry);
095: }
096:
097: return this .endObject();
098: }
099:
100: private JSONBuilder writeGeomCollection(
101: GeometryCollection collection) {
102: this .array();
103: this .key("geometries");
104:
105: for (int i = 0, n = collection.getNumGeometries(); i < n; i++) {
106: writeGeom(collection.getGeometryN(i));
107: }
108:
109: return this .endArray();
110: }
111:
112: /**
113: * Write the coordinates of a geometry
114: * @param coords The coordinates to write
115: * @return this
116: * @throws JSONException
117: */
118: private JSONBuilder writeCoordinates(Coordinate[] coords)
119: throws JSONException {
120: this .array();
121:
122: for (int i = 0; i < coords.length; i++) {
123: Coordinate coord = coords[i];
124: writeCoordinate(coord);
125: }
126:
127: return this .endArray();
128: }
129:
130: private JSONBuilder writeCoordinate(Coordinate coord) {
131: this .array();
132: this .value(coord.x);
133: this .value(coord.y);
134:
135: return this .endArray();
136: }
137:
138: /**
139: * Turns an envelope into an array [minX,minY,maxX,maxY]
140: * @param env envelope representing bounding box
141: * @return this
142: */
143: protected JSONBuilder writeBoundingBox(Envelope env) {
144: this .key("bbox");
145: this .array();
146: this .value(env.getMinX());
147: this .value(env.getMinY());
148: this .value(env.getMaxX());
149: this .value(env.getMaxY());
150: return this .endArray();
151: }
152:
153: /**
154: * Writes a polygon
155: * @param geometry The polygon to write
156: * @throws JSONException
157: */
158: private void writePolygon(Polygon geometry) throws JSONException {
159: this .array();
160: writeCoordinates(geometry.getExteriorRing().getCoordinates());
161:
162: for (int i = 0, ii = geometry.getNumInteriorRing(); i < ii; i++) {
163: writeCoordinates(geometry.getInteriorRingN(i)
164: .getCoordinates());
165: }
166:
167: this .endArray(); //end the linear ring
168: //this.endObject(); //end the
169: }
170:
171: /** Internal representation of OGC SF Point */
172: protected static final int POINT = 1;
173:
174: /** Internal representation of OGC SF LineString */
175: protected static final int LINESTRING = 2;
176:
177: /** Internal representation of OGC SF Polygon */
178: protected static final int POLYGON = 3;
179:
180: /** Internal representation of OGC SF MultiPoint */
181: protected static final int MULTIPOINT = 4;
182:
183: /** Internal representation of OGC SF MultiLineString */
184: protected static final int MULTILINESTRING = 5;
185:
186: /** Internal representation of OGC SF MultiPolygon */
187: protected static final int MULTIPOLYGON = 6;
188:
189: /** Internal representation of OGC SF MultiGeometry */
190: protected static final int MULTIGEOMETRY = 7;
191:
192: public static String getGeometryName(Geometry geometry) {
193: Class geomClass = geometry.getClass();
194: String returnValue = null;
195:
196: if (geomClass.equals(Point.class)) {
197: returnValue = "Point";
198: } else if (geomClass.equals(LineString.class)) {
199: returnValue = "LineString";
200: } else if (geomClass.equals(Polygon.class)) {
201: returnValue = "Polygon";
202: } else if (geomClass.equals(MultiPoint.class)) {
203: returnValue = "MultiPoint";
204: } else if (geomClass.equals(MultiLineString.class)) {
205: returnValue = "MultiLineString";
206: } else if (geomClass.equals(MultiPolygon.class)) {
207: returnValue = "MultiPolygon";
208: } else if (geomClass.equals(GeometryCollection.class)) {
209: returnValue = "GeometryCollection";
210: } else {
211: //HACK!!! throw exception
212: returnValue = null;
213: }
214:
215: return returnValue;
216: }
217:
218: /**
219: * Gets the internal representation for the given Geometry
220: *
221: * @param geometry a Geometry
222: *
223: * @return int representation of Geometry
224: */
225: public static int getGeometryType(Geometry geometry) {
226: //LOGGER.entering("GMLUtils", "getGeometryType", geometry);
227: Class geomClass = geometry.getClass();
228: int returnValue = -1;
229:
230: if (geomClass.equals(Point.class)) {
231: //LOGGER.finest("found point");
232: returnValue = POINT;
233: } else if (geomClass.equals(LineString.class)) {
234: //LOGGER.finest("found linestring");
235: returnValue = LINESTRING;
236: } else if (geomClass.equals(Polygon.class)) {
237: //LOGGER.finest("found polygon");
238: returnValue = POLYGON;
239: } else if (geomClass.equals(MultiPoint.class)) {
240: //LOGGER.finest("found multiPoint");
241: returnValue = MULTIPOINT;
242: } else if (geomClass.equals(MultiLineString.class)) {
243: returnValue = MULTILINESTRING;
244: } else if (geomClass.equals(MultiPolygon.class)) {
245: returnValue = MULTIPOLYGON;
246: } else if (geomClass.equals(GeometryCollection.class)) {
247: returnValue = MULTIGEOMETRY;
248: } else {
249: returnValue = -1;
250:
251: //HACK!!! throw exception.
252: }
253:
254: return returnValue;
255: }
256: }
|