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 }