001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/spatialschema/JTSAdapter.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.model.spatialschema; 037 038 import org.deegree.framework.log.ILogger; 039 import org.deegree.framework.log.LoggerFactory; 040 041 import com.vividsolutions.jts.geom.LinearRing; 042 import com.vividsolutions.jts.geom.PrecisionModel; 043 044 /** 045 * Adapter between deegree <code>Geometry</code>s and JTS <code>Geometry<code> objects. 046 * <p> 047 * Please note that the generated deegree-objects use null as 048 * coordinate system! 049 * 050 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider</a> 051 * @author last edited by: $Author: mschneider $ 052 * 053 * @version $Revision: 19906 $ $Date: 2009-10-01 16:31:29 +0200 (Do, 01 Okt 2009) $ 054 */ 055 public class JTSAdapter { 056 057 private static final ILogger LOG = LoggerFactory.getLogger( JTSAdapter.class ); 058 059 // precision model that is used for all JTS geometries 060 private static PrecisionModel pm = new PrecisionModel(); 061 062 // factory for creating JTS geometries 063 private static com.vividsolutions.jts.geom.GeometryFactory jtsFactory = new com.vividsolutions.jts.geom.GeometryFactory( 064 pm, 065 0 ); 066 067 /** 068 * Converts a deegree <code>Geometry</code> to a corresponding JTS <code>Geometry</code> object. 069 * <p> 070 * Currently, the following conversions are supported: 071 * <ul> 072 * <li>Curve -> LineString</li> 073 * <li>Point -> Point</li> 074 * <li>Surface -> Polygon</li> 075 * <li>MultiCurve -> MultiLineString</li> 076 * <li>MultiPoint -> MultiPoint</li> 077 * <li>MultiSurface -> MultiPolygon</li> 078 * <li>MultiPrimitive -> GeometryCollection</li> 079 * <li>MultiGeometry -> GeometryCollection</li> 080 * </ul> 081 * <p> 082 * 083 * @param gmObject 084 * the object to be converted 085 * @return the corresponding JTS-<code>Geometry</code> object 086 * @throws GeometryException 087 * if type unsupported or conversion failed 088 */ 089 public static synchronized com.vividsolutions.jts.geom.Geometry export( Geometry gmObject ) 090 throws GeometryException { 091 092 com.vividsolutions.jts.geom.Geometry geometry = null; 093 if ( gmObject instanceof Curve ) { 094 geometry = export( (Curve) gmObject ); 095 } else if ( gmObject instanceof Point ) { 096 geometry = export( (Point) gmObject ); 097 } else if ( gmObject instanceof Surface ) { 098 geometry = export( (Surface) gmObject ); 099 } else if ( gmObject instanceof MultiCurve ) { 100 geometry = export( (MultiCurve) gmObject ); 101 } else if ( gmObject instanceof MultiPoint ) { 102 geometry = export( (MultiPoint) gmObject ); 103 } else if ( gmObject instanceof MultiSurface ) { 104 geometry = export( (MultiSurface) gmObject ); 105 } else if ( gmObject instanceof MultiPrimitive ) { 106 geometry = export( (MultiPrimitive) gmObject ); 107 } else if ( gmObject instanceof MultiGeometry ) { 108 geometry = export( (MultiGeometry) gmObject ); 109 } else { 110 throw new GeometryException( "JTSAdapter.export does not support type '" + gmObject.getClass().getName() 111 + "'!" ); 112 } 113 return geometry; 114 } 115 116 /** 117 * Converts a JTS <code>Geometry</code> object to a corresponding deegree <code>Geometry</code>. 118 * <p> 119 * Currently, the following conversions are supported: 120 * <ul> 121 * <li>LineString -> Curve 122 * <li>Point -> Point 123 * <li>Polygon -> Surface 124 * <li>MultiLineString -> MultiCurve 125 * <li>MultiPoint -> MultiPoint 126 * <li>MultiPolygon -> MultiSurface 127 * <li>GeometryCollection -> MultiGeometry 128 * </ul> 129 * <p> 130 * 131 * @param geometry 132 * the JTS-<code>Geometry</code> to be converted 133 * @return the corresponding <code>Geometry</code> 134 * @throws GeometryException 135 * if type unsupported or conversion failed 136 */ 137 public static Geometry wrap( com.vividsolutions.jts.geom.Geometry geometry ) 138 throws GeometryException { 139 140 Geometry gmObject = null; 141 if ( geometry instanceof com.vividsolutions.jts.geom.LineString ) { 142 gmObject = wrap( (com.vividsolutions.jts.geom.LineString) geometry ); 143 } else if ( geometry instanceof com.vividsolutions.jts.geom.Point ) { 144 gmObject = wrap( (com.vividsolutions.jts.geom.Point) geometry ); 145 } else if ( geometry instanceof com.vividsolutions.jts.geom.Polygon ) { 146 gmObject = wrap( (com.vividsolutions.jts.geom.Polygon) geometry ); 147 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiLineString ) { 148 gmObject = wrap( (com.vividsolutions.jts.geom.MultiLineString) geometry ); 149 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPoint ) { 150 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPoint) geometry ); 151 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPolygon ) { 152 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPolygon) geometry ); 153 } else if ( geometry instanceof com.vividsolutions.jts.geom.GeometryCollection ) { 154 gmObject = wrap( (com.vividsolutions.jts.geom.GeometryCollection) geometry ); 155 } else { 156 throw new GeometryException( "JTSAdapter.wrap does not support type '" + geometry.getClass().getName() 157 + "'!" ); 158 } 159 return gmObject; 160 } 161 162 /** 163 * Converts a deegree <code>Point</code> to a JTS <code>Point</code>. 164 * 165 * @param gmPoint 166 * point to be converted 167 * @return the corresponding <code>Point</code> object 168 */ 169 private static synchronized com.vividsolutions.jts.geom.Point export( Point gmPoint ) { 170 171 com.vividsolutions.jts.geom.Coordinate coord = new com.vividsolutions.jts.geom.Coordinate( gmPoint.getX(), 172 gmPoint.getY() ); 173 174 return jtsFactory.createPoint( coord ); 175 } 176 177 /** 178 * Converts a deegree <code>MultiPoint</code> to a JTS <code>MultiPoint</code>. 179 * 180 * @param gmMultiPoint 181 * multipoint to be converted 182 * @return the corresponding <code>MultiPoint</code> object 183 */ 184 private static synchronized com.vividsolutions.jts.geom.MultiPoint export( MultiPoint gmMultiPoint ) { 185 Point[] gmPoints = gmMultiPoint.getAllPoints(); 186 com.vividsolutions.jts.geom.Point[] points = new com.vividsolutions.jts.geom.Point[gmPoints.length]; 187 for ( int i = 0; i < points.length; i++ ) { 188 points[i] = export( gmPoints[i] ); 189 } 190 return jtsFactory.createMultiPoint( points ); 191 } 192 193 /** 194 * Converts a deegree <code>Curve</code> to a JTS <code>LineString</code>. 195 * 196 * @param curve 197 * <code>Curve</code> to be converted 198 * @return the corresponding <code>LineString</code> object 199 * @throws GeometryException 200 */ 201 private static synchronized com.vividsolutions.jts.geom.LineString export( Curve curve ) 202 throws GeometryException { 203 204 LineString lineString = curve.getAsLineString(); 205 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[lineString.getNumberOfPoints()]; 206 for ( int i = 0; i < coords.length; i++ ) { 207 Position position = lineString.getPositionAt( i ); 208 coords[i] = new com.vividsolutions.jts.geom.Coordinate( position.getX(), position.getY() ); 209 } 210 return jtsFactory.createLineString( coords ); 211 } 212 213 /** 214 * Converts a deegree <code>MultiCurve</code> to a JTS <code>MultiLineString</code>. 215 * 216 * @param multi 217 * <code>MultiCurve</code> to be converted 218 * @return the corresponding <code>MultiLineString</code> object 219 * @throws GeometryException 220 */ 221 private static synchronized com.vividsolutions.jts.geom.MultiLineString export( MultiCurve multi ) 222 throws GeometryException { 223 224 Curve[] curves = multi.getAllCurves(); 225 com.vividsolutions.jts.geom.LineString[] lineStrings = new com.vividsolutions.jts.geom.LineString[curves.length]; 226 for ( int i = 0; i < curves.length; i++ ) { 227 lineStrings[i] = export( curves[i] ); 228 } 229 return jtsFactory.createMultiLineString( lineStrings ); 230 } 231 232 /** 233 * Converts an array of deegree <code>Position</code>s to a JTS <code>LinearRing</code>. 234 * 235 * @param positions 236 * an array of <code>Position</code>s 237 * @return the corresponding <code>LinearRing</code> object 238 */ 239 public static synchronized com.vividsolutions.jts.geom.LinearRing export( Position[] positions ) { 240 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[positions.length]; 241 for ( int i = 0; i < positions.length; i++ ) { 242 coords[i] = new com.vividsolutions.jts.geom.Coordinate( positions[i].getX(), positions[i].getY() ); 243 } 244 return jtsFactory.createLinearRing( coords ); 245 } 246 247 /** 248 * Converts a deegree <code>SurfacePatch</code> into a JTS <code>Polygon</code>. 249 * 250 * @param patch 251 * {@link SurfacePatch} 252 * @return corresponding JTS <code>Polygon</code> object 253 */ 254 public static synchronized com.vividsolutions.jts.geom.Polygon export( SurfacePatch patch ) { 255 256 // convert exterior ring 257 LinearRing jtsShell = export( patch.getExteriorRing() ); 258 259 // convert interior rings 260 LinearRing[] jtsHoles = null; 261 Ring[] interiorRings = patch.getInterior(); 262 if ( interiorRings != null ) { 263 jtsHoles = new LinearRing[interiorRings.length]; 264 for ( int i = 0; i < interiorRings.length; i++ ) { 265 jtsHoles[i] = export( interiorRings[i].getPositions() ); 266 } 267 } 268 return jtsFactory.createPolygon( jtsShell, jtsHoles ); 269 } 270 271 /** 272 * Converts a deegree <code>Surface</code> to a JTS <code>Polygon</code>. 273 * <p> 274 * Currently, the <code>Surface</code> _must_ contain exactly one patch! 275 * 276 * @param surface 277 * a <code>Surface</code> 278 * @return the corresponding <code>Polygon</code> object 279 */ 280 private static synchronized com.vividsolutions.jts.geom.Polygon export( Surface surface ) { 281 SurfacePatch patch = null; 282 try { 283 patch = surface.getSurfacePatchAt( 0 ); 284 Position[] exteriorRing = patch.getExteriorRing(); 285 Position[][] interiorRings = patch.getInteriorRings(); 286 287 com.vividsolutions.jts.geom.LinearRing shell = export( exteriorRing ); 288 com.vividsolutions.jts.geom.LinearRing[] holes = new com.vividsolutions.jts.geom.LinearRing[0]; 289 if ( interiorRings != null ) { 290 holes = new com.vividsolutions.jts.geom.LinearRing[interiorRings.length]; 291 for ( int i = 0; i < holes.length; i++ ) { 292 holes[i] = export( interiorRings[i] ); 293 } 294 } 295 return jtsFactory.createPolygon( shell, holes ); 296 } catch ( GeometryException e ) { 297 LOG.logError( "", e ); 298 } 299 return null; 300 } 301 302 /** 303 * Converts a JTS <code>MultiSurface</code> to a deegree <code>MultiPolygon</code>. 304 * <p> 305 * Currently, the contained <code>Surface</code> _must_ have exactly one patch! 306 * 307 * @param msurface 308 * a <code>MultiSurface</code> 309 * @return the corresponding <code>MultiPolygon</code> object 310 */ 311 private static synchronized com.vividsolutions.jts.geom.MultiPolygon export( MultiSurface msurface ) { 312 313 Surface[] surfaces = msurface.getAllSurfaces(); 314 com.vividsolutions.jts.geom.Polygon[] polygons = new com.vividsolutions.jts.geom.Polygon[surfaces.length]; 315 316 for ( int i = 0; i < surfaces.length; i++ ) { 317 polygons[i] = export( surfaces[i] ); 318 } 319 return jtsFactory.createMultiPolygon( polygons ); 320 } 321 322 /** 323 * Converts a JTS <code>MultiPrimitive</code> to a deegree <code>GeometryCollection</code>. 324 * 325 * @param multi 326 * a <code>MultiPrimitive</code> 327 * @return the corresponding <code>GeometryCollection</code> object 328 * @throws GeometryException 329 */ 330 private static synchronized com.vividsolutions.jts.geom.GeometryCollection export( MultiPrimitive multi ) 331 throws GeometryException { 332 333 Geometry[] primitives = multi.getAllPrimitives(); 334 com.vividsolutions.jts.geom.Geometry[] geometries = new com.vividsolutions.jts.geom.Geometry[primitives.length]; 335 336 for ( int i = 0; i < primitives.length; i++ ) { 337 geometries[i] = export( primitives[i] ); 338 } 339 return jtsFactory.createGeometryCollection( geometries ); 340 } 341 342 /** 343 * Converts a JTS <code>MultiGeometry</code> into a deegree <code>GeometryCollection</code>. 344 * 345 * @param multi 346 * a <code>MultiGeometry</code> 347 * @return corresponding <code>GeometryCollection</code> object 348 * @throws GeometryException 349 */ 350 private static synchronized com.vividsolutions.jts.geom.GeometryCollection export( MultiGeometry multi ) 351 throws GeometryException { 352 353 Geometry[] memberGeometries = multi.getAll(); 354 com.vividsolutions.jts.geom.Geometry[] jtsMemberGeometries = new com.vividsolutions.jts.geom.Geometry[memberGeometries.length]; 355 for ( int i = 0; i < memberGeometries.length; i++ ) { 356 jtsMemberGeometries[i] = export( memberGeometries[i] ); 357 } 358 return jtsFactory.createGeometryCollection( jtsMemberGeometries ); 359 } 360 361 /** 362 * Converts a JTS <code>Point</code> to a deegree <code>Point</code>. 363 * 364 * @param point 365 * a <code>Point</code> object 366 * @return the corresponding <code>Point</code> 367 */ 368 private static Point wrap( com.vividsolutions.jts.geom.Point point ) { 369 com.vividsolutions.jts.geom.Coordinate coord = point.getCoordinate(); 370 return Double.isNaN( coord.z ) ? new PointImpl( coord.x, coord.y, null ) : new PointImpl( coord.x, coord.y, 371 coord.z, null ); 372 } 373 374 /** 375 * Converts a JTS <code>MultiPoint</code> to a deegree <code>MultiPoint</code>. 376 * 377 * @param multi 378 * a <code>MultiPoint</code> object 379 * @return the corresponding <code>MultiPoint</code> 380 */ 381 private static MultiPoint wrap( com.vividsolutions.jts.geom.MultiPoint multi ) { 382 Point[] gmPoints = new Point[multi.getNumGeometries()]; 383 for ( int i = 0; i < gmPoints.length; i++ ) { 384 gmPoints[i] = wrap( (com.vividsolutions.jts.geom.Point) multi.getGeometryN( i ) ); 385 } 386 return new MultiPointImpl( gmPoints, null ); 387 } 388 389 /** 390 * Converts a <code>LineString</code> to a <code>Curve</code>. 391 * 392 * @param line 393 * a <code>LineString</code> object 394 * @return the corresponding <code>Curve</code> 395 * @throws GeometryException 396 */ 397 private static Curve wrap( com.vividsolutions.jts.geom.LineString line ) 398 throws GeometryException { 399 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 400 Position[] positions = new Position[coords.length]; 401 for ( int i = 0; i < coords.length; i++ ) { 402 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 403 } 404 return GeometryFactory.createCurve( positions, null ); 405 } 406 407 /** 408 * Converts a <code>MultiLineString</code> to a <code>MultiCurve</code>. 409 * 410 * @param multi 411 * a <code>MultiLineString</code> object 412 * @return the corresponding <code>MultiCurve</code> 413 * @throws GeometryException 414 */ 415 private static MultiCurve wrap( com.vividsolutions.jts.geom.MultiLineString multi ) 416 throws GeometryException { 417 Curve[] curves = new Curve[multi.getNumGeometries()]; 418 for ( int i = 0; i < curves.length; i++ ) { 419 curves[i] = wrap( (com.vividsolutions.jts.geom.LineString) multi.getGeometryN( i ) ); 420 } 421 return GeometryFactory.createMultiCurve( curves ); 422 } 423 424 /** 425 * Converts a <code>Polygon</code> to a <code>Surface</code>. 426 * 427 * @param polygon 428 * a <code>Polygon</code> 429 * @return the corresponding <code>Surface</code> object 430 * @throws GeometryException 431 */ 432 private static Surface wrap( com.vividsolutions.jts.geom.Polygon polygon ) 433 throws GeometryException { 434 435 Position[] exteriorRing = createGMPositions( polygon.getExteriorRing() ); 436 Position[][] interiorRings = new Position[polygon.getNumInteriorRing()][]; 437 438 for ( int i = 0; i < interiorRings.length; i++ ) { 439 interiorRings[i] = createGMPositions( polygon.getInteriorRingN( i ) ); 440 } 441 SurfacePatch patch = new PolygonImpl( new SurfaceInterpolationImpl(), exteriorRing, interiorRings, null ); 442 443 return new SurfaceImpl( patch ); 444 } 445 446 /** 447 * Converts a <code>MultiPolygon</code> to a <code>MultiSurface</code>. 448 * 449 * @param multiPolygon 450 * a <code>MultiPolygon</code> 451 * @return the corresponding <code>MultiSurface</code> object 452 * @throws GeometryException 453 */ 454 private static MultiSurface wrap( com.vividsolutions.jts.geom.MultiPolygon multiPolygon ) 455 throws GeometryException { 456 457 Surface[] surfaces = new Surface[multiPolygon.getNumGeometries()]; 458 for ( int i = 0; i < surfaces.length; i++ ) { 459 surfaces[i] = wrap( (com.vividsolutions.jts.geom.Polygon) multiPolygon.getGeometryN( i ) ); 460 } 461 return new MultiSurfaceImpl( surfaces ); 462 } 463 464 /** 465 * Converts a <code>GeometryCollection</code> to a <code>MultiGeometry</code>. 466 * 467 * @param collection 468 * a <code>GeometryCollection</code> 469 * @return the corresponding <code>MultiGeometry</code> object 470 * @throws GeometryException 471 */ 472 private static MultiGeometry wrap( com.vividsolutions.jts.geom.GeometryCollection collection ) 473 throws GeometryException { 474 475 MultiGeometry multi = new MultiGeometryImpl( null ); 476 for ( int i = 0; i < collection.getNumGeometries(); i++ ) { 477 multi.add( wrap( collection.getGeometryN( i ) ) ); 478 } 479 return multi; 480 } 481 482 /** 483 * Converts a <code>LineString</code> to an array of <code>Position</code>s. 484 * 485 * @param line 486 * a <code>LineString</code> object 487 * @return the corresponding array of <code>Position</code>s 488 */ 489 private static Position[] createGMPositions( com.vividsolutions.jts.geom.LineString line ) { 490 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 491 Position[] positions = new Position[coords.length]; 492 for ( int i = 0; i < coords.length; i++ ) { 493 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 494 } 495 return positions; 496 } 497 }