001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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 (Thu, 01 Oct 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 }