001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/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: " ");
406: ext[i] = GeometryFactory.createPosition(temp);
407: }
408: if (pos + 3 < wkt.length()) {
409: wkt = wkt.substring(pos + 3, wkt.length());
410: while (wkt.indexOf(")") > 0) {
411: pos = wkt.indexOf(")");
412: tmp = wkt.substring(0, pos);
413: // internal ring(s)
414: points = StringTools.toArray(tmp, ",", false);
415: Position[] intern = new Position[points.length];
416: for (int i = 0; i < points.length; i++) {
417: double[] temp = StringTools.toArrayDouble(
418: points[i], " ");
419: intern[i] = GeometryFactory
420: .createPosition(temp);
421: }
422: inn.add(intern);
423: if (pos + 3 < wkt.length()) {
424: wkt = wkt.substring(pos + 3, wkt.length());
425: } else {
426: break;
427: }
428: }
429: }
430: }
431: Position[][] inner = null;
432: if (inn.size() > 0) {
433: inner = (Position[][]) inn
434: .toArray(new Position[inn.size()][]);
435: }
436: Surface sur = GeometryFactory.createSurface(ext, inner,
437: new SurfaceInterpolationImpl(), crs);
438:
439: return sur;
440: }
441:
442: /**
443: * creates a MultiPoint from a WKT
444: *
445: * @param wkt
446: * multipoint WKT
447: */
448: public static MultiPoint wrapMultiPoint(String wkt,
449: CoordinateSystem crs) {
450:
451: wkt = wkt.trim();
452: wkt = wkt.substring(11, wkt.length() - 1);
453: String[] coords = StringTools.toArray(wkt, ",", false);
454: Position[] pos = new Position[coords.length];
455: for (int i = 0; i < coords.length; i++) {
456: double[] temp = StringTools.toArrayDouble(coords[i], " ");
457: pos[i] = GeometryFactory.createPosition(temp);
458: }
459:
460: Point[] points = new Point[pos.length];
461: for (int i = 0; i < pos.length; i++) {
462: points[i] = GeometryFactory.createPoint(pos[i], crs);
463: }
464: MultiPoint mp = GeometryFactory.createMultiPoint(points);
465:
466: return mp;
467: }
468:
469: /**
470: * creates a MultiCurve from a WKT
471: *
472: * @param wkt
473: * a WKT
474: */
475: public static MultiCurve wrapMultiCurve(String wkt,
476: CoordinateSystem crs) throws GeometryException {
477:
478: ArrayList crvs = new ArrayList();
479:
480: wkt = wkt.trim();
481: int pos = wkt.indexOf(")");
482: String tmp = wkt.substring(17, pos);
483: String[] coords = StringTools.toArray(tmp, ",", false);
484: Position[] posi = new Position[coords.length];
485: for (int i = 0; i < coords.length; i++) {
486: double[] temp = StringTools.toArrayDouble(coords[i], " ");
487: posi[i] = GeometryFactory.createPosition(temp);
488: }
489: crvs.add(GeometryFactory.createCurve(posi, crs));
490: wkt = wkt.substring(pos + 3, wkt.length() - 1);
491: while (wkt.indexOf(")") > 0) {
492: Position[] posi2 = new Position[coords.length];
493: pos = wkt.indexOf(")");
494: tmp = wkt.substring(0, pos);
495: coords = StringTools.toArray(tmp, ",", false);
496: for (int i = 0; i < coords.length; i++) {
497: double[] temp = StringTools.toArrayDouble(coords[i],
498: " ");
499: posi2[i] = GeometryFactory.createPosition(temp);
500: }
501: crvs.add(GeometryFactory.createCurve(posi2, crs));
502: if (pos + 3 < wkt.length()) {
503: wkt = wkt.substring(pos + 3, wkt.length());
504: } else {
505: break;
506: }
507: }
508:
509: Curve[] curves = (Curve[]) crvs.toArray(new Curve[crvs.size()]);
510: MultiCurve mc = GeometryFactory.createMultiCurve(curves);
511:
512: return mc;
513: }
514:
515: /**
516: * creates a MultiSurface from a WKT
517: *
518: * @param wkt
519: * a WKT
520: */
521: public static MultiSurface wrapMultiSurface(String wkt,
522: CoordinateSystem crs) throws GeometryException {
523:
524: ArrayList srfcs = new ArrayList();
525:
526: wkt = wkt.substring(13);
527: // for each polygon
528: while (wkt.indexOf("((") > -1) {
529: Position[] ext = null;
530: ArrayList inn = new ArrayList();
531: int pos1 = wkt.indexOf("))");
532: String tmp = wkt.substring(2, pos1 + 1);
533: // exterior ring
534: int pos = tmp.indexOf(")");
535: String tmp2 = tmp.substring(0, pos);
536: String[] points = StringTools.toArray(tmp2, ",", false);
537: ext = new Position[points.length];
538: for (int i = 0; i < points.length; i++) {
539: double[] temp = StringTools.toArrayDouble(points[i],
540: " ");
541: ext[i] = GeometryFactory.createPosition(temp);
542: }
543: if (pos + 3 < tmp.length()) {
544: tmp = tmp.substring(pos + 3, tmp.length());
545: // for each inner ring
546: while (tmp.indexOf(")") > 0) {
547: pos = tmp.indexOf(")");
548: tmp2 = tmp.substring(0, pos);
549: points = StringTools.toArray(tmp2, ",", false);
550: Position[] intern = new Position[points.length];
551: for (int i = 0; i < points.length; i++) {
552: double[] temp = StringTools.toArrayDouble(
553: points[i], " ");
554: intern[i] = GeometryFactory
555: .createPosition(temp);
556: }
557: inn.add(intern);
558: if (pos + 3 < tmp.length()) {
559: tmp = tmp.substring(pos + 3, tmp.length());
560: } else {
561: break;
562: }
563: }
564: }
565: Position[][] inner = null;
566: if (inn.size() > 0) {
567: inner = (Position[][]) inn.toArray(new Position[inn
568: .size()][]);
569: }
570: Surface sur = GeometryFactory.createSurface(ext, inner,
571: new SurfaceInterpolationImpl(), crs);
572: srfcs.add(sur);
573: wkt = wkt.substring(pos1 + 3);
574: }
575: Surface[] surfaces = (Surface[]) srfcs
576: .toArray(new Surface[srfcs.size()]);
577: MultiSurface ms = GeometryFactory.createMultiSurface(surfaces);
578:
579: return ms;
580: }
581:
582: }
|