001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/GMLGeometryAdapter.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2007 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 53177 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: klaus.greve@uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.model.spatialschema;
045
046 import java.io.OutputStream;
047 import java.io.PrintWriter;
048 import java.io.StringReader;
049 import java.rmi.RemoteException;
050 import java.util.ArrayList;
051 import java.util.HashMap;
052 import java.util.List;
053 import java.util.Map;
054 import java.util.StringTokenizer;
055
056 import org.deegree.framework.log.ILogger;
057 import org.deegree.framework.log.LoggerFactory;
058 import org.deegree.framework.util.StringTools;
059 import org.deegree.framework.xml.ElementList;
060 import org.deegree.framework.xml.NamespaceContext;
061 import org.deegree.framework.xml.XMLParsingException;
062 import org.deegree.framework.xml.XMLTools;
063 import org.deegree.i18n.Messages;
064 import org.deegree.model.crs.CRSFactory;
065 import org.deegree.model.crs.CoordinateSystem;
066 import org.deegree.model.crs.UnknownCRSException;
067 import org.deegree.ogcbase.CommonNamespaces;
068 import org.deegree.ogcbase.InvalidGMLException;
069 import org.w3c.dom.Document;
070 import org.w3c.dom.Element;
071 import org.w3c.dom.Node;
072
073 /**
074 * Adapter class for converting GML geometries to deegree geometries and vice versa. Some logical
075 * problems results from the fact that an envelope isn't a geometry according to ISO 19107 (where
076 * the deegree geometry model is based on) but according to GML2/3 specification it is.<br>
077 * So if the wrap(..) method is called with an envelope a <tt>Surface</tt> will be returned
078 * representing the envelops shape. To export an <tt>Envelope</tt> to a GML box/envelope two
079 * specialized export methods are available.<BR>
080 * The export method(s) doesn't return a DOM element as one may expect but a <tt>StringBuffer</tt>.
081 * This is done because the transformation from deegree geometries to GML mainly is required when a
082 * GML representation of a geometry shall be serialized to a file or to a network connection. For
083 * both cases the string representation is required and it is simply faster to create the string
084 * directly instead of first creating a DOM tree that after this must be serialized to a string.<BR>
085 * In future version geometries will be serialized to a stream.
086 *
087 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
088 * @author last edited by: $Author: aschmitz $
089 *
090 * @version $Revision: 8127 $, $Date: 2007-09-10 13:10:24 +0200 (Mo, 10 Sep 2007) $
091 */
092 public class GMLGeometryAdapter {
093
094 private static final ILogger LOG = LoggerFactory.getLogger( GMLGeometryAdapter.class );
095
096 private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
097
098 private static Map<String, CoordinateSystem> crsMap = new HashMap<String, CoordinateSystem>();
099
100 private static final String COORD = CommonNamespaces.GML_PREFIX + ":coord";
101
102 private static final String COORDINATES = CommonNamespaces.GML_PREFIX + ":coordinates";
103
104 private static final String POS = CommonNamespaces.GML_PREFIX + ":pos";
105
106 private static final String POSLIST = CommonNamespaces.GML_PREFIX + ":posList";
107
108 /**
109 * Converts the given string representation of a GML geometry object to a corresponding
110 * <code>Geometry</code>. Notice that GML Boxes will be converted to Surfaces because in ISO
111 * 19107 Envelopes are no geometries.
112 *
113 * @param gml
114 * @param srsName
115 * default SRS for the geometry (may be overwritten in geometry elements)
116 * @return corresponding geometry object
117 * @throws GeometryException
118 * @throws XMLParsingException
119 */
120 public static Geometry wrap( String gml, String srsName )
121 throws GeometryException, XMLParsingException {
122 StringReader sr = new StringReader( gml );
123 Document doc = null;
124 try {
125 doc = XMLTools.parse( sr );
126 } catch ( Exception e ) {
127 LOG.logError( "could not parse: '" + gml + "' as GML/XML", e );
128 throw new XMLParsingException( "could not parse: '" + gml + "' as GML/XML: " + e.getMessage() );
129 }
130 return wrap( doc.getDocumentElement(), srsName );
131 }
132
133 /**
134 * Converts the given DOM representation of a GML geometry to a corresponding
135 * <code>Geometry</code>. Notice that GML Boxes will be converted to Surfaces because in ISO
136 * 19107 Envelopes are no geometries.
137 * <p>
138 * Currently, the following conversions are supported:
139 * <ul>
140 * <li>GML Point -> Point
141 * <li>GML MultiPoint -> MultiPoint
142 * <li>GML LineString -> Curve
143 * <li>GML MultiLineString -> MultiCurve
144 * <li>GML Polygon -> Surface
145 * <li>GML MultiPolygon -> MultiSurface
146 * <li>GML Box -> Surface
147 * <li>GML Curve -> Curve
148 * <li>GML Surface -> Surface
149 * <li>GML MultiCurve -> MultiCurve
150 * <li>GML MultiSurface -> MultiSurface
151 * </ul>
152 * <p>
153 *
154 * @param element
155 * @param srsName
156 * default SRS for the geometry
157 * @return corresponding <code>Geometry</code> instance
158 * @throws GeometryException
159 * if type unsupported or conversion failed
160 */
161 public static Geometry wrap( Element element, String srsName )
162 throws GeometryException {
163
164 Geometry geometry = null;
165 try {
166 String name = element.getLocalName();
167 if ( ( name.equals( "Point" ) ) || ( name.equals( "Center" ) ) ) {
168 geometry = wrapPoint( element, srsName );
169 } else if ( name.equals( "LineString" ) ) {
170 geometry = wrapLineString( element, srsName );
171 } else if ( name.equals( "Polygon" ) ) {
172 geometry = wrapPolygon( element, srsName );
173 } else if ( name.equals( "MultiPoint" ) ) {
174 geometry = wrapMultiPoint( element, srsName );
175 } else if ( name.equals( "MultiLineString" ) ) {
176 geometry = wrapMultiLineString( element, srsName );
177 } else if ( name.equals( "MultiPolygon" ) ) {
178 geometry = wrapMultiPolygon( element, srsName );
179 } else if ( name.equals( "Box" ) || name.equals( "Envelope" ) ) {
180 geometry = wrapBoxAsSurface( element, srsName );
181 } else if ( name.equals( "Curve" ) ) {
182 geometry = wrapCurveAsCurve( element, srsName );
183 } else if ( name.equals( "Surface" ) ) {
184 geometry = wrapSurfaceAsSurface( element, srsName );
185 } else if ( name.equals( "MultiCurve" ) ) {
186 geometry = wrapMultiCurveAsMultiCurve( element, srsName );
187 } else if ( name.equals( "MultiSurface" ) ) {
188 geometry = wrapMultiSurfaceAsMultiSurface( element, srsName );
189 } else if ( name.equals( "CompositeSurface" ) ) {
190 geometry = wrapCompositeSurface( element, srsName );
191 } else {
192 new GeometryException( "Not a supported geometry type: " + name );
193 }
194 } catch ( Exception e ) {
195 LOG.logError( e.getMessage(), e );
196 throw new GeometryException( StringTools.stackTraceToString( e ) );
197 }
198 return geometry;
199 }
200
201 /**
202 * Returns an instance of {@link Envelope} created from the passed <code>gml:Box</code> or
203 * <code>gml:Envelope</code> element.
204 *
205 * @param element
206 * <code>gml:Box</code> or <code>gml:Envelope</code> element
207 * @param srsName
208 * default SRS for the geometry
209 * @return instance of <code>Envelope</code>
210 * @throws XMLParsingException
211 * @throws InvalidGMLException
212 * @throws UnknownCRSException
213 */
214 public static Envelope wrapBox( Element element, String srsName )
215 throws XMLParsingException, InvalidGMLException, UnknownCRSException {
216 Node elem = element;
217 while ( srsName == null && elem != null ) {
218 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
219 elem = elem.getParentNode();
220 }
221 CoordinateSystem crs = null;
222 if ( srsName != null ) {
223 crs = getCRS( srsName );
224 }
225 Position[] bb = null;
226 List nl = XMLTools.getNodes( element, COORD, nsContext );
227 if ( nl != null && nl.size() > 0 ) {
228 bb = new Position[2];
229 bb[0] = createPositionFromCoord( (Element) nl.get( 0 ) );
230 bb[1] = createPositionFromCoord( (Element) nl.get( 1 ) );
231 } else {
232 nl = XMLTools.getNodes( element, COORDINATES, nsContext );
233 if ( nl != null && nl.size() > 0 ) {
234 bb = createPositionFromCoordinates( (Element) nl.get( 0 ) );
235 } else {
236 nl = XMLTools.getNodes( element, POS, nsContext );
237 if ( nl != null && nl.size() > 0 ) {
238 bb = new Position[2];
239 bb[0] = createPositionFromPos( (Element) nl.get( 0 ) );
240 bb[1] = createPositionFromPos( (Element) nl.get( 1 ) );
241 } else {
242 Element lowerCorner = (Element) XMLTools.getRequiredNode( element, "gml:lowerCorner", nsContext );
243 Element upperCorner = (Element) XMLTools.getRequiredNode( element, "gml:upperCorner", nsContext );
244 bb = new Position[2];
245 bb[0] = createPositionFromCorner( lowerCorner );
246 bb[1] = createPositionFromCorner( upperCorner );
247 }
248 }
249 }
250 Envelope box = GeometryFactory.createEnvelope( bb[0], bb[1], crs );
251 return box;
252 }
253
254 /**
255 * Returns an instance of {@link Curve} created from the passed <code>gml:Curve</code>
256 * element.
257 *
258 * @param element
259 * <code>gml:Curve</code> element
260 * @param srsName
261 * default SRS for the geometry
262 * @return corresponding Curve instance
263 * @throws XMLParsingException
264 * @throws GeometryException
265 * @throws UnknownCRSException
266 */
267 protected static Curve wrapCurveAsCurve( Element element, String srsName )
268 throws XMLParsingException, GeometryException, UnknownCRSException {
269
270 Node elem = element;
271 while ( srsName == null && elem != null ) {
272 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
273 elem = elem.getParentNode();
274 }
275 CoordinateSystem crs = null;
276 if ( srsName != null ) {
277 crs = getCRS( srsName );
278 }
279
280 Element segment = (Element) XMLTools.getRequiredNode( element, "gml:segments", nsContext );
281 List list = XMLTools.getNodes( segment, "gml:LineStringSegment", nsContext );
282
283 CurveSegment[] segments = new CurveSegment[list.size()];
284 for ( int i = 0; i < list.size(); i++ ) {
285 Element lineStringSegment = (Element) list.get( i );
286 Position[] pos = null;
287 try {
288 pos = createPositions( lineStringSegment, srsName );
289 segments[i] = GeometryFactory.createCurveSegment( pos, crs );
290 } catch ( Exception e ) {
291 throw new GeometryException( "Error creating segments for the element LineStringSegment." );
292 }
293 }
294 return GeometryFactory.createCurve( segments, crs );
295 }
296
297 /**
298 * Returns an instance of {@link MultiCurve} created from the passed <code>gml:MultiCurve</code>
299 * element.
300 *
301 * @param element
302 * <code>gml:MultiCurve</code> element
303 * @param srsName
304 * default SRS for the geometry
305 * @return <code>MultiCurve</code> instance
306 * @throws XMLParsingException
307 * @throws GeometryException
308 * @throws UnknownCRSException
309 * @throws InvalidGMLException
310 */
311 protected static MultiCurve wrapMultiCurveAsMultiCurve( Element element, String srsName )
312 throws XMLParsingException, GeometryException, UnknownCRSException, InvalidGMLException {
313
314 Node elem = element;
315 while ( srsName == null && elem != null ) {
316 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
317 elem = elem.getParentNode();
318 }
319 CoordinateSystem crs = null;
320 if ( srsName != null ) {
321 crs = getCRS( srsName );
322 }
323
324 MultiCurve multiCurve = null;
325 try {
326 // gml:curveMember
327 List listCurveMember = XMLTools.getNodes( element, "gml:curveMember", nsContext );
328 List<Curve> curveList = new ArrayList<Curve>();
329 if ( listCurveMember.size() > 0 ) {
330
331 for ( int i = 0; i < listCurveMember.size(); i++ ) {
332 Element curveMember = (Element) listCurveMember.get( i );
333 Element curve = (Element) XMLTools.getNode( curveMember, "gml:Curve", nsContext );
334 if ( curve != null ) {
335 curveList.add( wrapCurveAsCurve( curve, srsName ) );
336 } else {
337 curve = (Element) XMLTools.getRequiredNode( curveMember, "gml:LineString", nsContext );
338 curveList.add( wrapLineString( curve, srsName ) );
339 }
340 }
341 }
342 Element curveMembers = (Element) XMLTools.getNode( element, "gml:curveMembers", nsContext );
343 if ( curveMembers != null ) {
344 // gml:curveMembers
345 List listCurves = XMLTools.getNodes( curveMembers, "gml:Curve", nsContext );
346 if ( listCurves != null ) {
347 for ( int i = 0; i < listCurves.size(); i++ ) {
348 Element curve = (Element) listCurves.get( i );
349 curveList.add( wrapCurveAsCurve( curve, srsName ) );
350 }
351 }
352 listCurves = XMLTools.getNodes( curveMembers, "gml:LineString", nsContext );
353 if ( listCurves != null ) {
354 for ( int i = 0; i < listCurves.size(); i++ ) {
355 Element curve = (Element) listCurves.get( i );
356 curveList.add( wrapLineString( curve, srsName ) );
357 }
358 }
359 }
360 Curve[] curves = new Curve[curveList.size()];
361 multiCurve = GeometryFactory.createMultiCurve( curveList.toArray( curves ), crs );
362 } catch ( XMLParsingException e ) {
363 LOG.logError( e.getMessage(), e );
364 throw new XMLParsingException( "Error parsing <gml:curveMember> elements. Please check the xml document." );
365 } catch ( GeometryException e ) {
366 LOG.logError( e.getMessage(), e );
367 throw new GeometryException(
368 "Error creating a curve from the curve element. Please check the GML specifications "
369 + "for correct element declaration." );
370 }
371 return multiCurve;
372 }
373
374 /**
375 * Returns an instance of {@link Surface} created from the passed <code>gml:Surface</code>
376 * element.
377 *
378 * @param element
379 * @param srsName
380 * default SRS for the geometry
381 * @return Surface
382 * @throws XMLParsingException
383 * @throws GeometryException
384 * @throws UnknownCRSException
385 */
386 protected static Surface wrapSurfaceAsSurface( Element element, String srsName )
387 throws XMLParsingException, GeometryException, UnknownCRSException {
388
389 Node elem = element;
390 while ( srsName == null && elem != null ) {
391 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
392 elem = elem.getParentNode();
393 }
394 CoordinateSystem crs = null;
395 if ( srsName != null ) {
396 crs = getCRS( srsName );
397 }
398
399 Element patches = extractPatches( element );
400 List<Element> polygonList = XMLTools.getRequiredElements( patches, "gml:Polygon | gml:PolygonPatch", nsContext );
401
402 Polygon[] polygons = new Polygon[polygonList.size()];
403
404 for ( int i = 0; i < polygonList.size(); i++ ) {
405 Element polygon = polygonList.get( i );
406 try {
407 Element exterior = (Element) XMLTools.getNode( polygon, "gml:exterior", nsContext );
408 Position[] exteriorRing = null;
409
410 if ( exterior != null ) {
411 Element linearRing = (Element) XMLTools.getRequiredNode( exterior, "gml:LinearRing", nsContext );
412 String ringSrsName = XMLTools.getNodeAsString( linearRing, "@srsName", nsContext, srsName );
413 exteriorRing = createPositions( linearRing, ringSrsName );
414 }
415
416 List<Element> interiorList = XMLTools.getElements( polygon, "gml:interior", nsContext );
417 Position[][] interiorRings = null;
418 if ( interiorList != null && interiorList.size() > 0 ) {
419
420 interiorRings = new Position[interiorList.size()][];
421
422 for ( int j = 0; j < interiorRings.length; j++ ) {
423 Element interior = interiorList.get( j );
424 Element linearRing = (Element) XMLTools.getRequiredNode( interior, "gml:LinearRing", nsContext );
425 String ringSrsName = XMLTools.getNodeAsString( linearRing, "@srsName", nsContext, srsName );
426 interiorRings[j] = createPositions( interior, ringSrsName );
427 }
428 }
429 SurfaceInterpolation si = new SurfaceInterpolationImpl();
430 polygons[i] = (Polygon) GeometryFactory.createSurfacePatch( exteriorRing, interiorRings, si, crs );
431 } catch ( InvalidGMLException e ) {
432 LOG.logError( e.getMessage(), e );
433 throw new XMLParsingException( "Error parsing the polygon element '" + polygon.getNodeName()
434 + "' to create a surface geometry." + e.getMessage() );
435 }
436
437 // catch ( Exception e ) {
438
439 // }
440 }
441 Surface surface = null;
442 try {
443 surface = GeometryFactory.createSurface( polygons, crs );
444 } catch ( GeometryException e ) {
445 throw new GeometryException( "Error creating a surface from '" + polygons.length + "' polygons." );
446 }
447 return surface;
448 }
449
450 /**
451 * Returns an instance of {@link MultiSurface} created from the passed
452 * <code>gml:MultiSurface</code> element.
453 *
454 * @param element
455 * <code>gml:MultiSurface</code> element
456 * @param srsName
457 * default SRS for the geometry
458 * @return MultiSurface
459 * @throws XMLParsingException
460 * @throws GeometryException
461 * @throws InvalidGMLException
462 * @throws UnknownCRSException
463 */
464 protected static MultiSurface wrapMultiSurfaceAsMultiSurface( Element element, String srsName )
465 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
466
467 Node elem = element;
468 while ( srsName == null && elem != null ) {
469 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
470 elem = elem.getParentNode();
471 }
472 CoordinateSystem crs = null;
473 if ( srsName != null ) {
474 crs = getCRS( srsName );
475 }
476 MultiSurface multiSurface = null;
477 try {
478 List<Surface> surfaceList = new ArrayList<Surface>();
479 // gml:surfaceMember
480 List listSurfaceMember = XMLTools.getNodes( element, "gml:surfaceMember", nsContext );
481 if ( listSurfaceMember != null ) {
482 for ( int i = 0; i < listSurfaceMember.size(); i++ ) {
483 Element surfaceMember = (Element) listSurfaceMember.get( i );
484 Element surface = (Element) XMLTools.getNode( surfaceMember, "gml:Surface", nsContext );
485 if ( surface != null ) {
486 surfaceList.add( wrapSurfaceAsSurface( surface, srsName ) );
487 } else {
488 surface = (Element) XMLTools.getRequiredNode( surfaceMember, ".//gml:Polygon", nsContext );
489 surfaceList.add( wrapPolygon( surface, srsName ) );
490 }
491 }
492 }
493
494 Element surfaceMembers = (Element) XMLTools.getNode( element, "gml:surfaceMembers", nsContext );
495 if ( surfaceMembers != null ) {
496 // gml:surfaceMembers
497
498 List listSurfaces = XMLTools.getNodes( surfaceMembers, "gml:Surface", nsContext );
499 if ( listSurfaces != null ) {
500 for ( int i = 0; i < listSurfaces.size(); i++ ) {
501 Element surface = (Element) listSurfaces.get( i );
502 surfaceList.add( wrapSurfaceAsSurface( surface, srsName ) );
503 }
504 }
505
506 listSurfaces = XMLTools.getNodes( surfaceMembers, ".//gml:Polygon", nsContext );
507 if ( listSurfaces != null ) {
508 for ( int i = 0; i < listSurfaces.size(); i++ ) {
509 Element surface = (Element) listSurfaces.get( i );
510 surfaceList.add( wrapPolygon( surface, srsName ) );
511 }
512 }
513 }
514 Surface[] surfaces = new Surface[surfaceList.size()];
515 surfaces = surfaceList.toArray( surfaces );
516 multiSurface = GeometryFactory.createMultiSurface( surfaces, crs );
517 } catch ( XMLParsingException e ) {
518 LOG.logError( e.getMessage(), e );
519 String msg = Messages.getMessage( "GEOM_MULTISURFACE_PARSING_ERROR" );
520 throw new XMLParsingException( msg );
521 } catch ( GeometryException e ) {
522 LOG.logError( e.getMessage(), e );
523 String msg = Messages.getMessage( "GEOM_MULTISURFACE_FORMAT_ERROR" );
524 throw new GeometryException( msg );
525 }
526 return multiSurface;
527 }
528
529 /**
530 * Returns a {@link Point} instance created from the passed <code>gml:Point</code> element.
531 *
532 * @param element
533 * <code>gml:Point</code> element
534 * @param srsName
535 * default SRS for the geometry
536 * @return instance of Point
537 * @throws XMLParsingException
538 * @throws UnknownCRSException
539 */
540 private static Point wrapPoint( Element element, String srsName )
541 throws XMLParsingException, InvalidGMLException, UnknownCRSException {
542
543 Node elem = element;
544 while ( srsName == null && elem != null ) {
545 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
546 elem = elem.getParentNode();
547 }
548 CoordinateSystem crs = null;
549 if ( srsName != null ) {
550 crs = getCRS( srsName );
551 }
552
553 Position[] bb = null;
554 List nl = XMLTools.getNodes( element, COORD, nsContext );
555 if ( nl != null && nl.size() > 0 ) {
556 bb = new Position[1];
557 bb[0] = createPositionFromCoord( (Element) nl.get( 0 ) );
558 } else {
559 nl = XMLTools.getNodes( element, COORDINATES, nsContext );
560 if ( nl != null && nl.size() > 0 ) {
561 bb = createPositionFromCoordinates( (Element) nl.get( 0 ) );
562 } else {
563 nl = XMLTools.getNodes( element, POS, nsContext );
564 bb = new Position[1];
565 bb[0] = createPositionFromPos( (Element) nl.get( 0 ) );
566 }
567 }
568 Point point = GeometryFactory.createPoint( bb[0], crs );
569 return point;
570 }
571
572 /**
573 * Returns a {@link Curve} instance created from the passed <code>gml:LineString</code>
574 * element.
575 *
576 * @param element
577 * <code>gml:LineString</code> element
578 * @param srsName
579 * default SRS for the geometry
580 * @return instance of Curve
581 * @throws XMLParsingException
582 * @throws UnknownCRSException
583 */
584 private static Curve wrapLineString( Element element, String srsName )
585 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
586
587 Node elem = element;
588 while ( srsName == null && elem != null ) {
589 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
590 elem = elem.getParentNode();
591 }
592 CoordinateSystem crs = null;
593 if ( srsName != null ) {
594 crs = getCRS( srsName );
595 }
596 Position[] pos = createPositions( element, srsName );
597 Curve curve = GeometryFactory.createCurve( pos, crs );
598 return curve;
599 }
600
601 /**
602 * Returns a {@link Surface} instance created from the passed <code>gml:Polygon</code>
603 * element.
604 *
605 * @param element
606 * <code>gml:Polygon</code> element
607 * @param srsName
608 * default SRS for the geometry
609 * @return instance of Surface
610 * @throws XMLParsingException
611 * @throws UnknownCRSException
612 */
613 private static Surface wrapPolygon( Element element, String srsName )
614 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
615
616 Node elem = element;
617 while ( srsName == null && elem != null ) {
618 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
619 elem = elem.getParentNode();
620 }
621 CoordinateSystem crs = null;
622 if ( srsName != null ) {
623 crs = getCRS( srsName );
624 }
625
626 List nl = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":outerBoundaryIs", nsContext );
627 if ( nl == null || nl.size() == 0 ) {
628 nl = XMLTools.getRequiredNodes( element, CommonNamespaces.GML_PREFIX + ":exterior", nsContext );
629 }
630 Element outs = (Element) nl.get( 0 );
631 nl = XMLTools.getRequiredNodes( outs, CommonNamespaces.GML_PREFIX + ":LinearRing", nsContext );
632 Element ring = (Element) nl.get( 0 );
633 nl = XMLTools.getNodes( ring, COORDINATES, nsContext );
634 Position[] outerRing = createPositions( ring, srsName );
635
636 Position[][] innerRings = null;
637 List inns = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":innerBoundaryIs", nsContext );
638 if ( inns == null || inns.size() == 0 ) {
639 inns = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":interior", nsContext );
640 }
641 if ( inns != null && inns.size() > 0 ) {
642 innerRings = new Position[inns.size()][];
643 for ( int i = 0; i < innerRings.length; i++ ) {
644
645 nl = XMLTools.getRequiredNodes( (Node) inns.get( i ), CommonNamespaces.GML_PREFIX + ":LinearRing",
646 nsContext );
647
648 ring = (Element) nl.get( 0 );
649 innerRings[i] = createPositions( ring, srsName );
650 }
651 }
652
653 SurfaceInterpolation si = new SurfaceInterpolationImpl();
654 Surface surface = GeometryFactory.createSurface( outerRing, innerRings, si, crs );
655 return surface;
656 }
657
658 /**
659 * Returns a {@link MultiPoint} instance created from the passed <code>gml:MultiPoint</code>
660 * element.
661 *
662 * @param element
663 * <code>gml:MultiPoint</code> element
664 * @param srsName
665 * default SRS for the geometry
666 * @return instance of MultiPoint
667 * @throws XMLParsingException
668 * @throws UnknownCRSException
669 */
670 private static MultiPoint wrapMultiPoint( Element element, String srsName )
671 throws XMLParsingException, InvalidGMLException, UnknownCRSException {
672
673 Node elem = element;
674 while ( srsName == null && elem != null ) {
675 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
676 elem = elem.getParentNode();
677 }
678 CoordinateSystem crs = null;
679 if ( srsName != null ) {
680 crs = getCRS( srsName );
681 }
682
683 List<Point> pointList = new ArrayList<Point>();
684 List listPointMember = XMLTools.getNodes( element, "gml:pointMember", nsContext );
685 if ( listPointMember != null ) {
686 for ( int i = 0; i < listPointMember.size(); i++ ) {
687 Element pointMember = (Element) listPointMember.get( i );
688 Element point = (Element) XMLTools.getNode( pointMember, "gml:Point", nsContext );
689 pointList.add( wrapPoint( point, srsName ) );
690 }
691 }
692
693 Element pointMembers = (Element) XMLTools.getNode( element, "gml:pointMembers", nsContext );
694 if ( pointMembers != null ) {
695 List pointElems = XMLTools.getNodes( pointMembers, "gml:Point", nsContext );
696 for ( int j = 0; j < pointElems.size(); j++ ) {
697 pointList.add( wrapPoint( (Element) pointElems.get( j ), srsName ) );
698 }
699 }
700
701 Point[] points = new Point[pointList.size()];
702 return GeometryFactory.createMultiPoint( pointList.toArray( points ), crs );
703
704 }
705
706 /**
707 * Returns a {@link MultiCurve} instance created from the passed
708 * <code>gml:MultiLineString</code> element.
709 *
710 * @param element
711 * <code>gml:MultiLineString</code> element
712 * @param srsName
713 * default SRS for the geometry
714 * @return instance of MultiCurve
715 * @throws XMLParsingException
716 * @throws UnknownCRSException
717 */
718 private static MultiCurve wrapMultiLineString( Element element, String srsName )
719 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
720
721 Node elem = element;
722 while ( srsName == null && elem != null ) {
723 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
724 elem = elem.getParentNode();
725 }
726 CoordinateSystem crs = null;
727 if ( srsName != null ) {
728 crs = getCRS( srsName );
729 }
730
731 ElementList el = XMLTools.getChildElements( "lineStringMember", CommonNamespaces.GMLNS, element );
732 Curve[] curves = new Curve[el.getLength()];
733 for ( int i = 0; i < curves.length; i++ ) {
734 curves[i] = wrapLineString( XMLTools.getFirstChildElement( el.item( i ) ), srsName );
735 }
736 MultiCurve mp = GeometryFactory.createMultiCurve( curves, crs );
737 return mp;
738 }
739
740 /**
741 * Returns a {@link MultiSurface} instance created from the passed <code>gml:MultiPolygon</code>
742 * element.
743 *
744 * @param element
745 * <code>gml:MultiPolygon</code> element
746 * @param srsName
747 * default SRS for the geometry
748 * @return instance of MultiCurve
749 *
750 * @throws XMLParsingException
751 * @throws UnknownCRSException
752 */
753 private static MultiSurface wrapMultiPolygon( Element element, String srsName )
754 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
755
756 Node elem = element;
757 while ( srsName == null && elem != null ) {
758 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
759 elem = elem.getParentNode();
760 }
761 CoordinateSystem crs = null;
762 if ( srsName != null ) {
763 crs = getCRS( srsName );
764 }
765
766 ElementList el = XMLTools.getChildElements( "polygonMember", CommonNamespaces.GMLNS, element );
767 Surface[] surfaces = new Surface[el.getLength()];
768 for ( int i = 0; i < surfaces.length; i++ ) {
769 surfaces[i] = wrapPolygon( XMLTools.getFirstChildElement( el.item( i ) ), srsName );
770 }
771 return GeometryFactory.createMultiSurface( surfaces, crs );
772 }
773
774 /**
775 * Returns a <code>Surface</code> created from the given <code>gml:Box</code> element. This
776 * method is useful because an Envelope that would normally be created from a Box isn't a
777 * geometry in context of ISO 19107.
778 *
779 * @param element
780 * <code>gml:Box</code> element
781 * @return instance of <code>Surface</code>
782 * @throws XMLParsingException
783 * @throws UnknownCRSException
784 */
785 private static Surface wrapBoxAsSurface( Element element, String srsName )
786 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
787 Envelope env = wrapBox( element, srsName );
788 return GeometryFactory.createSurface( env, env.getCoordinateSystem() );
789 }
790
791 /**
792 * Returns an instance of {@link CompositeSurface} created from the passed
793 * <code>gml:CompositeSurface</code> element.
794 *
795 * TODO
796 *
797 * @param element
798 * @param srsName
799 * default SRS for the geometry
800 * @return CompositeSurface
801 * @throws GeometryException
802 */
803 private static CompositeSurface wrapCompositeSurface( Element element, String srsName ) {
804 throw new UnsupportedOperationException( "#wrapCompositeSurface(Element) is not implemented as yet. Work in Progress." );
805 }
806
807 /**
808 * Extract the <gml:patches> node from a <gml:Surface> element.
809 *
810 * @param surface
811 * @return Element
812 * @throws XMLParsingException
813 */
814 private static Element extractPatches( Element surface )
815 throws XMLParsingException {
816 Element patches = null;
817 try {
818 patches = (Element) XMLTools.getRequiredNode( surface, "gml:patches", nsContext );
819 } catch ( XMLParsingException e ) {
820 throw new XMLParsingException( "Error retrieving the patches element from the surface element." );
821 }
822 return patches;
823 }
824
825 /**
826 * returns an instance of CS_CoordinateSystem corrsponding to the passed crs name
827 *
828 * @param name
829 * name of the crs
830 *
831 * @return CS_CoordinateSystem
832 * @throws UnknownCRSException
833 */
834 private static CoordinateSystem getCRS( String name )
835 throws UnknownCRSException {
836
837 if ( ( name != null ) && ( name.length() > 2 ) ) {
838 if ( name.startsWith( "http://www.opengis.net/gml/srs/" ) ) {
839 // as declared in the GML 2.1.1 specification
840 // http://www.opengis.net/gml/srs/epsg.xml#4326
841 int p = name.lastIndexOf( "/" );
842
843 if ( p >= 0 ) {
844 name = name.substring( p, name.length() );
845 p = name.indexOf( "." );
846
847 String s1 = name.substring( 1, p ).toUpperCase();
848 p = name.indexOf( "#" );
849
850 String s2 = name.substring( p + 1, name.length() );
851 name = s1 + ":" + s2;
852 }
853 }
854 }
855
856 CoordinateSystem crs = crsMap.get( name );
857 if ( crs == null ) {
858 crs = CRSFactory.create( name );
859 crsMap.put( name, crs );
860 }
861 return crs;
862 }
863
864 private static Position createPositionFromCorner( Element corner )
865 throws InvalidGMLException {
866
867 String tmp = XMLTools.getAttrValue( corner, null, "dimension", null );
868 int dim = 0;
869 if ( tmp != null ) {
870 dim = Integer.parseInt( tmp );
871 }
872 tmp = XMLTools.getStringValue( corner );
873 double[] vals = StringTools.toArrayDouble( tmp, ", " );
874 if ( dim != 0 ) {
875 if ( vals.length != dim ) {
876 throw new InvalidGMLException( "dimension must be equal to the number of coordinate values defined "
877 + "in pos element." );
878 }
879 } else {
880 dim = vals.length;
881 }
882
883 Position pos = null;
884 if ( dim == 3 ) {
885 pos = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
886 } else {
887 pos = GeometryFactory.createPosition( vals[0], vals[1] );
888 }
889
890 return pos;
891
892 }
893
894 /**
895 * returns an instance of Position created from the passed coord
896 *
897 * @param element
898 * <coord>
899 *
900 * @return instance of <tt>Position</tt>
901 *
902 * @throws XMLParsingException
903 */
904 private static Position createPositionFromCoord( Element element )
905 throws XMLParsingException {
906
907 Position pos = null;
908 Element elem = XMLTools.getRequiredChildElement( "X", CommonNamespaces.GMLNS, element );
909 double x = Double.parseDouble( XMLTools.getStringValue( elem ) );
910 elem = XMLTools.getRequiredChildElement( "Y", CommonNamespaces.GMLNS, element );
911 double y = Double.parseDouble( XMLTools.getStringValue( elem ) );
912 elem = XMLTools.getChildElement( "Z", CommonNamespaces.GMLNS, element );
913
914 if ( elem != null ) {
915 double z = Double.parseDouble( XMLTools.getStringValue( elem ) );
916 pos = GeometryFactory.createPosition( new double[] { x, y, z } );
917 } else {
918 pos = GeometryFactory.createPosition( new double[] { x, y } );
919 }
920
921 return pos;
922 }
923
924 /**
925 * returns an array of Positions created from the passed coordinates
926 *
927 * @param element
928 * <coordinates>
929 *
930 * @return instance of <tt>Position[]</tt>
931 *
932 * @throws XMLParsingException
933 */
934 private static Position[] createPositionFromCoordinates( Element element ) {
935
936 Position[] points = null;
937 //fixing the failure coming from the usage of the xmltools.getAttrib method
938 String ts = XMLTools.getAttrValue( element, null, "ts", " " );
939
940 // not used because javas current decimal seperator will be used
941 // String ds = XMLTools.getAttrValue( element, null, "decimal", "." );
942 String cs = XMLTools.getAttrValue( element, null, "cs", "," );
943
944 String value = XMLTools.getStringValue( element ).trim();
945
946 // first tokenizer, tokens the tuples
947 StringTokenizer tuple = new StringTokenizer( value, ts );
948 points = new Position[tuple.countTokens()];
949 int i = 0;
950 while ( tuple.hasMoreTokens() ) {
951 String s = tuple.nextToken();
952 // second tokenizer, tokens the coordinates
953 StringTokenizer coort = new StringTokenizer( s, cs );
954 double[] p = new double[coort.countTokens()];
955
956 for ( int k = 0; k < p.length; k++ ) {
957 s = coort.nextToken();
958 p[k] = Double.parseDouble( s );
959 }
960
961 points[i++] = GeometryFactory.createPosition( p );
962 }
963
964 return points;
965 }
966
967 /**
968 * creates a <tt>Point</tt> from the passed <pos> element containing a GML pos.
969 *
970 * @param element
971 * @return created <tt>Point</tt>
972 * @throws XMLParsingException
973 * @throws InvalidGMLException
974 */
975 private static Position createPositionFromPos( Element element )
976 throws InvalidGMLException {
977
978 String tmp = XMLTools.getAttrValue( element, null, "dimension", null );
979 int dim = 0;
980 if ( tmp != null ) {
981 dim = Integer.parseInt( tmp );
982 }
983 tmp = XMLTools.getStringValue( element );
984 double[] vals = StringTools.toArrayDouble( tmp, "\t\n\r\f ," );
985 if ( dim != 0 ) {
986 if ( vals.length != dim ) {
987 throw new InvalidGMLException( "dimension must be equal to the number of "
988 + "coordinate values defined in pos element." );
989 }
990 } else {
991 dim = vals.length;
992 }
993
994 Position pos = null;
995 if ( dim == 3 ) {
996 pos = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
997 } else {
998 pos = GeometryFactory.createPosition( vals[0], vals[1] );
999 }
1000
1001 return pos;
1002 }
1003
1004 /**
1005 *
1006 * @param element
1007 * @return Position
1008 * @throws InvalidGMLException
1009 * @throws XMLParsingException
1010 */
1011 private static Position[] createPositionFromPosList( Element element, String srsName )
1012 throws InvalidGMLException, XMLParsingException {
1013
1014 Node elem = element;
1015 while ( srsName == null && elem != null ) {
1016 srsName = XMLTools.getNodeAsString( elem, "@srsName", nsContext, srsName );
1017 elem = elem.getParentNode();
1018 }
1019
1020 String srsDimension = XMLTools.getAttrValue( element, null, "srsDimension", null );
1021 int dim = 0;
1022 if ( srsDimension != null ) {
1023 dim = Integer.parseInt( srsDimension );
1024 }
1025 if ( dim == 0 ) {
1026 // TODO
1027 // determine dimension from CRS
1028 // default dimension set.
1029 dim = 2;
1030
1031 }
1032
1033 String axisLabels = XMLTools.getAttrValue( element, null, "gml:axisAbbrev", null );
1034
1035 String uomLabels = XMLTools.getAttrValue( element, null, "uomLabels", null );
1036
1037 if ( srsName == null ) {
1038 if ( srsDimension != null ) {
1039 throw new InvalidGMLException(
1040 "Attribute srsDimension cannot be defined unless attribute srsName has been defined." );
1041 }
1042 if ( axisLabels != null ) {
1043 throw new InvalidGMLException(
1044 "Attribute axisLabels cannot be defined unless attribute srsName has been defined." );
1045 }
1046
1047 }
1048 if ( axisLabels == null ) {
1049 if ( uomLabels != null ) {
1050 throw new InvalidGMLException(
1051 "Attribute uomLabels cannot be defined unless attribute axisLabels has been defined." );
1052 }
1053 }
1054 String tmp = XMLTools.getStringValue( element );
1055 double[] values = StringTools.toArrayDouble( tmp, "\t\n\r\f ," );
1056 int size = values.length / dim;
1057 if ( values.length < 4 ) {
1058 throw new InvalidGMLException( "A point list must have minimum 2 coordinate tuples. Here only '" + size
1059 + "' are defined." );
1060 }
1061 double positions[][] = new double[size][dim];
1062 int a = 0, b = 0;
1063 for ( int i = 0; i < values.length; i++ ) {
1064 if ( b == dim ) {
1065 a++;
1066 b = 0;
1067 }
1068 positions[a][b] = values[i];
1069 b++;
1070 }
1071
1072 Position[] position = new Position[positions.length];
1073 for ( int i = 0; i < positions.length; i++ ) {
1074 double[] vals = positions[i];
1075 if ( dim == 3 ) {
1076 position[i] = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
1077 } else {
1078 position[i] = GeometryFactory.createPosition( vals[0], vals[1] );
1079 }
1080 }
1081
1082 return position;
1083
1084 }
1085
1086 /**
1087 * creates an array of <tt>Position</tt>s from the <coordinates> or <pos> Elements located as
1088 * children under the passed parent element.
1089 * <p>
1090 * example:<br>
1091 *
1092 * <pre>
1093 * <gml:Box>
1094 * <gml:coordinates cs="," decimal="." ts=" ">0,0 4000,4000</gml:coordinates>
1095 * </gml:Box>
1096 * </pre>
1097 *
1098 * </p>
1099 *
1100 * @param parent
1101 * @param srsName
1102 * @return
1103 * @throws XMLParsingException
1104 * @throws InvalidGMLException
1105 */
1106 private static Position[] createPositions( Element parent, String srsName )
1107 throws XMLParsingException, InvalidGMLException {
1108
1109 List nl = XMLTools.getNodes( parent, COORDINATES, nsContext );
1110 Position[] pos = null;
1111 if ( nl != null && nl.size() > 0 ) {
1112 pos = createPositionFromCoordinates( (Element) nl.get( 0 ) );
1113 } else {
1114 nl = XMLTools.getNodes( parent, POS, nsContext );
1115 if ( nl != null && nl.size() > 0 ) {
1116 pos = new Position[nl.size()];
1117 for ( int i = 0; i < pos.length; i++ ) {
1118 pos[i] = createPositionFromPos( (Element) nl.get( i ) );
1119 }
1120 } else {
1121 Element posList = (Element) XMLTools.getRequiredNode( parent, POSLIST, nsContext );
1122 if ( posList != null ) {
1123 pos = createPositionFromPosList( posList, srsName );
1124 }
1125 }
1126 }
1127 return pos;
1128 }
1129
1130 /**
1131 * Creates a GML representation from the passed <code>Geometry<code>
1132 *
1133 * @param geometry
1134 * @param target
1135 * @throws GeometryException
1136 */
1137 public static PrintWriter export( Geometry geometry, OutputStream target )
1138 throws GeometryException {
1139
1140 PrintWriter printwriter = new PrintWriter( target );
1141
1142 if ( geometry instanceof SurfacePatch ) {
1143 geometry = new SurfaceImpl( (SurfacePatch) geometry );
1144 } else if ( geometry instanceof LineString ) {
1145 geometry = new CurveImpl( (LineString) geometry );
1146 }
1147 // create geometries from the wkb considering the geomerty typ
1148 if ( geometry instanceof Point ) {
1149 exportPoint( (Point) geometry, printwriter );
1150 } else if ( geometry instanceof Curve ) {
1151 exportCurve( (Curve) geometry, printwriter );
1152 } else if ( geometry instanceof Surface ) {
1153 exportSurface( (Surface) geometry, printwriter );
1154 } else if ( geometry instanceof MultiPoint ) {
1155 exportMultiPoint( (MultiPoint) geometry, printwriter );
1156 } else if ( geometry instanceof MultiCurve ) {
1157 exportMultiCurve( (MultiCurve) geometry, printwriter );
1158 } else if ( geometry instanceof MultiSurface ) {
1159 exportMultiSurface( (MultiSurface) geometry, printwriter );
1160 }
1161 printwriter.flush();
1162 return printwriter;
1163 }
1164
1165 /**
1166 * Creates a GML representation from the passed <code>Geometry</code>.
1167 *
1168 * @param geometry
1169 * @return
1170 * @throws GeometryException
1171 */
1172 public static StringBuffer export( Geometry geometry )
1173 throws GeometryException {
1174
1175 if ( geometry instanceof SurfacePatch ) {
1176 geometry = new SurfaceImpl( (SurfacePatch) geometry );
1177 } else if ( geometry instanceof LineString ) {
1178 geometry = new CurveImpl( (LineString) geometry );
1179 }
1180
1181 StringBuffer sb = null;
1182 // create geometries from the wkb considering the geomerty typ
1183 if ( geometry instanceof Point ) {
1184 sb = exportPoint( (Point) geometry );
1185 } else if ( geometry instanceof Curve ) {
1186 sb = exportCurve( (Curve) geometry );
1187 } else if ( geometry instanceof Surface ) {
1188 sb = exportSurface( (Surface) geometry );
1189 } else if ( geometry instanceof MultiPoint ) {
1190 sb = exportMultiPoint( (MultiPoint) geometry );
1191 } else if ( geometry instanceof MultiCurve ) {
1192 sb = exportMultiCurve( (MultiCurve) geometry );
1193 } else if ( geometry instanceof MultiSurface ) {
1194 sb = exportMultiSurface( (MultiSurface) geometry );
1195 }
1196
1197 return sb;
1198 }
1199
1200 /**
1201 * creates a GML representation from the passed <tt>Envelope</tt>. This method is required
1202 * because in ISO 19107 Envelops are no geometries.
1203 *
1204 * @param envelope
1205 * @return
1206 * @throws GeometryException
1207 */
1208 public static StringBuffer exportAsBox( Envelope envelope ) {
1209
1210 StringBuffer sb = new StringBuffer( "<gml:Box xmlns:gml='http://www.opengis.net/gml'>" );
1211 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1212 sb.append( envelope.getMin().getX() ).append( ',' );
1213 sb.append( envelope.getMin().getY() );
1214 int dim = envelope.getMax().getCoordinateDimension();
1215 if ( dim == 3 ) {
1216 sb.append( ',' ).append( envelope.getMin().getZ() );
1217 }
1218 sb.append( ' ' ).append( envelope.getMax().getX() );
1219 sb.append( ',' ).append( envelope.getMax().getY() );
1220 if ( dim == 3 ) {
1221 sb.append( ',' ).append( envelope.getMax().getZ() );
1222 }
1223 sb.append( "</gml:coordinates></gml:Box>" );
1224
1225 return sb;
1226 }
1227
1228 /**
1229 * creates a GML representation from the passed <tt>Envelope</tt>. This method is required
1230 * because in ISO 19107 Envelops are no geometries.
1231 *
1232 * @param envelope
1233 * @return
1234 * @throws GeometryException
1235 */
1236 public static StringBuffer exportAsEnvelope( Envelope envelope ) {
1237
1238 StringBuffer sb = new StringBuffer( "<gml:Envelope " );
1239 sb.append( "xmlns:gml='http://www.opengis.net/gml'>" );
1240 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1241 sb.append( envelope.getMin().getX() ).append( ',' );
1242 sb.append( envelope.getMin().getY() );
1243 int dim = envelope.getMax().getCoordinateDimension();
1244 if ( dim == 3 ) {
1245 sb.append( ',' ).append( envelope.getMin().getZ() );
1246 }
1247 sb.append( ' ' ).append( envelope.getMax().getX() );
1248 sb.append( ',' ).append( envelope.getMax().getY() );
1249 if ( dim == 3 ) {
1250 sb.append( ',' ).append( envelope.getMax().getZ() );
1251 }
1252 sb.append( "</gml:coordinates></gml:Envelope>" );
1253
1254 return sb;
1255 }
1256
1257 /**
1258 * creates a GML expression of a point geometry
1259 *
1260 * @param o
1261 * point geometry
1262 *
1263 * @return
1264 */
1265 private static StringBuffer exportPoint( Point o ) {
1266
1267 StringBuffer sb = new StringBuffer( 200 );
1268 String crs = null;
1269 if ( o.getCoordinateSystem() != null ) {
1270 crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
1271 }
1272 if ( crs != null ) {
1273 sb.append( "<gml:Point srsName=\"" ).append( crs ).append( "\">" );
1274 } else {
1275 sb.append( "<gml:Point>" );
1276 }
1277 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1278 sb.append( o.getX() ).append( ',' ).append( o.getY() );
1279 if ( o.getCoordinateDimension() == 3 ) {
1280 sb.append( "," + o.getZ() );
1281 }
1282 sb.append( "</gml:coordinates>" );
1283 sb.append( "</gml:Point>" );
1284
1285 return sb;
1286 }
1287
1288 /**
1289 * creates a GML expression of a curve geometry
1290 *
1291 * @param o
1292 * curve geometry
1293 *
1294 * @return
1295 *
1296 * @throws GeometryException
1297 */
1298 private static StringBuffer exportCurve( Curve o )
1299 throws GeometryException {
1300
1301 Position[] p = o.getAsLineString().getPositions();
1302
1303 StringBuffer sb = new StringBuffer( p.length * 40 );
1304
1305 String crs = null;
1306 if ( o.getCoordinateSystem() != null ) {
1307 crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
1308 }
1309
1310 if ( crs != null ) {
1311 sb.append( "<gml:LineString srsName=\"" + crs + "\">" );
1312 } else {
1313 sb.append( "<gml:LineString>" );
1314 }
1315
1316 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1317
1318 for ( int i = 0; i < ( p.length - 1 ); i++ ) {
1319 sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
1320 if ( o.getCoordinateDimension() == 3 ) {
1321 sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
1322 } else {
1323 sb.append( ' ' );
1324 }
1325 }
1326
1327 sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
1328 if ( o.getCoordinateDimension() == 3 ) {
1329 sb.append( ',' ).append( p[p.length - 1].getZ() );
1330 }
1331 sb.append( "</gml:coordinates></gml:LineString>" );
1332
1333 return sb;
1334 }
1335
1336 /**
1337 * @param sur
1338 * @return
1339 * @throws RemoteException
1340 * @throws GeometryException
1341 */
1342 private static StringBuffer exportSurface( Surface sur )
1343 throws GeometryException {
1344
1345 StringBuffer sb = new StringBuffer( 5000 );
1346
1347 String crs = null;
1348 if ( sur.getCoordinateSystem() != null ) {
1349 crs = sur.getCoordinateSystem().getName().replace( ' ', ':' );
1350 }
1351
1352 if ( crs != null ) {
1353 sb.append( "<gml:Polygon srsName=\"" + crs + "\">" );
1354 } else {
1355 sb.append( "<gml:Polygon>" );
1356 }
1357
1358 SurfacePatch patch = sur.getSurfacePatchAt( 0 );
1359
1360 // exterior ring
1361 sb.append( "<gml:outerBoundaryIs><gml:LinearRing>" );
1362 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1363
1364 Position[] p = patch.getExteriorRing();
1365
1366 for ( int i = 0; i < ( p.length - 1 ); i++ ) {
1367 sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
1368 if ( sur.getCoordinateDimension() == 3 ) {
1369 sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
1370 } else {
1371 sb.append( ' ' );
1372 }
1373 }
1374
1375 sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
1376 if ( sur.getCoordinateDimension() == 3 ) {
1377 sb.append( ',' ).append( p[p.length - 1].getZ() );
1378 }
1379 sb.append( "</gml:coordinates>" );
1380 sb.append( "</gml:LinearRing></gml:outerBoundaryIs>" );
1381
1382 // interior rings
1383 Position[][] ip = patch.getInteriorRings();
1384
1385 if ( ip != null ) {
1386 for ( int j = 0; j < ip.length; j++ ) {
1387 sb.append( "<gml:innerBoundaryIs><gml:LinearRing>" );
1388 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1389
1390 for ( int i = 0; i < ( ip[j].length - 1 ); i++ ) {
1391 sb.append( ip[j][i].getX() ).append( ',' ).append( ip[j][i].getY() );
1392 if ( sur.getCoordinateDimension() == 3 ) {
1393 sb.append( ',' ).append( ip[j][i].getZ() ).append( ' ' );
1394 } else {
1395 sb.append( ' ' );
1396 }
1397 }
1398
1399 sb.append( ip[j][ip[j].length - 1].getX() ).append( ',' );
1400 sb.append( ip[j][ip[j].length - 1].getY() );
1401 if ( sur.getCoordinateDimension() == 3 ) {
1402 sb.append( ',' ).append( ip[j][ip[j].length - 1].getZ() );
1403 }
1404 sb.append( "</gml:coordinates>" );
1405 sb.append( "</gml:LinearRing></gml:innerBoundaryIs>" );
1406 }
1407 }
1408
1409 sb.append( "</gml:Polygon>" );
1410
1411 return sb;
1412 }
1413
1414 /**
1415 * @param mp
1416 * @return
1417 * @throws RemoteException
1418 */
1419 private static StringBuffer exportMultiPoint( MultiPoint mp ) {
1420
1421 StringBuffer sb = new StringBuffer( mp.getSize() * 35 );
1422 String srsName = "";
1423
1424 String crs = null;
1425 if ( mp.getCoordinateSystem() != null ) {
1426 crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
1427 }
1428
1429 if ( crs != null ) {
1430 srsName = " srsName=\"" + crs + "\"";
1431 }
1432
1433 sb.append( "<gml:MultiPoint" ).append( srsName ).append( ">" );
1434
1435 for ( int i = 0; i < mp.getSize(); i++ ) {
1436 sb.append( "<gml:pointMember>" );
1437 sb.append( "<gml:Point" ).append( srsName ).append( ">" );
1438
1439 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1440 sb.append( mp.getPointAt( i ).getX() ).append( ',' ).append( mp.getPointAt( i ).getY() );
1441 if ( mp.getPointAt( i ).getCoordinateDimension() == 3 ) {
1442 sb.append( ',' ).append( mp.getPointAt( i ).getZ() );
1443 }
1444 sb.append( "</gml:coordinates>" );
1445 sb.append( "</gml:Point>" );
1446 sb.append( "</gml:pointMember>" );
1447 }
1448
1449 sb.append( "</gml:MultiPoint>" );
1450
1451 return sb;
1452 }
1453
1454 /**
1455 * @param mp
1456 * @return
1457 * @throws RemoteException
1458 * @throws GeometryException
1459 */
1460 private static StringBuffer exportMultiCurve( MultiCurve mp )
1461 throws GeometryException {
1462
1463 StringBuffer sb = new StringBuffer( 50000 );
1464 String srsName = "";
1465 String crs = null;
1466 if ( mp.getCoordinateSystem() != null ) {
1467 crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
1468 }
1469
1470 if ( crs != null ) {
1471 srsName = " srsName=\"" + crs + "\"";
1472 }
1473
1474 sb.append( "<gml:MultiCurve" ).append( srsName ).append( ">" );
1475
1476 for ( int j = 0; j < mp.getSize(); j++ ) {
1477 sb.append( "<gml:curveMember>" );
1478 sb.append( "<gml:LineString" ).append( srsName ).append( ">" );
1479
1480 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1481
1482 Position[] p = mp.getCurveAt( j ).getAsLineString().getPositions();
1483
1484 for ( int i = 0; i < ( p.length - 1 ); i++ ) {
1485 sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
1486 if ( mp.getCoordinateDimension() == 3 ) {
1487 sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
1488 } else {
1489 sb.append( ' ' );
1490 }
1491 }
1492
1493 sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
1494 if ( mp.getCoordinateDimension() == 3 ) {
1495 sb.append( ',' ).append( p[p.length - 1].getZ() );
1496 }
1497 sb.append( "</gml:coordinates>" );
1498 sb.append( "</gml:LineString>" );
1499 sb.append( "</gml:curveMember>" );
1500 }
1501
1502 sb.append( "</gml:MultiCurve>" );
1503
1504 return sb;
1505 }
1506
1507 /**
1508 * @param mp
1509 * @return
1510 * @throws RemoteException
1511 * @throws GeometryException
1512 */
1513 private static StringBuffer exportMultiSurface( MultiSurface mp )
1514 throws GeometryException {
1515
1516 StringBuffer sb = new StringBuffer( 50000 );
1517 String srsName = "";
1518 String crs = null;
1519 if ( mp.getCoordinateSystem() != null ) {
1520 crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
1521 }
1522
1523 if ( crs != null ) {
1524 srsName = " srsName=\"" + crs + "\"";
1525 }
1526
1527 sb.append( "<gml:MultiSurface" ).append( srsName ).append( ">" );
1528
1529 for ( int k = 0; k < mp.getSize(); k++ ) {
1530 sb.append( "<gml:surfaceMember>" );
1531 sb.append( "<gml:Polygon" ).append( srsName ).append( ">" );
1532
1533 Surface sur = mp.getSurfaceAt( k );
1534 SurfacePatch patch = sur.getSurfacePatchAt( 0 );
1535
1536 // exterior ring
1537 sb.append( "<gml:exterior><gml:LinearRing>" );
1538 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1539
1540 Position[] p = patch.getExteriorRing();
1541
1542 for ( int i = 0; i < ( p.length - 1 ); i++ ) {
1543 sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
1544 if ( mp.getCoordinateDimension() == 3 ) {
1545 sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
1546 } else {
1547 sb.append( ' ' );
1548 }
1549 }
1550
1551 sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
1552 if ( mp.getCoordinateDimension() == 3 ) {
1553 sb.append( ',' ).append( p[p.length - 1].getZ() );
1554 }
1555 sb.append( "</gml:coordinates></gml:LinearRing></gml:exterior>" );
1556
1557 // interior rings
1558 Position[][] ip = patch.getInteriorRings();
1559
1560 if ( ip != null ) {
1561 for ( int j = 0; j < ip.length; j++ ) {
1562 sb.append( "<gml:interior><gml:LinearRing>" );
1563 sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
1564
1565 for ( int i = 0; i < ( ip[j].length - 1 ); i++ ) {
1566 sb.append( ip[j][i].getX() ).append( ',' ).append( ip[j][i].getY() );
1567 if ( mp.getCoordinateDimension() == 3 ) {
1568 sb.append( ',' ).append( ip[j][i].getZ() ).append( ' ' );
1569 } else {
1570 sb.append( ' ' );
1571 }
1572 }
1573
1574 sb.append( ip[j][ip[j].length - 1].getX() ).append( ',' );
1575 sb.append( ip[j][ip[j].length - 1].getY() );
1576 if ( mp.getCoordinateDimension() == 3 ) {
1577 sb.append( ',' ).append( ip[j][ip[j].length - 1].getZ() );
1578 }
1579 sb.append( "</gml:coordinates></gml:LinearRing></gml:interior>" );
1580 }
1581 }
1582
1583 sb.append( "</gml:Polygon></gml:surfaceMember>" );
1584 }
1585
1586 sb.append( "</gml:MultiSurface>" );
1587
1588 return sb;
1589 }
1590
1591 /**
1592 * creates a GML expression of a point geometry
1593 *
1594 * @param point
1595 * point geometry
1596 *
1597 * @return
1598 */
1599 private static void exportPoint( Point point, PrintWriter pw ) {
1600
1601 String crs = null;
1602 if ( point.getCoordinateSystem() != null ) {
1603 crs = point.getCoordinateSystem().getName().replace( ' ', ':' );
1604 }
1605 String srs = null;
1606 if ( crs != null ) {
1607 srs = "<gml:Point srsName=\"" + crs + "\">";
1608 } else {
1609 srs = "<gml:Point>";
1610 }
1611 pw.println( srs );
1612
1613 int dim = point.getCoordinateDimension();
1614 if ( dim != 0 ) {
1615 String dimension = "<gml:pos dimension=\"" + dim + "\">";
1616 pw.print( dimension );
1617 } else {
1618 pw.print( "<gml:pos>" );
1619 }
1620
1621 String coordinates = point.getX() + " " + point.getY();
1622 if ( point.getCoordinateDimension() == 3 ) {
1623 coordinates = coordinates + " " + point.getZ();
1624 }
1625 pw.print( coordinates );
1626 pw.println( "</gml:pos>" );
1627 pw.print( "</gml:Point>" );
1628
1629 }
1630
1631 /**
1632 * creates a GML expression of a curve geometry
1633 *
1634 * @param o
1635 * curve geometry
1636 *
1637 * @return
1638 *
1639 * @throws GeometryException
1640 */
1641 private static void exportCurve( Curve o, PrintWriter pw )
1642 throws GeometryException {
1643
1644 String crs = null;
1645 if ( o.getCoordinateSystem() != null ) {
1646 crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
1647 }
1648 String srs = null;
1649 if ( crs != null ) {
1650 srs = "<gml:Curve srsName=\"" + crs + "\">";
1651 } else {
1652 srs = "<gml:Curve>";
1653 }
1654 pw.println( srs );
1655 pw.println( "<gml:segments>" );
1656
1657 int curveSegments = o.getNumberOfCurveSegments();
1658 for ( int i = 0; i < curveSegments; i++ ) {
1659 pw.print( "<gml:LineStringSegment>" );
1660 CurveSegment segment = o.getCurveSegmentAt( i );
1661 Position[] p = segment.getAsLineString().getPositions();
1662 pw.print( "<gml:posList>" );
1663 for ( int j = 0; j < ( p.length - 1 ); j++ ) {
1664 pw.print( p[j].getX() + " " + p[j].getY() );
1665 if ( o.getCoordinateDimension() == 3 ) {
1666 pw.print( ' ' );
1667 pw.print( p[j].getZ() );
1668 pw.print( ' ' );
1669 } else {
1670 pw.print( ' ' );
1671 }
1672 }
1673 pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
1674 if ( o.getCoordinateDimension() == 3 ) {
1675 pw.print( " " + p[p.length - 1].getZ() );
1676 }
1677 pw.println( "</gml:posList>" );
1678 pw.println( "</gml:LineStringSegment>" );
1679 }
1680 pw.println( "</gml:segments>" );
1681 pw.print( "</gml:Curve>" );
1682
1683 }
1684
1685 /**
1686 * @param sur
1687 * @return
1688 * @throws RemoteException
1689 * @throws GeometryException
1690 */
1691 private static void exportSurface( Surface surface, PrintWriter pw )
1692 throws GeometryException {
1693
1694 String crs = null;
1695 if ( surface.getCoordinateSystem() != null ) {
1696 crs = surface.getCoordinateSystem().getName().replace( ' ', ':' );
1697 }
1698 String srs = null;
1699 if ( crs != null ) {
1700 srs = "<gml:Surface srsName=\"" + crs + "\">";
1701 } else {
1702 srs = "<gml:Surface>";
1703 }
1704 pw.println( srs );
1705 int patches = surface.getNumberOfSurfacePatches();
1706 pw.println( "<gml:patches>" );
1707 for ( int i = 0; i < patches; i++ ) {
1708 pw.println( "<gml:Polygon>" );
1709 SurfacePatch patch = surface.getSurfacePatchAt( i );
1710
1711 printExteriorRing( surface, pw, patch );
1712 printInteriorRing( surface, pw, patch );
1713 pw.println( "</gml:Polygon>" );
1714 }
1715 pw.println( "</gml:patches>" );
1716 pw.print( "</gml:Surface>" );
1717
1718 }
1719
1720 /**
1721 * @param surface
1722 * @param pw
1723 * @param patch
1724 */
1725 private static void printInteriorRing( Surface surface, PrintWriter pw, SurfacePatch patch ) {
1726 // interior rings
1727 Position[][] ip = patch.getInteriorRings();
1728 if ( ip != null ) {
1729 for ( int j = 0; j < ip.length; j++ ) {
1730 pw.println( "<gml:interior>" );
1731 pw.println( "<gml:LinearRing>" );
1732 pw.print( "<gml:posList>" );
1733
1734 for ( int k = 0; k < ( ip[k].length - 1 ); k++ ) {
1735 pw.print( ip[j][k].getX() + " " + ip[j][k].getY() );
1736 if ( surface.getCoordinateDimension() == 3 ) {
1737 pw.print( " " + ip[j][k].getZ() + " " );
1738 } else {
1739 pw.print( " " );
1740 }
1741 }
1742 pw.print( ip[j][ip[j].length - 1].getX() + " " + ip[j][ip[j].length - 1].getY() );
1743 if ( surface.getCoordinateDimension() == 3 ) {
1744 pw.print( " " + ip[j][ip[j].length - 1].getZ() );
1745 }
1746 pw.println( "</gml:posList>" );
1747 pw.println( "</gml:LinearRing>" );
1748 pw.println( "</gml:interior>" );
1749 }
1750 }
1751 }
1752
1753 /**
1754 * @param surface
1755 * @param pw
1756 * @param patch
1757 */
1758 private static void printExteriorRing( Surface surface, PrintWriter pw, SurfacePatch patch ) {
1759 // exterior ring
1760 pw.println( "<gml:exterior>" );
1761 pw.println( "<gml:LinearRing>" );
1762 pw.println( "<gml:posList>" );
1763 Position[] p = patch.getExteriorRing();
1764 for ( int j = 0; j < ( p.length - 1 ); j++ ) {
1765 pw.print( p[j].getX() + " " + p[j].getY() );
1766 if ( surface.getCoordinateDimension() == 3 ) {
1767 pw.print( " " + p[j].getZ() + " " );
1768 } else {
1769 pw.print( ' ' );
1770 }
1771 }
1772 pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
1773 if ( surface.getCoordinateDimension() == 3 ) {
1774 pw.print( " " + p[p.length - 1].getZ() );
1775 }
1776 pw.println( "</gml:posList>" );
1777 pw.println( "</gml:LinearRing>" );
1778 pw.println( "</gml:exterior>" );
1779 }
1780
1781 /**
1782 * @param mp
1783 * @return
1784 * @throws RemoteException
1785 */
1786 private static void exportMultiPoint( MultiPoint mp, PrintWriter pw ) {
1787
1788 String crs = null;
1789 if ( mp.getCoordinateSystem() != null ) {
1790 crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
1791 }
1792 String srs = null;
1793 if ( crs != null ) {
1794 srs = "<gml:MultiPoint srsName=\"" + crs + "\">";
1795 } else {
1796 srs = "<gml:MultiPoint>";
1797 }
1798 pw.println( srs );
1799 pw.println( "<gml:pointMembers>" );
1800 for ( int i = 0; i < mp.getSize(); i++ ) {
1801
1802 pw.println( "<gml:Point>" );
1803 pw.print( "<gml:pos>" );
1804 pw.print( mp.getPointAt( i ).getX() + " " + mp.getPointAt( i ).getY() );
1805 if ( mp.getPointAt( i ).getCoordinateDimension() == 3 ) {
1806 pw.print( " " + mp.getPointAt( i ).getZ() );
1807 }
1808 pw.println( "</gml:pos>" );
1809 pw.println( "</gml:Point>" );
1810 }
1811 pw.println( "</gml:pointMembers>" );
1812 pw.print( "</gml:MultiPoint>" );
1813
1814 }
1815
1816 /**
1817 * @param multiCurve
1818 * @return
1819 * @throws RemoteException
1820 * @throws GeometryException
1821 */
1822 private static void exportMultiCurve( MultiCurve multiCurve, PrintWriter pw )
1823 throws GeometryException {
1824
1825 String crs = null;
1826 if ( multiCurve.getCoordinateSystem() != null ) {
1827 crs = multiCurve.getCoordinateSystem().getName().replace( ' ', ':' );
1828 }
1829 String srs = null;
1830 if ( crs != null ) {
1831 srs = "<gml:MultiCurve srsName=\"" + crs + "\">";
1832 } else {
1833 srs = "<gml:MultiCurve>";
1834 }
1835 pw.println( srs );
1836
1837 Curve[] curves = multiCurve.getAllCurves();
1838 pw.println( "<gml:curveMembers>" );
1839 for ( int i = 0; i < curves.length; i++ ) {
1840 Curve curve = curves[i];
1841 pw.println( "<gml:Curve>" );
1842 pw.println( "<gml:segments>" );
1843 pw.println( "<gml:LineStringSegment>" );
1844 int numberCurveSegments = curve.getNumberOfCurveSegments();
1845 for ( int j = 0; j < numberCurveSegments; j++ ) {
1846 CurveSegment curveSegment = curve.getCurveSegmentAt( j );
1847 Position[] p = curveSegment.getAsLineString().getPositions();
1848 pw.print( "<gml:posList>" );
1849 for ( int k = 0; k < ( p.length - 1 ); k++ ) {
1850 pw.print( p[k].getX() + " " + p[k].getY() );
1851 if ( curve.getCoordinateDimension() == 3 ) {
1852 pw.print( " " + p[k].getZ() + " " );
1853 } else {
1854 pw.print( " " );
1855 }
1856 }
1857 pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
1858 if ( curve.getCoordinateDimension() == 3 ) {
1859 pw.print( " " + p[p.length - 1].getZ() );
1860 }
1861 pw.println( "</gml:posList>" );
1862 }
1863 pw.println( "</gml:LineStringSegment>" );
1864 pw.println( "</gml:segments>" );
1865 pw.println( "</gml:Curve>" );
1866 }
1867 pw.println( "</gml:curveMembers>" );
1868 pw.print( "</gml:MultiCurve>" );
1869
1870 }
1871
1872 /**
1873 * @param multiSurface
1874 * @return
1875 * @throws RemoteException
1876 * @throws GeometryException
1877 */
1878 private static void exportMultiSurface( MultiSurface multiSurface, PrintWriter pw )
1879 throws GeometryException {
1880
1881 String crs = null;
1882 if ( multiSurface.getCoordinateSystem() != null ) {
1883 crs = multiSurface.getCoordinateSystem().getName().replace( ' ', ':' );
1884 }
1885 String srs = null;
1886 if ( crs != null ) {
1887 srs = "<gml:MultiSurface srsName=\"" + crs + "\">";
1888 } else {
1889 srs = "<gml:MultiSurface>";
1890 }
1891 pw.println( srs );
1892
1893 Surface[] surfaces = multiSurface.getAllSurfaces();
1894
1895 pw.println( "<gml:surfaceMembers>" );
1896 for ( int i = 0; i < surfaces.length; i++ ) {
1897 Surface surface = surfaces[i];
1898 exportSurface( surface, pw );
1899 }
1900 pw.println( "</gml:surfaceMembers>" );
1901 // substitution as requested in issue
1902 // http://wald.intevation.org/tracker/index.php?func=detail&aid=477&group_id=27&atid=212
1903 // can be removed if it was inserted correctly
1904 // pw.println( "<gml:surfaceMembers>" );
1905 // for ( int i = 0; i < surfaces.length; i++ ) {
1906 // Surface surface = surfaces[i];
1907 // pw.println( "<gml:Surface>" );
1908 // pw.println( "<gml:patches>" );
1909 // pw.println( "<gml:Polygon>" );
1910 // int numberSurfaces = surface.getNumberOfSurfacePatches();
1911 // for ( int j = 0; j < numberSurfaces; j++ ) {
1912 // SurfacePatch surfacePatch = surface.getSurfacePatchAt( j );
1913 // printExteriorRing( surface, pw, surfacePatch );
1914 // printInteriorRing( surface, pw, surfacePatch );
1915 // }
1916 // pw.println( "</gml:Polygon>" );
1917 // pw.println( "</gml:patches>" );
1918 // pw.println( "</gml:Surface>" );
1919 // }
1920 // pw.println( "</gml:surfaceMembers>" );
1921 pw.print( "</gml:MultiSurface>" );
1922
1923 }
1924
1925 /**
1926 * Converts the string representation of a GML geometry object to a corresponding
1927 * <code>Geometry</code>. Notice that GML Boxes will be converted to Surfaces because in ISO
1928 * 19107 Envelopes are no geometries.
1929 *
1930 * @param gml
1931 * @return corresponding geometry object
1932 * @throws GeometryException
1933 * @throws XMLParsingException
1934 * @deprecated this method cannot provide default SRS information, please use
1935 * {@link #wrap(String,String)} instead
1936 */
1937 @Deprecated
1938 public static Geometry wrap( String gml )
1939 throws GeometryException, XMLParsingException {
1940 return wrap( gml, null );
1941 }
1942
1943 /**
1944 * Converts a GML geometry object to a corresponding <tt>Geometry</tt>. Notice that GML Boxes
1945 * will be converted to Surfaces because in ISO 19107 Envelops are no geometries.
1946 * <p>
1947 * Currently, the following conversions are supported:
1948 * <ul>
1949 * <li>GML Point -> Point
1950 * <li>GML MultiPoint -> MultiPoint
1951 * <li>GML LineString -> Curve
1952 * <li>GML MultiLineString -> MultiCurve
1953 * <li>GML Polygon -> Surface
1954 * <li>GML MultiPolygon -> MultiSurface
1955 * <li>GML Box -> Surface
1956 * <li>GML Curve -> Curve
1957 * <li>GML Surface -> Surface
1958 * <li>GML MultiCurve -> MultiCurve
1959 * <li>GML MultiSurface -> MultiSurface
1960 * </ul>
1961 * <p>
1962 *
1963 * @param gml
1964 * @return the corresponding <tt>Geometry</tt>
1965 * @throws GeometryException
1966 * if type unsupported or conversion failed
1967 * @deprecated this method cannot provide default SRS information, please use
1968 * {@link #wrap(Element,String)} instead
1969 */
1970 @Deprecated
1971 public static Geometry wrap( Element gml )
1972 throws GeometryException {
1973 return wrap( gml, null );
1974 }
1975
1976 /**
1977 * returns a Envelope created from Box element
1978 *
1979 * @param element
1980 * <boundedBy>
1981 *
1982 * @return instance of <tt>Envelope</tt>
1983 *
1984 * @throws XMLParsingException
1985 * @throws InvalidGMLException
1986 * @throws UnknownCRSException
1987 * @deprecated this method cannot provide default SRS information, please use
1988 * {@link #wrapBox(Element,String)} instead
1989 */
1990 @Deprecated
1991 public static Envelope wrapBox( Element element )
1992 throws XMLParsingException, InvalidGMLException, UnknownCRSException {
1993 return wrapBox( element, null );
1994 }
1995
1996 /**
1997 * Returns an instance of a Curve created from the passed <gml:Curve>
1998 *
1999 * @param element
2000 * @return Curve
2001 * @throws XMLParsingException
2002 * @throws GeometryException
2003 * @throws UnknownCRSException
2004 * @deprecated this method cannot provide default SRS information, please use
2005 * {@link #wrapCurveAsCurve(Element,String)} instead
2006 */
2007 @Deprecated
2008 protected static Curve wrapCurveAsCurve( Element element )
2009 throws XMLParsingException, GeometryException, UnknownCRSException {
2010 return wrapCurveAsCurve( element, null );
2011 }
2012
2013 /**
2014 * Returns an instance of {@link Surface} created from the passed <code>gml:Surface</code>
2015 * element.
2016 *
2017 * @param element
2018 * @return Surface
2019 * @throws XMLParsingException
2020 * @throws GeometryException
2021 * @throws UnknownCRSException
2022 * @deprecated this method cannot provide default SRS information, please use
2023 * {@link #wrapSurfaceAsSurface(Element,String)} instead
2024 */
2025 @Deprecated
2026 protected static Surface wrapSurfaceAsSurface( Element element )
2027 throws XMLParsingException, GeometryException, UnknownCRSException {
2028 return wrapSurfaceAsSurface( element, null );
2029 }
2030
2031 /**
2032 * Returns an instance of {@link MultiCurve} created from the passed <code>gml:MultiCurve</code>
2033 * element.
2034 *
2035 * @param element
2036 * @return MultiCurve
2037 * @throws XMLParsingException
2038 * @throws GeometryException
2039 * @throws UnknownCRSException
2040 * @throws InvalidGMLException
2041 * @deprecated this method cannot provide default SRS information, please use
2042 * {@link #wrapMultiCurveAsMultiCurve(Element,String)} instead
2043 */
2044 @Deprecated
2045 protected static MultiCurve wrapMultiCurveAsMultiCurve( Element element )
2046 throws XMLParsingException, GeometryException, UnknownCRSException, InvalidGMLException {
2047 return wrapMultiCurveAsMultiCurve( element, null );
2048 }
2049
2050 /**
2051 * Returns an instance of a MultiSurface created from the passed <gml:MultiSurface> element.
2052 *
2053 * @param multiSurfaceElement
2054 * @return MultiSurface
2055 * @throws XMLParsingException
2056 * @throws GeometryException
2057 * @throws InvalidGMLException
2058 * @throws UnknownCRSException
2059 * @deprecated this method cannot provide default SRS information, please use
2060 * {@link #wrapMultiSurfaceAsMultiSurface(Element,String)} instead
2061 */
2062 @Deprecated
2063 protected static MultiSurface wrapMultiSurfaceAsMultiSurface( Element multiSurfaceElement )
2064 throws XMLParsingException, GeometryException, InvalidGMLException, UnknownCRSException {
2065 return wrapMultiSurfaceAsMultiSurface( multiSurfaceElement, null );
2066 }
2067
2068 }