001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/xml/GeometryUtils.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53177 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.framework.xml; 044 045 import java.util.List; 046 047 import org.deegree.framework.util.StringTools; 048 import org.deegree.model.crs.GeoTransformer; 049 import org.deegree.model.spatialschema.Envelope; 050 import org.deegree.model.spatialschema.GMLGeometryAdapter; 051 import org.deegree.model.spatialschema.Geometry; 052 import org.deegree.model.spatialschema.MultiSurface; 053 import org.deegree.model.spatialschema.Point; 054 import org.deegree.model.spatialschema.Position; 055 import org.deegree.model.spatialschema.Ring; 056 import org.deegree.model.spatialschema.Surface; 057 import org.deegree.ogcbase.CommonNamespaces; 058 import org.w3c.dom.Element; 059 import org.w3c.dom.Node; 060 061 /** 062 * Utility methods for handling geometries within XSLT transformations 063 * 064 * 065 * @version $Revision: 9339 $ 066 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 067 * @author last edited by: $Author: apoth $ 068 * 069 * @version 1.0. $Revision: 9339 $, $Date: 2007-12-27 13:31:52 +0100 (Do, 27 Dez 2007) $ 070 * 071 * @since 2.0 072 */ 073 public class GeometryUtils { 074 075 private static NamespaceContext nsc = CommonNamespaces.getNamespaceContext(); 076 077 /** 078 * 079 * @param node 080 * @return 081 */ 082 public static String getPolygonCoordinatesFromEnvelope( Node node ) { 083 StringBuffer sb = new StringBuffer( 500 ); 084 try { 085 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null ); 086 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ).append( 087 ' ' ); 088 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMax().getY() ).append( 089 ' ' ); 090 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMax().getY() ).append( 091 ' ' ); 092 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMin().getY() ).append( 093 ' ' ); 094 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ); 095 } catch ( Exception e ) { 096 e.printStackTrace(); 097 sb.append( StringTools.stackTraceToString( e ) ); 098 } 099 return sb.toString(); 100 } 101 102 /** 103 * 104 * @param node 105 * @return 106 */ 107 public static String getEnvelopeFromGeometry( Node node ) { 108 StringBuffer sb = new StringBuffer( 500 ); 109 try { 110 Envelope env = GMLGeometryAdapter.wrap( (Element) node, null ).getEnvelope(); 111 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ).append( 112 ' ' ); 113 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMax().getY() ).append( 114 ' ' ); 115 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMax().getY() ).append( 116 ' ' ); 117 sb.append( env.getMax().getX() ).append( ',' ).append( env.getMin().getY() ).append( 118 ' ' ); 119 sb.append( env.getMin().getX() ).append( ',' ).append( env.getMin().getY() ); 120 } catch ( Exception e ) { 121 e.printStackTrace(); 122 sb.append( StringTools.stackTraceToString( e ) ); 123 } 124 return sb.toString(); 125 } 126 127 /** 128 * returns the coordinates of the out ring of a polygon as comma seperated 129 * list. The coordinate tuples are seperated by a blank. If required the 130 * polygon will first transformed to the target CRS 131 * 132 * @param node 133 * @param sourceCRS 134 * @param targetCRS 135 * @return 136 */ 137 public static String getPolygonOuterRing( Node node, String sourceCRS, String targetCRS ) { 138 StringBuffer coords = new StringBuffer( 10000 ); 139 140 try { 141 Surface surface = (Surface) GMLGeometryAdapter.wrap( (Element) node, sourceCRS ); 142 if ( !targetCRS.equals( sourceCRS ) ) { 143 GeoTransformer gt = new GeoTransformer( targetCRS ); 144 surface = (Surface) gt.transform( surface ); 145 } 146 Position[] pos = surface.getSurfaceBoundary().getExteriorRing().getPositions(); 147 int dim = pos[0].getCoordinateDimension(); 148 for ( int i = 0; i < pos.length; i++ ) { 149 coords.append( pos[i].getX() ).append( ',' ).append( pos[i].getY() ); 150 if ( dim == 3 ) { 151 coords.append( ',' ).append( pos[i].getZ() ); 152 } 153 coords.append( ' ' ); 154 } 155 } catch ( Exception e ) { 156 e.printStackTrace(); 157 } 158 159 return coords.toString(); 160 } 161 162 /** 163 * 164 * @param node 165 * @param index 166 * @param sourceCRS 167 * @param targetCRS 168 * @return 169 */ 170 public static String getPolygonInnerRing( Node node, int index, String sourceCRS, 171 String targetCRS ) { 172 StringBuffer coords = new StringBuffer( 10000 ); 173 174 if ( "Polygon".equals( node.getLocalName() ) || 175 "Surface".equals( node.getLocalName() ) ) { 176 try { 177 Surface surface = (Surface) GMLGeometryAdapter.wrap( (Element) node, sourceCRS ); 178 if ( !targetCRS.equals( sourceCRS ) ) { 179 GeoTransformer gt = new GeoTransformer( targetCRS ); 180 surface = (Surface) gt.transform( surface ); 181 } 182 Position[] pos = surface.getSurfaceBoundary().getInteriorRings()[index-1].getPositions(); 183 int dim = pos[0].getCoordinateDimension(); 184 for ( int i = 0; i < pos.length; i++ ) { 185 coords.append( pos[i].getX() ).append( ',' ).append( pos[i].getY() ); 186 if ( dim == 3 ) { 187 coords.append( ',' ).append( pos[i].getZ() ); 188 } 189 coords.append( ' ' ); 190 } 191 } catch ( Exception e ) { 192 e.printStackTrace(); 193 } 194 } 195 return coords.toString(); 196 } 197 198 /** 199 * 200 * @param node 201 * @return 202 */ 203 public static double calcArea( Node node ) { 204 double area = -1; 205 try { 206 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null ); 207 if ( geom instanceof Surface ) { 208 area = ( (Surface) geom ).getArea(); 209 } else if ( geom instanceof MultiSurface ) { 210 area = ( (MultiSurface) geom ).getArea(); 211 } 212 } catch ( Exception e ) { 213 e.printStackTrace(); 214 } 215 return area; 216 } 217 218 /** 219 * 220 * @param node 221 * @return 222 */ 223 public static double calcOuterBoundaryLength( Node node ) { 224 double length = 0; 225 try { 226 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null ); 227 if ( geom instanceof Surface ) { 228 Ring ring = ( (Surface) geom ).getSurfaceBoundary().getExteriorRing(); 229 length = ring.getAsCurveSegment().getLength(); 230 } else if ( geom instanceof MultiSurface ) { 231 MultiSurface ms =( (MultiSurface) geom ); 232 for ( int i = 0; i < ms.getSize(); i++ ) { 233 Ring ring = ms.getSurfaceAt( i ).getSurfaceBoundary().getExteriorRing(); 234 length += ring.getAsCurveSegment().getLength(); 235 } 236 } 237 } catch ( Exception e ) { 238 e.printStackTrace(); 239 } 240 return length; 241 } 242 243 244 /** 245 * returns the centroid X coordinate of the geometry represented by the 246 * passed Node 247 * 248 * @param node 249 * @param targetCRS 250 * @return 251 */ 252 public static double getCentroidX( Node node, String targetCRS ) { 253 if ( node != null ) { 254 Point point = null; 255 try { 256 if ( "Envelope".equals( node.getLocalName() ) ) { 257 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null ); 258 point = env.getCentroid(); 259 } else { 260 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null ); 261 point = geom.getCentroid(); 262 } 263 GeoTransformer gt = new GeoTransformer( targetCRS ); 264 point = (Point) gt.transform( point ); 265 } catch ( Exception e ) { 266 e.printStackTrace(); 267 } 268 269 return point.getX(); 270 } 271 return -1; 272 } 273 274 /** 275 * returns the centroid Y coordinate of the geometry represented by the 276 * passed Node 277 * 278 * @param node 279 * @param targetCRS 280 * @return 281 */ 282 public static double getCentroidY( Node node, String targetCRS ) { 283 if ( node != null ) { 284 Point point = null; 285 try { 286 if ( "Envelope".equals( node.getLocalName() ) ) { 287 Envelope env = GMLGeometryAdapter.wrapBox( (Element) node, null ); 288 point = env.getCentroid(); 289 } else { 290 Geometry geom = GMLGeometryAdapter.wrap( (Element) node, null ); 291 point = geom.getCentroid(); 292 } 293 GeoTransformer gt = new GeoTransformer( targetCRS ); 294 point = (Point) gt.transform( point ); 295 } catch ( Exception e ) { 296 e.printStackTrace(); 297 } 298 return point.getY(); 299 } 300 return -1; 301 } 302 303 public static String getCurveCoordinates(Node node) { 304 StringBuffer sb = new StringBuffer(10000); 305 try { 306 List<Node> list = XMLTools.getNodes( node, ".//gml:posList | gml:pos | gml:coordinates", nsc ); 307 for ( Node node2 : list ) { 308 String s = XMLTools.getStringValue( node2 ).trim(); 309 if ( node2.getLocalName().equals( "posList" ) ) { 310 String[] sl = StringTools.toArray( s, " ", false ); 311 int dim = XMLTools.getNodeAsInt( node2, "./@srsDimension", nsc, 2 ); 312 for ( int i = 0; i < sl.length; i++ ) { 313 sb.append( sl[i] ); 314 if ( (i+1) % dim == 0 ) { 315 sb.append( ' ' ); 316 } else { 317 sb.append( ',' ); 318 } 319 } 320 } else if ( node2.getLocalName().equals( "pos" ) ) { 321 String[] sl = StringTools.toArray( s, "\t\n\r\f ,", false ); 322 for ( int i = 0; i < sl.length; i++ ) { 323 sb.append( sl[i] ); 324 if ( i < sl.length-1) { 325 sb.append( ',' ); 326 } else { 327 sb.append( ' ' ); 328 } 329 } 330 } else if ( node2.getLocalName().equals( "coordinates" ) ) { 331 sb.append( s ); 332 } 333 } 334 } catch ( XMLParsingException e ) { 335 e.printStackTrace(); 336 } 337 return sb.toString(); 338 } 339 340 }