    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/io/datastore/sql/postgis/PGgeometryAdapter.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
    037    package org.deegree.io.datastore.sql.postgis;
    038
    039    import java.sql.SQLException;
    040    import java.util.ArrayList;
    041    import java.util.Iterator;
    042    import java.util.List;
    043
    044    import org.deegree.model.crs.CoordinateSystem;
    045    import org.deegree.model.spatialschema.Curve;
    046    import org.deegree.model.spatialschema.Envelope;
    047    import org.deegree.model.spatialschema.Geometry;
    048    import org.deegree.model.spatialschema.GeometryException;
    049    import org.deegree.model.spatialschema.GeometryFactory;
    050    import org.deegree.model.spatialschema.MultiCurve;
    051    import org.deegree.model.spatialschema.MultiGeometry;
    052    import org.deegree.model.spatialschema.MultiPoint;
    053    import org.deegree.model.spatialschema.MultiSurface;
    054    import org.deegree.model.spatialschema.Point;
    055    import org.deegree.model.spatialschema.Position;
    056    import org.deegree.model.spatialschema.Surface;
    057    import org.deegree.model.spatialschema.SurfaceInterpolationImpl;
    058    import org.deegree.model.spatialschema.WKTAdapter;
    059    import org.postgis.GeometryCollection;
    060    import org.postgis.LineString;
    061    import org.postgis.MultiLineString;
    062    import org.postgis.MultiPolygon;
    063    import org.postgis.PGbox3d;
    064    import org.postgis.PGboxbase;
    065    import org.postgis.PGgeometry;
    066    import org.postgis.Polygon;
    067
    068    /**
    069     * Adapter between deegree <code>Geometry</code> objects and PostGIS <code>Geometry</code> objects.
    070     *
    071     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </A>
    072     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
    073     *
    074     * @author last edited by: $Author: mschneider $
    075     *
    076     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    077     */
    078    public class PGgeometryAdapter {
    079
    080        private PGgeometryAdapter() {
    081            // avoid instantiation
    082        }
    083
    084        /**
    085         * Converts a deegree <code>Geometry</code> instance to a corresponding PostGIS {@link PGgeometry} object.
    086         *
    087         * @param geometry
    088         *            deegree <code>Geometry</code> to be converted
    089         * @param srid
    090         *            PostGIS SRS id that is used to store the geometry
    091         * @return corresponding PostGIS <code>Geometry</code>
    092         * @throws GeometryException
    093         */
    094        public static PGgeometry export( Geometry geometry, int srid )
    095                                throws GeometryException {
    096            PGgeometry pgGeometry = null;
    097            if ( geometry instanceof Point ) {
    098                pgGeometry = exportPoint( (Point) geometry, srid );
    099            } else if ( geometry instanceof MultiPoint ) {
    100                pgGeometry = exportMultiPoint( (MultiPoint) geometry, srid );
    101            } else if ( geometry instanceof Curve ) {
    102                pgGeometry = exportCurve( (Curve) geometry, srid );
    103            } else if ( geometry instanceof MultiCurve ) {
    104                pgGeometry = exportMultiCurve( (MultiCurve) geometry, srid );
    105            } else if ( geometry instanceof Surface ) {
    106                pgGeometry = exportSurface( (Surface) geometry, srid );
    107            } else if ( geometry instanceof MultiSurface ) {
    108                pgGeometry = exportMultiSurface( (MultiSurface) geometry, srid );
    109            } else if ( geometry instanceof MultiGeometry ) {
    110                pgGeometry = exportMultiGeometry( (MultiGeometry) geometry, srid );
    111            } else {
    112                throw new GeometryException( "Cannot export geometry of type '" + geometry.getClass()
    113                                             + "' to PostGIS geometry: Unsupported type." );
    114            }
    115            return pgGeometry;
    116        }
    117
    118        /**
    119         * Converts a deegree <code>Envelope</code> instance to a corresponding PostGIS <code>PGboxbase</code> object.
    120         *
    121         * @param envelope
    122         *            deegree <code>Envelope</code> to be converted
    123         * @return corresponding PostGIS <code>PGboxbase</code>
    124         * @throws GeometryException
    125         */
    126        public static PGboxbase export( Envelope envelope )
    127                                throws GeometryException {
    128            StringBuffer sb = WKTAdapter.export( envelope );
    129            PGbox3d box = null;
    130            try {
    131                box = new PGbox3d( sb.toString() );
    132            } catch ( Exception e ) {
    133                throw new GeometryException( e.toString() );
    134            }
    135
    136            return box;
    137        }
    138
    139        /**
    140         * Converts a PostGIS <code>PGGeometry</code> instance to a corresponding deegree <code>Geometry</code> object.
    141         *
    142         * @param pgGeometry
    143         *            PostGIS <code>PGgeometry</code> to be converted
    144         * @param crs
    145         *            coordinate system of the created deegree <code>Geometry</code> object
    146         * @return corresponding deegree <code>Geometry</code>
    147         * @throws GeometryException
    148         */
    149        public static Geometry wrap( PGgeometry pgGeometry, CoordinateSystem crs )
    150                                throws GeometryException {
    151            return wrap( pgGeometry.getGeometry(), crs );
    152        }
    153
    154        /**
    155         * Converts a PostGIS <code>Geometry</code> instance to a corresponding deegree <code>Geometry</code> object.
    156         *
    157         * @param geometry
    158         *            PostGIS <code>PGgeometry</code> to be converted
    159         * @param crs
    160         *            coordinate system of the created deegree <code>Geometry</code> object
    161         * @return corresponding deegree <code>Geometry</code>
    162         * @throws GeometryException
    163         */
    164        public static Geometry wrap( org.postgis.Geometry geometry, CoordinateSystem crs )
    165                                throws GeometryException {
    166            Geometry geo = null;
    167
    168            switch ( geometry.type ) {
    169            case org.postgis.Geometry.POINT:
    170                geo = wrapPoint( (org.postgis.Point) geometry, crs );
    171                break;
    172            case org.postgis.Geometry.LINESTRING:
    173                geo = wrapCurve( (LineString) geometry, crs );
    174                break;
    175            case org.postgis.Geometry.POLYGON:
    176                geo = wrapSurface( (Polygon) geometry, crs );
    177                break;
    178            case org.postgis.Geometry.MULTIPOINT:
    179                geo = wrapMultiPoint( (org.postgis.MultiPoint) geometry, crs );
    180                break;
    181            case org.postgis.Geometry.MULTILINESTRING:
    182                geo = wrapMultiCurve( (MultiLineString) geometry, crs );
    183                break;
    184            case org.postgis.Geometry.MULTIPOLYGON:
    185                geo = wrapMultiSurface( (MultiPolygon) geometry, crs );
    186                break;
    187            case org.postgis.Geometry.GEOMETRYCOLLECTION:
    188                geo = wrapMultiGeometry( (GeometryCollection) geometry, crs );
    189                break;
    190            default: {
    191                throw new GeometryException( "Cannot export PostGIS geometry of type '" + geometry.getType()
    192                                             + "' to deegree geometry: Unsupported type." );
    193            }
    194            }
    195            return geo;
    196        }
    197
    198        /**
    199         * Creates a PostGIS <code>MultiPoint</code> from a deegree <code>Point</code>.
    200         *
    201         * @param point
    202         * @param srid
    203         *            PostGIS SRS id that is used to store the geometry
    204         * @throws GeometryException
    205         */
    206        private static PGgeometry exportPoint( Point point, int srid )
    207                                throws GeometryException {
    208
    209            StringBuffer sb = WKTAdapter.export( point );
    210            org.postgis.Point pgPoint = null;
    211
    212            try {
    213                pgPoint = new org.postgis.Point( sb.toString() );
    214            } catch ( SQLException e ) {
    215                throw new GeometryException( e.toString() );
    216            }
    217
    218            pgPoint.setSrid( srid );
    219            return new PGgeometry( pgPoint );
    220        }
    221
    222        /**
    223         * Creates a PostGIS <code>MultiPoint</code> from a deegree <code>MultiPoint</code>.
    224         *
    225         * @param multiPoint
    226         * @param srid
    227         *            PostGIS SRS id that is used to store the geometry
    228         * @throws GeometryException
    229         */
    230        private static PGgeometry exportMultiPoint( MultiPoint multiPoint, int srid )
    231                                throws GeometryException {
    232
    233            StringBuffer sb = WKTAdapter.export( multiPoint );
    234            org.postgis.MultiPoint pgMPoint = null;
    235
    236            try {
    237                pgMPoint = new org.postgis.MultiPoint( sb.toString() );
    238            } catch ( Exception e ) {
    239                throw new GeometryException( e.toString() );
    240            }
    241
    242            pgMPoint.setSrid( srid );
    243            return new PGgeometry( pgMPoint );
    244        }
    245
    246        /**
    247         * Creates a PostGIS <code>LineString</code> from a deegree <code>Curve</code>.
    248         *
    249         * @param curve
    250         * @param srid
    251         *            PostGIS SRS id that is used to store the geometry
    252         */
    253        private static PGgeometry exportCurve( Curve curve, int srid )
    254                                throws GeometryException {
    255            StringBuffer sb = WKTAdapter.export( curve );
    256            org.postgis.LineString pgLineString = null;
    257
    258            try {
    259                pgLineString = new org.postgis.LineString( sb.toString() );
    260            } catch ( Exception e ) {
    261                throw new GeometryException( e.toString() );
    262            }
    263
    264            pgLineString.setSrid( srid );
    265            return new PGgeometry( pgLineString );
    266        }
    267
    268        /**
    269         * Creates a PostGIS <code>org.postgis.MultiCurve</code> from a deegree <code>MultiCurve</code>.
    270         *
    271         * @param multiCurve
    272         * @param srid
    273         *            PostGIS SRS id that is used to store the geometry
    274         * @throws GeometryException
    275         */
    276        private static PGgeometry exportMultiCurve( MultiCurve multiCurve, int srid )
    277                                throws GeometryException {
    278            StringBuffer sb = WKTAdapter.export( multiCurve );
    279            org.postgis.MultiLineString pgMLineString = null;
    280
    281            try {
    282                pgMLineString = new org.postgis.MultiLineString( sb.toString() );
    283            } catch ( Exception e ) {
    284                throw new GeometryException( e.toString() );
    285            }
    286
    287            pgMLineString.setSrid( srid );
    288            return new PGgeometry( pgMLineString );
    289        }
    290
    291        /**
    292         * Creates a PostGIS <code>Polygon</code> from a deegree <code>Surface</code>.
    293         *
    294         * @param surface
    295         * @param srid
    296         *            PostGIS SRS id that is used to store the geometry
    297         * @throws GeometryException
    298         */
    299        private static PGgeometry exportSurface( Surface surface, int srid )
    300                                throws GeometryException {
    301            StringBuffer sb = WKTAdapter.export( surface );
    302            org.postgis.Polygon pgPoly = null;
    303
    304            try {
    305                pgPoly = new org.postgis.Polygon( sb.toString() );
    306            } catch ( Exception e ) {
    307                throw new GeometryException( e.toString() );
    308            }
    309
    310            pgPoly.setSrid( srid );
    311            return new PGgeometry( pgPoly );
    312        }
    313
    314        /**
    315         * Creates a PostGIS <code>MultiSurface</code> from a deegree <code>MultiSurface</code>.
    316         *
    317         * @param multiSurface
    318         * @param srid
    319         *            PostGIS SRS id that is used to store the geometry
    320         * @throws GeometryException
    321         */
    322        private static PGgeometry exportMultiSurface( MultiSurface multiSurface, int srid )
    323                                throws GeometryException {
    324            StringBuffer sb = WKTAdapter.export( multiSurface );
    325            org.postgis.MultiPolygon pgMPoly = null;
    326
    327            try {
    328                pgMPoly = new org.postgis.MultiPolygon( sb.toString() );
    329            } catch ( Exception e ) {
    330                throw new GeometryException( e.toString() );
    331            }
    332
    333            pgMPoly.setSrid( srid );
    334            return new PGgeometry( pgMPoly );
    335        }
    336
    337        /**
    338         * Creates a PostGIS <code>GeometryCollection</code> from a deegree <code>MultiGeometry</code>.
    339         *
    340         * @param multiGeometry
    341         * @param srid
    342         *            PostGIS SRS id that is used to store the geometry
    343         * @throws GeometryException
    344         */
    345        private static PGgeometry exportMultiGeometry( MultiGeometry multiGeometry, int srid )
    346                                throws GeometryException {
    347
    348            StringBuffer sb = WKTAdapter.export( multiGeometry );
    349            GeometryCollection pgGeometryCollection = null;
    350
    351            try {
    352                pgGeometryCollection = new GeometryCollection( sb.toString() );
    353            } catch ( Exception e ) {
    354                throw new GeometryException( e.toString() );
    355            }
    356
    357            pgGeometryCollection.setSrid( srid );
    358            return new PGgeometry( pgGeometryCollection );
    359        }
    360
    361        /**
    362         * Creates a deegree <code>Point</code> from a PostGIS <code>Point</code>.
    363         *
    364         * @param pgPoint
    365         *            PostGIS <code>Point</code>
    366         * @param crs
    367         *            coordinate system of the created deegree <code>Geometry</code> object
    368         * @return deegree <code>Point</code>
    369         */
    370        private static Point wrapPoint( org.postgis.Point pgPoint, CoordinateSystem crs ) {
    371            // if geometry is 2-dimensional
    372            Position p = null;
    373            if ( pgPoint.getDimension() == 2 ) {
    374                // convert PostGIS Point to a Point using the GeometryFactory
    375                p = GeometryFactory.createPosition( new double[] { pgPoint.getX(), pgPoint.getY() } );
    376                // if geometry is 3-dimensional
    377            } else if ( pgPoint.getDimension() == 3 ) {
    378                // convert PostGIS Point to a Point using the GeometryFactory
    379                p = GeometryFactory.createPosition( new double[] { pgPoint.getX(), pgPoint.getY(), pgPoint.getZ() } );
    380            }
    381            return GeometryFactory.createPoint( p, crs );
    382        }
    383
    384        /**
    385         * Creates a deegree <code>MultiPoint</code> from a PostGIS <code>MultiPoint</code>.
    386         *
    387         * @param pgMultiPoint
    388         *            PostGIS <code>MultiPoint</code>
    389         * @param crs
    390         *            coordinate system of the created deegree <code>Geometry</code> object
    391         * @return deegree <code>MultiPoint</code>
    392         */
    393        private static MultiPoint wrapMultiPoint( org.postgis.MultiPoint pgMultiPoint, CoordinateSystem crs ) {
    394            // create a temporary Point Array to store the Points the
    395            // MultiPoint will consist of
    396            Point[] mpoints = new Point[pgMultiPoint.numPoints()];
    397            // for all Points
    398            for ( int i = 0; i < pgMultiPoint.numPoints(); i++ ) {
    399                // convert PostGIS Point to a Point using the GeometryFactory
    400                mpoints[i] = wrapPoint( pgMultiPoint.getPoint( i ), crs );
    401            }
    402            // create a Multipoint from the Array points
    403            return GeometryFactory.createMultiPoint( mpoints );
    404        }
    405
    406        /**
    407         * Creates a deegree <code>Curve</code> from a PostGIS <code>LineString</code>.
    408         *
    409         * @param pgLineString
    410         *            PostGIS <code>LineString</code>
    411         * @param crs
    412         *            coordinate system of the created deegree <code>Geometry</code> object
    413         * @return deegree <code>Curve</code>
    414         * @throws GeometryException
    415         */
    416        private static Curve wrapCurve( LineString pgLineString, CoordinateSystem crs )
    417                                throws GeometryException {
    418            // create a Position Array. Used to store the Points the
    419            // Curve will consist of
    420            Position[] points = new Position[pgLineString.numPoints()];
    421
    422            // if geometry is 2-dimensional
    423            if ( pgLineString.getDimension() == 2 ) {
    424                // for all Points
    425                for ( int i = 0; i < pgLineString.numPoints(); i++ ) {
    426                    // create a Position from the PostGIS Point using the
    427                    // GeometryFactory
    428                    double[] d = new double[] { pgLineString.getPoint( i ).getX(), pgLineString.getPoint( i ).getY() };
    429                    points[i] = GeometryFactory.createPosition( d );
    430                }
    431                // if geometry is 3-dimensional
    432            } else if ( pgLineString.getDimension() == 3 ) {
    433                // for all Points
    434                for ( int i = 0; i < pgLineString.numPoints(); i++ ) {
    435                    // create a Position from the PostGIS Point using the
    436                    // GeometryFactory
    437                    double[] d = new double[] { pgLineString.getPoint( i ).getX(), pgLineString.getPoint( i ).getY(),
    438                                               pgLineString.getPoint( i ).getZ() };
    439                    points[i] = GeometryFactory.createPosition( d );
    440                }
    441            }
    442            return GeometryFactory.createCurve( points, crs );
    443        }
    444
    445        /**
    446         * Creates a deegree <code>MultiCurve</code> from a PostGIS <code>MultiLineString</code>.
    447         *
    448         * @param pgMultiLineString
    449         *            PostGIS <code>MultiLineString</code>
    450         * @param crs
    451         *            coordinate system of the created deegree <code>Geometry</code> object
    452         * @return deegree <code>MultiCurve</code>
    453         * @throws GeometryException
    454         */
    455        private static MultiCurve wrapMultiCurve( MultiLineString pgMultiLineString, CoordinateSystem crs )
    456                                throws GeometryException {
    457            // create a Curve Array. Used to store the CurveSegments the
    458            // Curve will consist of
    459            Curve[] curves = new Curve[pgMultiLineString.numLines()];
    460            // for all Lines
    461            for ( int i = 0; i < pgMultiLineString.numLines(); i++ ) {
    462                // create a Curve form the positions Array using the
    463                // GeometryFactory
    464                curves[i] = wrapCurve( pgMultiLineString.getLine( i ), crs );
    465            }
    466            // create a Curve form all the CurveSegments stored in the
    467            // csegments Array using the GeometryFactory
    468            return GeometryFactory.createMultiCurve( curves );
    469        }
    470
    471        /**
    472         * Creates a deegree <code>Surface</code> from a PostGIS <code>Polygon</code>.
    473         *
    474         * @param pgPolygon
    475         *            PostGIS <code>Polygon</code>
    476         * @param crs
    477         *            coordinate system of the created deegree <code>Geometry</code> object
    478         * @return deegree <code>Surface</code>
    479         * @throws GeometryException
    480         */
    481        private static Surface wrapSurface( Polygon pgPolygon, CoordinateSystem crs )
    482                                throws GeometryException {
    483
    484            // create a Position Array. Used to store the Positions the
    485            // exterior Ring of the Surface will consist of
    486            Position[] eRing = new Position[pgPolygon.getRing( 0 ).numPoints()];
    487            // declares a Position[][] Array. Used to store the Positions
    488            // of the interior Rings the Surface will consist of. The exterior
    489            // Ring is stored seperately
    490            Position[][] iRings = null;
    491
    492            // if geometry is 2-dimensional
    493            if ( pgPolygon.getDimension() == 2 ) {
    494                // for all the Points of the fist LinearRing (which is the exterior)
    495                org.postgis.LinearRing ring = pgPolygon.getRing( 0 );
    496                for ( int j = 0; j < eRing.length; j++ ) {
    497                    // store all the Points of the exterior Ring in the Array
    498                    // eRing. Convert them using GeometryFactory
    499                    double[] d = new double[] { ring.getPoint( j ).getX(), ring.getPoint( j ).getY() };
    500                    eRing[j] = GeometryFactory.createPosition( d );
    501                }
    502
    503                if ( pgPolygon.numRings() > 1 ) {
    504                    iRings = new Position[pgPolygon.numRings() - 1][];
    505                    // for all LinearRings except the first one (which is the exterior one)
    506                    for ( int i = 1; i < pgPolygon.numRings(); i++ ) {
    507                        iRings[i - 1] = new Position[pgPolygon.getRing( i ).numPoints()];
    508                        // for all the Points in the ith LinearRing
    509                        ring = pgPolygon.getRing( i );
    510                        for ( int j = 0; j < ring.numPoints(); j++ ) {
    511                            // store all the Points of the ith interior Ring in
    512                            // the iRings Array
    513                            double[] d = new double[] { ring.getPoint( j ).getX(), ring.getPoint( j ).getY() };
    514                            iRings[i - 1][j] = GeometryFactory.createPosition( d );
    515                        }
    516                    }
    517                }
    518                // if geometry is 3-dimensional
    519            } else if ( pgPolygon.getDimension() == 3 ) {
    520                // for all the Points of the fist LinearRing (which is the exterior)
    521                org.postgis.LinearRing ring = pgPolygon.getRing( 0 );
    522                for ( int j = 0; j < ring.numPoints(); j++ ) {
    523                    // store all the Points of the exterior Ring in the Array
    524                    // eRing. Convert them using GeometryFactory
    525                    double[] d = new double[] { ring.getPoint( j ).getX(), ring.getPoint( j ).getY(),
    526                                               ring.getPoint( j ).getZ() };
    527                    eRing[j] = GeometryFactory.createPosition( d );
    528                }
    529
    530                if ( pgPolygon.numRings() > 1 ) {
    531                    iRings = new Position[pgPolygon.numRings() - 1][];
    532                    // for all LinearRings except the first one (which is the exterior one)
    533                    for ( int i = 1; i < pgPolygon.numRings(); i++ ) {
    534                        iRings[i - 1] = new Position[pgPolygon.getRing( i ).numPoints()];
    535                        // for all the Points in the ith LinearRing
    536                        ring = pgPolygon.getRing( i );
    537                        for ( int j = 0; j < ring.numPoints(); j++ ) {
    538                            // store all the Points of the ith interior Ring in the iRings Array
    539                            double[] d = new double[] { ring.getPoint( j ).getX(), ring.getPoint( j ).getY(),
    540                                                       ring.getPoint( j ).getZ() };
    541                            iRings[i - 1][j] = GeometryFactory.createPosition( d );
    542                        }
    543                    }
    544                }
    545            }
    546
    547            return GeometryFactory.createSurface( eRing, iRings, new SurfaceInterpolationImpl(), crs );
    548        }
    549
    550        /**
    551         * Creates a deegree <code>MultiSurface</code> from a PostGIS <code>MultiPolygon</code>.
    552         *
    553         * @param pgMultiPolygon
    554         *            PostGIS <code>MultiPolygon</code>
    555         * @param crs
    556         *            coordinate system of the created deegree <code>Geometry</code> object
    557         * @return deegree <code>MultiSurface</code>
    558         * @throws GeometryException
    559         */
    560        private static MultiSurface wrapMultiSurface( MultiPolygon pgMultiPolygon, CoordinateSystem crs )
    561                                throws GeometryException {
    562            // create a Surfaces Array. Used to store the Surfaces the
    563            // MultiSurface will consist of
    564            Surface[] surfaces = new Surface[pgMultiPolygon.numPolygons()];
    565            // for all Polygons the MultiPolygon consists of
    566            for ( int i = 0; i < pgMultiPolygon.numPolygons(); i++ ) {
    567                surfaces[i] = wrapSurface( pgMultiPolygon.getPolygon( i ), crs );
    568            }
    569
    570            return GeometryFactory.createMultiSurface( surfaces );
    571        }
    572
    573        /**
    574         * Creates a deegree <code>MultiGeometry</code> from a PostGIS <code>GeometryCollection</code>.
    575         *
    576         * @param pgGeometryCollection
    577         *            PostGIS <code>GeometryCollection</code>
    578         * @param crs
    579         *            coordinate system of the created deegree <code>Geometry</code> object
    580         * @return deegree <code>MultiGeometry</code>
    581         * @throws GeometryException
    582         */
    583        private static MultiGeometry wrapMultiGeometry( GeometryCollection pgGeometryCollection, CoordinateSystem crs )
    584                                throws GeometryException {
    585
    586            List<Geometry> members = new ArrayList<Geometry>();
    587            Iterator<?> memberIter = pgGeometryCollection.iterator();
    588            while ( memberIter.hasNext() ) {
    589                org.postgis.Geometry memberGeometry = (org.postgis.Geometry) memberIter.next();
    590                members.add( wrap( memberGeometry, crs ) );
    591            }
    592            return GeometryFactory.createMultiGeometry( members.toArray( new Geometry[members.size()] ), crs );
    593        }
    594    }