/* * 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.revolsys.record.io.format.wkt; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.Lineal; import com.revolsys.geometry.model.LinearRing; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.Polygon; import com.revolsys.geometry.model.Polygonal; import com.revolsys.geometry.model.Punctual; import com.revolsys.util.Exceptions; import com.revolsys.util.MathUtil; import com.revolsys.util.number.Doubles; public class EWktWriter { public static void append(final StringBuilder wkt, final int axisCount, final Point point) { for (int i = 0; i < axisCount; i++) { if (i > 0) { wkt.append(" "); } MathUtil.append(wkt, point.getCoordinate(i)); } } public static void appendLineString(final StringBuilder wkt, final Point... points) { wkt.append("LINESTRING"); int axisCount = 2; for (final Point point : points) { axisCount = Math.max(axisCount, point.getAxisCount()); } if (axisCount > 3) { wkt.append(" ZM"); } else if (axisCount > 2) { wkt.append(" Z"); } boolean first = true; for (final Point point : points) { if (first) { wkt.append('('); first = false; } else { wkt.append(','); } append(wkt, axisCount, point); } if (first) { wkt.append(" EMPTY"); } else { wkt.append(')'); } } public static void appendPoint(final StringBuilder wkt, final Point point) { wkt.append("POINT"); final int axisCount = point.getAxisCount(); if (axisCount > 3) { wkt.append(" ZM"); } else if (axisCount > 2) { wkt.append(" Z"); } append(wkt, axisCount, point); wkt.append(")"); } /** * Generates the WKT for a <tt>LINESTRING</tt> * specified by two {@link Coordinates}s. * * @param point1 the first coordinate * @param point2 the second coordinate * * @return the WKT */ public static String lineString(final Point... points) { final StringBuilder wkt = new StringBuilder(); appendLineString(wkt, points); return wkt.toString(); } /** * Generates the WKT for a <tt>POINT</tt> * specified by a {@link Coordinates}. * * @param p0 the point coordinate * * @return the WKT */ public static String point(final Point point) { final StringBuilder wkt = new StringBuilder(); appendPoint(wkt, point); return wkt.toString(); } public static String toString(final Geometry geometry) { final StringWriter out = new StringWriter(); final int srid = geometry.getCoordinateSystemId(); if (srid > 0) { out.write("SRID="); out.write(Integer.toString(srid)); out.write(';'); } write(out, geometry); out.flush(); return out.toString(); } public static String toString(final Geometry geometry, final boolean ewkt) { if (ewkt) { return toString(geometry); } else { return WktWriter.toString(geometry); } } public static void write(final Writer out, final Geometry geometry) { if (geometry != null) { if (geometry instanceof Point) { final Point point = (Point)geometry; write(out, point); } else if (geometry instanceof Punctual) { final Punctual punctual = (Punctual)geometry; write(out, punctual); } else if (geometry instanceof LinearRing) { final LinearRing line = (LinearRing)geometry; write(out, line); } else if (geometry instanceof LineString) { final LineString line = (LineString)geometry; write(out, line); } else if (geometry instanceof Lineal) { final Lineal lineal = (Lineal)geometry; write(out, lineal); } else if (geometry instanceof Polygon) { final Polygon polygon = (Polygon)geometry; write(out, polygon); } else if (geometry instanceof Polygonal) { final Polygonal polygonal = (Polygonal)geometry; write(out, polygonal); } else if (geometry.isGeometryCollection()) { writeGeometryCollection(out, geometry); } else { throw new IllegalArgumentException("Unknown geometry type" + geometry.getClass()); } } } private static void write(final Writer out, final Geometry geometry, final int axisCount) throws IOException { if (geometry != null) { if (geometry instanceof Point) { final Point point = (Point)geometry; write(out, point, axisCount); } else if (geometry instanceof Punctual) { final Punctual punctual = (Punctual)geometry; write(out, punctual, axisCount); } else if (geometry instanceof LinearRing) { final LinearRing line = (LinearRing)geometry; write(out, line, axisCount); } else if (geometry instanceof LineString) { final LineString line = (LineString)geometry; write(out, line, axisCount); } else if (geometry instanceof Lineal) { final Lineal lineal = (Lineal)geometry; write(out, lineal, axisCount); } else if (geometry instanceof Polygon) { final Polygon polygon = (Polygon)geometry; write(out, polygon, axisCount); } else if (geometry instanceof Polygonal) { final Polygonal polygonal = (Polygonal)geometry; write(out, polygonal, axisCount); } else if (geometry.isGeometryCollection()) { writeGeometryCollection(out, geometry, axisCount); } else { throw new IllegalArgumentException("Unknown geometry type" + geometry.getClass()); } } } private static void write(final Writer out, final Lineal lineal) { final int axisCount = Math.min(lineal.getAxisCount(), 4); try { write(out, lineal, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final Lineal lineal, final int axisCount) throws IOException { writeGeometryType(out, "MULTILINESTRING", axisCount); if (lineal.isEmpty()) { out.write(" EMPTY"); } else { out.write("("); LineString line = (LineString)lineal.getGeometry(0); LineString points = line; writeCoordinates(out, points, axisCount); for (int i = 1; i < lineal.getGeometryCount(); i++) { out.write(","); line = (LineString)lineal.getGeometry(i); points = line; writeCoordinates(out, points, axisCount); } out.write(")"); } } private static void write(final Writer out, final LinearRing line) { final int axisCount = Math.min(line.getAxisCount(), 4); try { write(out, line, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final LinearRing line, final int axisCount) throws IOException { writeGeometryType(out, "LINEARRING", axisCount); if (line.isEmpty()) { out.write(" EMPTY"); } else { final LineString coordinates = line; writeCoordinates(out, coordinates, axisCount); } } private static void write(final Writer out, final LineString line) { final int axisCount = Math.min(line.getAxisCount(), 4); try { write(out, line, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final LineString line, final int axisCount) throws IOException { writeGeometryType(out, "LINESTRING", axisCount); if (line.isEmpty()) { out.write(" EMPTY"); } else { final LineString coordinates = line; writeCoordinates(out, coordinates, axisCount); } } private static void write(final Writer out, final LineString coordinates, final int index, final int axisCount) throws IOException { writeCoordinate(out, coordinates, index, 0); for (int j = 1; j < axisCount; j++) { out.write(' '); writeCoordinate(out, coordinates, index, j); } } private static void write(final Writer out, final Point point) { final int axisCount = Math.min(point.getAxisCount(), 4); try { write(out, point, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final Point point, final int axisCount) throws IOException { writeGeometryType(out, "POINT", axisCount); if (point.isEmpty()) { out.write(" EMPTY"); } else { out.write("("); writeCoordinates(out, point, axisCount); out.write(')'); } } private static void write(final Writer out, final Polygon polygon) { final int axisCount = Math.min(polygon.getAxisCount(), 4); try { write(out, polygon, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final Polygon polygon, final int axisCount) throws IOException { writeGeometryType(out, "POLYGON", axisCount); if (polygon.isEmpty()) { out.write(" EMPTY"); } else { writePolygon(out, polygon, axisCount); } } private static void write(final Writer out, final Polygonal polygonal) { final int axisCount = Math.min(polygonal.getAxisCount(), 4); try { write(out, polygonal, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final Polygonal polygonal, final int axisCount) throws IOException { writeGeometryType(out, "MULTIPOLYGON", axisCount); if (polygonal.isEmpty()) { out.write(" EMPTY"); } else { out.write("("); Polygon polygon = (Polygon)polygonal.getGeometry(0); writePolygon(out, polygon, axisCount); for (int i = 1; i < polygonal.getGeometryCount(); i++) { out.write(","); polygon = (Polygon)polygonal.getGeometry(i); writePolygon(out, polygon, axisCount); } out.write(")"); } } private static void write(final Writer out, final Punctual punctual) { final int axisCount = Math.min(punctual.getAxisCount(), 4); try { write(out, punctual, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void write(final Writer out, final Punctual punctual, final int axisCount) throws IOException { writeGeometryType(out, "MULTIPOINT", axisCount); if (punctual.isEmpty()) { out.write(" EMPTY"); } else { Point point = punctual.getPoint(0); out.write("(("); writeCoordinates(out, point, axisCount); for (int i = 1; i < punctual.getGeometryCount(); i++) { out.write("),("); point = punctual.getPoint(i); writeCoordinates(out, point, axisCount); } out.write("))"); } } private static void writeAxis(final Writer out, final int axisCount) throws IOException { if (axisCount > 3) { out.write(" ZM"); } else if (axisCount > 2) { out.write(" Z"); } } private static void writeCoordinate(final Writer out, final LineString coordinates, final int index, final int ordinateIndex) throws IOException { if (ordinateIndex > coordinates.getAxisCount()) { out.write('0'); } else { final double ordinate = coordinates.getCoordinate(index, ordinateIndex); if (Double.isNaN(ordinate)) { out.write('0'); } else { out.write(Doubles.toString(ordinate)); } } } private static void writeCoordinates(final Writer out, final LineString coordinates, final int axisCount) throws IOException { out.write('('); write(out, coordinates, 0, axisCount); for (int i = 1; i < coordinates.getVertexCount(); i++) { out.write(','); write(out, coordinates, i, axisCount); } out.write(')'); } private static void writeCoordinates(final Writer out, final Point point, final int axisCount) throws IOException { final double x = point.getX(); String xString = Doubles.toString(x); out.write(xString); out.write(' '); final double y = point.getY(); String yString = Doubles.toString(y); out.write(yString); for (int axisIndex = 2; axisIndex < axisCount; axisIndex++) { out.write(' '); final double cordinate = point.getCoordinate(axisIndex); String coordinateString = Doubles.toString(cordinate); out.write(coordinateString); } } private static void writeGeometryCollection(final Writer out, final Geometry multiGeometry) { final int axisCount = Math.min(multiGeometry.getAxisCount(), 4); try { writeGeometryCollection(out, multiGeometry, axisCount); } catch (final IOException e) { throw Exceptions.wrap(e); } } private static void writeGeometryCollection(final Writer out, final Geometry multiGeometry, final int axisCount) throws IOException { writeGeometryType(out, "GEOMETRYCOLLECTION", axisCount); if (multiGeometry.isEmpty()) { out.write(" EMPTY"); } else { out.write("("); Geometry geometry = multiGeometry.getGeometry(0); write(out, geometry, axisCount); for (int i = 1; i < multiGeometry.getGeometryCount(); i++) { out.write(','); geometry = multiGeometry.getGeometry(i); write(out, geometry, axisCount); } out.write(')'); } } private static void writeGeometryType(final Writer out, final String geometryType, final int axisCount) throws IOException { out.write(geometryType); writeAxis(out, axisCount); } private static void writePolygon(final Writer out, final Polygon polygon, final int axisCount) throws IOException { out.write('('); final LinearRing shell = polygon.getShell().toCounterClockwise(); writeCoordinates(out, shell, axisCount); for (final LinearRing hole : polygon.holes()) { out.write(','); final LinearRing clockwiseHole = hole.toClockwise(); writeCoordinates(out, clockwiseHole, axisCount); } out.write(')'); } }