001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/model/spatialschema/WKTAdapter.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 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 geometries to deegree 053 * geometries. 054 * 055 * @version $Revision: 9343 $ 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 073 * if type unsupported or conversion failed 074 */ 075 public static Geometry wrap( String wkt, CoordinateSystem crs ) 076 throws GeometryException { 077 078 Geometry geo = null; 079 080 if ( wkt == null ) { 081 return null; 082 } else if ( wkt.startsWith( "POINT" ) ) { 083 geo = wrapPoint( wkt, crs ); 084 } else if ( wkt.startsWith( "LINE" ) ) { 085 geo = wrapCurve( wkt, crs ); 086 } else if ( wkt.startsWith( "POLY" ) ) { 087 geo = wrapSurface( wkt, crs ); 088 } else if ( wkt.startsWith( "MULTIPOINT" ) ) { 089 geo = wrapMultiPoint( wkt, crs ); 090 } else if ( wkt.startsWith( "MULTILINE" ) ) { 091 geo = wrapMultiCurve( wkt, crs ); 092 } else if ( wkt.startsWith( "MULTIPOLY" ) ) { 093 geo = wrapMultiSurface( wkt, crs ); 094 } 095 096 return geo; 097 } 098 099 /** 100 * @param geom 101 * geometry 102 * 103 * @return 104 */ 105 public static StringBuffer export( Geometry geom ) 106 throws GeometryException { 107 108 StringBuffer sb = null; 109 if ( geom instanceof Point ) { 110 sb = export( (Point) geom ); 111 } else if ( geom instanceof Curve ) { 112 sb = export( (Curve) geom ); 113 } else if ( geom instanceof Surface ) { 114 sb = export( (Surface) geom ); 115 } else if ( geom instanceof MultiPoint ) { 116 sb = export( (MultiPoint) geom ); 117 } else if ( geom instanceof MultiCurve ) { 118 sb = export( (MultiCurve) geom ); 119 } else if ( geom instanceof MultiSurface ) { 120 sb = export( (MultiSurface) geom ); 121 } 122 123 return sb; 124 } 125 126 /** 127 * exports an Envelope as a BOX3D WKT string. 128 * 129 * @param envelope 130 * @return 131 */ 132 public static StringBuffer export( Envelope envelope ) { 133 StringBuffer sb = new StringBuffer( 150 ); 134 sb.append( "BOX3D(" ); 135 int dim = envelope.getMin().getCoordinateDimension(); 136 double[] d = envelope.getMin().getAsArray(); 137 for ( int i = 0; i < dim - 1; i++ ) { 138 sb.append( Double.toString( d[i] ) ).append( " " ); 139 } 140 sb.append( Double.toString( d[dim - 1] ) ).append( "," ); 141 d = envelope.getMax().getAsArray(); 142 for ( int i = 0; i < dim - 1; i++ ) { 143 sb.append( Double.toString( d[i] ) ).append( " " ); 144 } 145 sb.append( Double.toString( d[dim - 1] ) ); 146 sb.append( ") " ); 147 return sb; 148 } 149 150 /** 151 * @param point 152 * point geometry 153 * 154 * @return 155 */ 156 private static StringBuffer export( Point point ) { 157 158 StringBuffer sb = new StringBuffer( 50 ); 159 sb.append( "POINT(" ); 160 double[] points = point.getAsArray(); 161 int dim = point.getCoordinateDimension(); 162 for ( int i = 0; i < dim - 1; i++ ) { 163 sb.append( points[i] ).append( ' ' ); 164 } 165 sb.append( points[dim - 1] ); 166 sb.append( ") " ); 167 168 return sb; 169 } 170 171 /** 172 * 173 * @param cur 174 * curve geometry 175 * 176 * @return 177 * 178 * @throws GeometryException 179 */ 180 private static StringBuffer export( Curve cur ) 181 throws GeometryException { 182 183 LineString ls = cur.getAsLineString(); 184 185 StringBuffer sb = new StringBuffer( ls.getNumberOfPoints() * 30 ); 186 sb.append( "LINESTRING(" ); 187 188 for ( int i = 0; i < ls.getNumberOfPoints() - 1; i++ ) { 189 Position pos = ls.getPositionAt( i ); 190 double[] positions = pos.getAsArray(); 191 int dim = pos.getCoordinateDimension(); 192 for ( int j = 0; j < dim - 1; j++ ) { 193 sb.append( positions[j] + " " ); 194 } 195 sb.append( positions[dim - 1] + "," ); 196 } 197 Position pos = ls.getPositionAt( ls.getNumberOfPoints() - 1 ); 198 double[] tmp = pos.getAsArray(); 199 int dim = pos.getCoordinateDimension(); 200 for ( int j = 0; j < dim - 1; j++ ) { 201 sb.append( tmp[j] + " " ); 202 } 203 sb.append( tmp[dim - 1] + ")" ); 204 205 return sb; 206 } 207 208 /** 209 * 210 * 211 * @param sur 212 * 213 * @return 214 * 215 */ 216 private static StringBuffer export( Surface sur ) { 217 218 SurfaceBoundary subo = sur.getSurfaceBoundary(); 219 Ring exter = subo.getExteriorRing(); 220 Ring[] inter = subo.getInteriorRings(); 221 222 StringBuffer sb = new StringBuffer( 10000 ); 223 sb.append( "POLYGON((" ); 224 // exterior ring 225 Position[] pos = exter.getPositions(); 226 int dim = pos[0].getCoordinateDimension(); 227 for ( int i = 0; i < pos.length - 1; i++ ) { 228 double[] positions = pos[i].getAsArray(); 229 for ( int j = 0; j < dim - 1; j++ ) { 230 sb.append( positions[j] + " " ); 231 } 232 sb.append( positions[dim - 1] + "," ); 233 } 234 double[] positions = pos[pos.length - 1].getAsArray(); 235 for ( int j = 0; j < dim - 1; j++ ) { 236 sb.append( positions[j] + " " ); 237 } 238 sb.append( positions[dim - 1] + ")" ); 239 // interior rings 240 if ( inter != null ) { 241 for ( int j = 0; j < inter.length; j++ ) { 242 sb.append( ",(" ); 243 pos = inter[j].getPositions(); 244 for ( int i = 0; i < pos.length - 1; i++ ) { 245 double[] intPos = pos[i].getAsArray(); 246 for ( int l = 0; l < dim - 1; l++ ) { 247 sb.append( intPos[l] + " " ); 248 } 249 sb.append( intPos[dim - 1] + "," );// 250 } 251 double[] intPos = pos[pos.length - 1].getAsArray(); 252 for ( int l = 0; l < dim - 1; l++ ) { 253 sb.append( intPos[l] + " " ); 254 } 255 sb.append( intPos[dim - 1] + ")" ); 256 } 257 } 258 sb.append( ")" ); 259 260 return sb; 261 } 262 263 /** 264 * @param mp 265 * @return 266 */ 267 private static StringBuffer export( MultiPoint mp ) { 268 269 StringBuffer sb = new StringBuffer( mp.getSize() * 30 ); 270 sb.append( "MULTIPOINT(" ); 271 int dim = mp.getPointAt( 0 ).getCoordinateDimension(); 272 for ( int i = 0; i < mp.getSize() - 1; i++ ) { 273 Point pt = mp.getPointAt( i ); 274 double[] points = pt.getAsArray(); 275 for ( int j = 0; j < dim - 1; j++ ) { 276 sb.append( points[j] + " " ); 277 } 278 sb.append( points[dim - 1] ); 279 sb.append( "," ); 280 } 281 Point pt = mp.getPointAt( mp.getSize() - 1 ); 282 double[] points = pt.getAsArray(); 283 for ( int j = 0; j < dim - 1; j++ ) { 284 sb.append( points[j] + " " ); 285 } 286 sb.append( points[dim - 1] + ")" ); 287 288 return sb; 289 } 290 291 /** 292 * 293 * 294 * @param mc 295 * 296 * @return 297 * 298 * @throws GeometryException 299 */ 300 private static StringBuffer export( MultiCurve mc ) 301 throws GeometryException { 302 303 StringBuffer sb = new StringBuffer( 10000 ); 304 sb.append( "MULTILINESTRING(" ); 305 306 for ( int i = 0; i < mc.getSize() - 1; i++ ) { 307 String s = export( mc.getCurveAt( i ) ).toString(); 308 s = s.substring( 10, s.length() ); 309 sb.append( s ).append( "," ); 310 } 311 String s = export( mc.getCurveAt( mc.getSize() - 1 ) ).toString(); 312 s = s.substring( 10, s.length() ); 313 sb.append( s ).append( ")" ); 314 315 return sb; 316 } 317 318 /** 319 * 320 * 321 * @param ms 322 * 323 * @return 324 * 325 * @throws GeometryException 326 */ 327 private static StringBuffer export( MultiSurface ms ) { 328 329 StringBuffer sb = new StringBuffer( 10000 ); 330 sb.append( "MULTIPOLYGON(" ); 331 332 for ( int i = 0; i < ms.getSize() - 1; i++ ) { 333 String s = export( ms.getSurfaceAt( i ) ).toString(); 334 s = s.substring( 7, s.length() ); 335 sb.append( s ).append( "," ); 336 } 337 String s = export( ms.getSurfaceAt( ms.getSize() - 1 ) ).toString(); 338 s = s.substring( 7, s.length() ); 339 sb.append( s ).append( ")" ); 340 341 return sb; 342 } 343 344 /** 345 * creates a Point from a WKT. 346 * 347 * @param wkt 348 * a Point WKT 349 */ 350 public static Point wrapPoint( String wkt, CoordinateSystem crs ) { 351 352 wkt = wkt.trim(); 353 wkt = wkt.substring( 6, wkt.length() - 1 ); 354 double[] tmp = StringTools.toArrayDouble( wkt, " " ); 355 Position pos = GeometryFactory.createPosition( tmp ); 356 Point point = GeometryFactory.createPoint( pos, crs ); 357 358 return point; 359 } 360 361 /** 362 * creates a Curve from a WKT. 363 * 364 * @param wkt 365 * linestring a WKT 366 */ 367 public static Curve wrapCurve( String wkt, CoordinateSystem crs ) 368 throws GeometryException { 369 370 wkt = wkt.trim(); 371 wkt = wkt.substring( 11, wkt.length() - 1 ); 372 String[] points = StringTools.toArray( wkt, ",", false ); 373 Position[] pos = new Position[points.length]; 374 for ( int i = 0; i < points.length; i++ ) { 375 double[] tmp = StringTools.toArrayDouble( points[i], " " ); 376 pos[i] = GeometryFactory.createPosition( tmp ); 377 } 378 Curve curve = GeometryFactory.createCurve( pos, crs ); 379 380 return curve; 381 } 382 383 /** 384 * creates a Surface 385 * 386 * @param wkt 387 * polygon WKT 388 */ 389 public static Surface wrapSurface( String wkt, CoordinateSystem crs ) 390 throws GeometryException { 391 392 wkt = wkt.trim(); 393 394 Position[] ext = null; 395 ArrayList inn = new ArrayList(); 396 if ( wkt.indexOf( "((" ) > 0 ) { 397 wkt = wkt.substring( 9, wkt.length() - 1 ); 398 int pos = wkt.indexOf( ")" ); 399 String tmp = wkt.substring( 0, pos ); 400 // external ring 401 String[] points = StringTools.toArray( tmp, ",", false ); 402 ext = new Position[points.length]; 403 for ( int i = 0; i < points.length; i++ ) { 404 double[] temp = StringTools.toArrayDouble( points[i], " " ); 405 ext[i] = GeometryFactory.createPosition( temp ); 406 } 407 if ( pos + 3 < wkt.length() ) { 408 wkt = wkt.substring( pos + 3, wkt.length() ); 409 while ( wkt.indexOf( ")" ) > 0 ) { 410 pos = wkt.indexOf( ")" ); 411 tmp = wkt.substring( 0, pos ); 412 // internal ring(s) 413 points = StringTools.toArray( tmp, ",", false ); 414 Position[] intern = new Position[points.length]; 415 for ( int i = 0; i < points.length; i++ ) { 416 double[] temp = StringTools.toArrayDouble( points[i], " " ); 417 intern[i] = GeometryFactory.createPosition( temp ); 418 } 419 inn.add( intern ); 420 if ( pos + 3 < wkt.length() ) { 421 wkt = wkt.substring( pos + 3, wkt.length() ); 422 } else { 423 break; 424 } 425 } 426 } 427 } 428 Position[][] inner = null; 429 if ( inn.size() > 0 ) { 430 inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); 431 } 432 Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(), crs ); 433 434 return sur; 435 } 436 437 /** 438 * creates a MultiPoint from a WKT 439 * 440 * @param wkt 441 * multipoint WKT 442 */ 443 public static MultiPoint wrapMultiPoint( String wkt, CoordinateSystem crs ) { 444 445 wkt = wkt.trim(); 446 wkt = wkt.substring( 11, wkt.length() - 1 ); 447 String[] coords = StringTools.toArray( wkt, ",", false ); 448 Position[] pos = new Position[coords.length]; 449 for ( int i = 0; i < coords.length; i++ ) { 450 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 451 pos[i] = GeometryFactory.createPosition( temp ); 452 } 453 454 Point[] points = new Point[pos.length]; 455 for ( int i = 0; i < pos.length; i++ ) { 456 points[i] = GeometryFactory.createPoint( pos[i], crs ); 457 } 458 MultiPoint mp = GeometryFactory.createMultiPoint( points ); 459 460 return mp; 461 } 462 463 /** 464 * creates a MultiCurve from a WKT 465 * 466 * @param wkt 467 * a WKT 468 */ 469 public static MultiCurve wrapMultiCurve( String wkt, CoordinateSystem crs ) 470 throws GeometryException { 471 472 ArrayList crvs = new ArrayList(); 473 474 wkt = wkt.trim(); 475 int pos = wkt.indexOf( ")" ); 476 String tmp = wkt.substring( 17, pos ); 477 String[] coords = StringTools.toArray( tmp, ",", false ); 478 Position[] posi = new Position[coords.length]; 479 for ( int i = 0; i < coords.length; i++ ) { 480 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 481 posi[i] = GeometryFactory.createPosition( temp ); 482 } 483 crvs.add( GeometryFactory.createCurve( posi, crs ) ); 484 wkt = wkt.substring( pos + 3, wkt.length() - 1 ); 485 while ( wkt.indexOf( ")" ) > 0 ) { 486 Position[] posi2 = new Position[coords.length]; 487 pos = wkt.indexOf( ")" ); 488 tmp = wkt.substring( 0, pos ); 489 coords = StringTools.toArray( tmp, ",", false ); 490 for ( int i = 0; i < coords.length; i++ ) { 491 double[] temp = StringTools.toArrayDouble( coords[i], " " ); 492 posi2[i] = GeometryFactory.createPosition( temp ); 493 } 494 crvs.add( GeometryFactory.createCurve( posi2, crs ) ); 495 if ( pos + 3 < wkt.length() ) { 496 wkt = wkt.substring( pos + 3, wkt.length() ); 497 } else { 498 break; 499 } 500 } 501 502 Curve[] curves = (Curve[]) crvs.toArray( new Curve[crvs.size()] ); 503 MultiCurve mc = GeometryFactory.createMultiCurve( curves ); 504 505 return mc; 506 } 507 508 /** 509 * creates a MultiSurface from a WKT 510 * 511 * @param wkt 512 * a WKT 513 */ 514 public static MultiSurface wrapMultiSurface( String wkt, CoordinateSystem crs ) 515 throws GeometryException { 516 517 ArrayList srfcs = new ArrayList(); 518 519 wkt = wkt.substring( 13 ); 520 // for each polygon 521 while ( wkt.indexOf( "((" ) > -1 ) { 522 Position[] ext = null; 523 ArrayList inn = new ArrayList(); 524 int pos1 = wkt.indexOf( "))" ); 525 String tmp = wkt.substring( 2, pos1 + 1 ); 526 // exterior ring 527 int pos = tmp.indexOf( ")" ); 528 String tmp2 = tmp.substring( 0, pos ); 529 String[] points = StringTools.toArray( tmp2, ",", false ); 530 ext = new Position[points.length]; 531 for ( int i = 0; i < points.length; i++ ) { 532 double[] temp = StringTools.toArrayDouble( points[i], " " ); 533 ext[i] = GeometryFactory.createPosition( temp ); 534 } 535 if ( pos + 3 < tmp.length() ) { 536 tmp = tmp.substring( pos + 3, tmp.length() ); 537 // for each inner ring 538 while ( tmp.indexOf( ")" ) > 0 ) { 539 pos = tmp.indexOf( ")" ); 540 tmp2 = tmp.substring( 0, pos ); 541 points = StringTools.toArray( tmp2, ",", false ); 542 Position[] intern = new Position[points.length]; 543 for ( int i = 0; i < points.length; i++ ) { 544 double[] temp = StringTools.toArrayDouble( points[i], " " ); 545 intern[i] = GeometryFactory.createPosition( temp ); 546 } 547 inn.add( intern ); 548 if ( pos + 3 < tmp.length() ) { 549 tmp = tmp.substring( pos + 3, tmp.length() ); 550 } else { 551 break; 552 } 553 } 554 } 555 Position[][] inner = null; 556 if ( inn.size() > 0 ) { 557 inner = (Position[][]) inn.toArray( new Position[inn.size()][] ); 558 } 559 Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(), crs ); 560 srfcs.add( sur ); 561 wkt = wkt.substring( pos1 + 3 ); 562 } 563 Surface[] surfaces = (Surface[]) srfcs.toArray( new Surface[srfcs.size()] ); 564 MultiSurface ms = GeometryFactory.createMultiSurface( surfaces ); 565 566 return ms; 567 } 568 569 }