001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/model/spatialschema/JTSAdapter.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 53177 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 package org.deegree.model.spatialschema; 044 045 import org.deegree.framework.log.ILogger; 046 import org.deegree.framework.log.LoggerFactory; 047 048 import com.vividsolutions.jts.geom.PrecisionModel; 049 050 /** 051 * Adapter between deegree-<tt>Geometry</tt>s and JTS-<tt>Geometry<tt> objects. 052 * <p> 053 * Please note that the generated deegree-objects use null as 054 * <tt>CS_CoordinateSystem</tt>! 055 * <p> 056 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider</a> 057 * @version $Revision: 9343 $ $Date: 2007-12-27 14:30:32 +0100 (Do, 27 Dez 2007) $ 058 */ 059 public class JTSAdapter { 060 061 private static final ILogger LOG = LoggerFactory.getLogger( JTSAdapter.class ); 062 063 // precision model that is used for all JTS-Geometries 064 private static PrecisionModel pm = new PrecisionModel(); 065 066 // factory for creating JTS-Geometries 067 private static com.vividsolutions.jts.geom.GeometryFactory jtsFactory = new com.vividsolutions.jts.geom.GeometryFactory( 068 pm, 069 0 ); 070 071 /** 072 * Converts a <tt>Geometry</tt> to a corresponding JTS-<tt>Geometry</tt> object. 073 * <p> 074 * Currently, the following conversions are supported: 075 * <ul> 076 * <li>Point -> Point 077 * <li>MultiPoint -> MultiPoint 078 * <li>Curve -> LineString 079 * <li>MultiCurve -> MultiLineString 080 * <li>Surface -> Polygon 081 * <li>MultiSurface -> MultiPolygon 082 * <li>MultiPrimitive -> GeometryCollection 083 * </ul> 084 * <p> 085 * 086 * @param gmObject 087 * the object to be converted 088 * @return the corresponding JTS-<tt>Geometry</tt> object 089 * @throws GeometryException 090 * if type unsupported or conversion failed 091 */ 092 public static com.vividsolutions.jts.geom.Geometry export( Geometry gmObject ) 093 throws GeometryException { 094 095 com.vividsolutions.jts.geom.Geometry geometry = null; 096 if ( gmObject instanceof Point ) { 097 geometry = export( (Point) gmObject ); 098 } else if ( gmObject instanceof MultiPoint ) { 099 geometry = export( (MultiPoint) gmObject ); 100 } else if ( gmObject instanceof Curve ) { 101 geometry = export( (Curve) gmObject ); 102 } else if ( gmObject instanceof MultiCurve ) { 103 geometry = export( (MultiCurve) gmObject ); 104 } else if ( gmObject instanceof Surface ) { 105 geometry = export( (Surface) gmObject ); 106 } else if ( gmObject instanceof MultiSurface ) { 107 geometry = export( (MultiSurface) gmObject ); 108 } else if ( gmObject instanceof MultiPrimitive ) { 109 geometry = export( (MultiPrimitive) gmObject ); 110 } else { 111 throw new GeometryException( "JTSAdapter.export does not support type '" + gmObject.getClass().getName() 112 + "'!" ); 113 } 114 return geometry; 115 } 116 117 /** 118 * Converts a JTS-<tt>Geometry</tt> object to a corresponding <tt>Geometry</tt>. 119 * <p> 120 * Currently, the following conversions are supported: 121 * <ul> 122 * <li>Point -> Point 123 * <li>MultiPoint -> MultiPoint 124 * <li>LineString -> Curve 125 * <li>MultiLineString -> MultiCurve 126 * <li>Polygon -> Surface 127 * <li>MultiPolygon -> MultiSurface 128 * <li>GeometryCollection -> MultiPrimitive 129 * </ul> 130 * <p> 131 * 132 * @param geometry 133 * the JTS-<tt>Geometry</tt> to be converted 134 * @return the corresponding <tt>Geometry</tt> 135 * @throws GeometryException 136 * if type unsupported or conversion failed 137 */ 138 public static Geometry wrap( com.vividsolutions.jts.geom.Geometry geometry ) 139 throws GeometryException { 140 141 Geometry gmObject = null; 142 if ( geometry instanceof com.vividsolutions.jts.geom.Point ) { 143 gmObject = wrap( (com.vividsolutions.jts.geom.Point) geometry ); 144 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPoint ) { 145 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPoint) geometry ); 146 } else if ( geometry instanceof com.vividsolutions.jts.geom.LineString ) { 147 gmObject = wrap( (com.vividsolutions.jts.geom.LineString) geometry ); 148 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiLineString ) { 149 gmObject = wrap( (com.vividsolutions.jts.geom.MultiLineString) geometry ); 150 } else if ( geometry instanceof com.vividsolutions.jts.geom.Polygon ) { 151 gmObject = wrap( (com.vividsolutions.jts.geom.Polygon) geometry ); 152 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPolygon ) { 153 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPolygon) geometry ); 154 } else if ( geometry instanceof com.vividsolutions.jts.geom.GeometryCollection ) { 155 gmObject = wrap( (com.vividsolutions.jts.geom.GeometryCollection) geometry ); 156 } else { 157 throw new GeometryException( "JTSAdapter.wrap does not support type '" + geometry.getClass().getName() 158 + "'!" ); 159 } 160 return gmObject; 161 } 162 163 /** 164 * Converts a <tt>Point</tt> to a <tt>Point</tt>. 165 * <p> 166 * 167 * @param gmPoint 168 * point to be converted 169 * @return the corresponding <tt>Point</tt> object 170 */ 171 private static com.vividsolutions.jts.geom.Point export( Point gmPoint ) { 172 173 com.vividsolutions.jts.geom.Coordinate coord = new com.vividsolutions.jts.geom.Coordinate( gmPoint.getX(), 174 gmPoint.getY() ); 175 176 return jtsFactory.createPoint( coord ); 177 } 178 179 /** 180 * Converts a <tt>MultiPoint</tt> to a <tt>MultiPoint</tt>. 181 * <p> 182 * 183 * @param gmMultiPoint 184 * multipoint to be converted 185 * @return the corresponding <tt>MultiPoint</tt> object 186 */ 187 private static com.vividsolutions.jts.geom.MultiPoint export( MultiPoint gmMultiPoint ) { 188 Point[] gmPoints = gmMultiPoint.getAllPoints(); 189 com.vividsolutions.jts.geom.Point[] points = new com.vividsolutions.jts.geom.Point[gmPoints.length]; 190 for ( int i = 0; i < points.length; i++ ) { 191 points[i] = export( gmPoints[i] ); 192 } 193 return jtsFactory.createMultiPoint( points ); 194 } 195 196 /** 197 * Converts a <tt>Curve</tt> to a <tt>LineString</tt>. 198 * <p> 199 * 200 * @param curve 201 * <tt>Curve</tt> to be converted 202 * @return the corresponding <tt>LineString</tt> object 203 * @throws GeometryException 204 */ 205 private static com.vividsolutions.jts.geom.LineString export( Curve curve ) 206 throws GeometryException { 207 208 LineString lineString = curve.getAsLineString(); 209 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[lineString.getNumberOfPoints()]; 210 for ( int i = 0; i < coords.length; i++ ) { 211 Position position = lineString.getPositionAt( i ); 212 coords[i] = new com.vividsolutions.jts.geom.Coordinate( position.getX(), position.getY() ); 213 } 214 return jtsFactory.createLineString( coords ); 215 } 216 217 /** 218 * Converts a <tt>MultiCurve</tt> to a <tt>MultiLineString</tt>. 219 * <p> 220 * 221 * @param multi 222 * <tt>MultiCurve</tt> to be converted 223 * @return the corresponding <tt>MultiLineString</tt> object 224 * @throws GeometryException 225 */ 226 private static com.vividsolutions.jts.geom.MultiLineString export( MultiCurve multi ) 227 throws GeometryException { 228 229 Curve[] curves = multi.getAllCurves(); 230 com.vividsolutions.jts.geom.LineString[] lineStrings = new com.vividsolutions.jts.geom.LineString[curves.length]; 231 for ( int i = 0; i < curves.length; i++ ) { 232 lineStrings[i] = export( curves[i] ); 233 } 234 return jtsFactory.createMultiLineString( lineStrings ); 235 } 236 237 /** 238 * Converts an array of <tt>Position</tt>s to a <tt>LinearRing</tt>. 239 * <p> 240 * 241 * @param positions 242 * an array of <tt>Position</tt>s 243 * @return the corresponding <tt>LinearRing</tt> object 244 */ 245 public static com.vividsolutions.jts.geom.LinearRing export( Position[] positions ) { 246 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[positions.length]; 247 for ( int i = 0; i < positions.length; i++ ) { 248 coords[i] = new com.vividsolutions.jts.geom.Coordinate( positions[i].getX(), positions[i].getY() ); 249 } 250 return jtsFactory.createLinearRing( coords ); 251 } 252 253 /** 254 * Converts a <tt>Surface</tt> to a <tt>Polygon</tt>. 255 * <p> 256 * Currently, the <tt>Surface</tt> _must_ contain exactly one patch! 257 * <p> 258 * 259 * @param surface 260 * a <tt>Surface</tt> 261 * @return the corresponding <tt>Polygon</tt> object 262 */ 263 private static com.vividsolutions.jts.geom.Polygon export( Surface surface ) { 264 SurfacePatch patch = null; 265 try { 266 patch = surface.getSurfacePatchAt( 0 ); 267 } catch ( GeometryException e ) { 268 LOG.logError( "", e ); 269 } 270 Position[] exteriorRing = patch.getExteriorRing(); 271 Position[][] interiorRings = patch.getInteriorRings(); 272 273 com.vividsolutions.jts.geom.LinearRing shell = export( exteriorRing ); 274 com.vividsolutions.jts.geom.LinearRing[] holes = new com.vividsolutions.jts.geom.LinearRing[0]; 275 if ( interiorRings != null ) 276 holes = new com.vividsolutions.jts.geom.LinearRing[interiorRings.length]; 277 for ( int i = 0; i < holes.length; i++ ) { 278 holes[i] = export( interiorRings[i] ); 279 } 280 return jtsFactory.createPolygon( shell, holes ); 281 } 282 283 /** 284 * Converts a <tt>MultiSurface</tt> to a <tt>MultiPolygon</tt>. 285 * <p> 286 * Currently, the contained <tt>Surface</tt> _must_ have exactly one patch! 287 * <p> 288 * 289 * @param msurface 290 * a <tt>MultiSurface</tt> 291 * @return the corresponding <tt>MultiPolygon</tt> object 292 */ 293 private static com.vividsolutions.jts.geom.MultiPolygon export( MultiSurface msurface ) { 294 295 Surface[] surfaces = msurface.getAllSurfaces(); 296 com.vividsolutions.jts.geom.Polygon[] polygons = new com.vividsolutions.jts.geom.Polygon[surfaces.length]; 297 298 for ( int i = 0; i < surfaces.length; i++ ) { 299 polygons[i] = export( surfaces[i] ); 300 } 301 return jtsFactory.createMultiPolygon( polygons ); 302 } 303 304 /** 305 * Converts a <tt>MultiPrimitive</tt> to a <tt>GeometryCollection</tt>. 306 * <p> 307 * 308 * @param multi 309 * a <tt>MultiPrimtive</tt> 310 * @return the corresponding <tt>GeometryCollection</tt> object 311 * @throws GeometryException 312 */ 313 private static com.vividsolutions.jts.geom.GeometryCollection export( MultiPrimitive multi ) 314 throws GeometryException { 315 316 Geometry[] primitives = multi.getAllPrimitives(); 317 com.vividsolutions.jts.geom.Geometry[] geometries = new com.vividsolutions.jts.geom.Geometry[primitives.length]; 318 319 for ( int i = 0; i < primitives.length; i++ ) { 320 geometries[i] = export( primitives[i] ); 321 } 322 return jtsFactory.createGeometryCollection( geometries ); 323 } 324 325 /** 326 * Converts a <tt>Point</tt> to a <tt>Point</tt>s. 327 * <p> 328 * 329 * @param point 330 * a <tt>Point</tt> object 331 * @return the corresponding <tt>Point</tt> 332 */ 333 private static Point wrap( com.vividsolutions.jts.geom.Point point ) { 334 com.vividsolutions.jts.geom.Coordinate coord = point.getCoordinate(); 335 return Double.isNaN( coord.z ) ? new PointImpl( coord.x, coord.y, null ) : new PointImpl( coord.x, coord.y, 336 coord.z, null ); 337 } 338 339 /** 340 * Converts a <tt>MultiPoint</tt> to a <tt>MultiPoint</tt>. 341 * <p> 342 * 343 * @param multi 344 * a <tt>MultiPoint</tt> object 345 * @return the corresponding <tt>MultiPoint</tt> 346 */ 347 private static MultiPoint wrap( com.vividsolutions.jts.geom.MultiPoint multi ) { 348 Point[] gmPoints = new Point[multi.getNumGeometries()]; 349 for ( int i = 0; i < gmPoints.length; i++ ) { 350 gmPoints[i] = wrap( (com.vividsolutions.jts.geom.Point) multi.getGeometryN( i ) ); 351 } 352 return new MultiPointImpl( gmPoints, null ); 353 } 354 355 /** 356 * Converts a <tt>LineString</tt> to a <tt>Curve</tt>. 357 * <p> 358 * 359 * @param line 360 * a <tt>LineString</tt> object 361 * @return the corresponding <tt>Curve</tt> 362 * @throws GeometryException 363 */ 364 private static Curve wrap( com.vividsolutions.jts.geom.LineString line ) 365 throws GeometryException { 366 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 367 Position[] positions = new Position[coords.length]; 368 for ( int i = 0; i < coords.length; i++ ) { 369 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 370 } 371 return GeometryFactory.createCurve( positions, null ); 372 } 373 374 /** 375 * Converts a <tt>MultiLineString</tt> to a <tt>MultiCurve</tt>. 376 * <p> 377 * 378 * @param multi 379 * a <tt>MultiLineString</tt> object 380 * @return the corresponding <tt>MultiCurve</tt> 381 * @throws GeometryException 382 */ 383 private static MultiCurve wrap( com.vividsolutions.jts.geom.MultiLineString multi ) 384 throws GeometryException { 385 Curve[] curves = new Curve[multi.getNumGeometries()]; 386 for ( int i = 0; i < curves.length; i++ ) { 387 curves[i] = wrap( (com.vividsolutions.jts.geom.LineString) multi.getGeometryN( i ) ); 388 } 389 return GeometryFactory.createMultiCurve( curves ); 390 } 391 392 /** 393 * 394 * Converts a <tt>Polygon</tt> to a <tt>Surface</tt>. 395 * <p> 396 * 397 * @param polygon 398 * a <tt>Polygon</tt> 399 * @return the corresponding <tt>Surface</tt> object 400 * @throws GeometryException 401 */ 402 private static Surface wrap( com.vividsolutions.jts.geom.Polygon polygon ) 403 throws GeometryException { 404 405 Position[] exteriorRing = createGMPositions( polygon.getExteriorRing() ); 406 Position[][] interiorRings = new Position[polygon.getNumInteriorRing()][]; 407 408 for ( int i = 0; i < interiorRings.length; i++ ) { 409 interiorRings[i] = createGMPositions( polygon.getInteriorRingN( i ) ); 410 } 411 SurfacePatch patch = new PolygonImpl( new SurfaceInterpolationImpl(), exteriorRing, interiorRings, null ); 412 413 return new SurfaceImpl( patch ); 414 } 415 416 /** 417 * Converts a <tt>MultiPolygon</tt> to a <tt>MultiSurface</tt>. 418 * <p> 419 * 420 * @param multiPolygon 421 * a <tt>MultiPolygon</tt> 422 * @return the corresponding <tt>MultiSurface</tt> object 423 * @throws GeometryException 424 */ 425 private static MultiSurface wrap( com.vividsolutions.jts.geom.MultiPolygon multiPolygon ) 426 throws GeometryException { 427 428 Surface[] surfaces = new Surface[multiPolygon.getNumGeometries()]; 429 for ( int i = 0; i < surfaces.length; i++ ) { 430 surfaces[i] = wrap( (com.vividsolutions.jts.geom.Polygon) multiPolygon.getGeometryN( i ) ); 431 } 432 return new MultiSurfaceImpl( surfaces ); 433 } 434 435 /** 436 * Converts a <tt>GeometryCollection</tt> to a <tt>MultiPrimitve</tt>. 437 * <p> 438 * 439 * @param collection 440 * a <tt>GeometryCollection</tt> 441 * @return the corresponding <tt>MultiPrimitive</tt> object 442 * @throws GeometryException 443 */ 444 private static MultiPrimitive wrap( com.vividsolutions.jts.geom.GeometryCollection collection ) 445 throws GeometryException { 446 447 MultiPrimitive multi = new MultiPrimitiveImpl( null ); 448 for ( int i = 0; i < collection.getNumGeometries(); i++ ) { 449 multi.add( wrap( collection.getGeometryN( i ) ) ); 450 } 451 return multi; 452 } 453 454 /** 455 * Converts a <tt>LineString</tt> to an array of <tt>Position</tt>s. 456 * <p> 457 * 458 * @param line 459 * a <tt>LineString</tt> object 460 * @return the corresponding array of <tt>Position</tt>s 461 */ 462 private static Position[] createGMPositions( com.vividsolutions.jts.geom.LineString line ) { 463 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 464 Position[] positions = new Position[coords.length]; 465 for ( int i = 0; i < coords.length; i++ ) { 466 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 467 } 468 return positions; 469 } 470 }