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