/* * 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. * */ /* * GeometryTransformer.java * * Created on October 24, 2003, 1:08 PM */ package org.geotools.gml.producer; import java.util.logging.Logger; import org.geotools.referencing.CRS; import org.geotools.referencing.CRS.AxisOrder; import org.geotools.util.logging.Logging; import org.geotools.xml.transform.TransformerBase; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateSequence; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence; /** * Used to walk through GeometryObjects issuing SAX events * as needed. *
* Please note that this GeometryTransformer issues GML2 events,
* the Coordinate
*
* @author Ian Schneider
*
*
* @source $URL$
*/
public class GeometryTransformer extends TransformerBase {
static final Logger LOGGER = Logging.getLogger(GeometryTransformer.class);
protected boolean useDummyZ = false;
protected int numDecimals = 4;
public void setUseDummyZ(boolean flag){
useDummyZ = flag;
}
public void setNumDecimals(int num) {
numDecimals = num;
}
/**
* @TODO remove constant from GometryTraslator contructor call
*/
public org.geotools.xml.transform.Translator createTranslator(
ContentHandler handler) {
return new GeometryTranslator(handler, numDecimals, useDummyZ);
}
public static class GeometryTranslator extends TranslatorSupport {
protected CoordinateWriter coordWriter = new CoordinateWriter();
public GeometryTranslator(ContentHandler handler) {
this(handler,"gml",GMLUtils.GML_URL);
}
public GeometryTranslator(ContentHandler handler, String prefix, String nsUri ) {
super(handler,prefix,nsUri);
coordWriter.setPrefix( prefix );
coordWriter.setNamespaceUri( nsUri );
}
public GeometryTranslator(ContentHandler handler, int numDecimals) {
this(handler,"gml",GMLUtils.GML_URL,numDecimals);
}
public GeometryTranslator(ContentHandler handler, String prefix, String nsUri, int numDecimals) {
this(handler,prefix,nsUri);
coordWriter = new CoordinateWriter(numDecimals, false);
coordWriter.setPrefix( prefix );
coordWriter.setNamespaceUri( nsUri );
}
public GeometryTranslator(ContentHandler handler, int numDecimals, boolean isDummyZEnabled) {
this(handler,"gml",GMLUtils.GML_URL,numDecimals,isDummyZEnabled);
}
public GeometryTranslator(ContentHandler handler, String prefix, String nsUri, int numDecimals, boolean isDummyZEnabled) {
this(handler,prefix,nsUri);
coordWriter = new CoordinateWriter(numDecimals, isDummyZEnabled);
coordWriter.setPrefix( prefix );
coordWriter.setNamespaceUri( nsUri );
}
/**
* Constructor for GeometryTranslator allowing the specification of the number of
* valid dimension represented in the Coordinates.
* @param handler
* @param prefix
* @param nsUri
* @param numDecimals
* @param isDummyZEnabled
* @param dimension If this value is 3; the coordinate.z will be used rather than dummyZ
* since 2.4.1
*/
public GeometryTranslator(ContentHandler handler, String prefix, String nsUri, int numDecimals, boolean isDummyZEnabled, int dimension) {
this(handler,prefix,nsUri);
coordWriter = new CoordinateWriter(numDecimals, isDummyZEnabled, dimension );
coordWriter.setPrefix( prefix );
coordWriter.setNamespaceUri( nsUri );
}
public boolean isDummyZEnabled(){
return coordWriter.isDummyZEnabled();
}
public int getNumDecimals(){
return coordWriter.getNumDecimals();
}
public void encode(Object o, String srsName)
throws IllegalArgumentException {
if (o instanceof Geometry) {
encode((Geometry) o, srsName);
} else {
throw new IllegalArgumentException("Unable to encode " + o);
}
}
public void encode(Object o) throws IllegalArgumentException {
encode(o, null);
}
public void encode(Envelope bounds) {
encode(bounds, null);
}
public void encode(Envelope bounds, String srsName) {
// DJB: old behavior for null bounds:
//
//null
* @param dimensions shall laid between 1, 2, or 3. Number of coordinate dimensions to force.
* TODO: dimensions is not being taken into account currently. Jody?
*/
public void encode(Geometry geometry, String srsName, final int dimensions) {
String geomName = GMLUtils.getGeometryName(geometry);
if ((srsName == null) || srsName.equals("")) {
start(geomName);
} else {
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "srsName", "srsName", "", srsName);
start(geomName, atts);
}
int geometryType = GMLUtils.getGeometryType(geometry);
CoordinateSequence coordSeq;
switch (geometryType) {
case GMLUtils.POINT:
coordSeq = ((Point) geometry).getCoordinateSequence();
try {
coordWriter.writeCoordinates(coordSeq, contentHandler);
} catch (SAXException e) {
throw new RuntimeException(e);
}
break;
case GMLUtils.LINESTRING:
coordSeq = ((LineString) geometry).getCoordinateSequence();
try {
coordWriter.writeCoordinates(coordSeq, contentHandler);
} catch (SAXException s) {
throw new RuntimeException(s);
}
break;
case GMLUtils.POLYGON:
writePolygon((Polygon) geometry);
break;
case GMLUtils.MULTIPOINT:
case GMLUtils.MULTILINESTRING:
case GMLUtils.MULTIPOLYGON:
case GMLUtils.MULTIGEOMETRY:
writeMulti((GeometryCollection) geometry,
GMLUtils.getMemberName(geometryType));
break;
}
end(geomName);
}
private void writePolygon(Polygon geometry) {
String outBound = "outerBoundaryIs";
String lineRing = "LinearRing";
String inBound = "innerBoundaryIs";
start(outBound);
start(lineRing);
CoordinateSequence coordSeq;
try {
coordSeq = geometry.getExteriorRing().getCoordinateSequence();
coordWriter.writeCoordinates(coordSeq, contentHandler);
} catch (SAXException s) {
throw new RuntimeException(s);
}
end(lineRing);
end(outBound);
for (int i = 0, ii = geometry.getNumInteriorRing(); i < ii; i++) {
start(inBound);
start(lineRing);
try {
coordSeq = geometry.getInteriorRingN(i).getCoordinateSequence();
coordWriter.writeCoordinates(coordSeq, contentHandler);
} catch (SAXException s) {
throw new RuntimeException(s);
}
end(lineRing);
end(inBound);
}
}
private void writeMulti(GeometryCollection geometry, String member) {
for (int i = 0, n = geometry.getNumGeometries(); i < n; i++) {
start(member);
encode(geometry.getGeometryN(i));
end(member);
}
}
}
}