/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de 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 Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.model.spatialschema; import java.util.ArrayList; import org.deegree.framework.util.StringTools; import org.deegree.model.crs.CoordinateSystem; /** * Adapter class for exporting deegree geometries to WKT and to wrap WKT code * geometries to deegree geometries. * * @version $Revision: 1.11 $ * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> */ public class WKTAdapter { // private static DecimalFormatSymbols dfs = new DecimalFormatSymbols(); // private static DecimalFormat frm = null; // static { // dfs.setDecimalSeparator( '.' ); // frm = new DecimalFormat( "#.#########", dfs ); // } /** * * @param wkt * @return the corresponding <tt>Geometry</tt> * @throws GeometryException if type unsupported or conversion failed */ public static Geometry wrap( String wkt, CoordinateSystem crs ) throws GeometryException { Geometry geo = null; if ( wkt == null ) { return null; } else if ( wkt.startsWith( "POINT" ) ) { geo = wrapPoint( wkt, crs ); } else if ( wkt.startsWith( "LINE" ) ) { geo = wrapCurve( wkt, crs ); } else if ( wkt.startsWith( "POLY" ) ) { geo = wrapSurface( wkt, crs ); } else if ( wkt.startsWith( "MULTIPOINT" ) ) { geo = wrapMultiPoint( wkt, crs ); } else if ( wkt.startsWith( "MULTILINE" ) ) { geo = wrapMultiCurve( wkt, crs ); } else if ( wkt.startsWith( "MULTIPOLY" ) ) { geo = wrapMultiSurface( wkt, crs ); } return geo; } /** * @param geom geometry * * @return */ public static StringBuffer export( Geometry geom ) throws GeometryException { StringBuffer sb = null; if ( geom instanceof Point ) { sb = export( (Point) geom ); } else if ( geom instanceof Curve ) { sb = export( (Curve) geom ); } else if ( geom instanceof Surface ) { sb = export( (Surface) geom ); } else if ( geom instanceof MultiPoint ) { sb = export( (MultiPoint) geom ); } else if ( geom instanceof MultiCurve ) { sb = export( (MultiCurve) geom ); } else if ( geom instanceof MultiSurface ) { sb = export( (MultiSurface) geom ); } return sb; } /** * exports an Envelope as a BOX3D WKT string. * @param envelope * @return */ public static StringBuffer export( Envelope envelope ) { StringBuffer sb = new StringBuffer( 150 ); sb.append( "BOX3D(" ); int dim = envelope.getMin().getCoordinateDimension(); double[] d = envelope.getMin().getAsArray(); for ( int i = 0; i < dim - 1; i++ ) { sb.append( Double.toString( d[i] ) ).append( " " ); } sb.append( Double.toString( d[dim - 1] ) ).append( "," ); d = envelope.getMax().getAsArray(); for ( int i = 0; i < dim - 1; i++ ) { sb.append( Double.toString( d[i] ) ).append( " " ); } sb.append( Double.toString( d[dim - 1] ) ); sb.append( ") " ); return sb; } /** * @param point point geometry * * @return */ private static StringBuffer export( Point point ) { StringBuffer sb = new StringBuffer( 50 ); sb.append( "POINT(" ); double[] points = point.getAsArray(); int dim = point.getCoordinateDimension(); for ( int i = 0; i < dim - 1; i++ ) { sb.append( points[i] ).append( ' ' ); } sb.append( points[dim - 1] ); sb.append( ") " ); return sb; } /** * * @param cur curve geometry * * @return * * @throws GeometryException */ private static StringBuffer export( Curve cur ) throws GeometryException { LineString ls = cur.getAsLineString(); StringBuffer sb = new StringBuffer( ls.getNumberOfPoints() * 30 ); sb.append( "LINESTRING(" ); for ( int i = 0; i < ls.getNumberOfPoints() - 1; i++ ) { Position pos = ls.getPositionAt( i ); double[] positions = pos.getAsArray(); int dim = pos.getCoordinateDimension(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( positions[j] + " " ); } sb.append( positions[dim - 1] + "," ); } Position pos = ls.getPositionAt( ls.getNumberOfPoints() - 1 ); double[] tmp = pos.getAsArray(); int dim = pos.getCoordinateDimension(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( tmp[j] + " " ); } sb.append( tmp[dim - 1] + ")" ); return sb; } /** * * * @param sur * * @return * */ private static StringBuffer export( Surface sur ) { SurfaceBoundary subo = sur.getSurfaceBoundary(); Ring exter = subo.getExteriorRing(); Ring[] inter = subo.getInteriorRings(); StringBuffer sb = new StringBuffer( 10000 ); sb.append( "POLYGON((" ); // exterior ring Position[] pos = exter.getPositions(); int dim = pos[0].getCoordinateDimension(); for ( int i = 0; i < pos.length - 1; i++ ) { double[] positions = pos[i].getAsArray(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( positions[j] + " " ); } sb.append( positions[dim - 1] + "," ); } double[] positions = pos[pos.length - 1].getAsArray(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( positions[j] + " " ); } sb.append( positions[dim - 1] + ")" ); //interior rings if ( inter != null ) { for ( int j = 0; j < inter.length; j++ ) { sb.append( ",(" ); pos = inter[j].getPositions(); for ( int i = 0; i < pos.length - 1; i++ ) { double[] intPos = pos[i].getAsArray(); for ( int l = 0; l < dim - 1; l++ ) { sb.append( intPos[l] + " " ); } sb.append( intPos[dim - 1] + "," );// } double[] intPos = pos[pos.length - 1].getAsArray(); for ( int l = 0; l < dim - 1; l++ ) { sb.append( intPos[l] + " " ); } sb.append( intPos[dim - 1] + ")" ); } } sb.append( ")" ); return sb; } /** * @param mp * @return */ private static StringBuffer export( MultiPoint mp ) { StringBuffer sb = new StringBuffer( mp.getSize() * 30 ); sb.append( "MULTIPOINT(" ); int dim = mp.getPointAt( 0 ).getCoordinateDimension(); for ( int i = 0; i < mp.getSize() - 1; i++ ) { Point pt = mp.getPointAt( i ); double[] points = pt.getAsArray(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( points[j] + " " ); } sb.append( points[dim - 1] ); sb.append( "," ); } Point pt = mp.getPointAt( mp.getSize() - 1 ); double[] points = pt.getAsArray(); for ( int j = 0; j < dim - 1; j++ ) { sb.append( points[j] + " " ); } sb.append( points[dim - 1] + ")" ); return sb; } /** * * * @param mc * * @return * * @throws GeometryException */ private static StringBuffer export( MultiCurve mc ) throws GeometryException { StringBuffer sb = new StringBuffer( 10000 ); sb.append( "MULTILINESTRING(" ); for ( int i = 0; i < mc.getSize() - 1; i++ ) { String s = export( mc.getCurveAt( i ) ).toString(); s = s.substring( 10, s.length() ); sb.append( s ).append( "," ); } String s = export( mc.getCurveAt( mc.getSize() - 1 ) ).toString(); s = s.substring( 10, s.length() ); sb.append( s ).append( ")" ); return sb; } /** * * * @param ms * * @return * * @throws GeometryException */ private static StringBuffer export( MultiSurface ms ) { StringBuffer sb = new StringBuffer( 10000 ); sb.append( "MULTIPOLYGON(" ); for ( int i = 0; i < ms.getSize() - 1; i++ ) { String s = export( ms.getSurfaceAt( i ) ).toString(); s = s.substring( 7, s.length() ); sb.append( s ).append( "," ); } String s = export( ms.getSurfaceAt( ms.getSize() - 1 ) ).toString(); s = s.substring( 7, s.length() ); sb.append( s ).append( ")" ); return sb; } /** * creates a Point from a WKT. * * @param wkt a Point WKT */ public static Point wrapPoint( String wkt, CoordinateSystem crs ) { wkt = wkt.trim(); wkt = wkt.substring( 6, wkt.length() - 1 ); double[] tmp = StringTools.toArrayDouble( wkt, " " ); Position pos = GeometryFactory.createPosition( tmp ); Point point = GeometryFactory.createPoint( pos, crs ); return point; } /** * creates a Curve from a WKT. * * @param wkt linestring a WKT */ public static Curve wrapCurve( String wkt, CoordinateSystem crs ) throws GeometryException { wkt = wkt.trim(); wkt = wkt.substring( 11, wkt.length() - 1 ); String[] points = StringTools.toArray( wkt, ",", false ); Position[] pos = new Position[points.length]; for ( int i = 0; i < points.length; i++ ) { double[] tmp = StringTools.toArrayDouble( points[i], " " ); pos[i] = GeometryFactory.createPosition( tmp ); } Curve curve = GeometryFactory.createCurve( pos, crs ); return curve; } /** * creates a Surface * * @param wkt polygon WKT */ public static Surface wrapSurface( String wkt, CoordinateSystem crs ) throws GeometryException { wkt = wkt.trim(); Position[] ext = null; ArrayList inn = new ArrayList(); if ( wkt.indexOf( "((" ) > 0 ) { wkt = wkt.substring( 9, wkt.length() - 1 ); int pos = wkt.indexOf( ")" ); String tmp = wkt.substring( 0, pos ); //external ring String[] points = StringTools.toArray( tmp, ",", false ); ext = new Position[points.length]; for ( int i = 0; i < points.length; i++ ) { double[] temp = StringTools.toArrayDouble( points[i], " " ); ext[i] = GeometryFactory.createPosition( temp ); } if ( pos + 3 < wkt.length() ) { wkt = wkt.substring( pos + 3, wkt.length() ); while ( wkt.indexOf( ")" ) > 0 ) { pos = wkt.indexOf( ")" ); tmp = wkt.substring( 0, pos ); //internal ring(s) points = StringTools.toArray( tmp, ",", false ); Position[] intern = new Position[points.length]; for ( int i = 0; i < points.length; i++ ) { double[] temp = StringTools.toArrayDouble( points[i], " " ); intern[i] = GeometryFactory.createPosition( temp ); } inn.add( intern ); if ( pos + 3 < wkt.length() ) { wkt = wkt.substring( pos + 3, wkt.length() ); } else { break; } } } } Position[][] inner = null; if ( inn.size() > 0 ) { inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); } Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(), crs ); return sur; } /** * creates a MultiPoint from a WKT * * @param wkt multipoint WKT */ public static MultiPoint wrapMultiPoint( String wkt, CoordinateSystem crs ) { wkt = wkt.trim(); wkt = wkt.substring( 11, wkt.length() - 1 ); String[] coords = StringTools.toArray( wkt, ",", false ); Position[] pos = new Position[coords.length]; for ( int i = 0; i < coords.length; i++ ) { double[] temp = StringTools.toArrayDouble( coords[i], " " ); pos[i] = GeometryFactory.createPosition( temp ); } Point[] points = new Point[pos.length]; for ( int i = 0; i < pos.length; i++ ) { points[i] = GeometryFactory.createPoint( pos[i], crs ); } MultiPoint mp = GeometryFactory.createMultiPoint( points ); return mp; } /** * creates a MultiCurve from a WKT * * @param wkt a WKT */ public static MultiCurve wrapMultiCurve( String wkt, CoordinateSystem crs ) throws GeometryException { ArrayList crvs = new ArrayList(); wkt = wkt.trim(); int pos = wkt.indexOf( ")" ); String tmp = wkt.substring( 17, pos ); String[] coords = StringTools.toArray( tmp, ",", false ); Position[] posi = new Position[coords.length]; for ( int i = 0; i < coords.length; i++ ) { double[] temp = StringTools.toArrayDouble( coords[i], " " ); posi[i] = GeometryFactory.createPosition( temp ); } crvs.add( GeometryFactory.createCurve( posi, crs ) ); wkt = wkt.substring( pos + 3, wkt.length() - 1 ); while ( wkt.indexOf( ")" ) > 0 ) { Position[] posi2 = new Position[coords.length]; pos = wkt.indexOf( ")" ); tmp = wkt.substring( 0, pos ); coords = StringTools.toArray( tmp, ",", false ); for ( int i = 0; i < coords.length; i++ ) { double[] temp = StringTools.toArrayDouble( coords[i], " " ); posi2[i] = GeometryFactory.createPosition( temp ); } crvs.add( GeometryFactory.createCurve( posi2, crs ) ); if ( pos + 3 < wkt.length() ) { wkt = wkt.substring( pos + 3, wkt.length() ); } else { break; } } Curve[] curves = (Curve[]) crvs.toArray( new Curve[crvs.size()] ); MultiCurve mc = GeometryFactory.createMultiCurve( curves ); return mc; } /** * creates a MultiSurface from a WKT * * @param wkt a WKT */ public static MultiSurface wrapMultiSurface( String wkt, CoordinateSystem crs ) throws GeometryException { ArrayList srfcs = new ArrayList(); wkt = wkt.substring( 13 ); // for each polygon while ( wkt.indexOf( "((" ) > -1 ) { Position[] ext = null; ArrayList inn = new ArrayList(); int pos1 = wkt.indexOf( "))" ); String tmp = wkt.substring( 2, pos1 + 1 ); // exterior ring int pos = tmp.indexOf( ")" ); String tmp2 = tmp.substring( 0, pos ); String[] points = StringTools.toArray( tmp2, ",", false ); ext = new Position[points.length]; for ( int i = 0; i < points.length; i++ ) { double[] temp = StringTools.toArrayDouble( points[i], " " ); ext[i] = GeometryFactory.createPosition( temp ); } if ( pos + 3 < tmp.length() ) { tmp = tmp.substring( pos + 3, tmp.length() ); // for each inner ring while ( tmp.indexOf( ")" ) > 0 ) { pos = tmp.indexOf( ")" ); tmp2 = tmp.substring( 0, pos ); points = StringTools.toArray( tmp2, ",", false ); Position[] intern = new Position[points.length]; for ( int i = 0; i < points.length; i++ ) { double[] temp = StringTools.toArrayDouble( points[i], " " ); intern[i] = GeometryFactory.createPosition( temp ); } inn.add( intern ); if ( pos + 3 < tmp.length() ) { tmp = tmp.substring( pos + 3, tmp.length() ); } else { break; } } } Position[][] inner = null; if ( inn.size() > 0 ) { inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); } Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(), crs ); srfcs.add( sur ); wkt = wkt.substring( pos1 + 3 ); } Surface[] surfaces = (Surface[]) srfcs.toArray( new Surface[srfcs.size()] ); MultiSurface ms = GeometryFactory.createMultiSurface( surfaces ); return ms; } }/* ******************************************************************** Changes to this class. What the people have been up to: $Log: WKTAdapter.java,v $ Revision 1.11 2006/08/07 12:23:35 poth deprecated clas/method calls removed // never thrown exceptions removed Revision 1.10 2006/07/12 14:46:15 poth comment footer added ********************************************************************** */