001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/WKTAdapter.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     53115 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     ---------------------------------------------------------------------------*/
044    package org.deegree.model.spatialschema;
045    
046    import java.util.ArrayList;
047    
048    import org.deegree.framework.util.StringTools;
049    import org.deegree.model.crs.CoordinateSystem;
050    
051    /**
052     * Adapter class for exporting deegree geometries to WKT and to wrap WKT code
053     * geometries to deegree geometries.
054     *
055     * @version $Revision: 6259 $
056     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
057     */
058    public class WKTAdapter {
059    
060        //    private static DecimalFormatSymbols dfs = new DecimalFormatSymbols();
061        //    private static  DecimalFormat frm = null;
062        //    static {
063        //        dfs.setDecimalSeparator( '.' );
064        //        frm = new DecimalFormat( "#.#########", dfs );
065        //    }
066    
067        /**
068         
069         *
070         * @param wkt
071         * @return the corresponding <tt>Geometry</tt>
072         * @throws GeometryException if type unsupported or conversion failed
073         */
074        public static Geometry wrap( String wkt, CoordinateSystem crs )
075                                throws GeometryException {
076    
077            Geometry geo = null;
078    
079            if ( wkt == null ) {
080                return null;
081            } else if ( wkt.startsWith( "POINT" ) ) {
082                geo = wrapPoint( wkt, crs );
083            } else if ( wkt.startsWith( "LINE" ) ) {
084                geo = wrapCurve( wkt, crs );
085            } else if ( wkt.startsWith( "POLY" ) ) {
086                geo = wrapSurface( wkt, crs );
087            } else if ( wkt.startsWith( "MULTIPOINT" ) ) {
088                geo = wrapMultiPoint( wkt, crs );
089            } else if ( wkt.startsWith( "MULTILINE" ) ) {
090                geo = wrapMultiCurve( wkt, crs );
091            } else if ( wkt.startsWith( "MULTIPOLY" ) ) {
092                geo = wrapMultiSurface( wkt, crs );
093            }
094    
095            return geo;
096        }
097    
098        /**
099         * @param geom geometry
100         *
101         * @return 
102         */
103        public static StringBuffer export( Geometry geom )
104                                throws GeometryException {
105    
106            StringBuffer sb = null;
107            if ( geom instanceof Point ) {
108                sb = export( (Point) geom );
109            } else if ( geom instanceof Curve ) {
110                sb = export( (Curve) geom );
111            } else if ( geom instanceof Surface ) {
112                sb = export( (Surface) geom );
113            } else if ( geom instanceof MultiPoint ) {
114                sb = export( (MultiPoint) geom );
115            } else if ( geom instanceof MultiCurve ) {
116                sb = export( (MultiCurve) geom );
117            } else if ( geom instanceof MultiSurface ) {
118                sb = export( (MultiSurface) geom );
119            }
120    
121            return sb;
122        }
123    
124        /**
125         * exports an Envelope as a BOX3D WKT string.
126         * @param envelope
127         * @return
128         */
129        public static StringBuffer export( Envelope envelope ) {
130            StringBuffer sb = new StringBuffer( 150 );
131            sb.append( "BOX3D(" );
132            int dim = envelope.getMin().getCoordinateDimension();
133            double[] d = envelope.getMin().getAsArray();
134            for ( int i = 0; i < dim - 1; i++ ) {
135                sb.append( Double.toString( d[i] ) ).append( " " );
136            }
137            sb.append( Double.toString( d[dim - 1] ) ).append( "," );
138            d = envelope.getMax().getAsArray();
139            for ( int i = 0; i < dim - 1; i++ ) {
140                sb.append( Double.toString( d[i] ) ).append( " " );
141            }
142            sb.append( Double.toString( d[dim - 1] ) );
143            sb.append( ") " );
144            return sb;
145        }
146    
147        /**
148         * @param point point geometry
149         *
150         * @return 
151         */
152        private static StringBuffer export( Point point ) {
153    
154            StringBuffer sb = new StringBuffer( 50 );
155            sb.append( "POINT(" );
156            double[] points = point.getAsArray();
157            int dim = point.getCoordinateDimension();
158            for ( int i = 0; i < dim - 1; i++ ) {
159                sb.append( points[i] ).append( ' ' );
160            }
161            sb.append( points[dim - 1] );
162            sb.append( ") " );
163    
164            return sb;
165        }
166    
167        /**
168         *
169         * @param cur curve geometry
170         *
171         * @return 
172         *
173         * @throws GeometryException 
174         */
175        private static StringBuffer export( Curve cur )
176                                throws GeometryException {
177    
178            LineString ls = cur.getAsLineString();
179    
180            StringBuffer sb = new StringBuffer( ls.getNumberOfPoints() * 30 );
181            sb.append( "LINESTRING(" );
182    
183            for ( int i = 0; i < ls.getNumberOfPoints() - 1; i++ ) {
184                Position pos = ls.getPositionAt( i );
185                double[] positions = pos.getAsArray();
186                int dim = pos.getCoordinateDimension();
187                for ( int j = 0; j < dim - 1; j++ ) {
188                    sb.append( positions[j] + " " );
189                }
190                sb.append( positions[dim - 1] + "," );
191            }
192            Position pos = ls.getPositionAt( ls.getNumberOfPoints() - 1 );
193            double[] tmp = pos.getAsArray();
194            int dim = pos.getCoordinateDimension();
195            for ( int j = 0; j < dim - 1; j++ ) {
196                sb.append( tmp[j] + " " );
197            }
198            sb.append( tmp[dim - 1] + ")" );
199    
200            return sb;
201        }
202    
203        /**
204         * 
205         *
206         * @param sur
207         *
208         * @return 
209         *
210         */
211        private static StringBuffer export( Surface sur ) {
212    
213            SurfaceBoundary subo = sur.getSurfaceBoundary();
214            Ring exter = subo.getExteriorRing();
215            Ring[] inter = subo.getInteriorRings();
216    
217            StringBuffer sb = new StringBuffer( 10000 );
218            sb.append( "POLYGON((" );
219            // exterior ring
220            Position[] pos = exter.getPositions();
221            int dim = pos[0].getCoordinateDimension();
222            for ( int i = 0; i < pos.length - 1; i++ ) {
223                double[] positions = pos[i].getAsArray();
224                for ( int j = 0; j < dim - 1; j++ ) {
225                    sb.append( positions[j] + " " );
226                }
227                sb.append( positions[dim - 1] + "," );
228            }
229            double[] positions = pos[pos.length - 1].getAsArray();
230            for ( int j = 0; j < dim - 1; j++ ) {
231                sb.append( positions[j] + " " );
232            }
233            sb.append( positions[dim - 1] + ")" );
234            //interior rings 
235            if ( inter != null ) {
236                for ( int j = 0; j < inter.length; j++ ) {
237                    sb.append( ",(" );
238                    pos = inter[j].getPositions();
239                    for ( int i = 0; i < pos.length - 1; i++ ) {
240                        double[] intPos = pos[i].getAsArray();
241                        for ( int l = 0; l < dim - 1; l++ ) {
242                            sb.append( intPos[l] + " " );
243                        }
244                        sb.append( intPos[dim - 1] + "," );//                    
245                    }
246                    double[] intPos = pos[pos.length - 1].getAsArray();
247                    for ( int l = 0; l < dim - 1; l++ ) {
248                        sb.append( intPos[l] + " " );
249                    }
250                    sb.append( intPos[dim - 1] + ")" );
251                }
252            }
253            sb.append( ")" );
254    
255            return sb;
256        }
257    
258        /**
259         * @param mp
260         * @return
261         */
262        private static StringBuffer export( MultiPoint mp ) {
263    
264            StringBuffer sb = new StringBuffer( mp.getSize() * 30 );
265            sb.append( "MULTIPOINT(" );
266            int dim = mp.getPointAt( 0 ).getCoordinateDimension();
267            for ( int i = 0; i < mp.getSize() - 1; i++ ) {
268                Point pt = mp.getPointAt( i );
269                double[] points = pt.getAsArray();
270                for ( int j = 0; j < dim - 1; j++ ) {
271                    sb.append( points[j] + " " );
272                }
273                sb.append( points[dim - 1] );
274                sb.append( "," );
275            }
276            Point pt = mp.getPointAt( mp.getSize() - 1 );
277            double[] points = pt.getAsArray();
278            for ( int j = 0; j < dim - 1; j++ ) {
279                sb.append( points[j] + " " );
280            }
281            sb.append( points[dim - 1] + ")" );
282    
283            return sb;
284        }
285    
286        /**
287         *
288         *
289         * @param mc
290         *
291         * @return 
292         *
293         * @throws GeometryException 
294         */
295        private static StringBuffer export( MultiCurve mc )
296                                throws GeometryException {
297    
298            StringBuffer sb = new StringBuffer( 10000 );
299            sb.append( "MULTILINESTRING(" );
300    
301            for ( int i = 0; i < mc.getSize() - 1; i++ ) {
302                String s = export( mc.getCurveAt( i ) ).toString();
303                s = s.substring( 10, s.length() );
304                sb.append( s ).append( "," );
305            }
306            String s = export( mc.getCurveAt( mc.getSize() - 1 ) ).toString();
307            s = s.substring( 10, s.length() );
308            sb.append( s ).append( ")" );
309    
310            return sb;
311        }
312    
313        /**
314         *
315         *     
316         * @param ms
317         *
318         * @return 
319         *
320         * @throws GeometryException 
321         */
322        private static StringBuffer export( MultiSurface ms ) {
323    
324            StringBuffer sb = new StringBuffer( 10000 );
325            sb.append( "MULTIPOLYGON(" );
326    
327            for ( int i = 0; i < ms.getSize() - 1; i++ ) {
328                String s = export( ms.getSurfaceAt( i ) ).toString();
329                s = s.substring( 7, s.length() );
330                sb.append( s ).append( "," );
331            }
332            String s = export( ms.getSurfaceAt( ms.getSize() - 1 ) ).toString();
333            s = s.substring( 7, s.length() );
334            sb.append( s ).append( ")" );
335    
336            return sb;
337        }
338    
339        /**
340         * creates a Point from a WKT.
341         *
342         * @param wkt a Point WKT
343         */
344        public static Point wrapPoint( String wkt, CoordinateSystem crs ) {
345    
346            wkt = wkt.trim();
347            wkt = wkt.substring( 6, wkt.length() - 1 );
348            double[] tmp = StringTools.toArrayDouble( wkt, " " );
349            Position pos = GeometryFactory.createPosition( tmp );
350            Point point = GeometryFactory.createPoint( pos, crs );
351    
352            return point;
353        }
354    
355        /**
356         * creates a Curve from a WKT.
357         *
358         * @param wkt linestring a WKT
359         */
360        public static Curve wrapCurve( String wkt, CoordinateSystem crs )
361                                throws GeometryException {
362    
363            wkt = wkt.trim();
364            wkt = wkt.substring( 11, wkt.length() - 1 );
365            String[] points = StringTools.toArray( wkt, ",", false );
366            Position[] pos = new Position[points.length];
367            for ( int i = 0; i < points.length; i++ ) {
368                double[] tmp = StringTools.toArrayDouble( points[i], " " );
369                pos[i] = GeometryFactory.createPosition( tmp );
370            }
371            Curve curve = GeometryFactory.createCurve( pos, crs );
372    
373            return curve;
374        }
375    
376        /** 
377         * creates a Surface
378         *
379         * @param wkt polygon WKT
380         */
381        public static Surface wrapSurface( String wkt, CoordinateSystem crs )
382                                throws GeometryException {
383    
384            wkt = wkt.trim();
385    
386            Position[] ext = null;
387            ArrayList inn = new ArrayList();
388            if ( wkt.indexOf( "((" ) > 0 ) {
389                wkt = wkt.substring( 9, wkt.length() - 1 );
390                int pos = wkt.indexOf( ")" );
391                String tmp = wkt.substring( 0, pos );
392                //external ring
393                String[] points = StringTools.toArray( tmp, ",", false );
394                ext = new Position[points.length];
395                for ( int i = 0; i < points.length; i++ ) {
396                    double[] temp = StringTools.toArrayDouble( points[i], " " );
397                    ext[i] = GeometryFactory.createPosition( temp );
398                }
399                if ( pos + 3 < wkt.length() ) {
400                    wkt = wkt.substring( pos + 3, wkt.length() );
401                    while ( wkt.indexOf( ")" ) > 0 ) {
402                        pos = wkt.indexOf( ")" );
403                        tmp = wkt.substring( 0, pos );
404                        //internal ring(s)
405                        points = StringTools.toArray( tmp, ",", false );
406                        Position[] intern = new Position[points.length];
407                        for ( int i = 0; i < points.length; i++ ) {
408                            double[] temp = StringTools.toArrayDouble( points[i], " " );
409                            intern[i] = GeometryFactory.createPosition( temp );
410                        }
411                        inn.add( intern );
412                        if ( pos + 3 < wkt.length() ) {
413                            wkt = wkt.substring( pos + 3, wkt.length() );
414                        } else {
415                            break;
416                        }
417                    }
418                }
419            }
420            Position[][] inner = null;
421            if ( inn.size() > 0 ) {
422                inner = (Position[][]) inn.toArray( new Position[inn.size()][] );
423            }
424            Surface sur = GeometryFactory.createSurface( ext, inner, new SurfaceInterpolationImpl(),
425                                                         crs );
426    
427            return sur;
428        }
429    
430        /**
431         * creates a MultiPoint from a WKT
432         *
433         * @param wkt  multipoint WKT
434         */
435        public static MultiPoint wrapMultiPoint( String wkt, CoordinateSystem crs ) {
436    
437            wkt = wkt.trim();
438            wkt = wkt.substring( 11, wkt.length() - 1 );
439            String[] coords = StringTools.toArray( wkt, ",", false );
440            Position[] pos = new Position[coords.length];
441            for ( int i = 0; i < coords.length; i++ ) {
442                double[] temp = StringTools.toArrayDouble( coords[i], " " );
443                pos[i] = GeometryFactory.createPosition( temp );
444            }
445    
446            Point[] points = new Point[pos.length];
447            for ( int i = 0; i < pos.length; i++ ) {
448                points[i] = GeometryFactory.createPoint( pos[i], crs );
449            }
450            MultiPoint mp = GeometryFactory.createMultiPoint( points );
451    
452            return mp;
453        }
454    
455        /**
456         * creates a MultiCurve from a WKT
457         *
458         * @param wkt a WKT
459         */
460        public static MultiCurve wrapMultiCurve( String wkt, CoordinateSystem crs )
461                                throws GeometryException {
462    
463            ArrayList crvs = new ArrayList();
464    
465            wkt = wkt.trim();
466            int pos = wkt.indexOf( ")" );
467            String tmp = wkt.substring( 17, pos );
468            String[] coords = StringTools.toArray( tmp, ",", false );
469            Position[] posi = new Position[coords.length];
470            for ( int i = 0; i < coords.length; i++ ) {
471                double[] temp = StringTools.toArrayDouble( coords[i], " " );
472                posi[i] = GeometryFactory.createPosition( temp );
473            }
474            crvs.add( GeometryFactory.createCurve( posi, crs ) );
475            wkt = wkt.substring( pos + 3, wkt.length() - 1 );
476            while ( wkt.indexOf( ")" ) > 0 ) {
477                Position[] posi2 = new Position[coords.length];
478                pos = wkt.indexOf( ")" );
479                tmp = wkt.substring( 0, pos );
480                coords = StringTools.toArray( tmp, ",", false );
481                for ( int i = 0; i < coords.length; i++ ) {
482                    double[] temp = StringTools.toArrayDouble( coords[i], " " );
483                    posi2[i] = GeometryFactory.createPosition( temp );
484                }
485                crvs.add( GeometryFactory.createCurve( posi2, crs ) );
486                if ( pos + 3 < wkt.length() ) {
487                    wkt = wkt.substring( pos + 3, wkt.length() );
488                } else {
489                    break;
490                }
491            }
492    
493            Curve[] curves = (Curve[]) crvs.toArray( new Curve[crvs.size()] );
494            MultiCurve mc = GeometryFactory.createMultiCurve( curves );
495    
496            return mc;
497        }
498    
499        /**
500         * creates a MultiSurface from a WKT
501         *
502         * @param wkt a WKT
503         */
504        public static MultiSurface wrapMultiSurface( String wkt, CoordinateSystem crs )
505                                throws GeometryException {
506    
507            ArrayList srfcs = new ArrayList();
508    
509            wkt = wkt.substring( 13 );
510            // for each polygon 
511            while ( wkt.indexOf( "((" ) > -1 ) {
512                Position[] ext = null;
513                ArrayList inn = new ArrayList();
514                int pos1 = wkt.indexOf( "))" );
515                String tmp = wkt.substring( 2, pos1 + 1 );
516                //  exterior ring        
517                int pos = tmp.indexOf( ")" );
518                String tmp2 = tmp.substring( 0, pos );
519                String[] points = StringTools.toArray( tmp2, ",", false );
520                ext = new Position[points.length];
521                for ( int i = 0; i < points.length; i++ ) {
522                    double[] temp = StringTools.toArrayDouble( points[i], " " );
523                    ext[i] = GeometryFactory.createPosition( temp );
524                }
525                if ( pos + 3 < tmp.length() ) {
526                    tmp = tmp.substring( pos + 3, tmp.length() );
527                    // for each inner ring
528                    while ( tmp.indexOf( ")" ) > 0 ) {
529                        pos = tmp.indexOf( ")" );
530                        tmp2 = tmp.substring( 0, pos );
531                        points = StringTools.toArray( tmp2, ",", false );
532                        Position[] intern = new Position[points.length];
533                        for ( int i = 0; i < points.length; i++ ) {
534                            double[] temp = StringTools.toArrayDouble( points[i], " " );
535                            intern[i] = GeometryFactory.createPosition( temp );
536                        }
537                        inn.add( intern );
538                        if ( pos + 3 < tmp.length() ) {
539                            tmp = tmp.substring( pos + 3, tmp.length() );
540                        } else {
541                            break;
542                        }
543                    }
544                }
545                Position[][] inner = null;
546                if ( inn.size() > 0 ) {
547                    inner = (Position[][]) inn.toArray( new Position[inn.size()][] );
548                }
549                Surface sur = GeometryFactory.createSurface( ext, inner,
550                                                             new SurfaceInterpolationImpl(), crs );
551                srfcs.add( sur );
552                wkt = wkt.substring( pos1 + 3 );
553            }
554            Surface[] surfaces = (Surface[]) srfcs.toArray( new Surface[srfcs.size()] );
555            MultiSurface ms = GeometryFactory.createMultiSurface( surfaces );
556    
557            return ms;
558        }
559    
560    }/* ********************************************************************
561     Changes to this class. What the people have been up to:
562     $Log$
563     Revision 1.11  2006/08/07 12:23:35  poth
564     deprecated clas/method calls removed // never thrown exceptions removed
565    
566     Revision 1.10  2006/07/12 14:46:15  poth
567     comment footer added
568    
569     ********************************************************************** */