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