All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vividsolutions.jts.io.gml2.GMLWriter Maven / Gradle / Ivy

There is a newer version: 0.1.4
Show newest version
/*
 * The JTS Topology Suite is a collection of Java classes that
 * implement the fundamental operations required to validate a given
 * geo-spatial data set to a known topological specification.
 *
 * Copyright (C) 2001 Vivid Solutions
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * For more information, contact:
 *
 *     Vivid Solutions
 *     Suite #1A
 *     2328 Government Street
 *     Victoria BC  V8T 5G5
 *     Canada
 *
 *     (250)385-6040
 *     www.vividsolutions.com
 */
package com.vividsolutions.jts.io.gml2;

import java.io.*;

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.util.Assert;

/**
 * Writes {@link Geometry}s as XML fragments in GML2 format.
 * Allows specifying the XML prefix, namespace and srsName
 * of the emitted GML.
 * Also allows adding custom root elements
 * to support GML extensions such as KML. 
 * With appropriate settings for prefix (none) and custom root elements
 * this class can be used to write out geometry in KML format.
 * 

* An example of the output that can be generated is: * *

 * 
 *   
 *     6.03,8.17 7.697,6.959 8.333,5.0 7.697,3.041 6.03,1.83 3.97,1.83 2.303,3.041 1.667,5.0 2.303,6.959 3.97,8.17 
 *   
 * 
 * 
* *

* This class does not rely on any external XML libraries. * * @author David Zwiers, Vivid Solutions * @author Martin Davis */ public class GMLWriter { private final String INDENT = " "; private int startingIndentIndex = 0; private int maxCoordinatesPerLine = 10; private boolean emitNamespace = false; private boolean isRootTag = false; private String prefix = GMLConstants.GML_PREFIX; private String namespace = GMLConstants.GML_NAMESPACE; private String srsName = null; private String[] customElements = null; /** * Creates a writer which outputs GML with default settings. * The defaults are: *

    *
  • the namespace prefix is gml: *
  • no namespace prefix declaration is written *
  • no srsName attribute is written *
*/ public GMLWriter() { } /** * Creates a writer which may emit the GML namespace prefix * declaration in the geometry root element. * * @param emitNamespace trueif the GML namespace prefix declaration should be written * in the geometry root element */ public GMLWriter(boolean emitNamespace) { this.setNamespace(emitNamespace); } /** * Specifies the namespace prefix to write on each GML tag. * A null or blank prefix may be used to indicate no prefix. *

* The default is to write gml: as the namespace prefix. * * @param prefix the namespace prefix to use (null or blank if none) */ public void setPrefix(String prefix) { this.prefix = prefix; } /** * Sets the value of the srsName attribute * to be written into the root geometry tag. * If the value is null or blank no srsName attribute will be written. * The provided value must be a valid XML attribute value * - it will not be XML-escaped. *

* The default is not to write the srsName attribute. * * @param srsName the srsName attribute value */ public void setSrsName(String srsName) { this.srsName = srsName; } /** * Determines whether a GML namespace declaration will be written in the * opening tag of geometries. Useful in XML-aware environments which * parse the geometries before use, such as XSLT. * * @param emitNamespace true if the GML namespace prefix declaration * should be written in the root geometry element */ public void setNamespace(boolean emitNamespace) { this.emitNamespace = emitNamespace; } /** * Specifies a list of custom elements * which are written after the opening tag * of the root element. * The text contained in the string sequence should form valid XML markup. * The specified strings are written one per line immediately after * the root geometry tag line. *

* For instance, this is useful for adding KML-specific geometry parameters * such as <extrude> * * @param customElements a list of the custom element strings, or null if none */ public void setCustomElements(String[] customElements) { this.customElements = customElements; } /** * Sets the starting column index for pretty printing * * @param indent */ public void setStartingIndentIndex(int indent) { if (indent < 0) indent = 0; startingIndentIndex = indent; } /** * Sets the number of coordinates printed per line. * * @param num */ public void setMaxCoordinatesPerLine(int num) { if (num < 1) throw new IndexOutOfBoundsException( "Invalid coordinate count per line, must be > 0"); maxCoordinatesPerLine = num; } /** * Writes a {@link Geometry} in GML2 format to a String. * * @param geom * @return String GML2 Encoded Geometry */ public String write(Geometry geom) { StringWriter writer = new StringWriter(); try { write(geom, writer); } catch (IOException ex) { Assert.shouldNeverReachHere(); } return writer.toString(); } /** * Writes a {@link Geometry} in GML2 format into a {@link Writer}. * * @param geom Geometry to encode * @param writer Stream to encode to. * @throws IOException */ public void write(Geometry geom, Writer writer) throws IOException { write(geom, writer, startingIndentIndex); } private void write(Geometry geom, Writer writer, int level) throws IOException { isRootTag = true; if (geom instanceof Point) { writePoint((Point) geom, writer, level); } else if (geom instanceof LineString) { writeLineString((LineString) geom, writer, level); } else if (geom instanceof Polygon) { writePolygon((Polygon) geom, writer, level); } else if (geom instanceof MultiPoint) { writeMultiPoint((MultiPoint) geom, writer, level); } else if (geom instanceof MultiLineString) { writeMultiLineString((MultiLineString) geom, writer, level); } else if (geom instanceof MultiPolygon) { writeMultiPolygon((MultiPolygon) geom, writer, level); } else if (geom instanceof GeometryCollection) { writeGeometryCollection((GeometryCollection) geom, writer, startingIndentIndex); } else { throw new IllegalArgumentException("Unhandled geometry type: " + geom.getGeometryType()); } writer.flush(); } // 1195156.78946687,382069.533723461 private void writePoint(Point p, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_POINT, p, writer); write(new Coordinate[] { p.getCoordinate() }, writer, level + 1); startLine(level, writer); endGeomTag(GMLConstants.GML_POINT, writer); } //1195123.37289257,381985.763974674 1195120.22369473,381964.660533343 1195118.14929823,381942.597718511 private void writeLineString(LineString ls, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_LINESTRING, ls, writer); write(ls.getCoordinates(), writer, level + 1); startLine(level, writer); endGeomTag(GMLConstants.GML_LINESTRING, writer); } //1226890.26761027,1466433.47430292 1226880.59239079,1466427.03208053...> private void writeLinearRing(LinearRing lr, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_LINEARRING, lr, writer); write(lr.getCoordinates(), writer, level + 1); startLine(level, writer); endGeomTag(GMLConstants.GML_LINEARRING, writer); } private void writePolygon(Polygon p, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_POLYGON, p, writer); startLine(level + 1, writer); startGeomTag(GMLConstants.GML_OUTER_BOUNDARY_IS, null, writer); writeLinearRing((LinearRing) p.getExteriorRing(), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_OUTER_BOUNDARY_IS, writer); for (int t = 0; t < p.getNumInteriorRing(); t++) { startLine(level + 1, writer); startGeomTag(GMLConstants.GML_INNER_BOUNDARY_IS, null, writer); writeLinearRing((LinearRing) p.getInteriorRingN(t), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_INNER_BOUNDARY_IS, writer); } startLine(level, writer); endGeomTag(GMLConstants.GML_POLYGON, writer); } private void writeMultiPoint(MultiPoint mp, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_MULTI_POINT, mp, writer); for (int t = 0; t < mp.getNumGeometries(); t++) { startLine(level + 1, writer); startGeomTag(GMLConstants.GML_POINT_MEMBER, null, writer); writePoint((Point) mp.getGeometryN(t), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_POINT_MEMBER, writer); } startLine(level, writer); endGeomTag(GMLConstants.GML_MULTI_POINT, writer); } private void writeMultiLineString(MultiLineString mls, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_MULTI_LINESTRING, mls, writer); for (int t = 0; t < mls.getNumGeometries(); t++) { startLine(level + 1, writer); startGeomTag(GMLConstants.GML_LINESTRING_MEMBER, null, writer); writeLineString((LineString) mls.getGeometryN(t), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_LINESTRING_MEMBER, writer); } startLine(level, writer); endGeomTag(GMLConstants.GML_MULTI_LINESTRING, writer); } private void writeMultiPolygon(MultiPolygon mp, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_MULTI_POLYGON, mp, writer); for (int t = 0; t < mp.getNumGeometries(); t++) { startLine(level + 1, writer); startGeomTag(GMLConstants.GML_POLYGON_MEMBER, null, writer); writePolygon((Polygon) mp.getGeometryN(t), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_POLYGON_MEMBER, writer); } startLine(level, writer); endGeomTag(GMLConstants.GML_MULTI_POLYGON, writer); } private void writeGeometryCollection(GeometryCollection gc, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_MULTI_GEOMETRY, gc, writer); for (int t = 0; t < gc.getNumGeometries(); t++) { startLine(level + 1, writer); startGeomTag(GMLConstants.GML_GEOMETRY_MEMBER, null, writer); write(gc.getGeometryN(t), writer, level + 2); startLine(level + 1, writer); endGeomTag(GMLConstants.GML_GEOMETRY_MEMBER, writer); } startLine(level, writer); endGeomTag(GMLConstants.GML_MULTI_GEOMETRY, writer); } private static final String coordinateSeparator = ","; private static final String tupleSeparator = " "; /** * Takes a list of coordinates and converts it to GML.
* 2d and 3d aware. * * @param coords array of coordinates * @throws IOException */ private void write(Coordinate[] coords, Writer writer, int level) throws IOException { startLine(level, writer); startGeomTag(GMLConstants.GML_COORDINATES, null, writer); int dim = 2; if (coords.length > 0) { if (!(Double.isNaN(coords[0].z))) dim = 3; } boolean isNewLine = true; for (int i = 0; i < coords.length; i++) { if (isNewLine) { startLine(level + 1, writer); isNewLine = false; } if (dim == 2) { writer.write("" + coords[i].x); writer.write(coordinateSeparator); writer.write("" + coords[i].y); } else if (dim == 3) { writer.write("" + coords[i].x); writer.write(coordinateSeparator); writer.write("" + coords[i].y); writer.write(coordinateSeparator); writer.write("" + coords[i].z); } writer.write(tupleSeparator); // break output lines to prevent them from getting too long if ((i + 1) % maxCoordinatesPerLine == 0 && i < coords.length - 1) { writer.write("\n"); isNewLine = true; } } if (!isNewLine) writer.write("\n"); startLine(level, writer); endGeomTag(GMLConstants.GML_COORDINATES, writer); } private void startLine(int level, Writer writer) throws IOException { for (int i = 0; i < level; i++) writer.write(INDENT); } private void startGeomTag(String geometryName, Geometry g, Writer writer) throws IOException { writer.write("<" + ((prefix == null || "".equals(prefix)) ? "" : prefix + ":")); writer.write(geometryName); writeAttributes(g, writer); writer.write(">\n"); writeCustomElements(g, writer); isRootTag = false; } private void writeAttributes(Geometry geom, Writer writer) throws IOException { if (geom == null) return; if (! isRootTag) return; if (emitNamespace) { writer.write(" xmlns" + ((prefix == null || "".equals(prefix)) ? "" : ":"+prefix ) + "='" + namespace + "'"); } if (srsName != null && srsName.length() > 0) { writer.write(" " + GMLConstants.GML_ATTR_SRSNAME + "='" + srsName + "'"); // MD - obsoleted // writer.write(geom.getSRID() + ""); } } private void writeCustomElements(Geometry geom, Writer writer) throws IOException { if (geom == null) return; if (! isRootTag) return; if (customElements == null) return; for (int i = 0; i < customElements.length; i++) { writer.write(customElements[i]); writer.write("\n"); } } private void endGeomTag(String geometryName, Writer writer) throws IOException { writer.write("\n"); } private String prefix() { if (prefix == null || prefix.length() == 0) return ""; return prefix + ":"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy