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 ********************************************************************** */