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 }