001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, 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: */
017: /*
018: * GeometryTransformer.java
019: *
020: * Created on October 24, 2003, 1:08 PM
021: */
022: package org.geotools.gml.producer;
023:
024: import org.geotools.xml.transform.TransformerBase;
025: import org.xml.sax.ContentHandler;
026: import org.xml.sax.SAXException;
027: import org.xml.sax.helpers.AttributesImpl;
028:
029: import com.vividsolutions.jts.geom.Coordinate;
030: import com.vividsolutions.jts.geom.Envelope;
031: import com.vividsolutions.jts.geom.Geometry;
032: import com.vividsolutions.jts.geom.GeometryCollection;
033: import com.vividsolutions.jts.geom.Polygon;
034:
035: /**
036: * Used to walk through GeometryObjects issuing SAX events
037: * as needed.
038: * <p>
039: * Please note that this GeometryTransformer issues GML2 events,
040: * the Coordinate
041: *
042: * @author Ian Schneider
043: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/gml/producer/GeometryTransformer.java $
044: */
045: public class GeometryTransformer extends TransformerBase {
046:
047: protected boolean useDummyZ = false;
048:
049: protected int numDecimals = 4;
050:
051: public void setUseDummyZ(boolean flag) {
052: useDummyZ = flag;
053: }
054:
055: public void setNumDecimals(int num) {
056: numDecimals = num;
057: }
058:
059: /**
060: * @TODO remove constant from GometryTraslator contructor call
061: */
062: public org.geotools.xml.transform.Translator createTranslator(
063: ContentHandler handler) {
064: return new GeometryTranslator(handler, numDecimals, useDummyZ);
065: }
066:
067: public static class GeometryTranslator extends TranslatorSupport {
068: protected CoordinateWriter coordWriter = new CoordinateWriter();
069:
070: public GeometryTranslator(ContentHandler handler) {
071: this (handler, "gml", GMLUtils.GML_URL);
072: }
073:
074: public GeometryTranslator(ContentHandler handler,
075: String prefix, String nsUri) {
076: super (handler, prefix, nsUri);
077: coordWriter.setPrefix(prefix);
078: coordWriter.setNamespaceUri(nsUri);
079: }
080:
081: public GeometryTranslator(ContentHandler handler,
082: int numDecimals) {
083: this (handler, "gml", GMLUtils.GML_URL, numDecimals);
084: }
085:
086: public GeometryTranslator(ContentHandler handler,
087: String prefix, String nsUri, int numDecimals) {
088: this (handler, prefix, nsUri);
089: coordWriter = new CoordinateWriter(numDecimals, false);
090: coordWriter.setPrefix(prefix);
091: coordWriter.setNamespaceUri(nsUri);
092: }
093:
094: public GeometryTranslator(ContentHandler handler,
095: int numDecimals, boolean isDummyZEnabled) {
096: this (handler, "gml", GMLUtils.GML_URL, numDecimals,
097: isDummyZEnabled);
098: }
099:
100: public GeometryTranslator(ContentHandler handler,
101: String prefix, String nsUri, int numDecimals,
102: boolean isDummyZEnabled) {
103: this (handler, prefix, nsUri);
104: coordWriter = new CoordinateWriter(numDecimals,
105: isDummyZEnabled);
106: coordWriter.setPrefix(prefix);
107: coordWriter.setNamespaceUri(nsUri);
108: }
109:
110: /**
111: * Constructor for GeometryTranslator allowing the specification of the number of
112: * valid dimension represented in the Coordinates.
113: * @param handler
114: * @param prefix
115: * @param nsUri
116: * @param numDecimals
117: * @param isDummyZEnabled
118: * @param dimension If this value is 3; the coordinate.z will be used rather than dummyZ
119: */
120: public GeometryTranslator(ContentHandler handler,
121: String prefix, String nsUri, int numDecimals,
122: boolean isDummyZEnabled, int dimension) {
123: this (handler, prefix, nsUri);
124: coordWriter = new CoordinateWriter(numDecimals,
125: isDummyZEnabled, dimension);
126: coordWriter.setPrefix(prefix);
127: coordWriter.setNamespaceUri(nsUri);
128: }
129:
130: public boolean isDummyZEnabled() {
131: return coordWriter.isDummyZEnabled();
132: }
133:
134: public int getNumDecimals() {
135: return coordWriter.getNumDecimals();
136: }
137:
138: public void encode(Object o, String srsName)
139: throws IllegalArgumentException {
140: if (o instanceof Geometry) {
141: encode((Geometry) o, srsName);
142: } else {
143: throw new IllegalArgumentException("Unable to encode "
144: + o);
145: }
146: }
147:
148: public void encode(Object o) throws IllegalArgumentException {
149: encode(o, null);
150: }
151:
152: public void encode(Envelope bounds) {
153: encode(bounds, null);
154: }
155:
156: public void encode(Envelope bounds, String srsName) {
157: // DJB: old behavior for null bounds:
158: //
159: //<gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#0">
160: //<gml:coordinates decimal="." cs="," ts=" ">0,0 -1,-1</gml:coordinates>
161: //</gml:Box>
162: //
163: // new behavior:
164: // <gml:null>unknown</gml:null>
165: if (bounds.isNull()) {
166: encodeNullBounds();
167:
168: return; // we're done!
169: }
170: String boxName = boxName();
171:
172: if ((srsName == null) || srsName.equals("")) {
173: start(boxName);
174: } else {
175: AttributesImpl atts = new AttributesImpl();
176: atts
177: .addAttribute("", "srsName", "srsName", "",
178: srsName);
179: start(boxName, atts);
180: }
181:
182: try {
183: Coordinate[] coords = new Coordinate[2];
184: coords[0] = new Coordinate(bounds.getMinX(), bounds
185: .getMinY());
186: //coords[1] = new Coordinate(bounds.getMinX(), bounds.getMaxY());
187: coords[1] = new Coordinate(bounds.getMaxX(), bounds
188: .getMaxY());
189: //coords[3] = new Coordinate(bounds.getMaxX(), bounds.getMinY());
190: coordWriter.writeCoordinates(coords, contentHandler);
191: } catch (SAXException se) {
192: throw new RuntimeException(se);
193: }
194:
195: end(boxName);
196: }
197:
198: /**
199: * Method to be subclasses in order to allow for gml3 encoding for null enevelope.
200: */
201: protected void encodeNullBounds() {
202: start("null");
203: String text = "unknown";
204: try {
205: contentHandler.characters(text.toCharArray(), 0, text
206: .length());
207: } catch (Exception e) //this shouldnt happen!!
208: {
209: System.out
210: .println("got exception while writing null boundedby:"
211: + e.getLocalizedMessage());
212: e.printStackTrace();
213: }
214: end("null");
215: }
216:
217: /**
218: * Method to be subclassed in order to allow for gml3 encoding of envelopes.
219: * @return "Box"
220: */
221: protected String boxName() {
222: return "Box";
223: }
224:
225: public void encode(Geometry geometry) {
226: encode(geometry, null);
227: }
228:
229: public void encode(Geometry geometry, String srsName) {
230: String geomName = GMLUtils.getGeometryName(geometry);
231:
232: if ((srsName == null) || srsName.equals("")) {
233: start(geomName);
234: } else {
235: AttributesImpl atts = new AttributesImpl();
236: atts
237: .addAttribute("", "srsName", "srsName", "",
238: srsName);
239: start(geomName, atts);
240: }
241:
242: int geometryType = GMLUtils.getGeometryType(geometry);
243:
244: switch (geometryType) {
245: case GMLUtils.POINT:
246: case GMLUtils.LINESTRING:
247:
248: try {
249: coordWriter.writeCoordinates(geometry
250: .getCoordinates(), contentHandler);
251: } catch (SAXException s) {
252: throw new RuntimeException(s);
253: }
254:
255: break;
256:
257: case GMLUtils.POLYGON:
258: writePolygon((Polygon) geometry);
259:
260: break;
261:
262: case GMLUtils.MULTIPOINT:
263: case GMLUtils.MULTILINESTRING:
264: case GMLUtils.MULTIPOLYGON:
265: case GMLUtils.MULTIGEOMETRY:
266: writeMulti((GeometryCollection) geometry, GMLUtils
267: .getMemberName(geometryType));
268:
269: break;
270: }
271:
272: end(geomName);
273: }
274:
275: public void encode(Geometry geometry, String srsName,
276: final int D) {
277: String geomName = GMLUtils.getGeometryName(geometry);
278:
279: if ((srsName == null) || srsName.equals("")) {
280: start(geomName);
281: } else {
282: AttributesImpl atts = new AttributesImpl();
283: atts
284: .addAttribute("", "srsName", "srsName", "",
285: srsName);
286: start(geomName, atts);
287: }
288:
289: int geometryType = GMLUtils.getGeometryType(geometry);
290:
291: switch (geometryType) {
292: case GMLUtils.POINT:
293: case GMLUtils.LINESTRING:
294:
295: try {
296: coordWriter.writeCoordinates(geometry
297: .getCoordinates(), contentHandler);
298: } catch (SAXException s) {
299: throw new RuntimeException(s);
300: }
301:
302: break;
303:
304: case GMLUtils.POLYGON:
305: writePolygon((Polygon) geometry);
306:
307: break;
308:
309: case GMLUtils.MULTIPOINT:
310: case GMLUtils.MULTILINESTRING:
311: case GMLUtils.MULTIPOLYGON:
312: case GMLUtils.MULTIGEOMETRY:
313: writeMulti((GeometryCollection) geometry, GMLUtils
314: .getMemberName(geometryType));
315:
316: break;
317: }
318:
319: end(geomName);
320: }
321:
322: private void writePolygon(Polygon geometry) {
323: String outBound = "outerBoundaryIs";
324: String lineRing = "LinearRing";
325: String inBound = "innerBoundaryIs";
326: start(outBound);
327: start(lineRing);
328:
329: try {
330: coordWriter.writeCoordinates(geometry.getExteriorRing()
331: .getCoordinates(), contentHandler);
332: } catch (SAXException s) {
333: throw new RuntimeException(s);
334: }
335:
336: end(lineRing);
337: end(outBound);
338:
339: for (int i = 0, ii = geometry.getNumInteriorRing(); i < ii; i++) {
340: start(inBound);
341: start(lineRing);
342:
343: try {
344: coordWriter.writeCoordinates(geometry
345: .getInteriorRingN(i).getCoordinates(),
346: contentHandler);
347: } catch (SAXException s) {
348: throw new RuntimeException(s);
349: }
350:
351: end(lineRing);
352: end(inBound);
353: }
354: }
355:
356: private void writeMulti(GeometryCollection geometry,
357: String member) {
358: for (int i = 0, n = geometry.getNumGeometries(); i < n; i++) {
359: start(member);
360:
361: encode(geometry.getGeometryN(i));
362:
363: end(member);
364: }
365: }
366: }
367: }
|