001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/WKTAdapter.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.model.spatialschema; 045 046 import java.util.ArrayList; 047 048 import org.deegree.framework.util.StringTools; 049 import org.deegree.model.crs.CoordinateSystem; 050 051 /** 052 * Adapter class for exporting deegree geometries to WKT and to wrap WKT code 053 * geometries to deegree geometries. 054 * 055 * @version $Revision: 6259 $ 056 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 057 */ 058 public class WKTAdapter { 059 060 // private static DecimalFormatSymbols dfs = new DecimalFormatSymbols(); 061 // private static DecimalFormat frm = null; 062 // static { 063 // dfs.setDecimalSeparator( '.' ); 064 // frm = new DecimalFormat( "#.#########", dfs ); 065 // } 066 067 /** 068 069 * 070 * @param wkt 071 * @return the corresponding <tt>Geometry</tt> 072 * @throws GeometryException if type unsupported or conversion failed 073 */ 074 public static Geometry wrap( String wkt, CoordinateSystem crs ) 075 throws GeometryException { 076 077 Geometry geo = null; 078 079 if ( wkt == null ) { 080 return null; 081 } else if ( wkt.startsWith( "POINT" ) ) { 082 geo = wrapPoint( wkt, crs ); 083 } else if ( wkt.startsWith( "LINE" ) ) { 084 geo = wrapCurve( wkt, crs ); 085 } else if ( wkt.startsWith( "POLY" ) ) { 086 geo = wrapSurface( wkt, crs ); 087 } else if ( wkt.startsWith( "MULTIPOINT" ) ) { 088 geo = wrapMultiPoint( wkt, crs ); 089 } else if ( wkt.startsWith( "MULTILINE" ) ) { 090 geo = wrapMultiCurve( wkt, crs ); 091 } else if ( wkt.startsWith( "MULTIPOLY" ) ) { 092 geo = wrapMultiSurface( wkt, crs ); 093 } 094 095 return geo; 096 } 097 098 /** 099 * @param geom geometry 100 * 101 * @return 102 */ 103 public static StringBuffer export( Geometry geom ) 104 throws GeometryException { 105 106 StringBuffer sb = null; 107 if ( geom instanceof Point ) { 108 sb = export( (Point) geom ); 109 } else if ( geom instanceof Curve ) { 110 sb = export( (Curve) geom ); 111 } else if ( geom instanceof Surface ) { 112 sb = export( (Surface) geom ); 113 } else if ( geom instanceof MultiPoint ) { 114 sb = export( (MultiPoint) geom ); 115 } else if ( geom instanceof MultiCurve ) { 116 sb = export( (MultiCurve) geom ); 117 } else if ( geom instanceof MultiSurface ) { 118 sb = export( (MultiSurface) geom ); 119 } 120 121 return sb; 122 } 123 124 /** 125 * exports an Envelope as a BOX3D WKT string. 126 * @param envelope 127 * @return 128 */ 129 public static StringBuffer export( Envelope envelope ) { 130 StringBuffer sb = new StringBuffer( 150 ); 131 sb.append( "BOX3D(" ); 132 int dim = envelope.getMin().getCoordinateDimension(); 133 double[] d = envelope.getMin().getAsArray(); 134 for ( int i = 0; i < dim - 1; i++ ) { 135 sb.append( Double.toString( d[i] ) ).append( " " ); 136 } 137 sb.append( Double.toString( d[dim - 1] ) ).append( "," ); 138 d = envelope.getMax().getAsArray(); 139 for ( int i = 0; i < dim - 1; i++ ) { 140 sb.append( Double.toString( d[i] ) ).append( " " ); 141 } 142 sb.append( Double.toString( d[dim - 1] ) ); 143 sb.append( ") " ); 144 return sb; 145 } 146 147 /** 148 * @param point point geometry 149 * 150 * @return 151 */ 152 private static StringBuffer export( Point point ) { 153 154 StringBuffer sb = new StringBuffer( 50 ); 155 sb.append( "POINT(" ); 156 double[] points = point.getAsArray(); 157 int dim = point.getCoordinateDimension(); 158 for ( int i = 0; i < dim - 1; i++ ) { 159 sb.append( points[i] ).append( ' ' ); 160 } 161 sb.append( points[dim - 1] ); 162 sb.append( ") " ); 163 164 return sb; 165 } 166 167 /** 168 * 169 * @param cur curve geometry 170 * 171 * @return 172 * 173 * @throws GeometryException 174 */ 175 private static StringBuffer export( Curve cur ) 176 throws GeometryException { 177 178 LineString ls = cur.getAsLineString(); 179 180 StringBuffer sb = new StringBuffer( ls.getNumberOfPoints() * 30 ); 181 sb.append( "LINESTRING(" ); 182 183 for ( int i = 0; i < ls.getNumberOfPoints() - 1; i++ ) { 184 Position pos = ls.getPositionAt( i ); 185 double[] positions = pos.getAsArray(); 186 int dim = pos.getCoordinateDimension(); 187 for ( int j = 0; j < dim - 1; j++ ) { 188 sb.append( positions[j] + " " ); 189 } 190 sb.append( positions[dim - 1] + "," ); 191 } 192 Position pos = ls.getPositionAt( ls.getNumberOfPoints() - 1 ); 193 double[] tmp = pos.getAsArray(); 194 int dim = pos.getCoordinateDimension(); 195 for ( int j = 0; j < dim - 1; j++ ) { 196 sb.append( tmp[j] + " " ); 197 } 198 sb.append( tmp[dim - 1] + ")" ); 199 200 return sb; 201 } 202 203 /** 204 * 205 * 206 * @param sur 207 * 208 * @return 209 * 210 */ 211 private static StringBuffer export( Surface sur ) { 212 213 SurfaceBoundary subo = sur.getSurfaceBoundary(); 214 Ring exter = subo.getExteriorRing(); 215 Ring[] inter = subo.getInteriorRings(); 216 217 StringBuffer sb = new StringBuffer( 10000 ); 218 sb.append( "POLYGON((" ); 219 // exterior ring 220 Position[] pos = exter.getPositions(); 221 int dim = pos[0].getCoordinateDimension(); 222 for ( int i = 0; i < pos.length - 1; i++ ) { 223 double[] positions = pos[i].getAsArray(); 224 for ( int j = 0; j < dim - 1; j++ ) { 225 sb.append( positions[j] + " " ); 226 } 227 sb.append( positions[dim - 1] + "," ); 228 } 229 double[] positions = pos[pos.length - 1].getAsArray(); 230 for ( int j = 0; j < dim - 1; j++ ) { 231 sb.append( positions[j] + " " ); 232 } 233 sb.append( positions[dim - 1] + ")" ); 234 //interior rings 235 if ( inter != null ) { 236 for ( int j = 0; j < inter.length; j++ ) { 237 sb.append( ",(" ); 238 pos = inter[j].getPositions(); 239 for ( int i = 0; i < pos.length - 1; i++ ) { 240 double[] intPos = pos[i].getAsArray(); 241 for ( int l = 0; l < dim - 1; l++ ) { 242 sb.append( intPos[l] + " " ); 243 } 244 sb.append( intPos[dim - 1] + "," );// 245 } 246 double[] intPos = pos[pos.length - 1].getAsArray(); 247 for ( int l = 0; l < dim - 1; l++ ) { 248 sb.append( intPos[l] + " " ); 249 } 250 sb.append( intPos[dim - 1] + ")" ); 251 } 252 } 253 sb.append( ")" ); 254 255 return sb; 256 } 257 258 /** 259 * @param mp 260 * @return 261 */ 262 private static StringBuffer export( MultiPoint mp ) { 263 264 StringBuffer sb = new StringBuffer( mp.getSize() * 30 ); 265 sb.append( "MULTIPOINT(" ); 266 int dim = mp.getPointAt( 0 ).getCoordinateDimension(); 267 for ( int i = 0; i < mp.getSize() - 1; i++ ) { 268 Point pt = mp.getPointAt( i ); 269 double[] points = pt.getAsArray(); 270 for ( int j = 0; j < dim - 1; j++ ) { 271 sb.append( points[j] + " " ); 272 } 273 sb.append( points[dim - 1] ); 274 sb.append( "," ); 275 } 276 Point pt = mp.getPointAt( mp.getSize() - 1 ); 277 double[] points = pt.getAsArray(); 278 for ( int j = 0; j < dim - 1; j++ ) { 279 sb.append( points[j] + " " ); 280 } 281 sb.append( points[dim - 1] + ")" ); 282 283 return sb; 284 } 285 286 /** 287 * 288 * 289 * @param mc 290 * 291 * @return 292 * 293 * @throws GeometryException 294 */ 295 private static StringBuffer export( MultiCurve mc ) 296 throws GeometryException { 297 298 StringBuffer sb = new StringBuffer( 10000 ); 299 sb.append( "MULTILINESTRING(" ); 300 301 for ( int i = 0; i < mc.getSize() - 1; i++ ) { 302 String s = export( mc.getCurveAt( i ) ).toString(); 303 s = s.substring( 10, s.length() ); 304 sb.append( s ).append( "," ); 305 } 306 String s = export( mc.getCurveAt( mc.getSize() - 1 ) ).toString(); 307 s = s.substring( 10, s.length() ); 308 sb.append( s ).append( ")" ); 309 310 return sb; 311 } 312 313 /** 314 * 315 * 316 * @param ms 317 * 318 * @return 319 * 320 * @throws GeometryException 321 */ 322 private static StringBuffer export( MultiSurface ms ) { 323 324 StringBuffer sb = new StringBuffer( 10000 ); 325 sb.append( "MULTIPOLYGON(" ); 326 327 for ( int i = 0; i < ms.getSize() - 1; i++ ) { 328 String s = export( ms.getSurfaceAt( i ) ).toString(); 329 s = s.substring( 7, s.length() ); 330 sb.append( s ).append( "," ); 331 } 332 String s = export( ms.getSurfaceAt( ms.getSize() - 1 ) ).toString(); 333 s = s.substring( 7, s.length() ); 334 sb.append( s ).append( ")" ); 335 336 return sb; 337 } 338 339 /** 340 * creates a Point from a WKT. 341 * 342 * @param wkt a Point WKT 343 */ 344 public static Point wrapPoint( String wkt, CoordinateSystem crs ) { 345 346 wkt = wkt.trim(); 347 wkt = wkt.substring( 6, wkt.length() - 1 ); 348 double[] tmp = StringTools.toArrayDouble( wkt, " " ); 349 Position pos = GeometryFactory.createPosition( tmp ); 350 Point point = GeometryFactory.createPoint( pos, crs ); 351 352 return point; 353 } 354 355 /** 356 * creates a Curve from a WKT. 357 * 358 * @param wkt linestring a WKT 359 */ 360 public static Curve wrapCurve( String wkt, CoordinateSystem crs ) 361 throws GeometryException { 362 363 wkt = wkt.trim(); 364 wkt = wkt.substring( 11, wkt.length() - 1 ); 365 String[] points = StringTools.toArray( wkt, ",", false ); 366 Position[] pos = new Position[points.length]; 367 for ( int i = 0; i < points.length; i++ ) { 368 double[] tmp = StringTools.toArrayDouble( points[i], " " ); 369 pos[i] = GeometryFactory.createPosition( tmp ); 370 } 371 Curve curve = GeometryFactory.createCurve( pos, crs ); 372 373 return curve; 374 } 375 376 /** 377 * creates a Surface 378 * 379 * @param wkt polygon WKT 380 */ 381 public static Surface wrapSurface( String wkt, CoordinateSystem crs ) 382 throws GeometryException { 383 384 wkt = wkt.trim(); 385 386 Position[] ext = null; 387 ArrayList inn = new ArrayList(); 388 if ( wkt.indexOf( "((" ) > 0 ) { 389 wkt = wkt.substring( 9, wkt.length() - 1 ); 390 int pos = wkt.indexOf( ")" ); 391 String tmp = wkt.substring( 0, pos ); 392 //external ring 393 String[] points = StringTools.toArray( tmp, ",", false ); 394 ext = new Position[points.length]; 395 for ( int i = 0; i < points.length; i++ ) { 396 double[] temp = StringTools.toArrayDouble( points[i], " " ); 397 ext[i] = GeometryFactory.createPosition( temp ); 398 } 399 if ( pos + 3 < wkt.length() ) { 400 wkt = wkt.substring( pos + 3, wkt.length() ); 401 while ( wkt.indexOf( ")" ) > 0 ) { 402 pos = wkt.indexOf( ")" ); 403 tmp = wkt.substring( 0, pos ); 404 //internal ring(s) 405 points = StringTools.toArray( tmp, ",", false ); 406 Position[] intern = new Position[points.length]; 407 for ( int i = 0; i < points.length; i++ ) { 408 double[] temp = StringTools.toArrayDouble( points[i], " " ); 409 intern[i] = GeometryFactory.createPosition( temp ); 410 } 411 inn.add( intern ); 412 if ( pos + 3 < wkt.length() ) { 413 wkt = wkt.substring( pos + 3, wkt.length() ); 414 } else { 415 break; 416 } 417 } 418 } 419 } 420 Position[][] inner = null; 421 if ( inn.size() > 0 ) { 422 inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); 423 } 424 Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(), 425 crs ); 426 427 return sur; 428 } 429 430 /** 431 * creates a MultiPoint from a WKT 432 * 433 * @param wkt multipoint WKT 434 */ 435 public static MultiPoint wrapMultiPoint( String wkt, CoordinateSystem crs ) { 436 437 wkt = wkt.trim(); 438 wkt = wkt.substring( 11, wkt.length() - 1 ); 439 String[] coords = StringTools.toArray( wkt, ",", false ); 440 Position[] pos = new Position[coords.length]; 441 for ( int i = 0; i < coords.length; i++ ) { 442 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 443 pos[i] = GeometryFactory.createPosition( temp ); 444 } 445 446 Point[] points = new Point[pos.length]; 447 for ( int i = 0; i < pos.length; i++ ) { 448 points[i] = GeometryFactory.createPoint( pos[i], crs ); 449 } 450 MultiPoint mp = GeometryFactory.createMultiPoint( points ); 451 452 return mp; 453 } 454 455 /** 456 * creates a MultiCurve from a WKT 457 * 458 * @param wkt a WKT 459 */ 460 public static MultiCurve wrapMultiCurve( String wkt, CoordinateSystem crs ) 461 throws GeometryException { 462 463 ArrayList crvs = new ArrayList(); 464 465 wkt = wkt.trim(); 466 int pos = wkt.indexOf( ")" ); 467 String tmp = wkt.substring( 17, pos ); 468 String[] coords = StringTools.toArray( tmp, ",", false ); 469 Position[] posi = new Position[coords.length]; 470 for ( int i = 0; i < coords.length; i++ ) { 471 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 472 posi[i] = GeometryFactory.createPosition( temp ); 473 } 474 crvs.add( GeometryFactory.createCurve( posi, crs ) ); 475 wkt = wkt.substring( pos + 3, wkt.length() - 1 ); 476 while ( wkt.indexOf( ")" ) > 0 ) { 477 Position[] posi2 = new Position[coords.length]; 478 pos = wkt.indexOf( ")" ); 479 tmp = wkt.substring( 0, pos ); 480 coords = StringTools.toArray( tmp, ",", false ); 481 for ( int i = 0; i < coords.length; i++ ) { 482 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 483 posi2[i] = GeometryFactory.createPosition( temp ); 484 } 485 crvs.add( GeometryFactory.createCurve( posi2, crs ) ); 486 if ( pos + 3 < wkt.length() ) { 487 wkt = wkt.substring( pos + 3, wkt.length() ); 488 } else { 489 break; 490 } 491 } 492 493 Curve[] curves = (Curve[]) crvs.toArray( new Curve[crvs.size()] ); 494 MultiCurve mc = GeometryFactory.createMultiCurve( curves ); 495 496 return mc; 497 } 498 499 /** 500 * creates a MultiSurface from a WKT 501 * 502 * @param wkt a WKT 503 */ 504 public static MultiSurface wrapMultiSurface( String wkt, CoordinateSystem crs ) 505 throws GeometryException { 506 507 ArrayList srfcs = new ArrayList(); 508 509 wkt = wkt.substring( 13 ); 510 // for each polygon 511 while ( wkt.indexOf( "((" ) > -1 ) { 512 Position[] ext = null; 513 ArrayList inn = new ArrayList(); 514 int pos1 = wkt.indexOf( "))" ); 515 String tmp = wkt.substring( 2, pos1 + 1 ); 516 // exterior ring 517 int pos = tmp.indexOf( ")" ); 518 String tmp2 = tmp.substring( 0, pos ); 519 String[] points = StringTools.toArray( tmp2, ",", false ); 520 ext = new Position[points.length]; 521 for ( int i = 0; i < points.length; i++ ) { 522 double[] temp = StringTools.toArrayDouble( points[i], " " ); 523 ext[i] = GeometryFactory.createPosition( temp ); 524 } 525 if ( pos + 3 < tmp.length() ) { 526 tmp = tmp.substring( pos + 3, tmp.length() ); 527 // for each inner ring 528 while ( tmp.indexOf( ")" ) > 0 ) { 529 pos = tmp.indexOf( ")" ); 530 tmp2 = tmp.substring( 0, pos ); 531 points = StringTools.toArray( tmp2, ",", false ); 532 Position[] intern = new Position[points.length]; 533 for ( int i = 0; i < points.length; i++ ) { 534 double[] temp = StringTools.toArrayDouble( points[i], " " ); 535 intern[i] = GeometryFactory.createPosition( temp ); 536 } 537 inn.add( intern ); 538 if ( pos + 3 < tmp.length() ) { 539 tmp = tmp.substring( pos + 3, tmp.length() ); 540 } else { 541 break; 542 } 543 } 544 } 545 Position[][] inner = null; 546 if ( inn.size() > 0 ) { 547 inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); 548 } 549 Surface sur = GeometryFactory.createSurface( ext, inner, 550 new SurfaceInterpolationImpl(), crs ); 551 srfcs.add( sur ); 552 wkt = wkt.substring( pos1 + 3 ); 553 } 554 Surface[] surfaces = (Surface[]) srfcs.toArray( new Surface[srfcs.size()] ); 555 MultiSurface ms = GeometryFactory.createMultiSurface( surfaces ); 556 557 return ms; 558 } 559 560 }/* ******************************************************************** 561 Changes to this class. What the people have been up to: 562 $Log$ 563 Revision 1.11 2006/08/07 12:23:35 poth 564 deprecated clas/method calls removed // never thrown exceptions removed 565 566 Revision 1.10 2006/07/12 14:46:15 poth 567 comment footer added 568 569 ********************************************************************** */