001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/JTSAdapter.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 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: 6259 $ $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 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> 073 * object. 074 * <p> 075 * Currently, the following conversions are supported: 076 * <ul> 077 * <li>Point -> Point 078 * <li>MultiPoint -> MultiPoint 079 * <li>Curve -> LineString 080 * <li>MultiCurve -> MultiLineString 081 * <li>Surface -> Polygon 082 * <li>MultiSurface -> MultiPolygon 083 * <li>MultiPrimitive -> GeometryCollection 084 * </ul> 085 * <p> 086 * @param gmObject the object to be converted 087 * @return the corresponding JTS-<tt>Geometry</tt> object 088 * @throws GeometryException if type unsupported or conversion failed 089 */ 090 public static com.vividsolutions.jts.geom.Geometry export( Geometry gmObject ) 091 throws GeometryException { 092 093 com.vividsolutions.jts.geom.Geometry geometry = null; 094 if ( gmObject instanceof Point ) { 095 geometry = export( (Point) gmObject ); 096 } else if ( gmObject instanceof MultiPoint ) { 097 geometry = export( (MultiPoint) gmObject ); 098 } else if ( gmObject instanceof Curve ) { 099 geometry = export( (Curve) gmObject ); 100 } else if ( gmObject instanceof MultiCurve ) { 101 geometry = export( (MultiCurve) gmObject ); 102 } else if ( gmObject instanceof Surface ) { 103 geometry = export( (Surface) gmObject ); 104 } else if ( gmObject instanceof MultiSurface ) { 105 geometry = export( (MultiSurface) gmObject ); 106 } else if ( gmObject instanceof MultiPrimitive ) { 107 geometry = export( (MultiPrimitive) gmObject ); 108 } else { 109 throw new GeometryException( "JTSAdapter.export does not support type '" 110 + gmObject.getClass().getName() + "'!" ); 111 } 112 return geometry; 113 } 114 115 /** 116 * Converts a JTS-<tt>Geometry</tt> object to a corresponding 117 * <tt>Geometry</tt>. 118 * <p> 119 * Currently, the following conversions are supported: 120 * <ul> 121 * <li>Point -> Point 122 * <li>MultiPoint -> MultiPoint 123 * <li>LineString -> Curve 124 * <li>MultiLineString -> MultiCurve 125 * <li>Polygon -> Surface 126 * <li>MultiPolygon -> MultiSurface 127 * <li>GeometryCollection -> MultiPrimitive 128 * </ul> 129 * <p> 130 * @param geometry the JTS-<tt>Geometry</tt> to be converted 131 * @return the corresponding <tt>Geometry</tt> 132 * @throws GeometryException if type unsupported or conversion failed 133 */ 134 public static Geometry wrap( com.vividsolutions.jts.geom.Geometry geometry ) 135 throws GeometryException { 136 137 Geometry gmObject = null; 138 if ( geometry instanceof com.vividsolutions.jts.geom.Point ) { 139 gmObject = wrap( (com.vividsolutions.jts.geom.Point) geometry ); 140 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPoint ) { 141 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPoint) geometry ); 142 } else if ( geometry instanceof com.vividsolutions.jts.geom.LineString ) { 143 gmObject = wrap( (com.vividsolutions.jts.geom.LineString) geometry ); 144 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiLineString ) { 145 gmObject = wrap( (com.vividsolutions.jts.geom.MultiLineString) geometry ); 146 } else if ( geometry instanceof com.vividsolutions.jts.geom.Polygon ) { 147 gmObject = wrap( (com.vividsolutions.jts.geom.Polygon) geometry ); 148 } else if ( geometry instanceof com.vividsolutions.jts.geom.MultiPolygon ) { 149 gmObject = wrap( (com.vividsolutions.jts.geom.MultiPolygon) geometry ); 150 } else if ( geometry instanceof com.vividsolutions.jts.geom.GeometryCollection ) { 151 gmObject = wrap( (com.vividsolutions.jts.geom.GeometryCollection) geometry ); 152 } else { 153 throw new GeometryException( "JTSAdapter.wrap does not support type '" 154 + geometry.getClass().getName() + "'!" ); 155 } 156 return gmObject; 157 } 158 159 /** 160 * Converts a <tt>Point</tt> to a <tt>Point</tt>. 161 * <p> 162 * @param gmPoint point to be converted 163 * @return the corresponding <tt>Point</tt> object 164 */ 165 private static com.vividsolutions.jts.geom.Point export( Point gmPoint ) { 166 167 com.vividsolutions.jts.geom.Coordinate coord = 168 new com.vividsolutions.jts.geom.Coordinate(gmPoint.getX(),gmPoint.getY() ); 169 170 return jtsFactory.createPoint( coord ); 171 } 172 173 /** 174 * Converts a <tt>MultiPoint</tt> to a <tt>MultiPoint</tt>. 175 * <p> 176 * @param gmMultiPoint multipoint to be converted 177 * @return the corresponding <tt>MultiPoint</tt> object 178 */ 179 private static com.vividsolutions.jts.geom.MultiPoint export( MultiPoint gmMultiPoint ) { 180 Point[] gmPoints = gmMultiPoint.getAllPoints(); 181 com.vividsolutions.jts.geom.Point[] points = new com.vividsolutions.jts.geom.Point[gmPoints.length]; 182 for ( int i = 0; i < points.length; i++ ) { 183 points[i] = export( gmPoints[i] ); 184 } 185 return jtsFactory.createMultiPoint( points ); 186 } 187 188 /** 189 * Converts a <tt>Curve</tt> to a <tt>LineString</tt>. 190 * <p> 191 * @param curve <tt>Curve</tt> to be converted 192 * @return the corresponding <tt>LineString</tt> object 193 * @throws GeometryException 194 */ 195 private static com.vividsolutions.jts.geom.LineString export( Curve curve ) 196 throws GeometryException { 197 198 LineString lineString = curve.getAsLineString(); 199 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[lineString.getNumberOfPoints()]; 200 for ( int i = 0; i < coords.length; i++ ) { 201 Position position = lineString.getPositionAt( i ); 202 coords[i] = new com.vividsolutions.jts.geom.Coordinate( position.getX(), 203 position.getY() ); 204 } 205 return jtsFactory.createLineString( coords ); 206 } 207 208 /** 209 * Converts a <tt>MultiCurve</tt> to a <tt>MultiLineString</tt>. 210 * <p> 211 * @param multi <tt>MultiCurve</tt> to be converted 212 * @return the corresponding <tt>MultiLineString</tt> object 213 * @throws GeometryException 214 */ 215 private static com.vividsolutions.jts.geom.MultiLineString export( MultiCurve multi ) 216 throws GeometryException { 217 218 Curve[] curves = multi.getAllCurves(); 219 com.vividsolutions.jts.geom.LineString[] lineStrings = new com.vividsolutions.jts.geom.LineString[curves.length]; 220 for ( int i = 0; i < curves.length; i++ ) { 221 lineStrings[i] = export( curves[i] ); 222 } 223 return jtsFactory.createMultiLineString( lineStrings ); 224 } 225 226 /** 227 * Converts an array of <tt>Position</tt>s to a <tt>LinearRing</tt>. 228 * <p> 229 * @param positions an array of <tt>Position</tt>s 230 * @return the corresponding <tt>LinearRing</tt> object 231 */ 232 public static com.vividsolutions.jts.geom.LinearRing export( Position[] positions ) { 233 com.vividsolutions.jts.geom.Coordinate[] coords = new com.vividsolutions.jts.geom.Coordinate[positions.length]; 234 for ( int i = 0; i < positions.length; i++ ) { 235 coords[i] = new com.vividsolutions.jts.geom.Coordinate( positions[i].getX(), 236 positions[i].getY() ); 237 } 238 return jtsFactory.createLinearRing( coords ); 239 } 240 241 /** 242 * Converts a <tt>Surface</tt> to a <tt>Polygon</tt>. 243 * <p> 244 * Currently, the <tt>Surface</tt> _must_ contain exactly one patch! 245 * <p> 246 * @param surface a <tt>Surface</tt> 247 * @return the corresponding <tt>Polygon</tt> object 248 */ 249 private static com.vividsolutions.jts.geom.Polygon export( Surface surface ) { 250 SurfacePatch patch = null; 251 try { 252 patch = surface.getSurfacePatchAt( 0 ); 253 } catch ( GeometryException e ) { 254 LOG.logError( "", e ); 255 } 256 Position[] exteriorRing = patch.getExteriorRing(); 257 Position[][] interiorRings = patch.getInteriorRings(); 258 259 com.vividsolutions.jts.geom.LinearRing shell = export( exteriorRing ); 260 com.vividsolutions.jts.geom.LinearRing[] holes = new com.vividsolutions.jts.geom.LinearRing[0]; 261 if ( interiorRings != null ) 262 holes = new com.vividsolutions.jts.geom.LinearRing[interiorRings.length]; 263 for ( int i = 0; i < holes.length; i++ ) { 264 holes[i] = export( interiorRings[i] ); 265 } 266 return jtsFactory.createPolygon( shell, holes ); 267 } 268 269 /** 270 * Converts a <tt>MultiSurface</tt> to a <tt>MultiPolygon</tt>. 271 * <p> 272 * Currently, the contained <tt>Surface</tt> _must_ have exactly one 273 * patch! 274 * <p> 275 * @param msurface a <tt>MultiSurface</tt> 276 * @return the corresponding <tt>MultiPolygon</tt> object 277 */ 278 private static com.vividsolutions.jts.geom.MultiPolygon export( MultiSurface msurface ) { 279 280 Surface[] surfaces = msurface.getAllSurfaces(); 281 com.vividsolutions.jts.geom.Polygon[] polygons = new com.vividsolutions.jts.geom.Polygon[surfaces.length]; 282 283 for ( int i = 0; i < surfaces.length; i++ ) { 284 polygons[i] = export( surfaces[i] ); 285 } 286 return jtsFactory.createMultiPolygon( polygons ); 287 } 288 289 /** 290 * Converts a <tt>MultiPrimitive</tt> to a <tt>GeometryCollection</tt>. 291 * <p> 292 * @param multi a <tt>MultiPrimtive</tt> 293 * @return the corresponding <tt>GeometryCollection</tt> object 294 * @throws GeometryException 295 */ 296 private static com.vividsolutions.jts.geom.GeometryCollection export( MultiPrimitive multi ) 297 throws GeometryException { 298 299 Geometry[] primitives = multi.getAllPrimitives(); 300 com.vividsolutions.jts.geom.Geometry[] geometries = new com.vividsolutions.jts.geom.Geometry[primitives.length]; 301 302 for ( int i = 0; i < primitives.length; i++ ) { 303 geometries[i] = export( primitives[i] ); 304 } 305 return jtsFactory.createGeometryCollection( geometries ); 306 } 307 308 /** 309 * Converts a <tt>Point</tt> to a <tt>Point</tt>s. 310 * <p> 311 * @param point a <tt>Point</tt> object 312 * @return the corresponding <tt>Point</tt> 313 */ 314 private static Point wrap( com.vividsolutions.jts.geom.Point point ) { 315 com.vividsolutions.jts.geom.Coordinate coord = point.getCoordinate(); 316 return Double.isNaN( coord.z ) ? new PointImpl( coord.x, coord.y, null ) 317 : new PointImpl( coord.x, coord.y, coord.z, null ); 318 } 319 320 /** 321 * Converts a <tt>MultiPoint</tt> to a <tt>MultiPoint</tt>. 322 * <p> 323 * @param multi a <tt>MultiPoint</tt> object 324 * @return the corresponding <tt>MultiPoint</tt> 325 */ 326 private static MultiPoint wrap( com.vividsolutions.jts.geom.MultiPoint multi ) { 327 Point[] gmPoints = new Point[multi.getNumGeometries()]; 328 for ( int i = 0; i < gmPoints.length; i++ ) { 329 gmPoints[i] = wrap( (com.vividsolutions.jts.geom.Point) multi.getGeometryN( i ) ); 330 } 331 return new MultiPointImpl( gmPoints, null ); 332 } 333 334 /** 335 * Converts a <tt>LineString</tt> to a <tt>Curve</tt>. 336 * <p> 337 * @param line a <tt>LineString</tt> object 338 * @return the corresponding <tt>Curve</tt> 339 * @throws GeometryException 340 */ 341 private static Curve wrap( com.vividsolutions.jts.geom.LineString line ) 342 throws GeometryException { 343 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 344 Position[] positions = new Position[coords.length]; 345 for ( int i = 0; i < coords.length; i++ ) { 346 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 347 } 348 return GeometryFactory.createCurve( positions, null ); 349 } 350 351 /** 352 * Converts a <tt>MultiLineString</tt> to a <tt>MultiCurve</tt>. 353 * <p> 354 * @param multi a <tt>MultiLineString</tt> object 355 * @return the corresponding <tt>MultiCurve</tt> 356 * @throws GeometryException 357 */ 358 private static MultiCurve wrap( com.vividsolutions.jts.geom.MultiLineString multi ) 359 throws GeometryException { 360 Curve[] curves = new Curve[multi.getNumGeometries()]; 361 for ( int i = 0; i < curves.length; i++ ) { 362 curves[i] = wrap( (com.vividsolutions.jts.geom.LineString) multi.getGeometryN( i ) ); 363 } 364 return GeometryFactory.createMultiCurve( curves ); 365 } 366 367 /** 368 * 369 * Converts a <tt>Polygon</tt> to a <tt>Surface</tt>. 370 * <p> 371 * @param polygon a <tt>Polygon</tt> 372 * @return the corresponding <tt>Surface</tt> object 373 * @throws GeometryException 374 */ 375 private static Surface wrap( com.vividsolutions.jts.geom.Polygon polygon ) 376 throws GeometryException { 377 378 Position[] exteriorRing = createGMPositions( polygon.getExteriorRing() ); 379 Position[][] interiorRings = new Position[polygon.getNumInteriorRing()][]; 380 381 for ( int i = 0; i < interiorRings.length; i++ ) { 382 interiorRings[i] = createGMPositions( polygon.getInteriorRingN( i ) ); 383 } 384 SurfacePatch patch = new PolygonImpl( new SurfaceInterpolationImpl(), exteriorRing, 385 interiorRings, null ); 386 387 return new SurfaceImpl( patch ); 388 } 389 390 /** 391 * Converts a <tt>MultiPolygon</tt> to a <tt>MultiSurface</tt>. 392 * <p> 393 * @param multiPolygon a <tt>MultiPolygon</tt> 394 * @return the corresponding <tt>MultiSurface</tt> object 395 * @throws GeometryException 396 */ 397 private static MultiSurface wrap( com.vividsolutions.jts.geom.MultiPolygon multiPolygon ) 398 throws GeometryException { 399 400 Surface[] surfaces = new Surface[multiPolygon.getNumGeometries()]; 401 for ( int i = 0; i < surfaces.length; i++ ) { 402 surfaces[i] = wrap( (com.vividsolutions.jts.geom.Polygon) multiPolygon.getGeometryN( i ) ); 403 } 404 return new MultiSurfaceImpl( surfaces ); 405 } 406 407 /** 408 * Converts a <tt>GeometryCollection</tt> to a <tt>MultiPrimitve</tt>. 409 * <p> 410 * @param collection a <tt>GeometryCollection</tt> 411 * @return the corresponding <tt>MultiPrimitive</tt> object 412 * @throws GeometryException 413 */ 414 private static MultiPrimitive wrap( com.vividsolutions.jts.geom.GeometryCollection collection ) 415 throws GeometryException { 416 417 MultiPrimitive multi = new MultiPrimitiveImpl( null ); 418 for ( int i = 0; i < collection.getNumGeometries(); i++ ) { 419 multi.add( wrap( collection.getGeometryN( i ) ) ); 420 } 421 return multi; 422 } 423 424 /** 425 * Converts a <tt>LineString</tt> to an array of <tt>Position</tt>s. 426 * <p> 427 * @param line a <tt>LineString</tt> object 428 * @return the corresponding array of <tt>Position</tt>s 429 */ 430 private static Position[] createGMPositions( com.vividsolutions.jts.geom.LineString line ) { 431 com.vividsolutions.jts.geom.Coordinate[] coords = line.getCoordinates(); 432 Position[] positions = new Position[coords.length]; 433 for ( int i = 0; i < coords.length; i++ ) { 434 positions[i] = new PositionImpl( coords[i].x, coords[i].y ); 435 } 436 return positions; 437 } 438 } 439 /* ******************************************************************** 440 Changes to this class. What the people have been up to: 441 $Log$ 442 Revision 1.13 2007/02/27 13:04:08 schmitz 443 Made a useful method public. 444 445 Revision 1.12 2006/11/27 09:07:51 poth 446 JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code. 447 448 Revision 1.11 2006/07/04 18:31:35 poth 449 bug fix handling GeometryCollections 450 451 452 ********************************************************************** */