//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/model/spatialschema/GMLGeometryAdapter.java,v 1.40 2006/11/27 09:07:51 poth Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: klaus.greve@uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.model.spatialschema;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.ElementList;
import org.deegree.framework.xml.NamespaceContext;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.XMLTools;
import org.deegree.model.crs.CRSFactory;
import org.deegree.model.crs.CoordinateSystem;
import org.deegree.model.crs.UnknownCRSException;
import org.deegree.ogcbase.CommonNamespaces;
import org.deegree.ogcbase.InvalidGMLException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Adapter class for converting GML geometries to deegree geometries and vice versa. Some logical
* problems results from the fact that an envelope isn't a geometry according to ISO 19107 (where
* the deegree geometry model is based on) but according to GML2/3 specification it is.<br>
* So if the wrap(..) method is called with an envelope a <tt>Surface</tt> will be returned
* representing the envelops shape. To export an <tt>Envelope</tt> to a GML box/envelope two
* specialized export methods are available.<BR>
* The export method(s) doesn't return a DOM element as one may expect but a <tt>StringBuffer</tt>.
* This is done because the transformation from deegree geometries to GML mainly is required when a
* GML representation of a geometry shall be serialized to a file or to a network connection. For
* both cases the string representation is required. and it is simply faster to create the string
* directly instead of first creating a DOM tree that after this must be serialized to a string.<BR>
* In future version geometries will be serialized to a stream.
*
* @version $Revision: 1.40 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author last edited by: $Author: poth $
*
* @version 1.0. $Revision: 1.40 $, $Date: 2006/11/27 09:07:51 $
*
* @since 2.0
*/
public class GMLGeometryAdapter {
private static final ILogger LOG = LoggerFactory.getLogger( GMLGeometryAdapter.class );
private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
private static Map crsMap = new HashMap();
private static final String COORD = CommonNamespaces.GML_PREFIX + ":coord";
private static final String COORDINATES = CommonNamespaces.GML_PREFIX + ":coordinates";
private static final String POS = CommonNamespaces.GML_PREFIX + ":pos";
private static final String POSLIST = CommonNamespaces.GML_PREFIX + ":posList";
/**
* Creates a GML representation from the passed <code>Geometry<code>
*
* @param geometry
* @param target
* @throws GeometryException
*/
public static PrintWriter export( Geometry geometry, OutputStream target )
throws GeometryException {
PrintWriter printwriter = new PrintWriter( target );
if ( geometry instanceof SurfacePatch ) {
geometry = new SurfaceImpl( (SurfacePatch) geometry );
} else if ( geometry instanceof LineString ) {
geometry = new CurveImpl( (LineString) geometry );
}
// create geometries from the wkb considering the geomerty typ
if ( geometry instanceof Point ) {
exportPoint( (Point) geometry, printwriter );
} else if ( geometry instanceof Curve ) {
exportCurve( (Curve) geometry, printwriter );
} else if ( geometry instanceof Surface ) {
exportSurface( (Surface) geometry, printwriter );
} else if ( geometry instanceof MultiPoint ) {
exportMultiPoint( (MultiPoint) geometry, printwriter );
} else if ( geometry instanceof MultiCurve ) {
exportMultiCurve( (MultiCurve) geometry, printwriter );
} else if ( geometry instanceof MultiSurface ) {
exportMultiSurface( (MultiSurface) geometry, printwriter );
}
printwriter.flush();
return printwriter;
}
/**
* creates a GML representation from the passed <tt>Geometry</tt>
*
* @param geometry
* @return
* @throws GeometryException
*/
public static StringBuffer export( Geometry geometry )
throws GeometryException {
if ( geometry instanceof SurfacePatch ) {
geometry = new SurfaceImpl( (SurfacePatch) geometry );
} else if ( geometry instanceof LineString ) {
geometry = new CurveImpl( (LineString) geometry );
}
StringBuffer sb = null;
// create geometries from the wkb considering the geomerty typ
if ( geometry instanceof Point ) {
sb = exportPoint( (Point) geometry );
} else if ( geometry instanceof Curve ) {
sb = exportCurve( (Curve) geometry );
} else if ( geometry instanceof Surface ) {
sb = exportSurface( (Surface) geometry );
} else if ( geometry instanceof MultiPoint ) {
sb = exportMultiPoint( (MultiPoint) geometry );
} else if ( geometry instanceof MultiCurve ) {
sb = exportMultiCurve( (MultiCurve) geometry );
} else if ( geometry instanceof MultiSurface ) {
sb = exportMultiSurface( (MultiSurface) geometry );
}
return sb;
}
/**
* creates a GML representation from the passed <tt>Envelope</tt>. This method is required
* because in ISO 19107 Envelops are no geometries.
*
* @param envelope
* @return
* @throws GeometryException
*/
public static StringBuffer exportAsBox( Envelope envelope ) {
StringBuffer sb = new StringBuffer( "<gml:Box xmlns:gml='http://www.opengis.net/gml'>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
sb.append( envelope.getMin().getX() ).append( ',' );
sb.append( envelope.getMin().getY() );
int dim = envelope.getMax().getCoordinateDimension();
if ( dim == 3 ) {
sb.append( ',' ).append( envelope.getMin().getZ() );
}
sb.append( ' ' ).append( envelope.getMax().getX() );
sb.append( ',' ).append( envelope.getMax().getY() );
if ( dim == 3 ) {
sb.append( ',' ).append( envelope.getMax().getZ() );
}
sb.append( "</gml:coordinates></gml:Box>" );
return sb;
}
/**
* creates a GML representation from the passed <tt>Envelope</tt>. This method is required
* because in ISO 19107 Envelops are no geometries.
*
* @param envelope
* @return
* @throws GeometryException
*/
public static StringBuffer exportAsEnvelope( Envelope envelope ) {
StringBuffer sb = new StringBuffer( "<gml:Envelope " );
sb.append( "xmlns:gml='http://www.opengis.net/gml'>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
sb.append( envelope.getMin().getX() ).append( ',' );
sb.append( envelope.getMin().getY() );
int dim = envelope.getMax().getCoordinateDimension();
if ( dim == 3 ) {
sb.append( ',' ).append( envelope.getMin().getZ() );
}
sb.append( ' ' ).append( envelope.getMax().getX() );
sb.append( ',' ).append( envelope.getMax().getY() );
if ( dim == 3 ) {
sb.append( ',' ).append( envelope.getMax().getZ() );
}
sb.append( "</gml:coordinates></gml:Envelope>" );
return sb;
}
/**
* Converts the string representation of a GML geometry object to a corresponding
* <tt>Geometry</tt>. Notice that GML Boxes will be converted to Surfaces because in ISO
* 19107 Envelops are no geometries.
*
* @param gml
* @return
* @throws GeometryException
* @throws XMLParsingException
*/
public static Geometry wrap( String gml )
throws GeometryException, XMLParsingException {
StringReader sr = new StringReader( gml );
Document doc = null;
try {
doc = XMLTools.parse( sr );
} catch ( Exception e ) {
LOG.logError( "could not parse: '" + gml + "' as GML/XML", e );
throw new XMLParsingException( "could not parse: '" + gml + "' as GML/XML: "
+ e.getMessage() );
}
return wrap( doc.getDocumentElement() );
}
/**
* Converts a GML geometry object to a corresponding <tt>Geometry</tt>. Notice that GML Boxes
* will be converted to Surfaces because in ISO 19107 Envelops are no geometries.
* <p>
* Currently, the following conversions are supported:
* <ul>
* <li>GML Point -> Point
* <li>GML MultiPoint -> MultiPoint
* <li>GML LineString -> Curve
* <li>GML MultiLineString -> MultiCurve
* <li>GML Polygon -> Surface
* <li>GML MultiPolygon -> MultiSurface
* <li>GML Box -> Surface
* <li>GML Curve -> Curve
* <li>GML Surface -> Surface
* <li>GML MultiCurve -> MultiCurve
* <li>GML MultiSurface -> MultiSurface
* </ul>
* <p>
*
* @param gml
* @return the corresponding <tt>Geometry</tt>
* @throws GeometryException
* if type unsupported or conversion failed
*/
public static Geometry wrap( Element gml )
throws GeometryException {
Geometry geometry = null;
try {
String name = gml.getLocalName();
if ( ( name.equals( "Point" ) ) || ( name.equals( "Center" ) ) ) {
geometry = wrapPoint( gml );
} else if ( name.equals( "LineString" ) ) {
geometry = wrapLineString( gml );
} else if ( name.equals( "Polygon" ) ) {
geometry = wrapPolygon( gml );
} else if ( name.equals( "MultiPoint" ) ) {
geometry = wrapMultiPoint( gml );
} else if ( name.equals( "MultiLineString" ) ) {
geometry = wrapMultiLineString( gml );
} else if ( name.equals( "MultiPolygon" ) ) {
geometry = wrapMultiPolygon( gml );
} else if ( name.equals( "Box" ) || name.equals( "Envelope" ) ) {
geometry = wrapBoxAsSurface( gml );
} else if ( name.equals( "Curve" ) ) {
geometry = wrapCurveAsCurve( gml );
} else if ( name.equals( "Surface" ) ) {
geometry = wrapSurfaceAsSurface( gml );
} else if ( name.equals( "MultiCurve" ) ) {
geometry = wrapMultiCurveAsMultiCurve( gml );
} else if ( name.equals( "MultiSurface" ) ) {
geometry = wrapMultiSurfaceAsMultiSurface( gml );
} else if ( name.equals( "CompositeSurface" ) ) {
geometry = wrapCompositeSurface( gml );
} else {
new GeometryException( "Not a supported geometry type: " + name );
}
} catch ( Exception e ) {
throw new GeometryException( StringTools.stackTraceToString( e ) );
}
return geometry;
}
/**
* Returns an instance of a CompositeSurface created from the passed <gml:CompositeSurface> TODO
*
* @param gml
* @return CompositeSurface
* @throws GeometryException
*/
private static CompositeSurface wrapCompositeSurface( Element gml ) {
throw new UnsupportedOperationException( "wrapCompositeSurface( Element) not "
+ "implemented as yet. Work in Progress." );
}
/**
* Returns an instance of a Curve created from the passed <gml:Curve>
*
* @param element
* @return Curve
* @throws XMLParsingException
* @throws GeometryException
* @throws UnknownCRSException
*/
protected static Curve wrapCurveAsCurve( Element curve )
throws XMLParsingException, GeometryException, UnknownCRSException {
String srs = XMLTools.getAttrValue( curve, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
Element segment = (Element) XMLTools.getRequiredNode( curve, "gml:segments", nsContext );
List list = XMLTools.getNodes( segment, "gml:LineStringSegment", nsContext );
CurveSegment[] segments = new CurveSegment[list.size()];
for ( int i = 0; i < list.size(); i++ ) {
Element lineStringSegment = (Element) list.get( i );
Position[] pos = null;
try {
pos = createPositions( lineStringSegment, srs );
segments[i] = GeometryFactory.createCurveSegment( pos, crs );
} catch ( Exception e ) {
throw new GeometryException(
"Error creating segments for the element LineStringSegment." );
}
}
return GeometryFactory.createCurve( segments );
}
/**
* Returns an instance of a Surface created from the passed <gml:Surface>
*
* @param gml
* @return Surface
* @throws XMLParsingException
* @throws GeometryException
*/
protected static Surface wrapSurfaceAsSurface( Element surfaceElement )
throws XMLParsingException, GeometryException {
CoordinateSystem crs = null;
Element patches = extractPatches( surfaceElement );
List polygonList = extractPolygons( patches );
Polygon[] polygons = new Polygon[polygonList.size()];
for ( int i = 0; i < polygonList.size(); i++ ) {
Element polygon = (Element) polygonList.get( i );
try {
Element exterior = (Element) XMLTools.getNode( polygon, "gml:exterior", nsContext );
Position[] exteriorRing = null;
if ( exterior != null ) {
Element linearRing = (Element) XMLTools.getRequiredNode( exterior,
"gml:LinearRing",
nsContext );
String srs = XMLTools.getAttrValue( linearRing, "srsName" );
if ( srs != null ) {
crs = getCRS( srs );
}
exteriorRing = createPositions( linearRing, srs );
}
List interiorList = XMLTools.getNodes( polygon, "gml:interior", nsContext );
Position[][] interiorRings = null;
if ( interiorList != null && interiorList.size() > 0 ) {
interiorRings = new Position[interiorList.size()][];
for ( int j = 0; j < interiorRings.length; j++ ) {
Element interior = (Element) interiorList.get( j );
Element linearRing = (Element) XMLTools.getRequiredNode( interior,
"gml:LinearRing",
nsContext );
String srs = XMLTools.getAttrValue( linearRing, "srsName" );
if ( srs != null ) {
crs = getCRS( srs );
}
interiorRings[j] = createPositions( interior, srs );
}
}
SurfaceInterpolation si = new SurfaceInterpolationImpl();
polygons[i] = (Polygon) GeometryFactory.createSurfacePatch( exteriorRing,
interiorRings, si, crs );
} catch ( Exception e ) {
throw new XMLParsingException( "Error parsing the polygon element '"
+ polygon.getNodeName()
+ "' to create a surface geometry." );
}
}
Surface surface = null;
try {
surface = GeometryFactory.createSurface( polygons );
} catch ( GeometryException e ) {
throw new GeometryException( "Error creating a surface from '" + polygons.length
+ "' polygons." );
}
return surface;
}
/**
* Extract the list <gml:Polygon> elements from <gml:patches>.
*
* @param patch
* @return List
* @throws XMLParsingException
*/
private static List extractPolygons( Element patch )
throws XMLParsingException {
List polygonList = null;
try {
polygonList = XMLTools.getRequiredNodes( patch, "gml:Polygon", nsContext );
} catch ( XMLParsingException e ) {
throw new XMLParsingException(
"Error retrieving the list of polygon element(s) from the patches element." );
}
return polygonList;
}
/**
* Extract the <gml:patches> node from a <gml:Surface> element.
*
* @param surface
* @return Element
* @throws XMLParsingException
*/
private static Element extractPatches( Element surface )
throws XMLParsingException {
Element patches = null;
try {
patches = (Element) XMLTools.getRequiredNode( surface, "gml:patches", nsContext );
} catch ( XMLParsingException e ) {
throw new XMLParsingException(
"Error retrieving the patches element from the surface element." );
}
return patches;
}
/**
* Returns an instance of a MultiCurve created from the passed <gml:MultiCurve> element.
*
* @param multiCurveElement
* @return MultiCurve
* @throws XMLParsingException
* @throws GeometryException
* @throws UnknownCRSException
*/
protected static MultiCurve wrapMultiCurveAsMultiCurve( Element multiCurveElement )
throws XMLParsingException, GeometryException, UnknownCRSException {
MultiCurve multiCurve = null;
try {
// gml:curveMember
List listCurveMember = XMLTools.getNodes( multiCurveElement, "gml:curveMember",
nsContext );
if ( listCurveMember.size() > 0 ) {
Curve[] curves = new Curve[listCurveMember.size()];
for ( int i = 0; i < listCurveMember.size(); i++ ) {
Element curveMember = (Element) listCurveMember.get( i );
Element curve = (Element) XMLTools.getRequiredNode( curveMember, "gml:Curve",
nsContext );
curves[i] = wrapCurveAsCurve( curve );
}
multiCurve = GeometryFactory.createMultiCurve( curves );
} else {
// gml:curveMembers
Element curveMembers = (Element) XMLTools.getRequiredNode( multiCurveElement,
"gml:curveMembers",
nsContext );
List listCurves = XMLTools.getRequiredNodes( curveMembers, "gml:Curve", nsContext );
Curve[] curves = new Curve[listCurves.size()];
for ( int i = 0; i < listCurves.size(); i++ ) {
Element curve = (Element) listCurves.get( i );
curves[i] = wrapCurveAsCurve( curve );
}
multiCurve = GeometryFactory.createMultiCurve( curves );
}
} catch ( XMLParsingException e ) {
throw new XMLParsingException(
"Error parsing <gml:curveMember> elements. Please check the xml document." );
} catch ( GeometryException e ) {
throw new GeometryException(
"Error creating a curve from the curve element. Please check the GML specifications "
+ "for correct element declaration." );
}
return multiCurve;
}
/**
* Returns an instance of a MultiSurface created from the passed <gml:MultiSurface> element.
*
* @param multiSurfaceElement
* @return MultiSurface
* @throws XMLParsingException
* @throws GeometryException
* @throws InvalidGMLException
* @throws UnknownCRSException
*/
protected static MultiSurface wrapMultiSurfaceAsMultiSurface( Element multiSurfaceElement )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
MultiSurface multiSurface = null;
try {
// gml:surfaceMember
List listSurfaceMember = XMLTools.getNodes( multiSurfaceElement, "gml:surfaceMember",
nsContext );
if ( listSurfaceMember.size() > 0 ) {
Surface[] surfaces = new Surface[listSurfaceMember.size()];
for ( int i = 0; i < listSurfaceMember.size(); i++ ) {
Element surfaceMember = (Element) listSurfaceMember.get( i );
Element surface = (Element) XMLTools.getNode( surfaceMember, "gml:Surface",
nsContext );
if ( surface != null ) {
surfaces[i] = wrapSurfaceAsSurface( surface );
} else {
surface = (Element) XMLTools.getRequiredNode( surfaceMember, "gml:Polygon",
nsContext );
surfaces[i] = wrapPolygon( surface );
}
}
multiSurface = GeometryFactory.createMultiSurface( surfaces );
} else {
// gml:surfaceMembers
Element surfaceMembers = (Element) XMLTools.getRequiredNode( multiSurfaceElement,
"gml:surfaceMembers",
nsContext );
List listSurfaces = XMLTools.getNodes( surfaceMembers, "gml:Surface", nsContext );
Surface[] surfaces = null;
if ( listSurfaces != null && listSurfaces.size() > 0 ) {
surfaces = new Surface[listSurfaces.size()];
for ( int i = 0; i < listSurfaces.size(); i++ ) {
Element surface = (Element) listSurfaces.get( i );
surfaces[i] = wrapSurfaceAsSurface( surface );
}
} else {
listSurfaces = XMLTools.getRequiredNodes( surfaceMembers, "gml:Polygon",
nsContext );
surfaces = new Surface[listSurfaces.size()];
for ( int i = 0; i < listSurfaces.size(); i++ ) {
Element surface = (Element) listSurfaces.get( i );
surfaces[i] = wrapPolygon( surface );
}
}
multiSurface = GeometryFactory.createMultiSurface( surfaces );
}
} catch ( XMLParsingException e ) {
LOG.logError( e.getMessage(), e );
throw new XMLParsingException(
"Error parsing <gml:surfaceMember> elements. Please check "
+ "the xml document." );
} catch ( GeometryException e ) {
throw new GeometryException(
"Error creating a curve from the curve element. Please check "
+ "the GML specifications for correct element declaration." );
}
return multiSurface;
}
/**
* returns an instance of CS_CoordinateSystem corrsponding to the passed crs name
*
* @param name
* name of the crs
*
* @return CS_CoordinateSystem
* @throws UnknownCRSException
*/
private static CoordinateSystem getCRS( String name )
throws UnknownCRSException {
if ( ( name != null ) && ( name.length() > 2 ) ) {
if ( name.startsWith( "http://www.opengis.net/gml/srs/" ) ) {
// as declared in the GML 2.1.1 specification
// http://www.opengis.net/gml/srs/epsg.xml#4326
int p = name.lastIndexOf( "/" );
if ( p >= 0 ) {
name = name.substring( p, name.length() );
p = name.indexOf( "." );
String s1 = name.substring( 1, p ).toUpperCase();
p = name.indexOf( "#" );
String s2 = name.substring( p + 1, name.length() );
name = s1 + ":" + s2;
}
}
}
CoordinateSystem crs = (CoordinateSystem) crsMap.get( name );
if ( crs == null ) {
crs = CRSFactory.create( name );
crsMap.put( name, crs );
}
return crs;
}
/**
* returns an instance of a point created from the passed <gml:Point>
*
* @param element
* <gml:Point>
*
* @return instance of Point
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static Point wrapPoint( Element element )
throws XMLParsingException, InvalidGMLException, UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
Position[] bb = null;
List nl = XMLTools.getNodes( element, COORD, nsContext );
if ( nl != null && nl.size() > 0 ) {
bb = new Position[1];
bb[0] = createPositionFromCoord( (Element) nl.get( 0 ) );
} else {
nl = XMLTools.getNodes( element, COORDINATES, nsContext );
if ( nl != null && nl.size() > 0 ) {
bb = createPositionFromCoordinates( (Element) nl.get( 0 ) );
} else {
nl = XMLTools.getNodes( element, POS, nsContext );
bb = new Position[1];
bb[0] = createPositionFromPos( (Element) nl.get( 0 ) );
}
}
Point point = GeometryFactory.createPoint( bb[0], crs );
return point;
}
/**
* returns an instance of a curve created from the passed <gml:LineString>
*
* @param element
* <gml:LineString>
*
* @return instance of Curve
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static Curve wrapLineString( Element element )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
Position[] pos = createPositions( element, srs );
Curve curve = GeometryFactory.createCurve( pos, crs );
return curve;
}
/**
* returns an instance of a surface created from the passed <gml:Polygon>
*
* @param element
* <gml:Polygon>
*
* @return instance of Surface
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static Surface wrapPolygon( Element element )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
List nl = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":outerBoundaryIs",
nsContext );
if ( nl == null || nl.size() == 0 ) {
nl = XMLTools.getRequiredNodes( element, CommonNamespaces.GML_PREFIX + ":exterior",
nsContext );
}
Element outs = (Element) nl.get( 0 );
nl = XMLTools.getRequiredNodes( outs, CommonNamespaces.GML_PREFIX + ":LinearRing",
nsContext );
Element ring = (Element) nl.get( 0 );
nl = XMLTools.getNodes( ring, COORDINATES, nsContext );
Position[] outterRing = createPositions( ring, srs );
Position[][] innerRings = null;
List inns = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":innerBoundaryIs",
nsContext );
if ( inns == null || inns.size() == 0 ) {
inns = XMLTools.getNodes( element, CommonNamespaces.GML_PREFIX + ":interior", nsContext );
}
if ( inns != null && inns.size() > 0 ) {
innerRings = new Position[inns.size()][];
for ( int i = 0; i < innerRings.length; i++ ) {
nl = XMLTools.getRequiredNodes( (Node) inns.get( i ), CommonNamespaces.GML_PREFIX
+ ":LinearRing", nsContext );
ring = (Element) nl.get( 0 );
innerRings[i] = createPositions( ring, srs );
}
}
SurfaceInterpolation si = new SurfaceInterpolationImpl();
Surface surface = GeometryFactory.createSurface( outterRing, innerRings, si, crs );
return surface;
}
/**
* returns an instance of a multi point created from the passed <gml:MultiPoint>
*
* @param element
* <gml:MultiPoint>
*
* @return instance of MultiPoint
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static MultiPoint wrapMultiPoint( Element element )
throws XMLParsingException, InvalidGMLException, UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
ElementList el = XMLTools.getChildElements( "pointMember", CommonNamespaces.GMLNS, element );
Point[] points = new Point[el.getLength()];
for ( int i = 0; i < points.length; i++ ) {
points[i] = wrapPoint( XMLTools.getFirstChildElement( el.item( i ) ) );
( (GeometryImpl) points[i] ).setCoordinateSystem( crs );
}
MultiPoint mp = GeometryFactory.createMultiPoint( points );
return mp;
}
/**
* returns an instance of a multi point created from the passed <gml:MultiLineString>
*
* @param element
* <gml:MultiLineString>
*
* @return instance of MultiCurve
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static MultiCurve wrapMultiLineString( Element element )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
ElementList el = XMLTools.getChildElements( "lineStringMember", CommonNamespaces.GMLNS,
element );
Curve[] curves = new Curve[el.getLength()];
for ( int i = 0; i < curves.length; i++ ) {
curves[i] = wrapLineString( XMLTools.getFirstChildElement( el.item( i ) ) );
( (GeometryImpl) curves[i] ).setCoordinateSystem( crs );
}
MultiCurve mp = GeometryFactory.createMultiCurve( curves );
return mp;
}
/**
* returns an instance of a multi point created from the passed <gml:MultiLineString>
*
* @param element
* <gml:MultiLineString>
*
* @return instance of MultiCurve
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static MultiSurface wrapMultiPolygon( Element element )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
ElementList el = XMLTools.getChildElements( "polygonMember", CommonNamespaces.GMLNS,
element );
Surface[] surfaces = new Surface[el.getLength()];
for ( int i = 0; i < surfaces.length; i++ ) {
surfaces[i] = wrapPolygon( XMLTools.getFirstChildElement( el.item( i ) ) );
( (GeometryImpl) surfaces[i] ).setCoordinateSystem( crs );
}
MultiSurface mp = GeometryFactory.createMultiSurface( surfaces );
return mp;
}
/**
* returns a Envelope created from Box element
*
* @param element
* <boundedBy>
*
* @return instance of <tt>Envelope</tt>
*
* @throws XMLParsingException
* @throws InvalidGMLException
* @throws UnknownCRSException
*/
public static Envelope wrapBox( Element element )
throws XMLParsingException, InvalidGMLException, UnknownCRSException {
String srs = XMLTools.getAttrValue( element, "srsName" );
CoordinateSystem crs = null;
if ( srs != null ) {
crs = getCRS( srs );
}
Position[] bb = null;
List nl = XMLTools.getNodes( element, COORD, nsContext );
if ( nl != null && nl.size() > 0 ) {
bb = new Position[2];
bb[0] = createPositionFromCoord( (Element) nl.get( 0 ) );
bb[1] = createPositionFromCoord( (Element) nl.get( 1 ) );
} else {
nl = XMLTools.getNodes( element, COORDINATES, nsContext );
if ( nl != null && nl.size() > 0 ) {
bb = createPositionFromCoordinates( (Element) nl.get( 0 ) );
} else {
nl = XMLTools.getNodes( element, POS, nsContext );
if ( nl != null && nl.size() > 0 ) {
bb = new Position[2];
bb[0] = createPositionFromPos( (Element) nl.get( 0 ) );
bb[1] = createPositionFromPos( (Element) nl.get( 1 ) );
} else {
Element lowerCorner = (Element) XMLTools.getRequiredNode( element,
"gml:lowerCorner",
nsContext );
Element upperCorner = (Element) XMLTools.getRequiredNode( element,
"gml:upperCorner",
nsContext );
bb = new Position[2];
bb[0] = createPositionFromCorner( lowerCorner );
bb[1] = createPositionFromCorner( upperCorner );
}
}
}
Envelope box = GeometryFactory.createEnvelope( bb[0], bb[1], crs );
return box;
}
private static Position createPositionFromCorner( Element corner )
throws InvalidGMLException {
String tmp = XMLTools.getAttrValue( corner, "dimension" );
int dim = 0;
if ( tmp != null ) {
dim = Integer.parseInt( tmp );
}
tmp = XMLTools.getStringValue( corner );
double[] vals = StringTools.toArrayDouble( tmp, ", " );
if ( dim != 0 ) {
if ( vals.length != dim ) {
throw new InvalidGMLException( "dimension must be equal to the number of "
+ "coordinate values defined in pos element." );
}
} else {
dim = vals.length;
}
Position pos = null;
if ( dim == 3 ) {
pos = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
} else {
pos = GeometryFactory.createPosition( vals[0], vals[1] );
}
return pos;
}
/**
* returns a Surface created from Box element. This method is useful because an Envelope that
* normaly should be created from a Box isn't a geometry in context of ISO 19107
*
* @param element
* <boundedBy>
*
* @return instance of <tt>Surface</tt>
*
* @throws XMLParsingException
* @throws UnknownCRSException
*/
private static Surface wrapBoxAsSurface( Element element )
throws XMLParsingException, GeometryException, InvalidGMLException,
UnknownCRSException {
Envelope env = wrapBox( element );
return GeometryFactory.createSurface( env, env.getCoordinateSystem() );
}
/**
* returns an instance of Position created from the passed coord
*
* @param element
* <coord>
*
* @return instance of <tt>Position</tt>
*
* @throws XMLParsingException
*/
private static Position createPositionFromCoord( Element element )
throws XMLParsingException {
Position pos = null;
Element elem = XMLTools.getRequiredChildElement( "X", CommonNamespaces.GMLNS, element );
double x = Double.parseDouble( XMLTools.getStringValue( elem ) );
elem = XMLTools.getRequiredChildElement( "Y", CommonNamespaces.GMLNS, element );
double y = Double.parseDouble( XMLTools.getStringValue( elem ) );
elem = XMLTools.getChildElement( "Z", CommonNamespaces.GMLNS, element );
if ( elem != null ) {
double z = Double.parseDouble( XMLTools.getStringValue( elem ) );
pos = GeometryFactory.createPosition( new double[] { x, y, z } );
} else {
pos = GeometryFactory.createPosition( new double[] { x, y } );
}
return pos;
}
/**
* returns an array of Positions created from the passed coordinates
*
* @param element
* <coordinates>
*
* @return instance of <tt>Position[]</tt>
*
* @throws XMLParsingException
*/
private static Position[] createPositionFromCoordinates( Element element ) {
Position[] points = null;
String ts = XMLTools.getAttrValue( element, "ts" );
if ( ts == null ) {
ts = " ";
}
String ds = XMLTools.getAttrValue( element, "decimal" );
if ( ds == null ) {
ds = ".";
}
String cs = XMLTools.getAttrValue( element, "cs" );
if ( cs == null ) {
cs = ",";
}
String value = XMLTools.getStringValue( element );
// first tokenizer, tokens the tuples
StringTokenizer tuple = new StringTokenizer( value, ts );
points = new Position[tuple.countTokens()];
int i = 0;
while ( tuple.hasMoreTokens() ) {
String s = tuple.nextToken();
// second tokenizer, tokens the coordinates
StringTokenizer coort = new StringTokenizer( s, cs );
double[] p = new double[coort.countTokens()];
for ( int k = 0; k < p.length; k++ ) {
p[k] = Double.parseDouble( coort.nextToken() );
}
points[i++] = GeometryFactory.createPosition( p );
}
return points;
}
/**
* creates a <tt>Point</tt> from the passed <pos> element containing a GML pos.
*
* @param element
* @return created <tt>Point</tt>
* @throws XMLParsingException
* @throws InvalidGMLException
*/
private static Position createPositionFromPos( Element element )
throws InvalidGMLException {
String tmp = XMLTools.getAttrValue( element, "dimension" );
int dim = 0;
if ( tmp != null ) {
dim = Integer.parseInt( tmp );
}
tmp = XMLTools.getStringValue( element );
double[] vals = StringTools.toArrayDouble( tmp, "\t\n\r\f ," );
if ( dim != 0 ) {
if ( vals.length != dim ) {
throw new InvalidGMLException( "dimension must be equal to the number of "
+ "coordinate values defined in pos element." );
}
} else {
dim = vals.length;
}
Position pos = null;
if ( dim == 3 ) {
pos = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
} else {
pos = GeometryFactory.createPosition( vals[0], vals[1] );
}
return pos;
}
/**
*
* @param element
* @return Position
* @throws InvalidGMLException
*/
private static Position[] createPositionFromPosList( Element element, String srsName )
throws InvalidGMLException {
if ( srsName == null ) {
srsName = XMLTools.getAttrValue( element, "srsName" );
}
String srsDimension = XMLTools.getAttrValue( element, "srsDimension" );
int dim = 0;
if ( srsDimension != null ) {
dim = Integer.parseInt( srsDimension );
}
if ( dim == 0 ) {
// TODO
// determine dimension from CRS
// default dimension set.
dim = 2;
}
String axisLabels = XMLTools.getAttrValue( element, "gml:axisAbbrev" );
String uomLabels = XMLTools.getAttrValue( element, "uomLabels" );
if ( srsName == null ) {
if ( srsDimension != null ) {
throw new InvalidGMLException( "Attribute srsDimension cannot be defined "
+ "unless attribute srsName has been defined." );
}
if ( axisLabels != null ) {
throw new InvalidGMLException( "Attribute axisLabels cannot be defined "
+ "unless attribute srsName has been defined." );
}
}
if ( axisLabels == null ) {
if ( uomLabels != null ) {
throw new InvalidGMLException( "Attribute uomLabels cannot be defined "
+ "unless attribute axisLabels has been defined." );
}
}
String tmp = XMLTools.getStringValue( element );
double[] values = StringTools.toArrayDouble( tmp, "\t\n\r\f ," );
int size = values.length / dim;
if ( values.length < 4 ) {
throw new InvalidGMLException( "A point list must have minimum 2 coordinate tuples. "
+ "Here only '" + size + "' are defined." );
}
double positions[][] = new double[size][dim];
int a = 0, b = 0;
for ( int i = 0; i < values.length; i++ ) {
if ( b == dim ) {
a++;
b = 0;
}
positions[a][b] = values[i];
b++;
}
Position[] position = new Position[positions.length];
for ( int i = 0; i < positions.length; i++ ) {
double[] vals = positions[i];
if ( dim == 3 ) {
position[i] = GeometryFactory.createPosition( vals[0], vals[1], vals[2] );
} else {
position[i] = GeometryFactory.createPosition( vals[0], vals[1] );
}
}
return position;
}
/**
* creates an array of <tt>Position</tt>s from the <coordinates> or <pos> Elements located as
* children under the passed parent element.
* <p>
* example:<br>
*
* <pre>
* <gml:Box>
* <gml:coordinates cs="," decimal="." ts=" ">0,0 4000,4000</gml:coordinates>
* </gml:Box>
* </pre>
*
* </p>
*
* @param parent
* @param srsName
* @return
* @throws XMLParsingException
* @throws InvalidGMLException
*/
private static Position[] createPositions( Element parent, String srsName )
throws XMLParsingException, InvalidGMLException {
List nl = XMLTools.getNodes( parent, COORDINATES, nsContext );
Position[] pos = null;
if ( nl != null && nl.size() > 0 ) {
pos = createPositionFromCoordinates( (Element) nl.get( 0 ) );
} else {
nl = XMLTools.getNodes( parent, POS, nsContext );
if ( nl != null && nl.size() > 0 ) {
pos = new Position[nl.size()];
for ( int i = 0; i < pos.length; i++ ) {
pos[i] = createPositionFromPos( (Element) nl.get( i ) );
}
} else {
Element posList = (Element) XMLTools.getRequiredNode( parent, POSLIST, nsContext );
if ( posList != null ) {
pos = createPositionFromPosList( posList, srsName );
}
}
}
return pos;
}
/**
* creates a GML expression of a point geometry
*
* @param o
* point geometry
*
* @return
*/
private static StringBuffer exportPoint( Point o ) {
StringBuffer sb = new StringBuffer( 200 );
String crs = null;
if ( o.getCoordinateSystem() != null ) {
crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
sb.append( "<gml:Point srsName=\"" ).append( crs ).append( "\">" );
} else {
sb.append( "<gml:Point>" );
}
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
sb.append( o.getX() ).append( ',' ).append( o.getY() );
if ( o.getCoordinateDimension() == 3 ) {
sb.append( "," + o.getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:Point>" );
return sb;
}
/**
* creates a GML expression of a curve geometry
*
* @param o
* curve geometry
*
* @return
*
* @throws GeometryException
*/
private static StringBuffer exportCurve( Curve o )
throws GeometryException {
Position[] p = o.getAsLineString().getPositions();
StringBuffer sb = new StringBuffer( p.length * 40 );
String crs = null;
if ( o.getCoordinateSystem() != null ) {
crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
sb.append( "<gml:LineString srsName=\"" + crs + "\">" );
} else {
sb.append( "<gml:LineString>" );
}
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
for ( int i = 0; i < ( p.length - 1 ); i++ ) {
sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
if ( o.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
if ( o.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[p.length - 1].getZ() );
}
sb.append( "</gml:coordinates></gml:LineString>" );
return sb;
}
/**
* @param sur
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static StringBuffer exportSurface( Surface sur )
throws GeometryException {
StringBuffer sb = new StringBuffer( 5000 );
String crs = null;
if ( sur.getCoordinateSystem() != null ) {
crs = sur.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
sb.append( "<gml:Polygon srsName=\"" + crs + "\">" );
} else {
sb.append( "<gml:Polygon>" );
}
SurfacePatch patch = sur.getSurfacePatchAt( 0 );
// exterior ring
sb.append( "<gml:outerBoundaryIs><gml:LinearRing>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
Position[] p = patch.getExteriorRing();
for ( int i = 0; i < ( p.length - 1 ); i++ ) {
sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
if ( sur.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
if ( sur.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[p.length - 1].getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:LinearRing></gml:outerBoundaryIs>" );
// interior rings
Position[][] ip = patch.getInteriorRings();
if ( ip != null ) {
for ( int j = 0; j < ip.length; j++ ) {
sb.append( "<gml:innerBoundaryIs><gml:LinearRing>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
for ( int i = 0; i < ( ip[j].length - 1 ); i++ ) {
sb.append( ip[j][i].getX() ).append( ',' ).append( ip[j][i].getY() );
if ( sur.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( ip[j][i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( ip[j][ip[j].length - 1].getX() ).append( ',' );
sb.append( ip[j][ip[j].length - 1].getY() );
if ( sur.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( ip[j][ip[j].length - 1].getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:LinearRing></gml:innerBoundaryIs>" );
}
}
sb.append( "</gml:Polygon>" );
return sb;
}
/**
* @param mp
* @return
* @throws RemoteException
*/
private static StringBuffer exportMultiPoint( MultiPoint mp ) {
StringBuffer sb = new StringBuffer( mp.getSize() * 35 );
String srsName = "";
String crs = null;
if ( mp.getCoordinateSystem() != null ) {
crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
srsName = " srsName=\"" + crs + "\"";
}
sb.append( "<gml:MultiPoint" ).append( srsName ).append( ">" );
for ( int i = 0; i < mp.getSize(); i++ ) {
sb.append( "<gml:pointMember>" );
sb.append( "<gml:Point" ).append( srsName ).append( ">" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
sb.append( mp.getPointAt( i ).getX() ).append( ',' ).append( mp.getPointAt( i ).getY() );
if ( mp.getPointAt( i ).getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( mp.getPointAt( i ).getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:Point>" );
sb.append( "</gml:pointMember>" );
}
sb.append( "</gml:MultiPoint>" );
return sb;
}
/**
* @param mp
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static StringBuffer exportMultiCurve( MultiCurve mp )
throws GeometryException {
StringBuffer sb = new StringBuffer( 50000 );
String srsName = "";
String crs = null;
if ( mp.getCoordinateSystem() != null ) {
crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
srsName = " srsName=\"" + crs + "\"";
}
sb.append( "<gml:MultiLineString" ).append( srsName ).append( ">" );
for ( int j = 0; j < mp.getSize(); j++ ) {
sb.append( "<gml:lineStringMember>" );
sb.append( "<gml:LineString" ).append( srsName ).append( ">" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
Position[] p = mp.getCurveAt( j ).getAsLineString().getPositions();
for ( int i = 0; i < ( p.length - 1 ); i++ ) {
sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[p.length - 1].getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:LineString>" );
sb.append( "</gml:lineStringMember>" );
}
sb.append( "</gml:MultiLineString>" );
return sb;
}
/**
* @param mp
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static StringBuffer exportMultiSurface( MultiSurface mp )
throws GeometryException {
StringBuffer sb = new StringBuffer( 50000 );
String srsName = "";
String crs = null;
if ( mp.getCoordinateSystem() != null ) {
crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
}
if ( crs != null ) {
srsName = " srsName=\"" + crs + "\"";
}
sb.append( "<gml:MultiPolygon" ).append( srsName ).append( ">" );
for ( int k = 0; k < mp.getSize(); k++ ) {
sb.append( "<gml:polygonMember>" );
sb.append( "<gml:Polygon" ).append( srsName ).append( ">" );
Surface sur = mp.getSurfaceAt( k );
SurfacePatch patch = sur.getSurfacePatchAt( 0 );
// exterior ring
sb.append( "<gml:outerBoundaryIs><gml:LinearRing>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
Position[] p = patch.getExteriorRing();
for ( int i = 0; i < ( p.length - 1 ); i++ ) {
sb.append( p[i].getX() ).append( ',' ).append( p[i].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( p[p.length - 1].getX() ).append( ',' ).append( p[p.length - 1].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( p[p.length - 1].getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:LinearRing></gml:outerBoundaryIs>" );
// interior rings
Position[][] ip = patch.getInteriorRings();
if ( ip != null ) {
for ( int j = 0; j < ip.length; j++ ) {
sb.append( "<gml:innerBoundaryIs><gml:LinearRing>" );
sb.append( "<gml:coordinates cs=\",\" decimal=\".\" ts=\" \">" );
for ( int i = 0; i < ( ip[j].length - 1 ); i++ ) {
sb.append( ip[j][i].getX() ).append( ',' ).append( ip[j][i].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( ip[j][i].getZ() ).append( ' ' );
} else {
sb.append( ' ' );
}
}
sb.append( ip[j][ip[j].length - 1].getX() ).append( ',' );
sb.append( ip[j][ip[j].length - 1].getY() );
if ( mp.getCoordinateDimension() == 3 ) {
sb.append( ',' ).append( ip[j][ip[j].length - 1].getZ() );
}
sb.append( "</gml:coordinates>" );
sb.append( "</gml:LinearRing></gml:innerBoundaryIs>" );
}
}
sb.append( "</gml:Polygon>" );
sb.append( "</gml:polygonMember>" );
}
sb.append( "</gml:MultiPolygon>" );
return sb;
}
/**
* creates a GML expression of a point geometry
*
* @param point
* point geometry
*
* @return
*/
private static void exportPoint( Point point, PrintWriter pw ) {
String crs = null;
if ( point.getCoordinateSystem() != null ) {
crs = point.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:Point srsName=\"" + crs + "\">";
} else {
srs = "<gml:Point>";
}
pw.println( srs );
int dim = point.getCoordinateDimension();
if ( dim != 0 ) {
String dimension = "<gml:pos dimension=\"" + dim + "\">";
pw.print( dimension );
} else {
pw.print( "<gml:pos>" );
}
String coordinates = point.getX() + " " + point.getY();
if ( point.getCoordinateDimension() == 3 ) {
coordinates = coordinates + " " + point.getZ();
}
pw.print( coordinates );
pw.println( "</gml:pos>" );
pw.print( "</gml:Point>" );
}
/**
* creates a GML expression of a curve geometry
*
* @param o
* curve geometry
*
* @return
*
* @throws GeometryException
*/
private static void exportCurve( Curve o, PrintWriter pw )
throws GeometryException {
String crs = null;
if ( o.getCoordinateSystem() != null ) {
crs = o.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:Curve srsName=\"" + crs + "\">";
} else {
srs = "<gml:Curve>";
}
pw.println( srs );
pw.println( "<gml:segments>" );
int curveSegments = o.getNumberOfCurveSegments();
for ( int i = 0; i < curveSegments; i++ ) {
pw.print( "<gml:LineStringSegment>" );
CurveSegment segment = o.getCurveSegmentAt( i );
Position[] p = segment.getAsLineString().getPositions();
pw.print( "<gml:posList>" );
for ( int j = 0; j < ( p.length - 1 ); j++ ) {
pw.print( p[j].getX() + " " + p[j].getY() );
if ( o.getCoordinateDimension() == 3 ) {
pw.print( ' ' );
pw.print( p[j].getZ() );
pw.print( ' ' );
} else {
pw.print( ' ' );
}
}
pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
if ( o.getCoordinateDimension() == 3 ) {
pw.print( " " + p[p.length - 1].getZ() );
}
pw.println( "</gml:posList>" );
pw.println( "</gml:LineStringSegment>" );
}
pw.println( "</gml:segments>" );
pw.print( "</gml:Curve>" );
}
/**
* @param sur
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static void exportSurface( Surface surface, PrintWriter pw )
throws GeometryException {
String crs = null;
if ( surface.getCoordinateSystem() != null ) {
crs = surface.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:Surface srsName=\"" + crs + "\">";
} else {
srs = "<gml:Surface>";
}
pw.println( srs );
int patches = surface.getNumberOfSurfacePatches();
pw.println( "<gml:patches>" );
for ( int i = 0; i < patches; i++ ) {
pw.println( "<gml:Polygon>" );
SurfacePatch patch = surface.getSurfacePatchAt( i );
printExteriorRing( surface, pw, patch );
printInteriorRing( surface, pw, patch );
pw.println( "</gml:Polygon>" );
}
pw.println( "</gml:patches>" );
pw.print( "</gml:Surface>" );
}
/**
* @param surface
* @param pw
* @param patch
*/
private static void printInteriorRing( Surface surface, PrintWriter pw, SurfacePatch patch ) {
// interior rings
Position[][] ip = patch.getInteriorRings();
if ( ip != null ) {
for ( int j = 0; j < ip.length; j++ ) {
pw.println( "<gml:interior>" );
pw.println( "<gml:LinearRing>" );
pw.print( "<gml:posList>" );
for ( int k = 0; k < ( ip[k].length - 1 ); k++ ) {
pw.print( ip[j][k].getX() + " " + ip[j][k].getY() );
if ( surface.getCoordinateDimension() == 3 ) {
pw.print( " " + ip[j][k].getZ() + " " );
} else {
pw.print( " " );
}
}
pw.print( ip[j][ip[j].length - 1].getX() + " " + ip[j][ip[j].length - 1].getY() );
if ( surface.getCoordinateDimension() == 3 ) {
pw.print( " " + ip[j][ip[j].length - 1].getZ() );
}
pw.println( "</gml:posList>" );
pw.println( "</gml:LinearRing>" );
pw.println( "</gml:interior>" );
}
}
}
/**
* @param surface
* @param pw
* @param patch
*/
private static void printExteriorRing( Surface surface, PrintWriter pw, SurfacePatch patch ) {
// exterior ring
pw.println( "<gml:exterior>" );
pw.println( "<gml:LinearRing>" );
pw.println( "<gml:posList>" );
Position[] p = patch.getExteriorRing();
for ( int j = 0; j < ( p.length - 1 ); j++ ) {
pw.print( p[j].getX() + " " + p[j].getY() );
if ( surface.getCoordinateDimension() == 3 ) {
pw.print( " " + p[j].getZ() + " " );
} else {
pw.print( ' ' );
}
}
pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
if ( surface.getCoordinateDimension() == 3 ) {
pw.print( " " + p[p.length - 1].getZ() );
}
pw.println( "</gml:posList>" );
pw.println( "</gml:LinearRing>" );
pw.println( "</gml:exterior>" );
}
/**
* @param mp
* @return
* @throws RemoteException
*/
private static void exportMultiPoint( MultiPoint mp, PrintWriter pw ) {
String crs = null;
if ( mp.getCoordinateSystem() != null ) {
crs = mp.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:MultiPoint srsName=\"" + crs + "\">";
} else {
srs = "<gml:MultiPoint>";
}
pw.println( srs );
pw.println( "<gml:pointMembers>" );
for ( int i = 0; i < mp.getSize(); i++ ) {
pw.println( "<gml:Point>" );
pw.print( "<gml:pos>" );
pw.print( mp.getPointAt( i ).getX() + " " + mp.getPointAt( i ).getY() );
if ( mp.getPointAt( i ).getCoordinateDimension() == 3 ) {
pw.print( " " + mp.getPointAt( i ).getZ() );
}
pw.println( "</gml:pos>" );
pw.println( "</gml:Point>" );
}
pw.println( "</gml:pointMembers>" );
pw.print( "</gml:MultiPoint>" );
}
/**
* @param multiCurve
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static void exportMultiCurve( MultiCurve multiCurve, PrintWriter pw )
throws GeometryException {
String crs = null;
if ( multiCurve.getCoordinateSystem() != null ) {
crs = multiCurve.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:MultiCurve srsName=\"" + crs + "\">";
} else {
srs = "<gml:MultiCurve>";
}
pw.println( srs );
Curve[] curves = multiCurve.getAllCurves();
pw.println( "<gml:curveMembers>" );
for ( int i = 0; i < curves.length; i++ ) {
Curve curve = curves[i];
pw.println( "<gml:Curve>" );
pw.println( "<gml:segments>" );
pw.println( "<gml:LineStringSegment>" );
int numberCurveSegments = curve.getNumberOfCurveSegments();
for ( int j = 0; j < numberCurveSegments; j++ ) {
CurveSegment curveSegment = curve.getCurveSegmentAt( j );
Position[] p = curveSegment.getAsLineString().getPositions();
pw.print( "<gml:posList>" );
for ( int k = 0; k < ( p.length - 1 ); k++ ) {
pw.print( p[k].getX() + " " + p[k].getY() );
if ( curve.getCoordinateDimension() == 3 ) {
pw.print( " " + p[k].getZ() + " " );
} else {
pw.print( " " );
}
}
pw.print( p[p.length - 1].getX() + " " + p[p.length - 1].getY() );
if ( curve.getCoordinateDimension() == 3 ) {
pw.print( " " + p[p.length - 1].getZ() );
}
pw.println( "</gml:posList>" );
}
pw.println( "</gml:LineStringSegment>" );
pw.println( "</gml:segments>" );
pw.println( "</gml:Curve>" );
}
pw.println( "</gml:curveMembers>" );
pw.print( "</gml:MultiCurve>" );
}
/**
* @param multiSurface
* @return
* @throws RemoteException
* @throws GeometryException
*/
private static void exportMultiSurface( MultiSurface multiSurface, PrintWriter pw )
throws GeometryException {
String crs = null;
if ( multiSurface.getCoordinateSystem() != null ) {
crs = multiSurface.getCoordinateSystem().getName().replace( ' ', ':' );
}
String srs = null;
if ( crs != null ) {
srs = "<gml:MultiSurface srsName=\"" + crs + "\">";
} else {
srs = "<gml:MultiSurface>";
}
pw.println( srs );
Surface[] surfaces = multiSurface.getAllSurfaces();
pw.println( "<gml:surfaceMembers>" );
for ( int i = 0; i < surfaces.length; i++ ) {
Surface surface = surfaces[i];
pw.println( "<gml:Surface>" );
pw.println( "<gml:patches>" );
pw.println( "<gml:Polygon>" );
int numberSurfaces = surface.getNumberOfSurfacePatches();
for ( int j = 0; j < numberSurfaces; j++ ) {
SurfacePatch surfacePatch = surface.getSurfacePatchAt( j );
printExteriorRing( surface, pw, surfacePatch );
printInteriorRing( surface, pw, surfacePatch );
}
pw.println( "</gml:Polygon>" );
pw.println( "</gml:patches>" );
pw.println( "</gml:Surface>" );
}
pw.println( "</gml:surfaceMembers>" );
pw.print( "</gml:MultiSurface>" );
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to:
* $Log: GMLGeometryAdapter.java,v $
* Revision 1.40 2006/11/27 09:07:51 poth
* JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
*
* Revision 1.39 2006/11/13 21:24:42 poth
* bug fix - wraping MultiSurfaces
*
* Revision 1.38 2006/09/27 16:47:50 poth
* bug fix parsing poslist
* Changes to this class. What the people have been up to:
* Revision 1.37 2006/08/08 09:14:54 poth
* wrapCompositeSurface( Element ) marked as unsupported operation / never read variable removed
* Changes to this class. What the people have been up to:
* Revision 1.36 2006/05/15 10:09:02 mschneider
* Renamed Position.getDimension() to Position.getCoordinateDimension() for consistency.
* Changes to this class. What the people have been up to:
* Revision 1.35 2006/05/03 17:26:26 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.34 2006/05/01 20:15:25 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.33 2006/04/26 13:34:09 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.32 2006/04/06 20:25:21 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.31 2006/03/30 21:20:23 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.30 2006/03/28 13:40:55 mschneider
* Changed delimiters in Pos / PosList elements. Now all whitespaces can act as delimiters.
* Changes to this class. What the people have been up to:
* Revision 1.29 2006/03/07 21:40:20 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.28 2006/01/25 10:42:02 poth
* *** empty log message ***
* Changes to this class. What the people have been up to:
* Revision 1.27 2006/01/06 16:06:34 deshmukh
* New Service WMPS handling PrintMap requests
* Changes
* to this class. What the people have been up to: Revision 1.26 2005/12/18 19:06:30 poth Changes to
* this class. What the people have been up to: no message Changes to this class. What the people
* have been up to: Revision 1.25 2005/12/05
* 09:25:17 deshmukh *** empty log message
* *** Changes to this class. What the
* people have been up to: Revision 1.24 2005/12/01 14:18:37 deshmukh Changes to this class. What
* the people have been up to: TODO fixed Changes to this class. What the people have been up to:
* Revision 1.23 2005/12/01 13:33:32
* deshmukh Modified Polygon wrapping
* functionality to support GML3.1 Changes
* to this class. What the people have been up to: Revision 1.21 2005/12/01 10:34:59 deshmukh
* *** empty log message *** Changes to this
* class. What the people have been up to: Changes to this class. What the people have been up to:
* Revision 1.20 2005/12/01 09:09:55 deshmukh Changes to this class. What the people have been up
* to: *** empty log message *** Changes to
* this class. What the people have been up to: Revision 1.19 2005/11/30 08:20:38 deshmukh Changes
* to this class. What the people have been up to: *** empty log message *** Changes to this class.
* What the people have been up to: Revision
* 1.18 2005/11/29 17:17:26 deshmukh ***
* empty log message *** Changes to this
* class. What the people have been up to: Revision 1.17 2005/11/25 14:14:36 deshmukh Changes to
* this class. What the people have been up to: *** empty log message *** Changes to this class.
* What the people have been up to: Revision
* 1.16 2005/11/25 07:48:00 deshmukh Changes to this class. What the people have been up to:
* wrapCurveAsCurve, wrapSurfaceAsSurface method implementation added Changes to this class. What
* the people have been up to: Revision 1.15
* 2005/11/17 08:18:35 deshmukh Renamed
* nsNode to nsContext Changes to this
* class. What the people have been up to: Revision 1.14 2005/11/16 13:45:01 mschneider Changes to
* this class. What the people have been up to: Merge of wfs development branch. Changes to this
* class. What the people have been up to: Changes to this class. What the people have been up to:
* Revision 1.13.2.2 2005/11/07 16:22:23 mschneider Changes to this class. What the people have been
* up to: Switch from NodeList to List. Changes to this class. What the people have been up to:
* Revision 1.13.2.1 2005/11/07 15:38:04
* mschneider Refactoring: use
* NamespaceContext instead of Node for namespace bindings. Changes to this class. What the people
* have been up to: Revision 1.13 2005/10/20 19:03:10 poth no message
*
* Revision 1.12 2005/09/27 19:53:18 poth no message
*
* Revision 1.11 2005/08/05 09:42:20 poth no message
*
* Revision 1.10 2005/04/06 13:44:06 poth no message
*
* Revision 1.9 2005/03/09 11:55:46 mschneider ** empty log message ***
*
* Revision 1.8 2005/03/01 14:39:08 mschneider ** empty log message ***
*
* Revision 1.7 2005/02/14 11:31:48 ncho bug fixes by AP [SN]
*
* Revision 1.6 2005/01/30 22:22:02 poth no message
*
* Revision 1.5 2005/01/19 17:22:26 poth no message
*
* Revision 1.4 2005/01/18 22:08:54 poth no message
*
* Revision 1.3 2005/01/16 22:30:33 poth no message
*
* Revision 1.2 2005/01/06 17:51:46 poth no message
*
* Revision 1.6 2004/08/24 07:31:33 ap no message
*
* Revision 1.5 2004/07/16 10:24:00 ap no message
*
* Revision 1.4 2004/07/14 06:52:48 ap no message
*
* Revision 1.3 2004/07/13 06:12:53 ap no message
*
* Revision 1.2 2004/07/12 14:25:35 ap no message
*
* Revision 1.1 2004/07/12 14:21:25 ap no message
*
*
**************************************************************************************************/